You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MarkText only rendered $$...$$ display math when the $$ fences were on their own lines. This PR lets $$...$$ render as display math on the same line as surrounding text, matching pandoc and GitHub — so markdown copied from those sources (or from tools that emit inline $$) renders correctly on paste instead of showing raw $$.
For example, both of these now render:
$$ E=MC^2 $$
Energy is $$E=mc^2$$ in physics.
What this PR does
Tokenizes single-line $$...$$ as inline display math. A dedicated rule recognizes non-empty $$...$$ spans and is tried before the (unchanged) single-dollar $...$ rule. Empty $$$$, unclosed openers, and multiline $$ fences are not treated as inline display math — multiline fences still go through the existing block parser, and single-dollar math is untouched (including soft line breaks inside $...$).
Keeps the document model and markdown unchanged. Same-line $$ stays an inline token in paragraph state; it is not promoted to a math-block. Source round-trips losslessly and paste behavior is preserved, including adjacent formulas like $$a$$$$b$$.
Renders display mode with the correct layout.$$ spans render through KaTeX in display mode; a new .mu-display-math class shows the hidden preview as a full-width, centered block, while the editing state (caret inside) stays inline-block so the source is editable in place.
Uses the real marker width for offsets. Cursor/format offsets and the preview's content range are derived from the actual marker length (2 for $$) instead of a hardcoded 1, so selecting or toggling a $$x$$ span targets the content correctly.
Type of change
Bug fix (non-breaking, fixes an issue)
New feature (non-breaking, adds functionality)
Breaking change (causes existing functionality to change)
Documentation update
Test plan
New tests added
Manually tested on: Windows (Chromium)
Passing checks:
48 Muya unit tests covering tokenization (adjacent formulas, empty/unclosed/multiline edge cases, escaping, single-dollar newlines), markdown round-trip, paste, and format/cursor offsets
2 real-Chromium E2E tests for the display-block layout and the block → inline-block editing interaction
Muya tsc type check and ESLint (0 errors), plus targeted inlineSyntax.css stylelint
Notes for reviewers
Same-line $$ is deliberately an inline token, not a math-block. That is what preserves source round-trip and paste; multiline $$ fences are unaffected and still go through the block parser.
The export path is unchanged — it already renders $$ via KaTeX display mode, so no export CSS was touched.
Pushed 7cf518c: the display-math rule is now a linear-time scanner instead of a regex.
A downstream review of this change flagged that inlineDisplayMathRule backtracked quadratically on malformed input — the \. content pairs overlap the (\*) trailing group, so $$ followed by 131,072 backslashes and a stray $ blocked the thread for ~10s (2.5s at 65,536). Since tryChunks runs synchronously during paragraph tokenization, one crafted line could freeze the window on open or paste, so this seemed worth fixing before merge rather than shipping another regexp/no-super-linear-backtracking suppression.
execInlineDisplayMath keeps the exact semantics: content ends at the first unescaped same-line $$; a backslash always escapes the next character (the regex's greedy pair-first behavior, so an escaped closer extends the content); a returned match always has an unescaped closer, so the isLengthEven(to[3]) gate is untouched — the parity group is always empty.
Evidence:
exhaustive parity sweep of all 349,525 strings of length ≤ 9 over {$, \, a, \n} (prefixed with $$), old regex (through the parity gate) vs scanner: 0 mismatches on both the accepted set and the matched content;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #4904
Summary
MarkText only rendered
$$...$$display math when the$$fences were on their own lines. This PR lets$$...$$render as display math on the same line as surrounding text, matching pandoc and GitHub — so markdown copied from those sources (or from tools that emit inline$$) renders correctly on paste instead of showing raw$$.For example, both of these now render:
What this PR does
$$...$$as inline display math. A dedicated rule recognizes non-empty$$...$$spans and is tried before the (unchanged) single-dollar$...$rule. Empty$$$$, unclosed openers, and multiline$$fences are not treated as inline display math — multiline fences still go through the existing block parser, and single-dollar math is untouched (including soft line breaks inside$...$).$$stays an inline token in paragraph state; it is not promoted to amath-block. Source round-trips losslessly and paste behavior is preserved, including adjacent formulas like$$a$$$$b$$.$$spans render through KaTeX in display mode; a new.mu-display-mathclass shows the hidden preview as a full-width, centered block, while the editing state (caret inside) stays inline-block so the source is editable in place.$$) instead of a hardcoded 1, so selecting or toggling a$$x$$span targets the content correctly.Type of change
Test plan
Passing checks:
tsctype check and ESLint (0 errors), plus targetedinlineSyntax.cssstylelintNotes for reviewers
$$is deliberately an inline token, not amath-block. That is what preserves source round-trip and paste; multiline$$fences are unaffected and still go through the block parser.$$via KaTeX display mode, so no export CSS was touched.developMuya spec baseline currently has three unrelated round-trip failures, tracked separately in [Bug] Muya round-trip spec has three baseline failures on develop #4934.$$...$$in pasted content now renders as display math, which covers the rendering half of that issue's example. This PR does not change paste newline → paragraph splitting (the core of Pasted newline characters should create new paragraph blocks #3741), so that issue stays open.By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.