diff --git a/packages/mermaid/src/docs.mts b/packages/mermaid/src/docs.mts index 356cd3cd1..f62c44f07 100644 --- a/packages/mermaid/src/docs.mts +++ b/packages/mermaid/src/docs.mts @@ -30,11 +30,20 @@ * @todo Write a test file for this. (Will need to be able to deal .mts file. Jest has trouble with * it.) */ +// @ts-ignore: we're importing internal jsonschema2md functions +import { default as schemaLoader } from '@adobe/jsonschema2md/lib/schemaProxy.js'; +// @ts-ignore: we're importing internal jsonschema2md functions +import { default as traverseSchemas } from '@adobe/jsonschema2md/lib/traverseSchema.js'; +// @ts-ignore: we're importing internal jsonschema2md functions +import { default as buildMarkdownFromSchema } from '@adobe/jsonschema2md/lib/markdownBuilder.js'; +// @ts-ignore: we're importing internal jsonschema2md functions +import { default as jsonSchemaReadmeBuilder } from '@adobe/jsonschema2md/lib/readmeBuilder.js'; import { readFileSync, writeFileSync, mkdirSync, existsSync, rmSync, rmdirSync } from 'fs'; import { exec } from 'child_process'; import { globby } from 'globby'; import { JSDOM } from 'jsdom'; -import type { Code, ListItem, Root, Text } from 'mdast'; +import { dump, load, JSON_SCHEMA } from 'js-yaml'; +import type { Code, ListItem, Root, Text, YAML } from 'mdast'; import { posix, dirname, relative, join } from 'path'; import prettier from 'prettier'; import { remark } from 'remark'; @@ -209,6 +218,8 @@ interface TransformMarkdownAstOptions { originalFilename: string; /** If `true`, add a warning that the file is autogenerated */ addAutogeneratedWarning?: boolean; + /** If `true`, adds an `editLink: "https://..."` YAML frontmatter field */ + addEditLink?: boolean; /** * If `true`, remove the YAML metadata from the Markdown input. * Generally, YAML metadata is only used for Vitepress. @@ -231,6 +242,7 @@ interface TransformMarkdownAstOptions { export function transformMarkdownAst({ originalFilename, addAutogeneratedWarning, + addEditLink, removeYAML, }: TransformMarkdownAstOptions) { return (tree: Root, _file?: any): Root => { @@ -270,6 +282,27 @@ export function transformMarkdownAst({ } } + if (addEditLink) { + // add originalFilename as custom editLink in YAML frontmatter + let yamlFrontMatter: YAML; + if (astWithTransformedBlocks.children[0].type === 'yaml') { + yamlFrontMatter = astWithTransformedBlocks.children[0]; + } else { + yamlFrontMatter = { + type: 'yaml', + value: '', + }; + astWithTransformedBlocks.children.unshift(yamlFrontMatter); + } + const filePathFromRoot = posix.join('packages/mermaid', originalFilename); + yamlFrontMatter.value = dump({ + ...(load(yamlFrontMatter.value, { schema: JSON_SCHEMA }) as + | Record + | undefined), + editLink: `https://github.com/mermaid-js/mermaid/edit/develop/${filePathFromRoot}`, + }); + } + if (removeYAML) { const firstNode = astWithTransformedBlocks.children[0]; if (firstNode.type == 'yaml') { @@ -306,6 +339,7 @@ const transformMarkdown = (file: string) => { // mermaid project specific plugin originalFilename: file, addAutogeneratedWarning: !noHeader, + addEditLink: noHeader, removeYAML: !noHeader, }) .processSync(doc) @@ -323,16 +357,6 @@ const transformMarkdown = (file: string) => { copyTransformedContents(file, !verifyOnly, formatted); }; -import { load, JSON_SCHEMA } from 'js-yaml'; -// @ts-ignore: we're importing internal jsonschema2md functions -import { default as schemaLoader } from '@adobe/jsonschema2md/lib/schemaProxy.js'; -// @ts-ignore: we're importing internal jsonschema2md functions -import { default as traverseSchemas } from '@adobe/jsonschema2md/lib/traverseSchema.js'; -// @ts-ignore: we're importing internal jsonschema2md functions -import { default as buildMarkdownFromSchema } from '@adobe/jsonschema2md/lib/markdownBuilder.js'; -// @ts-ignore: we're importing internal jsonschema2md functions -import { default as jsonSchemaReadmeBuilder } from '@adobe/jsonschema2md/lib/readmeBuilder.js'; - /** * Transforms the given JSON Schema into Markdown documentation */ @@ -420,16 +444,18 @@ async function transormJsonSchema(file: string) { } }); - const transformed = remark() + const transformer = remark() .use(remarkGfm) .use(remarkFrontmatter, ['yaml']) // support YAML front-matter in Markdown .use(transformMarkdownAst, { // mermaid project specific plugin originalFilename: file, addAutogeneratedWarning: !noHeader, + addEditLink: noHeader, removeYAML: !noHeader, - }) - .stringify(markdownAst as Root); + }); + + const transformed = transformer.stringify(await transformer.run(markdownAst as Root)); const formatted = prettier.format(transformed, { parser: 'markdown', diff --git a/packages/mermaid/src/docs.spec.ts b/packages/mermaid/src/docs.spec.ts index 50feaee6a..c84bc1bac 100644 --- a/packages/mermaid/src/docs.spec.ts +++ b/packages/mermaid/src/docs.spec.ts @@ -105,6 +105,29 @@ This Markdown should be kept. }); }); + it('should add an editLink in the YAML frontmatter if `addEditLink: true`', async () => { + const contents = `--- +title: Flowcharts Syntax +--- + +This Markdown should be kept. +`; + const withYaml = ( + await remarkBuilder() + .use(transformMarkdownAst, { originalFilename, addEditLink: true }) + .process(contents) + ).toString(); + expect(withYaml).toEqual(`--- +title: Flowcharts Syntax +editLink: >- + https://github.com/mermaid-js/mermaid/edit/develop/packages/mermaid/example-input-filename.md + +--- + +This Markdown should be kept. +`); + }); + describe('transformToBlockQuote', () => { // TODO Is there a way to test this with --vitepress given as a process argument? diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts index 330b088d9..2644fa088 100644 --- a/packages/mermaid/src/docs/.vitepress/config.ts +++ b/packages/mermaid/src/docs/.vitepress/config.ts @@ -35,7 +35,12 @@ export default defineConfig({ themeConfig: { nav: nav(), editLink: { - pattern: 'https://github.com/mermaid-js/mermaid/edit/develop/packages/mermaid/src/docs/:path', + pattern: ({ filePath, frontmatter }) => { + if (typeof frontmatter.editLink === 'string') { + return frontmatter.editLink; + } + return `https://github.com/mermaid-js/mermaid/edit/develop/packages/mermaid/src/docs/${filePath}`; + }, text: 'Edit this page on GitHub', }, sidebar: {