Skip to content

Frontmatter we write is not valid YAML when a value contains a colon #130

Description

@willkg

What happens

A page title containing : is written to frontmatter unquoted:

---
title: Deploy Runbook: Part 2
page_id: 123
---

That is not valid YAML. VSCode's YAML extension flags it, and any other tool that reads these files with a real YAML parser fails on it — yq, a linter, a static-site build over the same tree, another editor's frontmatter plugin. gopkg.in/yaml.v3 reports mapping values are not allowed in this context.

markfluence itself reads it back correctly, which is why this has gone unnoticed: frontmatter.Extract splits each line at the first : only, so title: a: b round-trips as a: b for us and breaks for everyone else. There is a test pinning the current output — internal/frontmatter/frontmatter_test.go, {"colon value bare", "title", "a: b", "", "title: a: b"}.

Why it happens

renderValue in internal/frontmatter/frontmatter.go decides whether to quote by asking "would our own ParseValue round-trip this?" rather than "is this valid YAML?". A colon round-trips through our parser, so it is never quoted.

The colon is one member of a larger class

The same predicate lets all of these through unquoted, and each is either invalid YAML or reads back as the wrong type:

written a real YAML parser sees
title: a: b parse error
title: true boolean true, not the string
title: 123 integer 123
title: null / title: ~ null
title: no boolean false
title: [draft] Foo flow sequence
title: @home / *star / &anchor / %pct / - dash / ` pipe`

parent has the same exposure, since it can hold a relative .md path.

Scope

markfluence has no YAML dependency today — internal/frontmatter is a hand-rolled flat-key parser. Fixing this by widening the quoting predicate means hand-maintaining a YAML plain-scalar rule set in a package with no YAML parser to check itself against, which is how the version that forgets % ships. The alternative is to adopt a real YAML library and let it decide quoting.

Related: #100 (markfluence.yaml project-wide settings) needs a real YAML parser anyway.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions