From a1781f034ebd1fc135624bac8ed3b13d99656353 Mon Sep 17 00:00:00 2001 From: hqhq1025 <1506751656@qq.com> Date: Sun, 19 Apr 2026 13:25:27 +0800 Subject: [PATCH] fix(exporters): quote YAML frontmatter titles starting with reserved indicators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `escapeYaml` only triggered on `:`, `#`, `"`, `'`, or newline, so titles beginning with YAML 1.2 reserved indicator chars (`-`, `?`, `[`, `{`, `>`, `|`, `!`, etc.) emitted unquoted scalars that strict parsers treat as sequences/flow nodes — corrupting the frontmatter for any artifact whose `
x
', { title, schemaVersion: 1 }); + expect(out).toContain(`title: ${JSON.stringify(title)}\n`); + } + }); + + it('quotes titles with leading or trailing whitespace', () => { + const out = htmlToMarkdown('x
', { title: ' padded ', schemaVersion: 1 }); + expect(out).toContain('title: " padded "\n'); + }); + it('strips javascript: links but keeps the visible text', () => { const out = htmlToMarkdown('', META); expect(out).toContain('x'); diff --git a/packages/exporters/src/markdown.ts b/packages/exporters/src/markdown.ts index 43d4edd94..eeee5efac 100644 --- a/packages/exporters/src/markdown.ts +++ b/packages/exporters/src/markdown.ts @@ -47,8 +47,20 @@ function renderFrontmatter(meta: MarkdownMeta): string { return `${lines.join('\n')}\n`; } +// YAML 1.2 reserved indicator chars that, at the start of a plain scalar, +// change parsing (sequence/flow/anchor/alias/directive/etc). Strings with +// leading/trailing whitespace also need quoting to round-trip correctly. +const YAML_LEADING_INDICATOR = /^[-?:,[\]{}#&*!|>'"%@`]/; +const YAML_NEEDS_QUOTING = /[:#"'\n]/; + function escapeYaml(value: string): string { - if (/[:#"'\n]/.test(value)) return JSON.stringify(value); + if ( + YAML_NEEDS_QUOTING.test(value) || + YAML_LEADING_INDICATOR.test(value) || + value !== value.trim() + ) { + return JSON.stringify(value); + } return value; }