fix(mdxish): preserve blank lines in JSX table parsing to fix roundtrip corruption#1430
Conversation
…rm-16064-jsx-table-parsing-roundtrip-breaks-markdown
|
The underlying bug here is really concerning. Do you know if this is a regression and when it started happening? |
…rm-16064-jsx-table-parsing-roundtrip-breaks-markdown
|
@kevinports I did a bit more digging and this is a genuine gap from my initial introduction of the table tokenizer in #1371. I had not accounted for the fact that since we are using a subparser, the position value of the this fell through the cracks since rendering didnt use positions (which is why this wasnt caught in the original PR) but the MdxishEditor does use it and specifically only uses it for syntax nodes (in Note we also need the blank line preservation in |
## Version 13.8.5 ### 🛠 Fixes & Updates * actually fix toc links with query params ([#1436](#1436)) ([b59ce5f](b59ce5f)) * **mdxish:** fix FA Emojis in Callouts ([#1421](#1421)) ([f7caa3e](f7caa3e)) * **mdxish:** preserve blank lines in JSX table parsing to fix roundtrip corruption ([#1430](#1430)) ([9fa040c](9fa040c)), closes [#1371](#1371) * proper spacing in empty callouts ([#1433](#1433)) ([97b8a41](97b8a41)) * scope link color inheritance to headings ([#1432](#1432)) ([cd78a62](cd78a62)) <!--SKIP CI-->
This PR was released!🚀 Changes included in v13.8.5 |

🎯 What does this PR do?
The
jsxTablemicromark tokenizer captures<Table>...</Table>as a single opaquehtmlnode.mdxishTablesthen re-parses that node'svaluethrough a separateunified()pipeline (tableNodeProcessor) to extract structured cells.The problem is that every node produced by that re-parse carries positions relative to the
htmlnode'svaluestring and not the outer document. So when a downstream consumer slicesoriginalSourcebynode.position.offset(as the editor'snodeToSourcedoes forSyntaxFlowandSyntaxText), it's reading bytes from the wrong location in the outer source.This was a gap that #1371 failed to account for mainly because:
mdxish()→ hast) doesn't use positionsmdast()→mdxishMdastToMd()) don't slice by offsetnodeToSourceand the slicingThe fix had 2 places:
preserve blank lines while reassembling the
htmlnode'svalue. The original code joined per-line chunks with'\n', collapsing multi-line gaps. This is a prerequisite for (2): without it, inner offsets drift relative to the outer source past the first blank line.after
tableNodeProcessorreturns its subtree, walk every node and shiftposition.start.offset/position.end.offset/position.start.line/position.end.lineby the outerhtmlnode's base offset and line. This translates inner coordinates into the outer source coordinate space so downstream consumers can slice correctly.The blank-line fix isn't the actual bug (it happens at the reassembly stage), but rather simply a hard prerequisite for the position translation to produce byte-identical slices against the outer source.
🧪 QA tips
<Table>with<ul>/<li>inside a<td>in the mdxish editor📸 Screenshot or Loom
Screen.Recording.2026-04-10.at.00.11.30.mov