Skip to content

feat!: remove AsciiMath support - #44

Open
jamliaoo wants to merge 4 commits into
mainfrom
feat/remove-asciimath
Open

feat!: remove AsciiMath support#44
jamliaoo wants to merge 4 commits into
mainfrom
feat/remove-asciimath

Conversation

@jamliaoo

@jamliaoo jamliaoo commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

背景描述 (Why)

SeeMark 的 AsciiMath 一直是靠 MathJax 的 v2 legacy shim 實作的,那份程式碼裡有
arguments.calleemathjax-full/js/input/asciimath/mathjax2/legacy/MathJax.js 第 22、180 行),
在 strict mode 下必然 throw。因此只要 bundler 的輸出是 ESM(ESM 永遠 strict),
轉換 AsciiMath 就會崩潰 —— Vite 的依賴預打包(optimizeDeps,底層 esbuild 轉 ESM)必踩

這不是可以繞過的問題:

  • 升級無解:MathJax v4 仍沿用同一份 v2 legacy 碼(官方文件確認 AsciiMath 尚未移植到 v3/v4)。
    issue #2748 雖標記 Fixed,實測 3.2.2 中 arguments.callee 仍在。
  • 預設路徑就會踩:AsciiMath 分隔符是反引號,enableAsciimath 又預設 true
    所以任何一行普通的行內程式碼(`foo`)都會被路由到 AsciiMath。
  • 既有緩解只是止血:lazy loading 把崩潰從 import 時延到渲染時;Vue entry 另外把預設關掉。
    兩者都讓 API 表面更複雜,卻沒有解決根因。

評估後決定移除 AsciiMath,而不是繼續維護緩解措施。

破壞性變更 (Breaking)

項目 變更後行為
反引號 `...` 一律渲染為標準 markdown code span,永不解析為數學
enableAsciimath 選項移除;傳入無害,會被靜默忽略
asciimathDelimiter 同上
LaTeX / Nemeth 不受影響

版本已在本 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 為它保留的 commonjs ignore: mathjax-full/* 特例與 .cjs extension 一併移除。
  • marked-extentions/math.js 回歸純 LaTeX:單一 regex(不再是雙 pattern 併集)、typed 恆為 'latex'
  • enableAsciimath / asciimathDelimiteroptions.jsmarked-wrapper.js
    markdown-processor.jscreate-table-of-contents.js 全鏈路移除。
  • Vue entry 的特例整段刪除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 路徑也中。)
  • 沒修:反引號 run 等長配對。markdown 允許用 N 個連續反引號開場來夾字面反引號
    a`b ),但目前的 regex 一次只認一顆,導致這種 code span 被切錯、內容未受遮蔽。
    修它要改成等長 run 比對,會改變既有內容的轉換結果,需獨立決策並盤點下游內容,
    因此不混進這支 breaking PR,已在 regex 旁留註解記錄限制。

實際變更

  • 刪除 2 檔、新增 1 檔(測試)、修改 18 檔,淨 +156 / −339
  • README:移除 AsciiMath 選項列與整段 bundler 相容性警告(限制已消失),新增 ## Migration

測試驗證

  • 375 測試全過(原 361,本 PR 淨增 14),lint 乾淨,三個 bundle build 成功
  • content-processor 補上首批單元測試(14 個):兩種轉換模式、code span 遮蔽、空分隔符對。
    其中兩組經 mutation test 驗證有效 —— 拿掉 regex 的 code-span pattern 會紅 3 個、
    拿掉 ?? '' 也會紅 3 個
  • 新增遷移守門測試:傳入已移除的 enableAsciimath / asciimathDelimiter 不影響輸出
  • 2 個 snapshot 更新,人工確認差異僅為 MathJax 自增 element id 位移,語意零變化
  • 三個 bundle grep asciimath / arguments.callee 皆為 0
  • Vite 實機驗證(Vite 6.4.3 + Vue 3,用 chore: add Vue adapter Vite playground (live example) #42 的 playground 在本機合併後實跑):
    刻意設 enableAsciimath: true(舊版必崩潰的路徑)→ 應用正常掛載、console 全乾淨、
    LaTeX 出 MathJax SVG + sr-only MathML、反引號 x+y / a/b 渲染為 <code>
    自訂組件覆寫與即時編輯皆正常
    (註:驗證時需先清 node_modules/.vite —— 舊的 dep 預打包快取會讓人誤判成「還是壞的」)
  • 已 rebase 至 15b78f2refactor: extract shared image source resolution util #43 圖片來源重構),無衝突;rebase 後完整重跑測試/lint/build,
    並確認新進的 image-source.js 與數學管線無耦合

下游影響

  • Access8MathWeb/srcAccess8MathTemplate/src 全量 grep asciimath零命中
    沒有 UI 設定、沒有 content-config 欄位、沒有翻譯字串 —— 升級不需要任何下游程式碼修改
  • Access8MathWeb 使用的兩個 API(createMarkdownToReactParserlatexDelimiterConvertor
    簽名與行為皆不變。
  • 唯一的使用者可見變化:既有內容中若有人以反引號書寫數學,升級後會顯示為 code span。

補充說明

若未來要讓 AsciiMath 回歸,已做過可行性 spike:把 asciimath2mml 換成 strict-safe 的實作即可,
mml-to-svg.js 完全不用動。候選為 ascii2mathml(方言 7/7 相容但上游凍結)與其活躍後繼
mathup(5/7,矩陣與 root 語法有變)。屬共用數學管線的獨立議題,不在本 PR 範圍。

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.
@jamliaoo jamliaoo changed the title feat!: remove AsciiMath support feat: remove AsciiMath support Aug 8, 2026
@jamliaoo jamliaoo changed the title feat: remove AsciiMath support feat!: remove AsciiMath support Aug 8, 2026
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
jamliaoo requested a review from wendyyuchensun August 8, 2026 14:03
@jamliaoo
jamliaoo marked this pull request as ready for review August 8, 2026 14:03

@wendyyuchensun wendyyuchensun left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

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.

2 participants