Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/cli/src/ui/utils/MarkdownDisplay.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ Some text before.
expect(lastFrame()).toMatchSnapshot();
});

it('renders escaped pipe characters inside table cells', () => {
const text = `
| Type | Example |
|------|---------|
| Union | A\\|B |
| Plain | Hello |
`.replace(/\n/g, eol);
const { lastFrame } = renderWithProviders(
<MarkdownDisplay {...baseProps} text={text} />,
);
const frame = lastFrame()!;
expect(frame).toContain('A|B');
expect(frame).not.toContain('A\\|B');
});

it('inserts a single space between paragraphs', () => {
const text = `Paragraph 1.

Expand Down
14 changes: 12 additions & 2 deletions packages/cli/src/ui/utils/MarkdownDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ const CODE_BLOCK_PREFIX_PADDING = 1;
const LIST_ITEM_PREFIX_PADDING = 1;
const LIST_ITEM_TEXT_FLEX_GROW = 1;

/**
* Splits a markdown table row on unescaped `|` delimiters,
* then un-escapes any `\|` sequences within each cell.
*/
function splitTableCells(row: string): string[] {
return row
.split(/(?<!\\)\|/)
.map((cell) => cell.replace(/\\\|/g, '|').trim());
}

const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
text,
isPending,
Expand Down Expand Up @@ -111,7 +121,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
lines[index + 1].match(tableSeparatorRegex)
) {
inTable = true;
tableHeaders = tableRowMatch[1].split('|').map((cell) => cell.trim());
tableHeaders = splitTableCells(tableRowMatch[1]);
tableRows = [];
} else {
// Not a table, treat as regular text
Expand All @@ -127,7 +137,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
// Skip separator line - already handled
} else if (inTable && tableRowMatch) {
// Add table row
const cells = tableRowMatch[1].split('|').map((cell) => cell.trim());
const cells = splitTableCells(tableRowMatch[1]);
// Ensure row has same column count as headers
while (cells.length < tableHeaders.length) {
cells.push('');
Expand Down
Loading