From 834e2821e0f823bc6f1f198bce2c2d869b869087 Mon Sep 17 00:00:00 2001 From: Paul Sachs <11449728+paul-sachs@users.noreply.github.com> Date: Thu, 16 Feb 2023 10:56:50 -0500 Subject: [PATCH] fix(svg): prevent svg transform from clobbering previous nodes (#86) --- lib/src/mdxast-mermaid.spec.ts | 25 +++++++++++++++++++++++++ lib/src/mdxast-mermaid.ts | 13 +++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/lib/src/mdxast-mermaid.spec.ts b/lib/src/mdxast-mermaid.spec.ts index 22a6fb8..6c93718 100644 --- a/lib/src/mdxast-mermaid.spec.ts +++ b/lib/src/mdxast-mermaid.spec.ts @@ -79,4 +79,29 @@ function MDXContent(props = {}) { export default MDXContent; `) }) + + test('multiple mermaid instances in svg don\'t clobber previous node', async () => { + const result = await compileMdx( + `## Framework AARRR + + Some content + + \`\`\`mermaid + graph TD; + A-->B; + \`\`\` + + And some more: + + + \`\`\`mermaid + graph TD; + A-->B; + \`\`\``, + { output: 'svg' } + ); + expect(result.value).toContain('And some more'); + }) }) + + diff --git a/lib/src/mdxast-mermaid.ts b/lib/src/mdxast-mermaid.ts index ca24b8a..861d482 100644 --- a/lib/src/mdxast-mermaid.ts +++ b/lib/src/mdxast-mermaid.ts @@ -138,13 +138,18 @@ export default function plugin(config?: Config) { if (config?.output === 'svg') { return async function transformer(ast: any): Promise { // Find all the mermaid diagram code blocks. i.e. ```mermaid - const instances = findInstances(ast) + let instances = findInstances(ast); // Replace each Mermaid code block with the Mermaid component - for (let i = 0; i < instances.length; i++) { - const [node, index, parent] = instances[i] + // Here we iterate over the instances and replace them with the SVG + // and run findInstances again to get the next set instances. We do this + // because the replacement process can change the AST and cause + // the indexes to be incorrect. + while (instances.length > 0) { + const [node, index, parent] = instances[0]; const result = await outputSVG(node as any, index, parent, config); - Array.prototype.splice.apply(parent.children, [index, 1, ...result]) + Array.prototype.splice.apply(parent.children, [index, 1, ...result]); + instances = findInstances(ast); } return ast }