diff --git a/CHANGELOG.md b/CHANGELOG.md index 6424a6c6..8540b1f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 (`…`) 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 diff --git a/static/ui.js b/static/ui.js index b7e01bc4..c7b9eec6 100644 --- a/static/ui.js +++ b/static/ui.js @@ -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>)/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=>`${inlineMd(_restorePipes(c.trim()))}`).join('');}; const parseHeader=r=>{r=_protectPipes(r);return r.trim().replace(/^\|/,'').replace(/\|$/,'').split('|').map(c=>`${inlineMd(_restorePipes(c.trim()))}`).join('');}; diff --git a/tests/test_renderer_js_behaviour.py b/tests/test_renderer_js_behaviour.py index 0c63cc6e..501a4e88 100644 --- a/tests/test_renderer_js_behaviour.py +++ b/tests/test_renderer_js_behaviour.py @@ -242,6 +242,25 @@ class TestCommonLLMShapes: assert "

" 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 "field" in out + assert "expr" in out + # The code cell should contain both pipes + assert "" in out + assert "||" in out + # Must NOT split into extra cells + assert out.count("") == 2, ( + f"Expected exactly 2 cells, got {out.count('')}: {out!r}" + ) + def test_strikethrough_outside_quote(self, driver_path): out = _render(driver_path, "This was ~~outdated~~ but is now fine.") assert "outdated" in out