diff --git a/web/src/utils/markdown-table.test.ts b/web/src/utils/markdown-table.test.ts index 40c541507..6c0875db8 100644 --- a/web/src/utils/markdown-table.test.ts +++ b/web/src/utils/markdown-table.test.ts @@ -138,6 +138,18 @@ describe("serializeMarkdownTable", () => { expect(new Set(lines.map((l) => l.length)).size).toBe(1); }); + it("round-trips a cell containing a pipe character", () => { + const data: TableData = { + headers: ["A", "B"], + rows: [["foo|bar", "baz"]], + alignments: ["none", "none"], + }; + const md = serializeMarkdownTable(data); + const parsed = parseMarkdownTable(md); + expect(parsed?.rows[0][0]).toBe("foo|bar"); + expect(parsed?.rows[0][1]).toBe("baz"); + }); + it("round-trips through parse and serialize", () => { const original = `| Name | Age | | ----- | --- | diff --git a/web/src/utils/markdown-table.ts b/web/src/utils/markdown-table.ts index 2f1babc55..7c2567f4c 100644 --- a/web/src/utils/markdown-table.ts +++ b/web/src/utils/markdown-table.ts @@ -41,7 +41,7 @@ export function parseMarkdownTable(md: string): TableData | null { let trimmed = line; if (trimmed.startsWith("|")) trimmed = trimmed.slice(1); if (trimmed.endsWith("|")) trimmed = trimmed.slice(0, -1); - return trimmed.split(/(? cell.trim()); + return trimmed.split(/(? cell.trim().replace(/\\\|/g, "|")); }; const headers = parseRow(lines[0]); @@ -84,12 +84,14 @@ export function serializeMarkdownTable(data: TableData): string { const { headers, rows, alignments } = data; const colCount = headers.length; + const escapeCell = (text: string): string => text.replace(/(? { const formatted = cells.map((cell, i) => { const align = alignments[i] || "none"; - return padCell(cell, widths[i], align); + return padCell(escapeCell(cell), widths[i], align); }); return "| " + formatted.join(" | ") + " |"; };