Port upstream 4935: render same-line double-dollar display math#141
Conversation
|
Addressed the Codex P1 (super-linear backtracking in the display-math rule) in 92c86bb. Fix. Equivalence evidence. An exhaustive parity sweep over all 349,525 strings of length ≤ 9 from the alphabet Performance evidence. Reproduced the reported blow-up, then eliminated it: Regression tests added (spec now 15 tests): the adversarial 131,072-backslash input asserted under 500ms and never matched as display math; escaped-closer-extends-content; even-backslash-run content; escaped-only-closer rejected; dangling backslash / backslash-before-newline rejected. Full re-verification: Muya app gate 212 files / 1440 tests, app suite 75 files / 577 tests (vendor-sync contract included), typecheck, and the display-math e2e all pass. Note: the pre-existing single-dollar |
Summary
Port of marktext#4935 (issue marktext#4904, authored upstream by this repo's owner) into the vendored Muya tree.
$$...$$display math only rendered when the fences sat on their own lines; markdown copied from pandoc/GitHub-style sources showed raw$$instead. On Android, paste-from-other-apps is a primary input path, so this lands as a paste-fidelity fix.Changes (adapted onto our vendored tree, byte-equivalent to upstream)
inlineRenderer/rules.ts+lexer.ts— a dedicatedinlineDisplayMathRulerecognizes non-empty single-line$$...$$spans, tried before the unchanged$...$rule. Empty$$$$, unclosed openers, and multiline fences are excluded — multiline$$still goes through the block parser, and single-dollar math (including soft line breaks) is untouched.inlineRenderer/renderer/inlineMath.ts—$$tokens render through KaTeX in display mode; the KaTeX cache key now includes the mode; preview content offsets use the real marker length instead of a hardcoded 1.config/index.ts+assets/styles/inlineSyntax.css— newmu-display-mathclass: the hidden preview renders as a full-width centered block, while the editing state (caret inside) stays inline-block so the source is editable in place.block/base/format.ts— format/cursor offsets forinline_mathderive fromtoken.marker.length, so selecting or toggling a$$x$$span targets the content correctly.$$stays an inline token (never promoted tomath-block): source round-trips losslessly and paste behavior is preserved.Tests: upstream's Muya unit specs ported (
sameLineDisplayMath.spec.ts, plusformatToggle/pasteBlockMergeadditions). Upstream's real-Chromium e2e (our vendored tree has no Muya e2e harness) is replaced by an app-side Playwright spec (mobile-display-math.spec.ts) that verifies what happy-dom cannot — the shipped CSS lays the preview out as a full-width centered block in the real editor, and$x$stays inline.node_modules/@muyajs/coresynced per the vendor contract (the contract test passes in the app suite).Verification
pnpm typecheckand focused ESLint passed. Muyatsc --noEmitreports only the two pre-existingimport.meta.globerrors inutils/prism/loadLanguage.ts(verified identical on a clean tree — zero new type errors). Muya'slint:csscannot run in the vendored tree (the monorepo-root stylelint config was never vendored); the CSS addition is byte-identical to upstream's, which passed stylelint there.node_modulesreverted to main's Muya files, the spec fails (.mu-math.mu-display-mathnever appears — the raw-$$behavior); restored, it passes.Notes