feat!: remove AsciiMath support - #44
Open
jamliaoo wants to merge 4 commits into
Open
Conversation
AsciiMath relied on MathJax's v2 legacy shim, which cannot run in strict mode and therefore breaks under ESM-strict bundlers (Vite dep pre-bundling). MathJax v4 still ships the same legacy code, so the upgrade path is closed. - Backtick content always renders as a standard markdown code span - enableAsciimath / asciimathDelimiter options are silently ignored - Delete the lazy loader (load-asciimath.cjs) and its rollup commonjs ignore workaround; the Vue entry no longer needs a divergent default - latexDelimiterConvertor keeps shielding backtick code spans from delimiter conversion (renamed from asciimath-content to codespan-content) - LaTeX and Nemeth are unaffected
content-processor had no test coverage, yet latexDelimiterConvertor is the only API here that downstream consumes directly. Covers both conversion modes and the backtick shielding that keeps a delimiter inside inline code literal (verified load-bearing: disabling the shield fails 3 of these).
… pairs An empty pair (`$$`, `\(\)`, `\`\``) leaves the regex's optional content group unmatched, and the undefined reached the caller's template literal — so `a $$ b` converted to `a \(undefined\) b`, corrupting user content. Pre-existing on both the LaTeX and code-span paths; surfaced by review of the AsciiMath removal. Also documents the known backtick-run limitation next to the regex: a code span opened with several backticks is mis-segmented and its contents are not shielded. Fixing that changes how existing content converts, so it is tracked separately.
AsciiMath removal is a breaking change. Also syncs package-lock.json, whose top-level version was still 1.11.0 after the 1.11.1 bump.
jamliaoo
marked this pull request as ready for review
August 8, 2026 14:03
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
背景描述 (Why)
SeeMark 的 AsciiMath 一直是靠 MathJax 的 v2 legacy shim 實作的,那份程式碼裡有
arguments.callee(mathjax-full/js/input/asciimath/mathjax2/legacy/MathJax.js第 22、180 行),在 strict mode 下必然 throw。因此只要 bundler 的輸出是 ESM(ESM 永遠 strict),
轉換 AsciiMath 就會崩潰 —— Vite 的依賴預打包(optimizeDeps,底層 esbuild 轉 ESM)必踩。
這不是可以繞過的問題:
issue #2748 雖標記 Fixed,實測 3.2.2 中
arguments.callee仍在。enableAsciimath又預設true,所以任何一行普通的行內程式碼(
`foo`)都會被路由到 AsciiMath。兩者都讓 API 表面更複雜,卻沒有解決根因。
評估後決定移除 AsciiMath,而不是繼續維護緩解措施。
破壞性變更 (Breaking)
`...`enableAsciimathasciimathDelimiter版本已在本 PR 內 bump 為 2.0.0(依 repo 慣例,功能 PR 自帶版本號;
publish.yml是手動workflow_dispatch,直接發佈 main 當下的package.json,所以版本必須隨 PR 進 main)。順帶修正
package-lock.json的頂層版本 —— 它在 1.11.1 那次 bump 後仍停在 1.11.0。實作方法 (How)
load-asciimath.cjs(lazy loader)與ascii-math-to-mml.js;rollup 為它保留的
commonjsignore: mathjax-full/*特例與.cjsextension 一併移除。marked-extentions/math.js回歸純 LaTeX:單一 regex(不再是雙 pattern 併集)、typed恆為'latex'。enableAsciimath/asciimathDelimiter從options.js、marked-wrapper.js、markdown-processor.js、create-table-of-contents.js全鏈路移除。create-markdown-to-vue-parser.js不再需要enableAsciimath: false的分歧預設,三個 adapter 的 parser 現在完全對稱。
mathjax-full依賴保留 —— LaTeX→MathML 與 MathML→SVG 都是原生 v3,不受影響。一處刻意保留的機制
latexDelimiterConvertor(下游 Access8MathWeb 直接使用)原本把反引號區段辨識為asciimath-content,其實際作用是保護 code span 不被 delimiter 轉換波及 —— 少了它,
`code with $x$`裡的$x$會被錯誤轉成\(x\)。因此機制保留,只把語意正名為codespan-content。順帶修掉的既有 bug(非本次改動引入)
Codex review 在上述 code span 遮蔽的程式碼附近,指出一個既有的內容污染問題。已用 main 建
bundle 逐條比對確認:移除前後輸出 byte-identical,本 PR 未引入、也未惡化它。因為就在剛動過
的函式裡,順手修掉一半:
"undefined"。regex 的內容 group 是 optional,空的/ `$$` / `\(\)` 會讓它不匹配,`undefined` 一路流進呼叫端的模板字串 —— `a $$ b` 會被轉成a (undefined) b ``,直接污染使用者內容。修法是?? ''。(此 bug 兩條路徑都有,連本 PR 完全沒碰的 LaTeX 路徑也中。)
(
a`b),但目前的 regex 一次只認一顆,導致這種 code span 被切錯、內容未受遮蔽。修它要改成等長 run 比對,會改變既有內容的轉換結果,需獨立決策並盤點下游內容,
因此不混進這支 breaking PR,已在 regex 旁留註解記錄限制。
實際變更
## Migration節測試驗證
content-processor補上首批單元測試(14 個):兩種轉換模式、code span 遮蔽、空分隔符對。其中兩組經 mutation test 驗證有效 —— 拿掉 regex 的 code-span pattern 會紅 3 個、
拿掉
?? ''也會紅 3 個enableAsciimath/asciimathDelimiter不影響輸出asciimath/arguments.callee皆為 0刻意設
enableAsciimath: true(舊版必崩潰的路徑)→ 應用正常掛載、console 全乾淨、LaTeX 出 MathJax SVG + sr-only MathML、反引號
x+y/a/b渲染為<code>、自訂組件覆寫與即時編輯皆正常
(註:驗證時需先清
node_modules/.vite—— 舊的 dep 預打包快取會讓人誤判成「還是壞的」)15b78f2(refactor: extract shared image source resolution util #43 圖片來源重構),無衝突;rebase 後完整重跑測試/lint/build,並確認新進的
image-source.js與數學管線無耦合下游影響
Access8MathWeb/src、Access8MathTemplate/src全量 grepasciimath:零命中。沒有 UI 設定、沒有 content-config 欄位、沒有翻譯字串 —— 升級不需要任何下游程式碼修改。
createMarkdownToReactParser、latexDelimiterConvertor)簽名與行為皆不變。
補充說明
若未來要讓 AsciiMath 回歸,已做過可行性 spike:把
asciimath2mml換成 strict-safe 的實作即可,mml-to-svg.js完全不用動。候選為ascii2mathml(方言 7/7 相容但上游凍結)與其活躍後繼mathup(5/7,矩陣與 root 語法有變)。屬共用數學管線的獨立議題,不在本 PR 範圍。