mirror of https://github.com/usememos/memos.git
fix(table): escape pipe chars in cells on serialize, unescape on parse
- escapeCell() replaces unescaped | with \| before writing each cell, applied in both width calculation and formatRow so padding is accurate - parseRow unescapes \| back to | after splitting on unescaped pipes - Adds round-trip regression test for cells containing pipe characters Addresses coderabbitai review comment on PR #5680.
This commit is contained in:
parent
314ab03715
commit
004e667b7a
|
|
@ -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 |
|
||||
| ----- | --- |
|
||||
|
|
|
|||
|
|
@ -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(/(?<!\\)\|/).map((cell) => cell.trim());
|
||||
return trimmed.split(/(?<!\\)\|/).map((cell) => 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(/(?<!\\)\|/g, "\\|");
|
||||
|
||||
// Calculate maximum width per column (minimum 3 for the separator).
|
||||
const widths: number[] = [];
|
||||
for (let c = 0; c < colCount; c++) {
|
||||
let max = Math.max(3, headers[c].length);
|
||||
let max = Math.max(3, escapeCell(headers[c]).length);
|
||||
for (const row of rows) {
|
||||
max = Math.max(max, (row[c] || "").length);
|
||||
max = Math.max(max, escapeCell(row[c] || "").length);
|
||||
}
|
||||
widths.push(max);
|
||||
}
|
||||
|
|
@ -110,7 +112,7 @@ export function serializeMarkdownTable(data: TableData): string {
|
|||
const formatRow = (cells: string[]): string => {
|
||||
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(" | ") + " |";
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue