fix: list/blockquote newlines and table width

This commit is contained in:
mitchell 2026-05-26 03:43:23 -04:00
parent a887e1b185
commit c277418349

View file

@ -17,7 +17,7 @@ let highligherLangs = "";
class SWCell extends Cell { class SWCell extends Cell {
public override get length() { public override get length() {
return stringWidth(this.toString(), { ambiguousIsNarrow: true }); return stringWidth(this.toString());
} }
} }
@ -25,7 +25,7 @@ class LmcRenderer extends Renderer {
private columns: number; private columns: number;
constructor(columns: number) { constructor(columns: number) {
super({ gfm: true }); super();
this.columns = columns; this.columns = columns;
} }
@ -49,14 +49,13 @@ class LmcRenderer extends Renderer {
override paragraph({ tokens }: Tokens.Paragraph) { override paragraph({ tokens }: Tokens.Paragraph) {
const text = this.parser.parseInline(tokens); const text = this.parser.parseInline(tokens);
return wrapAnsi(`\n${text}\n`, this.columns, { trim: false }); return wrapAnsi(`\n${text}\n`, this.columns - 2, { trim: false });
} }
override blockquote({ tokens }: Tokens.Blockquote) { override blockquote({ tokens }: Tokens.Blockquote) {
const text = this.parser.parse(tokens).trim(); let text = this.parser.parse(tokens).trim();
const lines = wrapAnsi(`\n${text}\n`, this.columns - 2, { if (!text.includes("\n")) text = wrapAnsi(text, this.columns - 2);
trim: false, const lines = `\n${text}\n`.split("\n");
}).split("\n");
const toRender = lines.map((line) => `> ${line}`).join("\n"); const toRender = lines.map((line) => `> ${line}`).join("\n");
return `${toRender.replaceAll(">", chalk.dim(">"))}\n`; return `${toRender.replaceAll(">", chalk.dim(">"))}\n`;
} }
@ -85,33 +84,36 @@ class LmcRenderer extends Renderer {
this.listitem(item, ordered ? num + index : undefined), this.listitem(item, ordered ? num + index : undefined),
) )
.join("\n"); .join("\n");
return `\n${renderedItems}\n`.replaceAll("\n\n", "\n"); return `\n${renderedItems}\n`;
} }
override listitem({ task, checked, tokens }: Tokens.ListItem, num?: number) { override listitem({ tokens }: Tokens.ListItem, num?: number) {
const text = this.parser.parse(tokens); const text = this.parser.parse(tokens).trim();
let marker = ""; let marker = "";
if (task) { if (num !== undefined) {
marker = checked ? "• [✓]" : "• [ ]";
} else if (num !== undefined) {
marker = `${num}.`; marker = `${num}.`;
} else { } else {
marker = "•"; marker = "•";
} }
const cols = this.columns - 2; let item = `${marker} ${text}`;
return wrapAnsi(`${marker} ${text}`, cols, { trim: false }) if (!item.includes("\n")) item = wrapAnsi(item, this.columns - 2);
return item
.split("\n") .split("\n")
.map((line) => (line.length > 0 ? ` ${line}` : "")) .map((line) => (line.length > 0 ? ` ${line}` : ""))
.join("\n"); .join("\n");
} }
override checkbox({ checked }: Tokens.Checkbox): string {
return checked ? "[✓] " : "[ ] ";
}
override hr() { override hr() {
return `\n${chalk.dim("─".repeat(this.columns))}\n`; return `\n${chalk.dim("─".repeat(this.columns))}\n`;
} }
override table({ header, rows }: Tokens.Table) { override table({ header, rows }: Tokens.Table) {
const headerCells = header.map((col) => { const headers = header.map((col) => {
const text = this.parser.parseInline(col.tokens); const text = this.parser.parseInline(col.tokens);
return new SWCell(chalk.red.bold(text)); return new SWCell(chalk.red.bold(text));
}); });
@ -123,11 +125,13 @@ class LmcRenderer extends Renderer {
}), }),
); );
const cols = this.columns - (headers.length * 3 + 1);
const maxWidth = Math.floor(cols / headers.length);
const table = new Table() const table = new Table()
.header(headerCells) .header(headers)
.body(body) .body(body)
.border() .border()
.maxColWidth(Math.floor((this.columns - 4) / headerCells.length)) .maxColWidth(maxWidth)
.toString(); .toString();
return `\n${table}\n`; return `\n${table}\n`;
@ -161,8 +165,8 @@ class LmcRenderer extends Renderer {
return chalk.red("\nImages are unsupported (for now)\n"); return chalk.red("\nImages are unsupported (for now)\n");
} }
override text(token: Tokens.Text) { override text(token: Tokens.Text | Tokens.Escape) {
if (token.tokens) { if (token.type === "text" && token.tokens) {
return this.parser.parseInline(token.tokens); return this.parser.parseInline(token.tokens);
} }
return token.text return token.text
@ -205,12 +209,7 @@ export async function renderMarkdown(
} }
const renderer = new LmcRenderer(columns); const renderer = new LmcRenderer(columns);
marked.setOptions({ const rendered = await marked.parse(md, { renderer });
renderer,
gfm: true,
});
const rendered = await marked.parse(md);
return rendered.trimStart(); return rendered.trimStart();
} }