Skip to content

Commit 3022fcd

Browse files
cgreenoclaude
andcommitted
fix: YAML-parity title edges — inline comments, colon-space mapping rule
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 5e980e3 commit 3022fcd

2 files changed

Lines changed: 15 additions & 15 deletions

File tree

pkg/diagram/frontmatter.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,18 @@ func StripFrontmatter(input string) (rest string, title string) {
3333
return strings.Join(lines[i+1:], "\n"), title
3434
}
3535
// Only a top-level `title:` key counts — indented occurrences are
36-
// nested config values (e.g. inside themeCSS), not the title.
36+
// nested config values (e.g. inside themeCSS), not the title. YAML
37+
// requires whitespace after the colon for a mapping ("title:xyz" is a
38+
// plain scalar, not a key), and an unquoted value ends at a comment.
3739
trimmed := strings.TrimRight(lines[i], " \t\r")
38-
if v, ok := strings.CutPrefix(trimmed, indent+"title:"); ok {
39-
title = strings.Trim(strings.TrimSpace(v), `"'`)
40+
if v, ok := strings.CutPrefix(trimmed, indent+"title:"); ok && (v == "" || v[0] == ' ' || v[0] == '\t') {
41+
v = strings.TrimSpace(v)
42+
if !strings.HasPrefix(v, `"`) && !strings.HasPrefix(v, `'`) {
43+
if idx := strings.Index(v, " #"); idx != -1 {
44+
v = strings.TrimSpace(v[:idx])
45+
}
46+
}
47+
title = strings.Trim(v, `"'`)
4048
}
4149
}
4250
return input, ""

pkg/diagram/frontmatter_test.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ func TestStripFrontmatter(t *testing.T) {
2525
{"indented title is not the title", "---\nconfig:\n title: nested\n---\ndiagram", "diagram", ""},
2626
{"crlf input", "---\r\ntitle: t\r\n---\r\ndiagram", "diagram", "t"},
2727
{"multiline themeCSS config", "---\nconfig:\n themeCSS: |\n rect { fill: red; }\n---\nerDiagram", "erDiagram", ""},
28+
{"inline comment stripped from title", "---\ntitle: hi # note\n---\ndiagram", "diagram", "hi"},
29+
{"hash kept inside quoted title", "---\ntitle: \"a # b\"\n---\ndiagram", "diagram", "a # b"},
30+
{"no space after colon is not a mapping", "---\ntitle:xyz\n---\ndiagram", "diagram", ""},
2831
}
2932
for _, c := range cases {
3033
t.Run(c.name, func(t *testing.T) {
3134
rest, title := StripFrontmatter(c.in)
32-
if rest != c.wantRest && normalize(rest) != c.wantRest {
35+
if rest != c.wantRest {
3336
t.Errorf("rest = %q, want %q", rest, c.wantRest)
3437
}
3538
if title != c.wantTitle {
@@ -38,14 +41,3 @@ func TestStripFrontmatter(t *testing.T) {
3841
})
3942
}
4043
}
41-
42-
// normalize strips \r so CRLF inputs compare against \n expectations.
43-
func normalize(s string) string {
44-
out := make([]rune, 0, len(s))
45-
for _, r := range s {
46-
if r != '\r' {
47-
out = append(out, r)
48-
}
49-
}
50-
return string(out)
51-
}

0 commit comments

Comments
 (0)