Repository navigation
Conversation
@tiptap/markdown's escapeMarkdownSyntax backslash-escapes every `_` character unconditionally when re-serializing an edited block. This turns any identifier containing underscores (e.g. `user_name_field`) into `user\_name\_field` on save, which then renders literally with visible backslashes. Patch @tiptap/markdown@3.31.3 (via pnpm patch) so an underscore is only escaped when it is NOT flanked by word characters on both sides, matching CommonMark's intraword-underscore-is-literal rule. Emphasis- style underscores (leading/trailing/whitespace-flanked) keep escaping exactly as before. Scope: this only fixes underscores. Backslash, backtick, asterisk, and brackets are unchanged. Tilde is also left unchanged: GFM strikethrough delimiters in the actual parser (marked) can pair up across arbitrary distance within a text run based on flanking rules, not just adjacent `~~`, so a safe per-character fix for tilde isn't possible without a full delimiter-matching pass - out of scope here. Fixes stablyai#22014 (partially; see scope note above).
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. 📝 WalkthroughWalkthroughThe TipTap markdown patch now preserves underscores between word characters and escapes underscores in other positions. The patched dependency is registered in the pnpm workspace. New tests cover serialization, markdown round trips, boundary cases, punctuation, and preservation of existing escaping for other markdown syntax characters. Priority: ⬇️ Low Merge Risk: 🔵 Low · up to Identifiers containing non-ASCII letters can still be rewritten with escaped underscores when rich Markdown is serialized. Extend the intraword check before merging to preserve the intended behavior consistently. 🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
Full details: Description checkExplanation The description explains the bug, solution, scope, linked issue, implementation, and testing. However, it omits the required Visual Proof section and does not complete the required template sections and checklist items. Resolution Add the required template sections, including Visual Proof with screenshots or an explicit N/A and reason, Agent skill upstream boundary, Notes, and completed Checklist items. Keep the linked issue in the Linked Issue section and document platform testing and command results. Full details: Linked Issues checkExplanation Issue Resolution Extend the markdown serialization fix for the remaining syntax characters and the document-wide corruption behavior described in Full details: Docstring CoverageExplanation Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 1 files. (2 skipped: 2 unsupported.)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: e53afed9-4d76-48b4-9434-0d41afe0b92e
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
config/patches/@tiptap__markdown@3.31.3.patchpnpm-workspace.yamlsrc/renderer/src/components/editor/rich-markdown-escape-syntax.test.ts
Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.
| + const before = str[offset - 1]; | ||
| + const after = str[offset + 1]; | ||
| + const intraword = before !== void 0 && after !== void 0 && /\w/.test(before) && /\w/.test(after); | ||
| + return intraword ? match : `\\${match}`; |
ELI5
When you edit a rich-markdown block that contains a word with an underscore in it (like
user_name_field), saving turns it intouser\_name\_field. The visible backslashes then just sit there in the text.Problem
escapeMarkdownSyntaxin@tiptap/markdownbackslash-escapes every_character unconditionally whenever a block gets re-serialized after an edit:Any identifier, filename, or variable name containing an underscore gets corrupted with visible backslashes the moment the containing block is edited and saved.
Solution
Patched
@tiptap/markdown@3.31.3(viapnpm patch, following the project's existingconfig/patches/*.patchconvention) so an underscore is only escaped when it is not flanked by word characters on both sides — matching CommonMark's rule that intraword underscores are literal, not emphasis delimiters:Leading/trailing/whitespace-flanked underscores (the ones that actually could be emphasis delimiters, e.g.
_word,word_,a _ b) still get escaped exactly as before.Why this scope only
The linked issue reports five broken characters:
[,],_,~, and backtick/*. This PR fixes only_.marked, GFM mode) pairs up strikethrough delimiters using left/right-flanking rules that can span arbitrary distance within a text run, not just adjacent~~. A round-trip test caught this —~5 dollars, see v2~betagot silently reparsed as strikethrough even though neither tilde was doubled. Getting this right requires reimplementingmarked's delimiter-matching pass, which is too risky to hand-roll in a vendor patch. Left unchanged (still always escaped, same as before — no regression, no fix).escapeMarkdownSyntaxin ways I didn't fully trace, and touching it without full understanding risks new corruption.Testing
New test file
src/renderer/src/components/editor/rich-markdown-escape-syntax.test.ts, run through a realEditorinstance (same pattern as the existingrich-markdown-literal-serialization.test.ts), including a round-trip check (serialize → reparse → compare JSON) proving no corruption on save:Also re-ran the existing
rich-markdown-literal-serialization.test.tsandrich-markdown-normalize.test.ts(8 tests) to confirm no regression from the patch.Review
config/patches/@tiptap__markdown@3.31.3.patch— the actual fix, applied tosrc/MarkdownManager.ts,dist/index.js, anddist/index.cjsidentically (all three are part of the published package and get patched in sync).pnpm-workspace.yaml— registers the new patch underpatchedDependencies, same convention as the existing@xterm/*/lint-staged/etc. patches.src/renderer/src/components/editor/rich-markdown-escape-syntax.test.ts— new, focused test file.Checklist
pnpm patchFixes #22014 (partial — see "Why this scope only" above).