公式模块
数学与科学符号表示——分数、指数、下标、希腊字母,以及通过 \ce{...} 书写的化学式——在服务器端渲染为带有真实替代文本的图片,因为没有任何电子邮件客户端能够排版真正的数学公式。
工作原理
该模块接收一段类似 LaTeX 的简化符号字符串(例如 \frac{-b \pm \sqrt{b^2-4ac}}{2a}),通过 GET /api/formula 在服务器端将其渲染为 PNG 图片。这是一个经过签名的端点,构建在分析图表模块已经使用的同一套从零编写的光栅化/PNG 编码基础之上:全程不涉及任何客户端数学库,渲染器背后也没有任何 npm 依赖。
公式的内容一旦写好就固定不变,这一点与必须在每次查看时重新生成才能保持实时的倒计时 GIF 不同。因此整个渲染请求(符号内容、显示模式、颜色)都会被签入 URL 本身,该端点不需要任何 Firestore 读取——响应会带上一个长期有效的不可变缓存头。
符号语法涵盖分数、指数(^)、下标(_)、平方根、希腊字母、命名函数(\sin、\lim、\log 等)、集合/逻辑符号(\forall、\in、\cup、\neg 等)以及常见运算符。\left(/\right( 可以被识别,但会按正常大小渲染,而不会根据其内容自动缩放,因为这是一个小型位图渲染器,而不是完整的 TeX 引擎。\text{...} 会在公式中间切换回普通文字,用于给某一项加标签。
化学式拥有自己专属的 \ce{...} 宏,是一个类似 mhchem 的精简子集。元素个数会自动加下标(H2O 会渲染出下标 2),末尾的离子电荷会自动加上标(H3O+、SO4^2-),-> 会渲染为反应箭头。这意味着书写 \ce{2H2 + O2 -> 2H2O} 时,不必为每个原子数和电荷手动书写 ^/_。
解析器无法识别的语法——完整的 LaTeX 文档、宏包、矩阵、表格——绝不会导致发送失败。它会转而将原始符号字符串按纯字面文本渲染。这一保证由两层机制共同保障:解析器本身会把未知宏降级为字面文本,而渲染器最外层的调用即便遇到排版方面的极端情况也绝不会抛出异常。
图片会按适合其显示模式的比例进行排版:块级模式更大,行内模式更小。如果超出邮件安全的大小预算,系统会自动逐级缩小。大多数公式一次就能排布完成;只有异常长的表达式才需要更小的比例,而极端病态的表达式会被限制在最小比例,而不会陷入无限循环。
渲染出的 <img> 会带有从这一排版过程计算出的明确 width/height 属性,因此 Outlook 及其他客户端不会在图片加载时发生跳动重排。更重要的是,它还带有一个设为原始符号字符串本身的 alt 属性。对于屏蔽图片的客户端,或是无法解析位图的屏幕阅读器,公式永远不会被困在一张没有文字对应内容的图片里。
可配置字段:
- 符号内容(类 LaTeX)——公式文本,上限为 300 个字符(超长的值会在渲染前被静默截断,绝不会导致发送失败)。
- 显示模式——行内(较小,置于文本行内)或块级(较大,独占一行)。
- 对齐方式——左对齐、居中或右对齐(仅在块级模式下生效)。
- 颜色——符号的描边颜色;无效或留空的值会回退到渲染器自身接近黑色的默认值,而不会带着一个会被拒绝的值去请求已签名的端点。
- 卡片的背景色、内边距、边框与圆角半径。
符号内容为空时不会渲染任何东西,而不是渲染一张空白图片——如果没有需要排版的文字,该模块就直接不输出任何内容。
支持的语法
下面的每个示例都是来自真实 /api/formula 端点的实时签名图片,而不是效果图,所以你在这里看到的就是收件人收件箱中实际渲染出的效果。不在此列表中的内容(完整的 LaTeX 文档、宏包、矩阵、表格,\bar/\hat 之类的重音符号,\dots 之类的省略号)都无法被识别。它们会按字面原样渲染为文字,而不会导致发送失败,因此在预览中通常很容易看出某个宏不受支持。
分数
\frac{a+b}{c-d}指数与下标
a_n = a_1 + (n-1)d平方根,嵌套在分数中
\sigma = \sqrt{\frac{1}{n}\sum (x_i - \mu)^2}二次方程求根公式——分数、± 与平方根的组合
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}希腊字母
\Delta = b^2 - 4ac命名函数与极限(正体,非斜体)
\lim_{x \to 0} \frac{\sin x}{x} = 1集合与逻辑符号
\forall x \in S,\ x^2 \geq 0\left(/\right) 分隔符——已识别,但不会根据内容自动缩放
y = \left(x+1\right)^2\text{...} 用于在公式中间插入文字标签
d = 5\text{ mi}通过 \ce{...} 书写化学式——原子数自动加下标,并带有反应箭头
\ce{2H2 + O2 -> 2H2O}\ce{...}——离子电荷自动加上标
\ce{SO4^2-}示例
Subject
This week in study group: the quadratic formula
一封化学课复习邮件可以在句子中行内排版一个配平的反应式:"光合作用:\ce{6CO2 + 6H2O -> C6H12O6 + 6O2}",紧挨着解释性文字。参见教育了解公式模块如何与作业、测验和闪卡组一起构成课堂摘要邮件。一份物理习题集可以把二次方程求根公式以块级模式单独成行放在配套例题之前,字号更大且居中显示。一份统计学通讯可以在句子中间使用像 \mu = \frac{\sum x_i}{n} 这样的简短行内公式,而不会打断周围段落的行文。注意这里用的是 \mu,而不是 \bar{x}:像 \bar/\hat 这样的重音符号宏不在上面列出的支持语法之列,因此在需要表示均值时,一个普通的希腊字母是安全的替代写法。
静态回退效果是什么样子
<div style="margin:8px 0;text-align:left">
<img src="https://mailinapp.com/api/formula?d=eyJub3RhdGlvbiI6...&s=abc123..."
width="184" height="52" alt="E = mc^2"
style="display:inline-block;max-width:100%;height:auto;vertical-align:middle" />
</div>
这里只有一个渲染层级——一个已签名的 <img>,其 alt 文本始终携带精确的符号字符串,因此即便图片本身无法加载,公式依然能够传达信息。