diff --git a/src/generators/ast/generate.mjs b/src/generators/ast/generate.mjs index eed01d42..97724e03 100644 --- a/src/generators/ast/generate.mjs +++ b/src/generators/ast/generate.mjs @@ -27,10 +27,15 @@ export async function processChunk(inputSlice, itemIndices) { for (const [path, parent] of filePaths) { const content = await readFile(path, 'utf-8'); - const value = content.replace( - QUERIES.stabilityIndexPrefix, - match => `[${match}](${STABILITY_INDEX_URL})` - ); + const value = content + .replace( + QUERIES.standardYamlFrontmatter, + (_, yaml) => '\n' + ) + .replace( + QUERIES.stabilityIndexPrefix, + match => `[${match}](${STABILITY_INDEX_URL})` + ); const relativePath = sep + withExt(relative(parent, path)); diff --git a/src/utils/queries/__tests__/index.test.mjs b/src/utils/queries/__tests__/index.test.mjs index c7adf4ad..4bf4a840 100644 --- a/src/utils/queries/__tests__/index.test.mjs +++ b/src/utils/queries/__tests__/index.test.mjs @@ -1,9 +1,39 @@ -import { strictEqual } from 'node:assert'; +import { strictEqual, ok } from 'node:assert'; import { describe, it } from 'node:test'; import { u as createTree } from 'unist-builder'; -import { UNIST } from '../index.mjs'; +import { QUERIES, UNIST } from '../index.mjs'; + +describe('QUERIES', () => { + describe('standardYamlFrontmatter', () => { + it('matches standard YAML frontmatter at the beginning of the text', () => { + const content = '---\nintroduced_in: v1.0.0\ntype: module\n---'; + ok(QUERIES.standardYamlFrontmatter.test(content)); + + const match = QUERIES.standardYamlFrontmatter.exec(content); + strictEqual(match[1], 'introduced_in: v1.0.0\ntype: module'); + }); + + it('matches standard YAML frontmatter with Windows line endings (CRLF)', () => { + const content = '---\r\nintroduced_in: v1.0.0\r\n---'; + ok(QUERIES.standardYamlFrontmatter.test(content)); + + const match = QUERIES.standardYamlFrontmatter.exec(content); + strictEqual(match[1], 'introduced_in: v1.0.0'); + }); + + it('does not match horizontal rules or dashes not at the start of the string', () => { + const content = '# Hello\n\n---\n\nSome text'; + strictEqual(QUERIES.standardYamlFrontmatter.test(content), false); + }); + + it('does not match unclosed frontmatter blocks', () => { + const content = '---\nintroduced_in: v1.0.0\nSome text...'; + strictEqual(QUERIES.standardYamlFrontmatter.test(content), false); + }); + }); +}); describe('UNIST', () => { describe('isStronglyTypedList', () => { diff --git a/src/utils/queries/index.mjs b/src/utils/queries/index.mjs index 9bccb448..cd120347 100644 --- a/src/utils/queries/index.mjs +++ b/src/utils/queries/index.mjs @@ -18,6 +18,8 @@ export const QUERIES = { stabilityIndexPrefix: /Stability: ([0-5](?:\.[0-3])?)/, // ReGeX for retrieving the inner content from a YAML block yamlInnerContent: /^/, + // ReGeX for standard Markdown YAML frontmatter + standardYamlFrontmatter: /^---\r?\n([\s\S]*?)\r?\n---/, // ReGeX for finding references to Unix manuals unixManualPage: /\b([a-z.]+)\((\d)([a-z]?)\)/g, // ReGeX for determing a typed list's non-property names