Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/blog-converter-setext-heading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@dualmark/converters": patch
---

Fix the blog converter turning a post's last body line into a heading.

The footer was concatenated directly onto the body with no blank line, so the output ended with `last body line\n---`. CommonMark parses a line of text immediately followed by `---` as a setext H2, which turned the final line of every blog post body into a heading and dropped the intended horizontal rule before the footer links. The body and footer are now separated by a blank line so the `---` is a thematic break.
6 changes: 5 additions & 1 deletion packages/converters/src/blog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export function blogConverter(
footer.push(`- [All articles](${config.siteUrl}${basePath})`);
}
if (config.brandFooter) footer.push("", config.brandFooter);
return normalizeUnicode(base + footer.join("\n"));
// Separate the body from the footer with a blank line. `base` ends with the
// body's last line (no trailing newline) and `footer` starts with "---";
// without the blank line CommonMark parses "lastline\n---" as a setext H2,
Comment on lines +55 to +57
// turning the final body line into a heading and swallowing the rule.
return normalizeUnicode(base + "\n" + footer.join("\n"));
};
}
12 changes: 12 additions & 0 deletions packages/converters/test/converters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ describe("blogConverter", () => {
});
expect(out).toContain("## About Acme");
});

it("separates the body from the footer so the last line is not a setext heading", () => {
const out = convert({
id: "p",
data: { title: "T", publishedDate: new Date("2026-01-01T00:00:00Z") },
body: "Final body line.",
});
// "Final body line.\n---" would render as a setext H2 in CommonMark,
// turning the last body line into a heading and dropping the rule.
expect(out).toContain("Final body line.\n\n---");
expect(out).not.toContain("Final body line.\n---\n");
});
});

describe("caseStudyConverter", () => {
Expand Down
Loading