用 8 个公式测一测 你的 LaTeX 笔记 App
今晚你要整理一整页公式,手机上的笔记软件说它支持 LaTeX。可“支持 LaTeX”背后有四种不同的实现方式,它们之间的差距,到第三个公式就会显现出来。
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}
分数线要在上下两部分之间,而不是挤在旁边。把 8 个测试公式粘贴进 App,看看渲染出来是什么样子。嵌套分数、上下限写在上方和下方的求和、pmatrix 矩阵、可伸缩括号、align 对齐块、cases 分段、\def 宏和 \ce 化学式,能把真正的 LaTeX 笔记 App 和只会画几个行内分数的 App 区分开。渲染成普通文本,或者变成一张不能编辑的图片,都算不合格。
粘贴这 8 个公式, 看看 渲染 结果
这项检查不到一分钟,也不用注册账户。把下面的内容复制到你要测试的 App 里的一条新笔记中,可以一段一段贴,也可以一次全贴,再把结果和每段后面那行说明对照。这里的每一段都是 KaTeX 能渲染的有效 LaTeX,所以出了问题,是 App 的问题,不是输入的问题。
笔记 App 的 LaTeX 自测
一次粘贴一段,和“正确效果”那一行对照。
1. 嵌套分数
\frac{1}{1 + \frac{1}{1 + \frac{1}{x}}}
正确效果:三层叠起来的分数线,每一层都比外面那层短,
字号也更小。
2. 带上下限的运算符
\sum_{n=1}^{\infty} \frac{1}{n^2} = \frac{\pi^2}{6}
正确效果:在行间公式(display)模式下,n=1 和无穷大分别位于
求和号的正下方和正上方,而不是在它右边;求和号也比周围的文字高。
3. 矩阵环境
\begin{pmatrix} a & b \\ c & d \end{pmatrix}^{-1} =
\frac{1}{ad - bc} \begin{pmatrix} d & -b \\ -c & a \end{pmatrix}
正确效果:两行,圆括号撑满矩阵的整个高度,
-1 位于右括号的右上角。
4. 可伸缩定界符
\left( \sum_{i=1}^{n} a_i b_i \right)^2 \le
\left( \sum_{i=1}^{n} a_i^2 \right) \left( \sum_{i=1}^{n} b_i^2 \right)
正确效果:每个括号都撑到它所包含的求和式的高度,
成对的两个括号高度相同。
5. 对齐
\begin{align}
(a+b)^2 &= a^2 + 2ab + b^2 \\
(a-b)^2 &= a^2 - 2ab + b^2
\end{align}
正确效果:一个两行的公式块,两个等号在同一列上。
6. 分段
f(x) = \begin{cases}
x^2 & \text{if } x \ge 0 \\
-x^2 & \text{if } x < 0
\end{cases}
正确效果:一个大括号跨越两行,两个条件用直立的罗马字体,
并且单独排成一列。
7. 宏定义
\def\dd#1{\mathrm{d}#1}
\int_0^1 x^2 \dd{x} = \frac{1}{3}
正确效果:宏被展开,x 前面出现一个直立的 d,
积分号上标着 0 和 1。
8. 化学式
\ce{H2SO4 + 2NaOH -> Na2SO4 + 2H2O}
正确效果:数字是下标,元素符号是直立体而不是斜体变量,
反应箭头完整。
8 个测完之后
- 把光标放进一个渲染好的公式里,选中一个字符。
如果选不中,这个公式就是一张图片。
- 把系统切换到深色模式。公式仍然是黑色的,说明它自带了浅色背景。
- 把笔记的字号调到最大。图片会变模糊,排版出来的公式依然清晰。 下载文本文件要看的是失败的地方,而不是成功的地方。第 1 段能看出 App 做的是排版,还是字符串替换。第 3 段和第 6 段,是靠一张简短替换表撑起来的渲染器止步的地方。第 7 段区分的是 LaTeX 解析器和看起来像 LaTeX 的显示效果,因为忽略 \def 的 App 会原样打印文字,或者报解析错误。第 8 段需要 mhchem,这是建立在核心数学语法之上的一个宏包,所以一个 App 可能前 7 段都通过,最后一段却不行。
App 说“支持 LaTeX”, 可能指四种 不同的 东西
两个 App 可能都在功能页上写着 LaTeX,表现却完全不同。下面四种实现方式,各有各的失败方式,从外面就能看出来,不用读任何人的源代码。
| 等级 | 原理 | 怎么识别 | 在哪儿吃亏 |
|---|---|---|---|
| 行内子集 | 一张简短的替换表,处理美元符号之间的分数、上标和希腊字母 | 第 3 段渲染后还能看到 pmatrix 这个词,或者挤成一整行 | 你写下的第一个矩阵、积分或分段函数 |
| 渲染成图片 | LaTeX 交给转换器,返回一张位图或 SVG,放进笔记里 | 光标放不进公式里,字号调大后图片会变模糊 | 深色模式下,黑色字形留在深色页面上;想修改就得重新输入源码 |
| 浏览器引擎 | 一个隐藏的 WebView 用 JavaScript 运行 KaTeX 或 MathJax | 每次打开后的第一个公式,总比笔记其他内容慢半拍出现 | WebView 占用 50 至 150 MB 内存,第一个公式出现前还有启动延迟 |
| 原生引擎 | TeX 的盒子与粘连(box-and-glue)规则在 App 自己的代码里运行,全程不经过浏览器 | 滚动到哪一行,公式就绘制到哪一行,颜色也随系统外观变化 | 悬而未决的变成了覆盖范围,而不是速度,所以 8 段公式照样要测 |
第三行的数字来自 SwaTex 的 README。它这样描述常见的跨平台做法:一个隐藏的 WebView 吃掉 50 至 150 MB 内存,第一个公式出现前有启动延迟,也不保证断网时能用。这是复用一个并非 App 自己编写的 JavaScript 库的代价。第四种做起来成本高得多,但把浏览器从页面里彻底拿掉了。
原生 排版 引擎有 什么 不同
Phrase 用 SwaTex 渲染数学公式。SwaTex 是一个用纯 Swift 编写、与 KaTeX 兼容的数学渲染引擎,不用 JavaScript,不用 WebView,也没有 DOM。它采用 MIT 许可证,公开在 github.com/PhraseHQ/SwaTex,是对 RaTeX(用 Rust 编写、与 KaTeX 兼容的数学渲染器)从零开始的 Swift 移植。Phrase 的 AI 笔记里,每一个公式都由 SwaTex 渲染。它的排版引擎依据内置的 KaTeX 字体度量来执行 TeX 的盒子与粘连规则,而不是依赖平台的文字 API,所以输出和 KaTeX、RaTeX 逐个字形一致。

它覆盖了 KaTeX 官方支持表 1008 项中的 1007 项,包括 pmatrix、align、cases 和 CD 环境,以及可伸缩定界符、重音符号和 \def、\newcommand、\expandafter 等宏。化学方面,通过 \ce 和 \pu 完整支持 mhchem,这部分移植自一个状态机,在 253 个用例的语料上验证与 RaTeX 逐字节一致。证明树使用 bussproofs 风格的 prooftree,可以写推理规则和相继式演算。上面的第 3、5、6、7、8 段都在这个范围之内。
下面的速度数据,是在同一台机器上、用相同的语料,与 Rust 参考引擎对比测出的,取 3 次运行的中位数;2541 个基准公式在两个引擎之间逐位一致。每个数字都能用仓库 BENCHMARKS.md 里的命令复现。
| 测试项 | RaTeX(Rust) | SwaTex |
|---|---|---|
| 从解析到排版再到显示列表 | 41.4 µs/公式 | 12.5 µs/公式(3.3 倍) |
| 批量生成 PNG,100 个公式 @40px 2× | 约 200 µs/公式 | 等效 34 µs(并行,5.9 倍) |
| 重复公式,编辑器缓存命中 | 41.4 µs | 105 ns(约 390 倍) |
| 编辑器滚动 | 无对应数据 | 0 次字形光栅化(updateLayer) |
一致性是验证出来的,不是宣称出来的。仓库里附有 scripts/diff_layout.py,在 1000 多个公式的基准语料上,把 LayoutDump 工具和 RaTeX 的排版程序逐一比对;测试套件也把 RaTeX 自己的词法分析器、解析器、环境、mhchem 和排版测试移植到了 Swift。把公式画出来,只是编辑器问题的一半。公式块还需要准确的高度,还得经得起视图复用,这正是两篇文章的主题:《公式块的高度是怎么算出来的》和《让计算过程和讲解待在一起》。
笔记写好之后,可以让助手用它生成作品。开通 Pro,Phrase 就能把一条笔记做成幻灯片、页面、仪表盘、记忆卡片、测验和思维导图;一页写满推导过程的笔记,很适合拿来出测验或做一套卡片。带公式的课堂笔记也一样。
SwaTex 唯一不 渲染的那 一项
缺的那一项是 \includegraphics,也就是 1008 项里唯一的例外,而 KaTeX 自己也把这个命令放在 trust(信任)设置之后。这个命令会把外部图片引入公式,所以上游把它当作权限问题,而不是排版问题。四个 \html* 命令会渲染其中的内容,但丢弃只对 DOM 有意义的属性,因为原生渲染器没有 DOM,这些属性无从描述。
KaTeX 支持表 1008 项中的 1007 项
- 可以渲染1003
- 可以渲染,但丢弃只对 DOM 有意义的属性(四个 \html* 命令)4
- 不渲染:\includegraphics,KaTeX 自己也把它放在 trust 设置之后1
- 最低部署版本是 iOS 18、macOS 15、tvOS 18、watchOS 11 和 visionOS 2,由 Synchronization.Mutex 决定。面向更早系统版本的 App,目前还用不了 SwaTex。
- 只支持原生 Apple 平台,没有 React Native、Flutter 或 Web 封装。
- 有几处行为是有意和 RaTeX 不同的,每一处都有回归测试锁定。未闭合的 \verb 和 x\limits^2 会报解析错误,而不是被默默接受。
- 深层嵌套的输入由递归计数和栈余量把关,只会报解析错误,绝不会崩溃。不过,恶意输入仍应由宿主 App 限制长度。
本页没有涉及两件事。手写公式是另一个问题,因为 Phrase 接收的是输入、录音和导入的材料,而不是手写笔迹。图表和代码块是和公式分开的另一个问题,上面链接的两篇工程文章讲了它们怎样和公式共处于同一个编辑器。
还有一组事实要分开看。SwaTex 可以为 macOS 15 编译,而 Phrase Mac 版需要 macOS 26 或更高版本。引擎能在某个平台上编译,并不代表 App 支持哪些系统。Phrase 可以在 iPhone、iPad 和 Mac 上使用,三者都用 SwaTex 渲染公式;另有一个用来录音的 Apple Watch App。


要复习公式很多的内容,可以拿一组你已经写好的推导,跟着一条笔记变成一套闪卡的过程走一遍。
关于 笔记 App 里的 LaTeX
苹果自带的“备忘录”能写数学公式吗?与其相信一年前写下的说法,不如在你手头的 App 里跑一遍自测。“备忘录”能做什么,Apple 在自己的支持页面上有说明,而答案会随 iOS 版本变化。第 1 段和第 3 段,大约十秒就能见分晓。
能在“备忘录”里写 LaTeX 公式吗?输入 LaTeX 和渲染 LaTeX 是两个问题。任何 App 都能把 \frac{a}{b} 这几个字符当作文本存下来。关键在于会不会出现一条横线,a 在上,b 在下,这正是第 1 段要检查的。
支持 LaTeX 的笔记软件应该能处理什么?拿 KaTeX 支持表当共同的标尺,它是公开的,共有 1008 项。能处理环境、可伸缩定界符、宏和 mhchem 的 App,用的是和参考实现相同的语法。只能处理行内分数的 App,做的事情要小得多。
数学笔记 App 画一个公式需要联网吗?要看是哪一种。返回图片的转换器需要一个来回,WebView 引擎在第一个公式之前有启动成本。SwaTex 在 App 自己的代码里完成解析和排版,全程不经过浏览器。
出处和 编辑 说明
出处核对于 2026年9月25日。涉及 Apple 功能的步骤以 Apple 当前的官方文档为准,链接见下方。这些条件会随每次 iOS 更新而变化。
- SwaTex:用纯 Swift 编写、与 KaTeX 兼容的数学渲染引擎 覆盖 KaTeX 1008 项中的 1007 项、\includegraphics 这个例外、通过 \ce 和 \pu 支持 mhchem、基准测试表,以及最低部署版本。已于 2026 年 9 月 20 日核对。
- KaTeX:支持的函数与支持表 覆盖率所依据的 1008 项支持表,以及 \includegraphics 的 trust 限制。
- MathJax 的 mhchem:\ce 和 \pu 语法 自测第 8 段用到的化学式语法。
