summaryrefslogtreecommitdiff
path: root/packages/integrations/markdoc/src
diff options
context:
space:
mode:
authorGravatar Bjorn Lu <bjornlu.dev@gmail.com> 2024-09-26 14:59:39 +0100
committerGravatar GitHub <noreply@github.com> 2024-09-26 14:59:39 +0100
commita19530e377b7d7afad58a33b23c0a5df1c376819 (patch)
tree40eb6c305f2daec6bf2d5ef41eaba05f1e8dd8d9 /packages/integrations/markdoc/src
parentacf264d8c003718cda5a0b9ce5fb7ac1cd6641b6 (diff)
downloadastro-a19530e377b7d7afad58a33b23c0a5df1c376819.tar.gz
astro-a19530e377b7d7afad58a33b23c0a5df1c376819.tar.zst
astro-a19530e377b7d7afad58a33b23c0a5df1c376819.zip
Parse frontmatter ourselves (#12075)
Diffstat (limited to 'packages/integrations/markdoc/src')
-rw-r--r--packages/integrations/markdoc/src/content-entry-type.ts43
1 files changed, 17 insertions, 26 deletions
diff --git a/packages/integrations/markdoc/src/content-entry-type.ts b/packages/integrations/markdoc/src/content-entry-type.ts
index 303251d66..67a8be531 100644
--- a/packages/integrations/markdoc/src/content-entry-type.ts
+++ b/packages/integrations/markdoc/src/content-entry-type.ts
@@ -1,11 +1,11 @@
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
+import { parseFrontmatter } from '@astrojs/markdown-remark';
import type { Config as MarkdocConfig, Node } from '@markdoc/markdoc';
import Markdoc from '@markdoc/markdoc';
import type { AstroConfig, ContentEntryType } from 'astro';
import { emitESMImage } from 'astro/assets/utils';
-import matter from 'gray-matter';
import type { Rollup, ErrorPayload as ViteErrorPayload } from 'vite';
import type { ComponentConfig } from './config.js';
import { htmlTokenTransform } from './html/transform/html-token-transform.js';
@@ -26,12 +26,20 @@ export async function getContentEntryType({
}): Promise<ContentEntryType> {
return {
extensions: ['.mdoc'],
- getEntryInfo,
+ getEntryInfo({ fileUrl, contents }) {
+ const parsed = safeParseFrontmatter(contents, fileURLToPath(fileUrl));
+ return {
+ data: parsed.frontmatter,
+ body: parsed.content.trim(),
+ slug: parsed.frontmatter.slug,
+ rawData: parsed.rawFrontmatter,
+ };
+ },
handlePropagation: true,
async getRenderModule({ contents, fileUrl, viteId }) {
- const entry = getEntryInfo({ contents, fileUrl });
+ const parsed = safeParseFrontmatter(contents, fileURLToPath(fileUrl));
const tokenizer = getMarkdocTokenizer(options);
- let tokens = tokenizer.tokenize(entry.body);
+ let tokens = tokenizer.tokenize(parsed.content);
if (options?.allowHTML) {
tokens = htmlTokenTransform(tokenizer, tokens);
@@ -47,7 +55,6 @@ export async function getContentEntryType({
ast,
/* Raised generics issue with Markdoc core https://github.com/markdoc/markdoc/discussions/400 */
markdocConfig: markdocConfig as MarkdocConfig,
- entry,
viteId,
astroConfig,
filePath,
@@ -64,7 +71,6 @@ export async function getContentEntryType({
raiseValidationErrors({
ast: partialAst,
markdocConfig: markdocConfig as MarkdocConfig,
- entry,
viteId,
astroConfig,
filePath: partialPath,
@@ -224,14 +230,12 @@ async function resolvePartials({
function raiseValidationErrors({
ast,
markdocConfig,
- entry,
viteId,
astroConfig,
filePath,
}: {
ast: Node;
markdocConfig: MarkdocConfig;
- entry: ReturnType<typeof getEntryInfo>;
viteId: string;
astroConfig: AstroConfig;
filePath: string;
@@ -250,8 +254,6 @@ function raiseValidationErrors({
});
if (validationErrors.length) {
- // Heuristic: take number of newlines for `rawData` and add 2 for the `---` fences
- const frontmatterBlockOffset = entry.rawData.split('\n').length + 2;
const rootRelativePath = path.relative(fileURLToPath(astroConfig.root), filePath);
throw new MarkdocError({
message: [
@@ -261,7 +263,7 @@ function raiseValidationErrors({
location: {
// Error overlay does not support multi-line or ranges.
// Just point to the first line.
- line: frontmatterBlockOffset + validationErrors[0].lines[0],
+ line: validationErrors[0].lines[0],
file: viteId,
},
});
@@ -282,16 +284,6 @@ function getUsedTags(markdocAst: Node) {
return tags;
}
-function getEntryInfo({ fileUrl, contents }: { fileUrl: URL; contents: string }) {
- const parsed = parseFrontmatter(contents, fileURLToPath(fileUrl));
- return {
- data: parsed.data,
- body: parsed.content,
- slug: parsed.data.slug,
- rawData: parsed.matter,
- };
-}
-
/**
* Emits optimized images, and appends the generated `src` to each AST node
* via the `__optimizedSrc` attribute.
@@ -410,12 +402,11 @@ function getStringifiedMap(
* Match YAML exception handling from Astro core errors
* @see 'astro/src/core/errors.ts'
*/
-function parseFrontmatter(fileContents: string, filePath: string) {
+function safeParseFrontmatter(fileContents: string, filePath: string) {
try {
- // `matter` is empty string on cache results
- // clear cache to prevent this
- (matter as any).clearCache();
- return matter(fileContents);
+ // empty with lines to preserve sourcemap location, but not `empty-with-spaces`
+ // because markdoc struggles with spaces
+ return parseFrontmatter(fileContents, { frontmatter: 'empty-with-lines' });
} catch (e: any) {
if (e.name === 'YAMLException') {
const err: Error & ViteErrorPayload['err'] = e;