Skip to content

fix(tables): an escaped pipe stays inside its cell - #44

Merged
b451c merged 1 commit into
b451c:mainfrom
rinh:fix/table-escaped-pipe
Oct 29, 2026
Merged

b451c merged 1 commit into
b451c:mainfrom
rinh:fix/table-escaped-pipe

Conversation

@rinh

@rinh rinh commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

What

In a table cell, an escaped pipe (\|) is now a literal |, the way GitHub renders it. Before this change it started a new column.

Source Before After
`--part 1|2` two cells, broken code span --part 1|2 (code)
a | b two cells a | b

Why

GFM documents \| as the way to put a pipe into a table cell, including inside inline code. It is common in tables of CLI options such as --part 1|2. QuickMD split such a row into one cell too many: the rest of the row moved one column to the right, and the backticks ended up in different cells.

How

  • parseTableRow scans the row character by character instead of calling components(separatedBy: "|"). Only an unescaped | separates cells.
  • \| becomes | in the cell text, inside code spans too (GFM). \\| is an escaped backslash followed by a real separator. Other escapes stay in the text for the inline renderer, as before.
  • Leading and trailing pipes, padding, and trimming of trailing empty cells work as before. Table detection is unchanged.

Testing

  • New ParserTests.testEscapedPipeStaysInsideItsCell: escaped pipe inside a code span and in plain text, \\|, and an escaped pipe at the end of a cell.
  • xcodebuild … test: all 757 tests pass. The Release build and the -DAPPSTORE build both succeed.
  • Manually checked in the app with a table of CLI commands: each command stays in one cell and shows 1|2.
  • CHANGELOG has a line under [Unreleased].

🤖 Generated with Claude Code

parseTableRow split on every `|`, so `\|` (GFM's way to put a pipe in a
cell) started a new column: `` `--part 1\|2` `` became two cells, the row
gained a column and the code span broke apart.

Rows are now scanned character by character: only an unescaped `|`
separates cells, and `\|` becomes a literal `|` in the cell, inside code
spans too, as GFM specifies. `\\|` is an escaped backslash followed by a
real separator. Other escapes are left for the inline renderer as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@b451c
b451c merged commit baef57a into b451c:main Oct 29, 2026
3 checks passed
@b451c

b451c commented Oct 29, 2026

Copy link
Copy Markdown
Owner

Thanks again, @rinh! Merged (via #45) with one small follow-up: GitHub never splits a row at a pipe right after a backslash, even after \\ (path\\| c stays one cell there, and `p\\|q` shows p\|q), so the scanner now does the same. Your test is kept and extended. It will ship in the next release.

@b451c b451c mentioned this pull request Oct 29, 2026
@b451c

b451c commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Shipped in v1.14.0: GitHub download and Homebrew (brew upgrade --cask b451c/quickmd/quickmd) now; the Mac App Store update follows after Apple's review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants