feat: implement pandoc's tex_math_gfm, replacing the GitLab compatibility option (#5446) by Jocs · Pull Request #5451 · marktext/marktext · GitHub
Skip to content

feat: implement pandoc's tex_math_gfm, replacing the GitLab compatibility option (#5446) - #5451

Closed
Jocs wants to merge 6 commits into
feat/muya-tex-math-dollars-preferencefrom
feat/muya-tex-math-gfm
Closed

Jocs wants to merge 6 commits into
feat/muya-tex-math-dollars-preferencefrom
feat/muya-tex-math-gfm

Conversation

@Jocs

@Jocs Jocs commented Sep 18, 2026 •

Copy link
Copy Markdown
Member

Task 3 of #5446. Stacked on #5450 (Task 2) — review that one first; this branch targets it, and I will rebase onto develop once it merges.

isGitlabCompatibilityEnabled was one third of an extension

The preference was named for a vendor and filed under Compatibility, but it did exactly one thing: promote a ```math fence to a math block. That is the display half of tex_math_gfm — GitHub's syntax as much as GitLab's — and the inline half was missing entirely.

Missing, and worse than missing: $`e=mc^2`$ was silently mis-rendered. The dollar rule claimed the span and handed the backticks to KaTeX as part of the formula:

src    = $`e=mc^2`$
tokens = [{ "type": "inline_math", "marker": "$", "content": "`e=mc^2`" }]
render = ‘e=mc2‘        ← stray backtick glyphs at both ends

katex-error was false — nothing reported a problem, it just came out wrong, in the editor and in the export alike. Any document copied from GitHub broke this way.

Now

One preference, texMathGfm, covering both forms, under Preferences → Markdown → Extensions with the other pandoc-named toggles. Default off, as in pandoc, where only tex_math_dollars ships enabled.

The old key is dropped rather than migrated. electron-store keys migrations to app versions, so a prerelease tester who has already run a 0.20.0 build could never receive one — their stored version is already at or past any key we could write. Before 1.0.0 the cheaper trade is to let the setting go: the preference loader already deletes keys that leave static/preference.json, so nothing errors, and anyone who had GitLab compatibility on turns the new toggle on once.

Notes on the implementation

Marker asymmetry. $`…`$ opens and closes with mirror images rather than one repeated marker. Both are two characters wide, so everything downstream that does arithmetic off marker.length — caret offsets, the Tab-past-the-closer hit test, the three render slices and the preview's data-start/data-end — still lands correctly. The one place that genuinely needed the closer is the clipboard renderer, which reassembled marker + text + marker and would have written $`e=mc^2$` ; it now carries an explicit close marker, and there is a test for exactly that round trip.

Rule precedence. Both math forms open on $, and the dollar rule would swallow the gfm span whole. In the editor the gfm rule goes ahead of it in the chunk list; on the marked side the extension is registered after the dollar one, because Marked.use unshifts, so the later registration is tried first. marked runs extensions ahead of its built-in codespan, so inline code never gets a chance to claim it either.

With the extension off, the span keeps its current reading. That is pandoc's behaviour — tex_math_dollars alone does treat $`…`$ as dollar math whose content happens to contain backticks — so Gap 2 in the issue is fixed by opting in, not by default. Deliberate, and pinned by a test so it cannot drift silently.

Only the single-backtick form is supported ($`…`$), which is what GitHub documents. Multi-backtick $…$ is not.

Behaviour changes worth calling out

before after
$`e=mc^2`$ with the extension on backticks inside the formula parsed as gfm inline math
```math promotion needed the dollar flag and the gitlab flag rides texMathGfm alone — turning dollar math off no longer takes the fenced form with it
meta.mathStyle on such a block 'gitlab' 'gfm' (muya state shape; nothing persists it — markdown is the file format, and the fence is unchanged)
muya's own default isGitlabCompatibilityEnabled: true texMathGfm: false, including the ?? true fallbacks in markdownToHtml and the public renderToStaticHTML

That last row changes the default for a standalone @muyajs/core consumer. MarkText already defaulted it off, so this closes a standing disagreement between the two packages rather than opening one.

Commits

  1. refactor(muya) — rename the option, flip the default.
  2. refactor(muya) — mathStyle: 'gitlab' → 'gfm'.
  3. feat(muya) — the inline form, in both tokenizers, plus texMathGfmInline.spec.ts.
  4. feat(muya) — ```math rides texMathGfm alone.
  5. feat(desktop) — the preference swap.
  6. docs — the PREFERENCES.md row.

Verification

muya 252 files / 1880 tests, CommonMark 0.31 + GFM 0.29 conformance 1347, desktop unit 820 (locale parity included), lint, typecheck, check-circular, and the muya Playwright math suite (70 passed).

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Website preview ready: https://pr-5451-marktext-website.ransixi.workers.dev

Built from d10d4207d873342d9bc6d0169383cf49af7fdb52 · Worker: marktext-website · Version: 834f7d29-c279-40aa-a6e6-b6d4f9e42c18 · Alias: pr-5451

@Jocs
Jocs force-pushed the feat/muya-tex-math-gfm branch from ea1ee2f to d794004 Compare September 18, 2026 19:33
@github-actions

github-actions Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Build artifacts for PR #5451:

Run: https://github.com/marktext/marktext/actions/runs/35437142016

Artifact Size Link
marktext-macos-arm64 287.4 MB Download
marktext-linux 638.2 MB Download
marktext-windows-arm64 279.4 MB Download
marktext-macos-x64 297.8 MB Download
marktext-windows-x64 287.6 MB Download

Jocs and others added 6 commits September 19, 2026 17:27
)

The option does exactly one thing: promote a ```math fence to a math
block. That is not "GitLab compatibility" — it is the display half of
pandoc's `tex_math_gfm`, and GitHub writes it the same way. Name it
after the extension, so the inline half can join it under one switch.

The default flips from true to false to match pandoc, where only
`tex_math_dollars` ships enabled — including the `?? true` fallbacks in
markdownToHtml and the public `renderToStaticHTML`. MarkText already
defaulted it off, so this closes a standing disagreement between the two
packages rather than opening one; a standalone @muyajs/core consumer that
relied on the old default now has to ask for it.

Task 3 of #5446.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`meta.mathStyle` records which syntax a math block was written in, so
that the serializer can put it back the way it came. Its non-default
value named the wrong vendor: ```` ```math ```` is GitHub's syntax as much as
GitLab's, and it is what pandoc's `tex_math_gfm` covers.

State-shape change for @muyajs/core: a math block promoted from a
```` ```math ```` fence now carries `mathStyle: 'gfm'`. Nothing persists the
value — markdown is the file format, and the fence it round-trips to is
unchanged.

Task 3 of #5446.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`` $`e=mc^2`$ `` was silently mis-rendered: the dollar rule claimed the
span, the backticks went to KaTeX as part of the formula, and
`katex-error` stayed false — nothing reported a problem, it just came
out wrong, in the editor and in the export alike. Any document copied
from GitHub broke this way.

Both tokenizers now recognise it, under `texMathGfm`. The rule goes
ahead of the dollar rule in the chunk list, and the marked extension is
registered after the dollar one (`Marked.use` unshifts), so in both
engines the longer, more specific form is tried first.

Opener and closer are mirror images instead of one repeated marker, but
both are two characters wide, so the marker arithmetic downstream — the
caret offsets, the Tab-past-the-closer hit test, the three render slices
— lands correctly without changes. The one place that genuinely needed
the closing marker is the clipboard renderer, which reassembled
`marker + text + marker`; it now carries an explicit close.

With the extension off the span keeps its current reading, as pandoc
does: `tex_math_dollars` alone treats `` $`…`$ `` as dollar math whose
content happens to contain backticks.

Task 3 of #5446.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Promoting a ```math fence needed `math` as well as the GitLab flag —
an accident of the old naming, where `math` read as a master switch.
```` ```math ```` is the display half of `tex_math_gfm` and has nothing to do
with the dollar syntax, so it now rides its own extension: turning the
dollar forms off no longer takes the fenced form with it.

Task 3 of #5446.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…thGfm (#5446)

The preference was named for a vendor and filed under Compatibility, but
it switched a markdown extension: ```` ```math ```` blocks, which GitHub writes
the same way GitLab does. It now sits with the other pandoc-named
toggles under Extensions, links at the pandoc manual like they do, and
covers the inline `` $`…`$ `` form as well.

The old key is dropped rather than migrated. Before 1.0.0 that is the
cheaper trade: the preference loader already deletes keys that leave
static/preference.json, so nothing errors, and anyone who had GitLab
compatibility on turns the new toggle on once.

Task 3 of #5446.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Task 3 of #5446.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Jocs
Jocs force-pushed the feat/muya-tex-math-gfm branch from d794004 to d10d420 Compare September 19, 2026 10:20
@Jocs
Jocs deleted the branch feat/muya-tex-math-dollars-preference September 19, 2026 11:06
@Jocs Jocs closed this Sep 19, 2026
@Jocs

Jocs commented Sep 19, 2026

Copy link
Copy Markdown
Member Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant