mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-02-04 07:13:25 +08:00
build(docs): add auto-generated header after YAML
Add the auto-generated header after any YAML front-matter blocks. YAML front-matter is normally only valid in Markdown when it's at the beginning of the Markdown file. GitHub/Vitepress may otherwise render it incorrectly.
This commit is contained in:
parent
8f4caa4537
commit
2f1a521db6
@ -199,17 +199,32 @@ const transformIncludeStatements = (file: string, text: string): string => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Options for {@link transformMarkdownAst} */
|
||||||
|
interface TransformMarkdownAstOptions {
|
||||||
|
/**
|
||||||
|
* Used to indicate the original/source file.
|
||||||
|
*/
|
||||||
|
originalFilename: string;
|
||||||
|
/** If `true`, add a warning that the file is autogenerated */
|
||||||
|
addAutogeneratedWarning?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remark plugin that transforms code blocks in a Markdown file.
|
* Remark plugin that transforms mermaid repo markdown to Vitepress/GFM markdown.
|
||||||
*
|
*
|
||||||
* For any AST node that is a code block: transform it as needed:
|
* For any AST node that is a code block: transform it as needed:
|
||||||
* - blocks marked as MERMAID_DIAGRAM_ONLY will be set to a 'mermaid' code block so it will be rendered as (only) a diagram
|
* - blocks marked as MERMAID_DIAGRAM_ONLY will be set to a 'mermaid' code block so it will be rendered as (only) a diagram
|
||||||
* - blocks marked as MERMAID_EXAMPLE_KEYWORDS will be copied and the original node will be a code only block and the copy with be rendered as the diagram
|
* - blocks marked as MERMAID_EXAMPLE_KEYWORDS will be copied and the original node will be a code only block and the copy with be rendered as the diagram
|
||||||
* - blocks marked as BLOCK_QUOTE_KEYWORDS will be transformed into block quotes
|
* - blocks marked as BLOCK_QUOTE_KEYWORDS will be transformed into block quotes
|
||||||
*
|
*
|
||||||
|
* If `addAutogeneratedWarning` is `true`, generates a header stating that this file is autogenerated.
|
||||||
|
*
|
||||||
* @returns plugin function for Remark
|
* @returns plugin function for Remark
|
||||||
*/
|
*/
|
||||||
export function transformMarkdownAst() {
|
export function transformMarkdownAst({
|
||||||
|
originalFilename,
|
||||||
|
addAutogeneratedWarning,
|
||||||
|
}: TransformMarkdownAstOptions) {
|
||||||
return (tree: Root, _file?: any): Root => {
|
return (tree: Root, _file?: any): Root => {
|
||||||
const astWithTransformedBlocks = flatmap(tree, (node: Code) => {
|
const astWithTransformedBlocks = flatmap(tree, (node: Code) => {
|
||||||
if (node.type !== 'code' || !node.lang) {
|
if (node.type !== 'code' || !node.lang) {
|
||||||
@ -236,6 +251,17 @@ export function transformMarkdownAst() {
|
|||||||
return [node]; // default is to do nothing to the node
|
return [node]; // default is to do nothing to the node
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (addAutogeneratedWarning) {
|
||||||
|
// Add the header to the start of the file
|
||||||
|
const headerNode = remark.parse(generateHeader(originalFilename)).children[0];
|
||||||
|
if (astWithTransformedBlocks.children[0].type === 'yaml') {
|
||||||
|
// insert header after the YAML frontmatter if it exists
|
||||||
|
astWithTransformedBlocks.children.splice(1, 0, headerNode);
|
||||||
|
} else {
|
||||||
|
astWithTransformedBlocks.children.unshift(headerNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return astWithTransformedBlocks;
|
return astWithTransformedBlocks;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -260,13 +286,9 @@ const transformMarkdown = (file: string) => {
|
|||||||
let transformed = remark()
|
let transformed = remark()
|
||||||
.use(remarkGfm)
|
.use(remarkGfm)
|
||||||
.use(remarkFrontmatter, ['yaml']) // support YAML front-matter in Markdown
|
.use(remarkFrontmatter, ['yaml']) // support YAML front-matter in Markdown
|
||||||
.use(transformMarkdownAst) // mermaid project specific plugin
|
.use(transformMarkdownAst, { originalFilename: file, addAutogeneratedWarning: !noHeader }) // mermaid project specific plugin
|
||||||
.processSync(doc).toString();
|
.processSync(doc)
|
||||||
|
.toString();
|
||||||
if (!noHeader) {
|
|
||||||
// Add the header to the start of the file
|
|
||||||
transformed = `${generateHeader(file)}\n${transformed}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vitepress && file === 'src/docs/index.md') {
|
if (vitepress && file === 'src/docs/index.md') {
|
||||||
// Skip transforming index if vitepress is enabled
|
// Skip transforming index if vitepress is enabled
|
||||||
|
@ -7,13 +7,15 @@ afterEach(() => {
|
|||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const originalFilename = 'example-input-filename.md';
|
||||||
|
|
||||||
describe('docs.mts', () => {
|
describe('docs.mts', () => {
|
||||||
describe('transformMarkdownAst', () => {
|
describe('transformMarkdownAst', () => {
|
||||||
describe('checks each AST node', () => {
|
describe('checks each AST node', () => {
|
||||||
it('does no transformation if there are no code blocks', async () => {
|
it('does no transformation if there are no code blocks', async () => {
|
||||||
const contents = 'Markdown file contents\n';
|
const contents = 'Markdown file contents\n';
|
||||||
const result = (
|
const result = (
|
||||||
await remarkBuilder().use(transformMarkdownAst).process(contents)
|
await remarkBuilder().use(transformMarkdownAst, { originalFilename }).process(contents)
|
||||||
).toString();
|
).toString();
|
||||||
expect(result).toEqual(contents);
|
expect(result).toEqual(contents);
|
||||||
});
|
});
|
||||||
@ -28,7 +30,9 @@ describe('docs.mts', () => {
|
|||||||
|
|
||||||
it('changes the language to "mermaid"', async () => {
|
it('changes the language to "mermaid"', async () => {
|
||||||
const result = (
|
const result = (
|
||||||
await remarkBuilder().use(transformMarkdownAst).process(contents)
|
await remarkBuilder()
|
||||||
|
.use(transformMarkdownAst, { originalFilename })
|
||||||
|
.process(contents)
|
||||||
).toString();
|
).toString();
|
||||||
expect(result).toEqual(
|
expect(result).toEqual(
|
||||||
beforeCodeLine + '\n' + '```' + 'mermaid' + '\n' + diagram_text + '\n```\n'
|
beforeCodeLine + '\n' + '```' + 'mermaid' + '\n' + diagram_text + '\n```\n'
|
||||||
@ -45,7 +49,9 @@ describe('docs.mts', () => {
|
|||||||
|
|
||||||
it('changes the language to "mermaid-example" and adds a copy of the code block with language = "mermaid"', async () => {
|
it('changes the language to "mermaid-example" and adds a copy of the code block with language = "mermaid"', async () => {
|
||||||
const result = (
|
const result = (
|
||||||
await remarkBuilder().use(transformMarkdownAst).process(contents)
|
await remarkBuilder()
|
||||||
|
.use(transformMarkdownAst, { originalFilename })
|
||||||
|
.process(contents)
|
||||||
).toString();
|
).toString();
|
||||||
expect(result).toEqual(
|
expect(result).toEqual(
|
||||||
beforeCodeLine +
|
beforeCodeLine +
|
||||||
@ -67,7 +73,7 @@ describe('docs.mts', () => {
|
|||||||
beforeCodeLine + '```' + lang_keyword + '\n' + 'This is the text\n' + '```\n';
|
beforeCodeLine + '```' + lang_keyword + '\n' + 'This is the text\n' + '```\n';
|
||||||
|
|
||||||
const result = (
|
const result = (
|
||||||
await remarkBuilder().use(transformMarkdownAst).process(contents)
|
await remarkBuilder().use(transformMarkdownAst, { originalFilename }).process(contents)
|
||||||
).toString();
|
).toString();
|
||||||
expect(result).toEqual(beforeCodeLine + '\n> **Note**\n' + '> This is the text\n');
|
expect(result).toEqual(beforeCodeLine + '\n> **Note**\n' + '> This is the text\n');
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user