From ceaf1ae90c26ebda7f6eecd49b3566cc2b6ac36b Mon Sep 17 00:00:00 2001 From: showiix <2138757206@qq.com> Date: Wed, 29 Apr 2026 09:09:18 +0800 Subject: [PATCH 1/2] fix: skip frontmatter when rewriting wiki links --- src/ui/file-preview/src/markdown/linking.ts | 16 +++++++++++++- test/test-markdown-preview.js | 23 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/ui/file-preview/src/markdown/linking.ts b/src/ui/file-preview/src/markdown/linking.ts index dfe0baac..62425bab 100644 --- a/src/ui/file-preview/src/markdown/linking.ts +++ b/src/ui/file-preview/src/markdown/linking.ts @@ -17,6 +17,7 @@ interface ParsedWikiLink { const WIKI_LINK_PATTERN = /\[\[([^\]|#]*)(?:#([^\]|]+))?(?:\|([^\]]+))?\]\]/g; const FENCE_PATTERN = /^(`{3,}|~{3,})/; +const FRONTMATTER_DELIMITER = '---'; function encodeLinkPath(pathValue: string): string { return encodeURI(normalizePathSeparators(pathValue)); @@ -218,8 +219,21 @@ export function restoreWikiLinks(markdown: string): string { export function rewriteWikiLinks(source: string): string { const lines = source.split('\n'); let activeFence: string | null = null; + let inFrontmatter = lines[0]?.trim() === FRONTMATTER_DELIMITER + && lines.slice(1).some((line) => line.trim() === FRONTMATTER_DELIMITER); + + return lines.map((line, index) => { + if (index === 0 && inFrontmatter) { + return line; + } + + if (inFrontmatter) { + if (line.trim() === FRONTMATTER_DELIMITER) { + inFrontmatter = false; + } + return line; + } - return lines.map((line) => { const trimmedStart = line.trimStart(); const fenceMatch = trimmedStart.match(FENCE_PATTERN); if (fenceMatch) { diff --git a/test/test-markdown-preview.js b/test/test-markdown-preview.js index 5f48ebb0..ccf4c8de 100644 --- a/test/test-markdown-preview.js +++ b/test/test-markdown-preview.js @@ -145,6 +145,29 @@ async function testWikiRewriteAndRendering() { assert.ok(fencedRewrite.includes('[[Inside Code]]'), 'Long code fences should remain open until a matching-length close fence appears'); assert.ok(fencedRewrite.includes('[Outside Code](./Outside%20Code.md "mcp-wiki:'), 'Wiki links outside closed fences should still rewrite'); + const frontmatterRewrite = rewriteWikiLinks([ + '---', + 'title: My Note', + 'source_talk: "[[Other Note]]"', + 'tags: [example]', + '---', + '', + 'Body text with a [[Body Link]] for comparison.', + ].join('\n')); + assert.strictEqual( + frontmatterRewrite, + [ + '---', + 'title: My Note', + 'source_talk: "[[Other Note]]"', + 'tags: [example]', + '---', + '', + 'Body text with a [Body Link](./Body%20Link.md "mcp-wiki:%5B%5BBody%20Link%5D%5D") for comparison.', + ].join('\n'), + 'YAML frontmatter wikilinks should stay literal while body wikilinks still render', + ); + const html = renderMarkdown([ '# Title', '## Details', From bc1ab72719ad9bb51e1a3f7547194e19c01a73ab Mon Sep 17 00:00:00 2001 From: showiix <2138757206@qq.com> Date: Wed, 29 Apr 2026 09:18:47 +0800 Subject: [PATCH 2/2] fix: handle indented frontmatter block scalars --- src/ui/file-preview/src/markdown/linking.ts | 12 ++++++---- test/test-markdown-preview.js | 25 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/ui/file-preview/src/markdown/linking.ts b/src/ui/file-preview/src/markdown/linking.ts index 62425bab..3b540e64 100644 --- a/src/ui/file-preview/src/markdown/linking.ts +++ b/src/ui/file-preview/src/markdown/linking.ts @@ -17,7 +17,11 @@ interface ParsedWikiLink { const WIKI_LINK_PATTERN = /\[\[([^\]|#]*)(?:#([^\]|]+))?(?:\|([^\]]+))?\]\]/g; const FENCE_PATTERN = /^(`{3,}|~{3,})/; -const FRONTMATTER_DELIMITER = '---'; +const FRONTMATTER_DELIMITER_PATTERN = /^---\s*$/; + +function isFrontmatterDelimiter(line: string | undefined): boolean { + return typeof line === 'string' && FRONTMATTER_DELIMITER_PATTERN.test(line); +} function encodeLinkPath(pathValue: string): string { return encodeURI(normalizePathSeparators(pathValue)); @@ -219,8 +223,8 @@ export function restoreWikiLinks(markdown: string): string { export function rewriteWikiLinks(source: string): string { const lines = source.split('\n'); let activeFence: string | null = null; - let inFrontmatter = lines[0]?.trim() === FRONTMATTER_DELIMITER - && lines.slice(1).some((line) => line.trim() === FRONTMATTER_DELIMITER); + let inFrontmatter = isFrontmatterDelimiter(lines[0]) + && lines.slice(1).some((line) => isFrontmatterDelimiter(line)); return lines.map((line, index) => { if (index === 0 && inFrontmatter) { @@ -228,7 +232,7 @@ export function rewriteWikiLinks(source: string): string { } if (inFrontmatter) { - if (line.trim() === FRONTMATTER_DELIMITER) { + if (isFrontmatterDelimiter(line)) { inFrontmatter = false; } return line; diff --git a/test/test-markdown-preview.js b/test/test-markdown-preview.js index ccf4c8de..0185b734 100644 --- a/test/test-markdown-preview.js +++ b/test/test-markdown-preview.js @@ -168,6 +168,31 @@ async function testWikiRewriteAndRendering() { 'YAML frontmatter wikilinks should stay literal while body wikilinks still render', ); + const frontmatterBlockScalarRewrite = rewriteWikiLinks([ + '---', + 'title: |', + ' intro text', + ' ---', + 'source_talk: "[[Frontmatter Link]]"', + '---', + '', + 'Body text with a [[Body Link]] for comparison.', + ].join('\n')); + assert.strictEqual( + frontmatterBlockScalarRewrite, + [ + '---', + 'title: |', + ' intro text', + ' ---', + 'source_talk: "[[Frontmatter Link]]"', + '---', + '', + 'Body text with a [Body Link](./Body%20Link.md "mcp-wiki:%5B%5BBody%20Link%5D%5D") for comparison.', + ].join('\n'), + 'Indented --- inside YAML block scalars should not close frontmatter early', + ); + const html = renderMarkdown([ '# Title', '## Details',