优化 Mermaid 渲染

This commit is contained in:
2026-09-25 01:45:31 +08:00
parent 5929a356e9
commit 2368fcc005
25 changed files with 2468 additions and 1014 deletions
+36
View File
@@ -0,0 +1,36 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { createMarkdownProcessor } from '@astrojs/markdown-remark';
import remarkMermaid from '../src/plugins/remark-mermaid.mjs';
import rehypeStaticMermaid from '../src/plugins/rehype-mermaid.mjs';
const renderer = await createMarkdownProcessor({
remarkPlugins: [remarkMermaid],
rehypePlugins: [rehypeStaticMermaid],
});
const fence = (diagram) => `\`\`\`mermaid\n${diagram}\n\`\`\``;
test('multiple diagrams and both themes have distinct IDs and working arrow references', async () => {
const sequence = fence('sequenceDiagram\nAlice->>Bob: Hello');
const source = [fence('flowchart LR\nA[中文标签] --> B[完成]'), sequence, sequence].join('\n\n');
const { code } = await renderer.render(source);
assert.equal([...code.matchAll(/data-rendered="static"/g)].length, 3);
assert.equal([...code.matchAll(/<svg\b/g)].length, 6);
const ids = [...code.matchAll(/\sid="([^"]+)"/g)].map((match) => match[1]);
assert.equal(ids.length, new Set(ids).size);
const markers = [...code.matchAll(/marker-(?:start|end)="url\(#([^)]*)\)"/g)];
assert(markers.length > 0);
for (const match of markers) assert(ids.includes(match[1]), `Missing arrow marker: ${match[1]}`);
});
test('invalid diagram rejects compilation with source position', async (t) => {
// Astro logs the expected parse failure before throwing it.
t.mock.method(console, 'error', () => {});
await assert.rejects(
renderer.render(fence('flowchart LR\nA[Unclosed'), {
fileURL: new URL('./invalid-mermaid.md', import.meta.url),
}),
(error) => error.fatal === true && error.ruleId === 'rehype-mermaid'
&& error.line === 1 && error.file.endsWith('invalid-mermaid.md'),
);
});