mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 13:00:33 +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));
|
styledHeading = this.theme.heading(this.theme.bold(headingPrefix + headingText));
|
||||||
}
|
}
|
||||||
lines.push(styledHeading);
|
lines.push(styledHeading);
|
||||||
lines.push(""); // Add spacing after headings
|
if (nextTokenType !== "space") {
|
||||||
|
lines.push(""); // Add spacing after headings (unless space token follows)
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -293,13 +295,17 @@ export class Markdown implements Component {
|
||||||
for (const quoteLine of quoteLines) {
|
for (const quoteLine of quoteLines) {
|
||||||
lines.push(this.theme.quoteBorder("│ ") + this.theme.quote(this.theme.italic(quoteLine)));
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "hr":
|
case "hr":
|
||||||
lines.push(this.theme.hr("─".repeat(Math.min(width, 80))));
|
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;
|
break;
|
||||||
|
|
||||||
case "html":
|
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", () => {
|
describe("HTML-like tags in text", () => {
|
||||||
it("should render content with HTML-like tags as text", () => {
|
it("should render content with HTML-like tags as text", () => {
|
||||||
// When the model emits something like <thinking>content</thinking> in regular text,
|
// When the model emits something like <thinking>content</thinking> in regular text,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue