Skip to content

fix: 移除 KaTeX 自递归宏定义,修复含 \text 公式无法渲染#4

Open
hjnnjh wants to merge 3 commits into
Sophomoresty:mainfrom
hjnnjh:fix/katex-text-macro-infinite-loop
Open

fix: 移除 KaTeX 自递归宏定义,修复含 \text 公式无法渲染#4
hjnnjh wants to merge 3 commits into
Sophomoresty:mainfrom
hjnnjh:fix/katex-text-macro-infinite-loop

Conversation

@hjnnjh

@hjnnjh hjnnjh commented May 29, 2026

Copy link
Copy Markdown

问题

在 VSCode 中使用本扩展时,任何包含 \text{...} 的公式都无法渲染,会显示为红色的 KaTeX 报错:

ParseError: KaTeX parse error: Too many expansions: infinite loop or need to increase maxExpand setting

不含 \text 的公式则正常。例如下面这个块级公式会稳定触发:

$$\text{Mem}_{\text{KV}} = 2 \times 1 \times 4096 \times 32 \times 32 \times 128 \times 2 \ \text{bytes} \approx 2\ \text{GB}$$

根因

renderLaTeX() 中块级 $$...$$katex.renderToString 传入了一段自递归 macros:

return katex.renderToString(fixed, { displayMode: true, throwOnError: false, macros: {
  "\\begin{cases}": "\\begin{cases}",
  "\\end{cases}": "\\end{cases}",
  "\\text": "\\text"
}});

\text(以及 \begin{cases} / \end{cases})定义成「展开为它自己」。KaTeX 在展开 \text 时会 \text → \text → \text → ... 无限递归,最终触发 maxExpand 上限并报错。而这三个本来就是 KaTeX 内置命令,根本无需重定义宏。

这也解释了「有的公式能渲染、有的不能」:只有命中 \text / cases 的公式才会触发无限展开。

修复

删除该 macros 配置:

return katex.renderToString(fixed, { displayMode: true, throwOnError: false });

验证

katex@0.16.9 对触发公式做对照测试:

  • 带原 macros → 抛 Too many expansions: infinite loop or need to increase maxExpand setting(与线上报错一字不差)
  • 删除 macros → 正常渲染

\text 的公式恢复正常,其余公式不受影响。

hjnnjh added 2 commits May 29, 2026 16:24
块级 $$ 公式渲染时传入的 macros 把 \text、\begin{cases}、\end{cases} 定义为展开成它们自己,导致 KaTeX 无限展开并报错 "Too many expansions: infinite loop or need to increase maxExpand setting"。这些都是 KaTeX 内置命令,无需重定义。删除该 macros 配置后,含 \text 的公式恢复正常渲染。
旧 renderLaTeX 在 Markdown 渲染「之后」逐文本节点抓取 textContent,
此时数学块里成对的 `_` 已被当作 emphasis 吃掉、文本节点被 <em> 切碎,
导致下标丢失、$$...$$ 经常匹配不全。

改为按「最内层含公式的块容器」整体重建 LaTeX 源串再喂 KaTeX:
- reconstructInline: <em>x</em>→_x_、<strong>→**、<br>→\n 逆向还原被吃的
  下划线;链接/代码/已渲染公式存为私有区哨兵(U+E000/E001)令牌,渲染后回填
- renderBlockSource: 抽数学段渲染 KaTeX,残留 markdown 复原,转义 HTML,回填令牌
- renderLaTeX: 选最内层块、整体替换 innerHTML,解决节点切碎

注:Markdown 反斜杠转义对 \{ \} \| 是无痕有损的,无法从 DOM 逆推,需在源头
改用 \lbrace \rbrace \lVert \rVert 规避。
Copilot AI review requested due to automatic review settings June 11, 2026 16:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

- 新增「公式书写约定」: Markdown 在 KaTeX 前会去掉反斜杠转义标点
  (\{ \} \| \, 等) 且不可逆推, 应改用 \lbrace \rbrace \lVert \rVert 等
  字母命令; 下标/上标/反斜杠+字母命令安全无需改动。
- 在「LaTeX 自动修复」补充块容器重建说明 (还原被吃的下划线、合并切碎节点)。
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