写机器学习笔记的时候总会遇到公式。静态博客里有两个主流选择:KaTeX 和 MathJax。我最后选了前者。
行内公式
用 $...$ 包起来就行。比如梯度下降的更新规则可以写成 $x_{t+1} = x_t - \eta \nabla f(x_t)$,其中 $\eta$ 是学习率。
注意一个问题:$ 出现在正文里(比如讲价格)时会被误判成公式开头。KaTeX 的 auto-render 对这种情况比较宽容,实在不行就用 \$ 转义。
独立公式
两个 $ 包住一整行:
$$ \mathcal{L}(\theta) = -\frac{1}{N}\sum_{i=1}^{N} \log p_\theta(y_i \mid x_i) $$
交叉熵损失,几乎每篇笔记都会出现。
再比如高斯分布的概率密度:
$$ p(x) = \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right) $$
接入方式
KaTeX 可以直接从 npm 装进来,构建时打包进站点,不依赖任何 CDN:
npm install katex
然后在需要的页面里渲染:
import renderMathInElement from 'katex/contrib/auto-render';
import 'katex/dist/katex.min.css';
renderMathInElement(document.body, {
delimiters: [
{ left: '$$', right: '$$', display: true },
{ left: '$', right: '$', display: false },
],
ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
throwOnError: false,
});
ignoredTags 一定要包含 pre 和 code,否则代码块里的 $ 也会被当成公式解析,排版直接爆炸。
为什么不用 MathJax
MathJax 语法支持更全,\begin{aligned}、\operatorname 这类写法几乎不会翻车。但它体积大得多,而且默认走 CDN,在国内访问经常转圈。
我的原则是:能自托管的东西就不要依赖 CDN。字体和公式库都是。
KaTeX 渲染速度也快,一次 renderMathInElement 下来几乎无感。对一个总共几十个公式的博客来说,完全够用。