mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 08:03:39 +00:00
Fix double new line issues in markdown rendering (#199)
* prevent double blank lines after markdown elements * prevent double blank lines after markdown elements
This commit is contained in:
parent
ce9ffaff91
commit
92577316e0
2 changed files with 97 additions and 3 deletions
|
|
@ -245,7 +245,9 @@ export class Markdown implements Component {
|
|||
styledHeading = this.theme.heading(this.theme.bold(headingPrefix + headingText));
|
||||
}
|
||||
lines.push(styledHeading);
|
||||
lines.push(""); // Add spacing after headings
|
||||
if (nextTokenType !== "space") {
|
||||
lines.push(""); // Add spacing after headings (unless space token follows)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -293,13 +295,17 @@ export class Markdown implements Component {
|
|||
for (const quoteLine of quoteLines) {
|
||||
lines.push(this.theme.quoteBorder("│ ") + this.theme.quote(this.theme.italic(quoteLine)));
|
||||
}
|
||||
lines.push(""); // Add spacing after blockquotes
|
||||
if (nextTokenType !== "space") {
|
||||
lines.push(""); // Add spacing after blockquotes (unless space token follows)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "hr":
|
||||
lines.push(this.theme.hr("─".repeat(Math.min(width, 80))));
|
||||
lines.push(""); // Add spacing after horizontal rules
|
||||
if (nextTokenType !== "space") {
|
||||
lines.push(""); // Add spacing after horizontal rules (unless space token follows)
|
||||
}
|
||||
break;
|
||||
|
||||
case "html":
|
||||
|
|
|
|||
|
|
@ -285,6 +285,94 @@ again, hello world`,
|
|||
});
|
||||
});
|
||||
|
||||
describe("Spacing after dividers", () => {
|
||||
it("should have only one blank line between divider and following paragraph", () => {
|
||||
const markdown = new Markdown(
|
||||
`hello world
|
||||
|
||||
---
|
||||
|
||||
again, hello world`,
|
||||
0,
|
||||
0,
|
||||
defaultMarkdownTheme,
|
||||
);
|
||||
|
||||
const lines = markdown.render(80);
|
||||
const plainLines = lines.map((line) => line.replace(/\x1b\[[0-9;]*m/g, "").trimEnd());
|
||||
|
||||
const dividerIndex = plainLines.findIndex((line) => line.includes("─"));
|
||||
assert.ok(dividerIndex !== -1, "Should have divider");
|
||||
|
||||
const afterDivider = plainLines.slice(dividerIndex + 1);
|
||||
const emptyLineCount = afterDivider.findIndex((line) => line !== "");
|
||||
|
||||
assert.strictEqual(
|
||||
emptyLineCount,
|
||||
1,
|
||||
`Expected 1 empty line after divider, but found ${emptyLineCount}. Lines after divider: ${JSON.stringify(afterDivider.slice(0, 5))}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Spacing after headings", () => {
|
||||
it("should have only one blank line between heading and following paragraph", () => {
|
||||
const markdown = new Markdown(
|
||||
`# Hello
|
||||
|
||||
This is a paragraph`,
|
||||
0,
|
||||
0,
|
||||
defaultMarkdownTheme,
|
||||
);
|
||||
|
||||
const lines = markdown.render(80);
|
||||
const plainLines = lines.map((line) => line.replace(/\x1b\[[0-9;]*m/g, "").trimEnd());
|
||||
|
||||
const headingIndex = plainLines.findIndex((line) => line.includes("Hello"));
|
||||
assert.ok(headingIndex !== -1, "Should have heading");
|
||||
|
||||
const afterHeading = plainLines.slice(headingIndex + 1);
|
||||
const emptyLineCount = afterHeading.findIndex((line) => line !== "");
|
||||
|
||||
assert.strictEqual(
|
||||
emptyLineCount,
|
||||
1,
|
||||
`Expected 1 empty line after heading, but found ${emptyLineCount}. Lines after heading: ${JSON.stringify(afterHeading.slice(0, 5))}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Spacing after blockquotes", () => {
|
||||
it("should have only one blank line between blockquote and following paragraph", () => {
|
||||
const markdown = new Markdown(
|
||||
`hello world
|
||||
|
||||
> This is a quote
|
||||
|
||||
again, hello world`,
|
||||
0,
|
||||
0,
|
||||
defaultMarkdownTheme,
|
||||
);
|
||||
|
||||
const lines = markdown.render(80);
|
||||
const plainLines = lines.map((line) => line.replace(/\x1b\[[0-9;]*m/g, "").trimEnd());
|
||||
|
||||
const quoteIndex = plainLines.findIndex((line) => line.includes("This is a quote"));
|
||||
assert.ok(quoteIndex !== -1, "Should have blockquote");
|
||||
|
||||
const afterQuote = plainLines.slice(quoteIndex + 1);
|
||||
const emptyLineCount = afterQuote.findIndex((line) => line !== "");
|
||||
|
||||
assert.strictEqual(
|
||||
emptyLineCount,
|
||||
1,
|
||||
`Expected 1 empty line after blockquote, but found ${emptyLineCount}. Lines after quote: ${JSON.stringify(afterQuote.slice(0, 5))}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("HTML-like tags in text", () => {
|
||||
it("should render content with HTML-like tags as text", () => {
|
||||
// When the model emits something like <thinking>content</thinking> in regular text,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue