What's wrong
When a document has more than one frontmatter block, AddFrontmatter (Frontmatter/Frontmatter.cs:173-184) does the following:
- It calls
ExtractFrontmatter(input), which returns only frontmatterObjects.First() (:138).
- It merges the new properties into that first block.
- It calls
ReplaceFrontmatter(input, combined), which rebuilds the document from the body that comes after all blocks (ExtractFrontmatterObjects(input, out string body), :208).
So the properties from the second and later blocks are neither merged nor preserved; they are simply removed from the document.
Repro
string doc = "---\ntitle: T\n---\n---\ntags: [x]\n---\nbody\n";
Frontmatter.AddFrontmatter(doc, new() { ["author"] = "Me" });
- Actual:
---\ntitle: T\nauthor: Me\n---\nbody. The tags value is gone.
- Expected:
title, tags and author in the header, which is what CombineFrontmatter produces for the same input.
Why it matters
A call meant to add one property deletes existing properties, and nothing reports it. Multiple stacked blocks are exactly the input CombineFrontmatter exists to handle, and the recent hardening in AddFrontmatter ("frontmatter it cannot read is left alone", from the #132/#133 fix) shows the intent is never to lose data. This path still loses data the library can read.
Suggested fix
In AddFrontmatter, fold every parsed block together (ExtractFrontmatterObjects + CombineFrontmatterObjects, as CombineFrontmatter does at :87-91) before merging in the new properties. If any non-blank block fails to parse, return the input unchanged, matching the existing guard.
Acceptance: the repro keeps tags, with a regression test covering two stacked blocks.
What's wrong
When a document has more than one frontmatter block,
AddFrontmatter(Frontmatter/Frontmatter.cs:173-184) does the following:ExtractFrontmatter(input), which returns onlyfrontmatterObjects.First()(:138).ReplaceFrontmatter(input, combined), which rebuilds the document from the body that comes after all blocks (ExtractFrontmatterObjects(input, out string body),:208).So the properties from the second and later blocks are neither merged nor preserved; they are simply removed from the document.
Repro
---\ntitle: T\nauthor: Me\n---\nbody. Thetagsvalue is gone.title,tagsandauthorin the header, which is whatCombineFrontmatterproduces for the same input.Why it matters
A call meant to add one property deletes existing properties, and nothing reports it. Multiple stacked blocks are exactly the input
CombineFrontmatterexists to handle, and the recent hardening inAddFrontmatter("frontmatter it cannot read is left alone", from the #132/#133 fix) shows the intent is never to lose data. This path still loses data the library can read.Suggested fix
In
AddFrontmatter, fold every parsed block together (ExtractFrontmatterObjects+CombineFrontmatterObjects, asCombineFrontmatterdoes at:87-91) before merging in the new properties. If any non-blank block fails to parse, return the input unchanged, matching the existing guard.Acceptance: the repro keeps
tags, with a regression test covering two stacked blocks.