Skip to content

[v3.0.0] Add mathDelimiterMode option: strict-by-default double-backslash delimiters#418

Open
OlgaRedozubova wants to merge 2 commits into
masterfrom
dev/olga/math-delimiter-mode
Open

[v3.0.0] Add mathDelimiterMode option: strict-by-default double-backslash delimiters#418
OlgaRedozubova wants to merge 2 commits into
masterfrom
dev/olga/math-delimiter-mode

Conversation

@OlgaRedozubova

Copy link
Copy Markdown
Contributor

Summary

Adds mathDelimiterMode?: 'strict' | 'legacy' (default 'strict') controlling whether DOUBLE-backslash delimiters \\( ... \\) and \\[ ... \\] are treated as math.

  • 'strict' (default): only single-backslash \( / \[ (and $ / $$) open math. \\( is not a math delimiter — it follows CommonMark escape semantics (\\ → literal \) and renders as literal text.
  • 'legacy': also accept \\( / \\[ as math openers — the behavior inherited from markdown-it-mathjax, default in all versions ≤ 2.x.

The doubled form was never a deliberate feature (forked from markdown-it-mathjax). It (1) renders corrupted pipeline output as plausible math, masking regressions in QA views, and (2) removes the plain-text escape hatch for a literal \(. Single-backslash \(/\[ and $/$$ are unchanged.

Breaking change (semver major → 3.0.0)

A renderer-behavior change is a format-spec change. Versions ≤ 2.x rendered \\( ... \\) as math; under the new 'strict' default such content renders as literal \(...\).

Migration: consumers that rely on double-backslash delimiters (pasted / legacy MathJax-era content) must pass mathDelimiterMode: 'legacy' explicitly. Recommended per-surface choice: user-content surfaces (editors, desktop bundle, website, document conversion) → 'legacy'; pipeline-output / QA surfaces (API console, render diff/preview) → 'strict' (default).

What changed

  • optionsMathpixMarkdown / TMarkdownItOptions: new mathDelimiterMode?: 'strict' | 'legacy', threaded onto md.options across all option-assembly sites (parity with defaultCellVerticalAlign).
  • multiMath (mdPluginRaw.ts): in 'strict' the doubled openers \\( / \\[ return false, falling through to the escape rule (literal \(). Generic — no context logic.
  • lstlisting [mathescape=true] (parse-math-escape-inline.ts): code is verbatim, so the math-only parser has no escape rule. It now installs a verbatim backslash rule (instead of the default escape) that keeps \\ literal and consumes the pair together, so the second backslash cannot re-open a single \(. Result in 'strict': every non-math backslash (\\, \n, \textbf, \\(, …) stays verbatim; single \( is still math (what mathescape enables). 'legacy' keeps \\( as math.
  • Browser auto-render (browser/auto-render.ts): MathpixRenderConfig.mathDelimiterMode (default 'strict'); stripOuterMathDelimitersIfWhole accepts \\(...\\) / \\[...\\] only in 'legacy' — symmetry with the server parser.

Testing

  • tests/_math-delimiter-mode.js: prose + lstlisting × strict/legacy/default, for single \(/\[, doubled \\(/\\[, and $/$$; literal-preservation (prose escape-collapse vs lstlisting verbatim); legacy doubled ≡ single math.
  • tests/_auto_render.js: strict does not render doubled \\(; legacy renders \\(/\\[; single \( renders in both modes.
  • Full suite green (3504 passing). Default 'strict' is a no-op on single-backslash content.

Spec

pr-specs/2026-06-math-delimiter-mode.md

New mathDelimiterMode?: 'strict' | 'legacy' (default 'strict') controls whether
double-backslash delimiters \( ... \) / \[ ... \] are treated as math.
strict: only single-backslash \( \[ (and $) are math; legacy: also accept
\( \[ (pre-3.0.0 behavior).

- threaded onto md.options across all option-assembly sites
- multiMath rejects doubled openers in strict (fall through to escape)
- lstlisting[mathescape]: verbatim backslash rule keeps \( literal in strict;
  single \( still renders as math
- browser auto-render (renderMathInElement) honors the mode for parity
- golden tests for both modes (tests/_math-delimiter-mode.js, _auto_render.js)
- breaking renderer-behavior change: semver major 3.0.0

See pr-specs/2026-06-math-delimiter-mode.md
@OlgaRedozubova OlgaRedozubova self-assigned this Jun 12, 2026
@OlgaRedozubova OlgaRedozubova added the enhancement New feature or request label Jun 12, 2026
- Add strict edge-case tests: mixed prose (literal \\( + real \( math),
  lstlisting doubled opener abutting a single opener, and unknown mode
  value treated as strict (fail-safe), in both the server and auto-render
  suites; default-equals-strict and double display \\[ ... \\] checks too.
- README: note any value other than 'legacy' is treated as 'strict';
  list $/$$ alongside \( as always-math.
- parse-math-escape-inline.ts: clarify rule-precedence and options-cache
  docstrings for the verbatim-backslash listing parser.
- pr-spec: drop the N>=3 backslash non-goal.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant