Release XF (v0.51.650): protect table-cell pipes inside inline code (#4896)

Release XF (v0.51.650): protect table-cell pipes inside inline code (#4896)
This commit is contained in:
nesquena-hermes 2026-06-25 01:40:06 -07:00 committed by GitHub
commit 6403c8d459
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 26 additions and 1 deletions

View file

@ -3,6 +3,12 @@
## [Unreleased]
## [v0.51.650] — 2026-06-25 — Release XF (table cells with a pipe inside inline code render correctly)
### Fixed
- **Markdown tables no longer break when a cell contains a `|` inside inline code.** A table cell like `` `updates.model = modelState.model || null` `` rendered the `|` (or `||`) as extra column separators, splitting one cell into several and corrupting the row. The table parser already protected pipes inside bracket pairs; it now also protects pipes inside inline-code (`<code>…</code>`) spans — which is what backtick spans become before the table pass runs — so the code renders intact in a single cell. Thanks @luandnh. (#4896)
## [v0.51.649] — 2026-06-25 — Release XE (gallery-installed extensions actually activate)
### Fixed

View file

@ -5177,7 +5177,7 @@ function renderMd(raw){
// Bracket set is paren / square / curly only -- NOT angle brackets, since
// angle brackets are overwhelmingly comparison operators in real LLM table
// output (`| x < 5 | y > 10 |`) and treating them as a pair collapses cells.
const _protectPipes=r=>{let prev;do{prev=r;r=r.replace(/([([\x7b][^)\]\x7d]*)[|]([^)\]\x7d]*[)\]\x7d])/g,(_,a,b)=>a+'\x00PIPE\x00'+b);}while(r!==prev);return r;};
const _protectPipes=r=>{let prev;do{prev=r;r=r.replace(/([([\x7b][^)\]\x7d]*)[|]([^)\]\x7d]*[)\]\x7d])/g,(_,a,b)=>a+'\x00PIPE\x00'+b);r=r.replace(/(<code>[^<]*)[|]([^<]*<\/code>)/g,(_,a,b)=>a+'\x00PIPE\x00'+b);}while(r!==prev);return r;};
const _restorePipes=s=>s.replace(/\x00PIPE\x00/g,'|');
const parseRow=r=>{r=_protectPipes(r);return r.trim().replace(/^\|/,'').replace(/\|$/,'').split('|').map(c=>`<td>${inlineMd(_restorePipes(c.trim()))}</td>`).join('');};
const parseHeader=r=>{r=_protectPipes(r);return r.trim().replace(/^\|/,'').replace(/\|$/,'').split('|').map(c=>`<th>${inlineMd(_restorePipes(c.trim()))}</th>`).join('');};

View file

@ -242,6 +242,25 @@ class TestCommonLLMShapes:
assert "<p><table" not in out
assert "</table></p>" not in out
def test_table_pipe_inside_inline_code_is_protected(self, driver_path):
"""Pipes inside backtick code in table cells must not create extra columns."""
src = (
"| field | expr |\n"
"| --- | --- |\n"
"| set | `updates.model = modelState.model || null` |\n"
)
out = _render(driver_path, src)
# Must be exactly 2 cells in the data row
assert "<th>field</th>" in out
assert "<th>expr</th>" in out
# The code cell should contain both pipes
assert "<code>" in out
assert "||" in out
# Must NOT split into extra cells
assert out.count("<td>") == 2, (
f"Expected exactly 2 <td> cells, got {out.count('<td>')}: {out!r}"
)
def test_strikethrough_outside_quote(self, driver_path):
out = _render(driver_path, "This was ~~outdated~~ but is now fine.")
assert "<del>outdated</del>" in out