背景
博客之前不支持数学公式渲染,对于技术文章中涉及数学表达式的内容(如算法分析、机器学习公式等)无法正确显示。本次更新通过集成 KaTeX 引擎,为博客添加了数学公式渲染能力。
技术方案
选择 KaTeX 而非 MathJax,主要考虑以下因素:
- 渲染速度:KaTeX 的渲染速度比 MathJax 快得多
- 体积轻量:CDN 加载,不增加项目体积
- Hugo 原生支持:Hugo 的 Goldmark 扩展支持 passthrough 模式,与 KaTeX 配合良好
改动内容
1. 修改 config.yml
Hugo Goldmark passthrough 扩展配置
在 markup 部分添加了 passthrough 扩展,让 Hugo 在处理 Markdown 时保留数学公式的原始内容,而不是转义其中的特殊字符:
markup:
goldmark:
extensions:
passthrough:
delimiters:
block:
- - \[
- \]
- - $$
- $$
inline:
- - \(
- \)
- - $
- $
enable: true
全局启用数学公式
在 params 中添加 math: true,使所有页面默认支持数学公式:
params:
math: true
2. 修改 layouts/partials/extend_head.html
引入 KaTeX 的 CSS 样式表和 JavaScript 库:
{{ if .Params.math | default .Site.Params.math }}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js" crossorigin="anonymous"></script>
{{ end }}
3. 修改 layouts/partials/extend_footer.html
添加 KaTeX auto-render 初始化脚本,在页面 DOM 加载完成后自动渲染数学公式:
{{ if .Params.math | default .Site.Params.math }}
<script>
document.addEventListener("DOMContentLoaded", function () {
renderMathInElement(document.body, {
delimiters: [
{ left: "$$", right: "$$", display: true },
{ left: "$", right: "$", display: false },
{ left: "\\[", right: "\\]", display: true },
{ left: "\\(", right: "\\)", display: false }
],
throwOnError: false
});
});
</script>
{{ end }}
使用方式
行内公式
使用单个 $ 或 \(...\) 包裹:
质能方程 $E = mc^2$ 是物理学中著名的公式。
渲染效果:质能方程 $E = mc^2$ 是物理学中著名的公式。
块级公式
使用双 $$ 或 \[...\] 包裹:
$$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$$
渲染效果:
$$ \int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi} $$更多示例
矩阵:
$$ \begin{bmatrix} a & b \\ c & d \end{bmatrix} $$求和公式:
$$ \sum_{i=1}^{n} i = \frac{n(n+1)}{2} $$欧拉公式:
$$ e^{i\pi} + 1 = 0 $$薛定谔方程:
$$ i\hbar\frac{\partial}{\partial t}\Psi(\mathbf{r},t) = \hat{H}\Psi(\mathbf{r},t) $$踩坑记录
在初次部署后发现数学公式无法渲染,排查发现是 KaTeX CDN 资源的 integrity(SRI hash)值写错了,导致浏览器在加载 CSS 和 JS 文件时校验失败,资源被拒绝加载。移除错误的 integrity 属性后问题解决。
教训:使用 CDN 资源时,SRI hash 必须与实际文件内容完全匹配。如果不确定正确的 hash 值,建议不添加
integrity属性,仅使用crossorigin="anonymous"即可。
注意事项
- 数学公式使用 KaTeX CDN 加载,需要网络连接
- KaTeX 支持大部分 LaTeX 数学语法,但不支持所有 LaTeX 宏包
- 如果某篇文章不需要数学公式,可以在 front matter 中设置
math: false来禁用,减少不必要的资源加载 - 行内公式中避免使用
$符号作为货币单位,如需使用可用\$转义
...