数学公式网页可视化 | KaTeX 在网页中显示数学公式的应用与优化
注:本文为 “KaTeX 在网页中显示数学公式的应用” 相关合辑。
 图片清晰度受引文原图所限。
 略作重排,未整理去重。
 如有内容异常,请看原文。
动手微调 KaTeX,让你的博客完美显示数学公式(上)
晓雾喵
 2021年02月09日 20:44
为数学公式头疼的攻城狮和理科生
对于理科生而言,数学公式常常构成一项挑战。从视觉上看,公式结构复杂;在书写时,过程繁琐;而在电脑上显示公式,更是面临诸多技术难题。与普通文字按顺序排列不同,公式中的字符需要通过不同的位置来表示从属关系,例如右下角、右上角、符号上方等。以表示求和的 Σ\SigmaΣ 符号为例,其尺寸比普通字符大得多,且可以在符号的上方和下方添加其他符号。此外,仔细观察可以发现,数学公式中的括号高度各不相同。

外层括号的高度更高,以此来表示从属关系。更复杂的结构如矩阵、积分和方程组,需要在横向和纵向上进行精确排列。以下图为例,展示了上世纪铅字排版时期,如何将密密麻麻的铅条排列成数学公式。

铅字时期(上世纪)排版数学公式
理工科学生在撰写报告、论文以及参加数学建模比赛时,不可避免地要处理各种数学公式。因此,如何在电脑上高效地编辑和显示公式,成为了一个亟待解决的问题。
制订互联网标准的国际组织 W3C 在很久之前设计了 MathML 标准,用于在网页上显示公式。MathML 标准使用 XML 格式,将公式中的各个数字、字母和符号通过 XML 表示其从属关系,生成一段非常长且复杂的代码,然后通过浏览器渲染成人们可以识别的公式。然而,这一标准在实际应用中并未得到广泛推广。

MathML 排版数学公式,效果欠佳
1977 年,斯坦福大学的 Donald E. Knuth 开发了一套排版系统 TeX。之后,Leslie Lamport 在 TeX 的基础上进行了改进,开发出了现代最常用的排版系统 LaTeX。LaTeX 使用各种指令代码来控制排版,描述数学公式,并通过其引擎将文本文件转换成如 pdf 这样的可以交付印刷的格式。然而,LaTeX 在使用时需要记住许多命令和符号,因此学习难度较大。大多数人更习惯使用 MathType、Office 自带公式编辑器这类可以点选符号的工具。
MathType 的原理是将绘制的矢量图格式以图片的形式嵌入文档中。如果需要编辑,双击公式,调用 MathType 程序进行修改。这样绘制的公式放大后不会失真,公式的样式符合标准,但编辑起来较为麻烦。尤其是当文档中嵌入大量公式时,需要一一双击修改,且与文字混排时不易对齐,较长的公式也无法换行等。
微软的 Office 从 2010 版本开始提供了自带的公式编辑器,可以编辑一些相对简单的公式。与 MathType 相比,微软自带的公式编辑器可以换行、批量选中更改大小和字体,使用起来非常方便。

Word 2019 自带公式编辑器
值得一提的是,Office 的公式编辑器兼容 MathML 标准,微软还在原有标准的基础上做了一些完善。因此,如果复制一段 MathML 代码,在 Word 中粘贴会直接得到公式。更重要的是,自带公式编辑器还支持 LaTeX。有了 LaTeX 代码,可以直接转换成 Word 公式,无需再手动誊写一遍。
LaTeX 常见问题,你一定遇到过
LaTeX 如今已成为数学公式编辑领域的事实标准,以下将介绍使用 LaTeX 时最常见的几个问题。
大于等于号和书上的不一样
在 LaTeX 中,用 \geq 或 \ge(greater equal)表示大于等于。无论是在 LaTeX、Word 还是 MathType 中,等于号都是以水平的形式出现的,与书上倾斜的等于号不同。这两种样式在 Unicode 中是不同的编码字符,LaTeX 指令也不同。水平式的用 \geq 或 \ge 表示,斜式用 \geqslant 表示。

普通样式的符号和书本上常见的 slanted(倾斜)样式
如果更倾向于倾斜的风格,可以使用 \geqslant、\leqslant 指令。
分式扁扁的……
在 LaTeX 中,表示分式使用 \frac{a}{b} 指令,其中 aaa 是分子,bbb 是分母。使用 \frac 指令时,有时会看到分式被压扁的情况。

分式被压扁
这是因为数学公式有两种排版方式,类似于 Word 中的“环绕”、“四周”、“浮于文字”等设置。一种是“显示”(Display),表示公式单独占一行;另一种是“内嵌”(Inline),表示公式与其他文字混排。上图展示的是“内嵌”型公式,LaTeX 为了使分式不影响正文行的高度,会强行将分式压扁。如果不需要 LaTeX 进行这样的调整,可以使用 \cfrac{}{} 指令代替 \frac{}{}。

使用 \cfrac,分式不会被压扁
建议使用
\dfrac{}{}指令代替\frac{}{},因为\dfrac表示 display(显示),而\cfrac表示 continued(连分式)。二者效果相同,但语义不同。2022-04-19 09:38
方程组、换行等号不对齐
在 LaTeX 中,换行使用两个斜线 \\ 表示,前后用 \begin{aligned} {公式} \end{aligned} 包裹起来可以让换行后的公式自动对齐。然而,仔细观察下图可以发现,第一行和第二行的等号并没有完全对齐。

等号没有对齐
这种情况下,可以使用 & 符号锚定要对齐的位置。例如,按等号对齐,就在 = 前加 &,这样 LaTeX 就知道这两行的公式要在等号处对齐。

注意黄色标注的 & 符号
这种技巧同样适用于 Word 自带公式编辑器。在 Word 中插入一个分段函数的公式时,可以观察到以下情况。

Word 中还提供有许多公式供参考
可以看到,这个公式在 nnn 为偶数或奇数的条件处并没有对齐。

注意到 nnn 偶数前的灰色竖线了吗
在“nnn 偶数”前有一道灰色的竖线,其实就是 & 符号的效果,表示“对齐”。然而,只有这一行有竖线,因此为了保持对齐,需要在“nnn 奇数”前插入一个 &。& 不会显示出来,而是出现灰色竖线,表示两行对齐。

对齐
MathJax?KaTeX?哪个更好用
目前,在网页上显示数学公式最常用的方案是引入 JavaScript 对 LaTeX 代码进行渲染。例如,维基百科和 SegmentFault 都采用这种方案,其中使用最多的库是 MathJax 和 KaTeX。

KaTeX 官网的对比图
那么,应该选择哪一个呢?
与 MathJax 相比,KaTeX 的最大优点是整个库体积小巧,支持同步加载,公式绘制速度非常快。此外,KaTeX 也支持简单的化学反应式的编辑。因此,如果不是使用特别复杂、罕见的公式,建议使用 KaTeX。
MathJax 提供了多种数学字体,包括 Asana Math、Gyre Pagella、Latin Modern、Neo Euler、STIX Web 等。而 KaTeX 无法指定字体,仅提供默认的 Latin Modern Math。不过,本文将在下篇中介绍替换字体的方法。
如果希望使用类似教科书的数学字体,可以参考以下内容。国内的图书排版大多使用方正字体全家桶,而排版公式的字体也是方正独有的。因此,想要与教科书上完全一致的字体是不可能的。不过,可以选择一些风格接近的字体。例如,在撰写论文时,编辑部通常要求英文和数字字体使用 Times New Roman,这与教科书的字体风格较为接近。然而,Times New Roman 是为英文设计的字体,无法正常显示数学的特殊符号。
STIX 字体是专门为数学公式设计的一款 Times 风格字体。由 STIX 衍生的 XITS 字体增加了更多特殊符号的支持,XITS Math 可以在 Word 公式编辑器中使用。
Word 默认的数学字体是微软设计的 Cambria Math;而 LaTeX,包括 KaTeX 和 MathJax,默认的字体是 Latin Modern Math。个人比较喜欢 Times 风格字体,因为这种字体严肃、干净,装饰较少,在显示器这种分辨率较低的设备上显示较为清晰。

动手微调 KaTeX,让你的博客完美显示数学公式(下)
晓雾喵
 2021 年 02 月 17 日 20:47
KaTeX 使用
上文中介绍了为了在电脑上显示数学公式,众多研究者所做出的努力,并介绍了目前数学公式表示的事实标准——LaTeX,以及对比了 MathJax 和 KaTeX 这两款最常用的渲染数学公式的 Web 模块。本篇将专门讲解 KaTeX 的使用方法以及如何对其进行微调。
KaTeX 安装
首先需要安装 KaTeX。作为 JavaScript 库(模块),或者说是脚本,最常规的模式是在网页中载入脚本文件,由浏览器解析并绘制公式。
普通网页加载
<\link href="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/katex.min.css" ; rel="stylesheet"><\script src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/katex.min.js" ;>
<\script src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/auto-render.min.js" ;></script>
 
使用现代模块化前端技术的网页
const katex = require('katex');
 
基于 NodeJS 服务端的应用
如果是基于 NodeJS 服务端的应用,则是配合模块在服务端先渲染完成静态的 HTML 文件,再展示给客户端。
npm install katex
 
多脚本解析时间不一致可能出错
考虑到不同浏览器载入 JavaScript 脚本文件的机制可能不同,有时会出现脚本尚未完全解析完就开始绘制渲染公式,从而引发错误。此时可以在 ⟨script⟩\langle\text{script}\rangle⟨script⟩ 标签中加入一个 defer 属性。
<\script defer src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/katex.min.js" ;><\script defer src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/auto-render.min.js" ;>
 
在 HTML 中,浏览器解析时,遇到属性为 defer 的脚本会在后台进行下载,但不会阻止文档的解析。当页面解析完成且所有脚本加载完毕后,脚本会按照顺序执行,执行完毕后会触发事件,即开始渲染公式。
KaTeX 配置
完成安装后,需要在网页中创建并调用 KaTeX 对象。不过,这一步可以通过引用官方的 auto-render.min.js 脚本自动完成。
以下代码展示了 KaTeX 常用的配置方法。
document.addEventListener("DOMContentLoaded", function() {renderMathInElement(document.body, {delimiters: [{left: "$$", right: "$$", display: true},{left: "$", right: "$", display: false}],macros: {"\\ge": "\\geqslant","\\le": "\\leqslant","\\geq": "\\geqslant","\\leq": "\\leqslant"}});
});
 
分隔符
分隔符用于限定 KaTeX 的代码范围,可以手动指定多种不同的分隔符。对于公式排版,有内嵌(Inline)和显示(Display)两种文字环绕方式。前者表示公式与文字混排,与其他正文在同一行中;后者表示公式单独列出一行,内容居中。
在 Markdown 中,$$ 和 $$$$ 是最常用的公式分隔符,其中 $$ 表示 inline,$$$$ 表示 display,配置如下。
delimiters: [{left: "$$", right: "$$", display: true},{left: "$", right: "$", display: false}
]
 
配置宏
宏可以用于设置别名(alias)或缩短指令长度。例如,宏可以解决前文提到的大于等于号或小于等于号样式不一致的问题。通过指定宏,例如将 \ge 替换为 \geqslant,可以在不修改 LaTeX 代码的情况下统一不等号的样式。
macros: {"\\ge": "\\geqslant","\\le": "\\leqslant","\\geq": "\\geqslant","\\leq": "\\leqslant"
}
 
KaTeX 样式调整
默认情况下,KaTeX 与 MathJax 绘制的公式文字会略大于标准文字大小。例如,KaTeX 的默认大小为 1.2em。在与正文混排时,公式可能会显得不协调。根据 KaTeX 的官方文档,可以在 CSS 中将字体大小修改为 1.1em,以使公式与正文保持一致的大小,配置如下。
.katex {font-size: 1.1em;text-indent: 0;text-rendering: auto;
}
 
KaTeX 扩展
KaTeX 提供了许多扩展功能,方便有额外需求的用户使用。
例如,KaTeX 在绘制公式后,如果选中公式并复制,得到的是一串没有格式的字母。而使用 copy-tex 扩展可以直接复制页面上的公式为 LaTeX 代码。

你以为选中的是一堆字符?不,其实是 LaTeX 代码
只需在网页中加入以下 CSS 文件和脚本即可。
<\link href="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/copy-tex.css" ; rel="stylesheet"><\script src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/copy-tex.js" ;>
 
如果用户是化学相关专业的从业人员、学生或教师,可以使用 mhchem 扩展。
该扩展不受 LaTeX 语法的束缚,可以用最简明的代码写出规范的化学方程式。

−>-\gt−> 表示箭头,元素下标不用 _\__ 表示,大大简化了代码
同样,只需在网页中加入以下脚本即可。
<script src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/mhchem.min.js" ;>
 
更换 STIX 字体
在 KaTeX 中,通过引用具体的字体文件,定义字体族名,再对 CSS 绘制的公式各个部分应用不同的字体样式,实现公式渲染功能。
@font-face {font-family: KaTeX_AMS;src: url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype");font-weight: 400;font-style: normal
}
 
在最初的尝试中,我将字体定义的文件路径修改为 STIX 文件的绝对路径。然而,CSS 中引用绝对路径的文件存在跨域问题,触发服务器安全机制,导致无法正常加载字体文件。最终,我决定直接替换原有的字体文件。
查看 KaTeX 默认字体的文件列表(以 woff 为例,除此之外还有 ttf、woff2 格式的同名文件):
KaTeX_AMS-Regular.woff
KaTeX_Caligraphic-Bold.woff
KaTeX_Caligraphic-Regular.woff
KaTeX_Fraktur-Bold.woff
KaTeX_Fraktur-Regular.woff
KaTeX_Main-Bold.woff
KaTeX_Main-BoldItalic.woff
KaTeX_Main-Italic.woff
KaTeX_Main-Regular.woff
KaTeX_Math-BoldItalic.woff
KaTeX_Math-Italic.woff
KaTeX_SansSerif-Bold.woff
KaTeX_SansSerif-Italic.woff
KaTeX_SansSerif-Regular.woff
KaTeX_Script-Regular.woff
KaTeX_Size1-Regular.woff
KaTeX_Size2-Regular.woff
KaTeX_Size3-Regular.woff
KaTeX_Size4-Regular.woff
KaTeX_Typewriter-Regular.woff
 
MathJax 提供了多种数学字体,包括 Asana Math、Gyre Pagella、Latin Modern、Neo Euler、STIX Web 等。字体格式有 eot、otf、woff 等。以 STIX 字体的 woff 格式为例,再将 woff 转换为 KaTeX 所需的 woff2、ttf 格式。
STIXMathJax_Alphabets-Bold.woff
STIXMathJax_Alphabets-BoldItalic.woff
STIXMathJax_Alphabets-Italic.woff
STIXMathJax_Alphabets-Regular.woff
STIXMathJax_Arrows-Bold.woff
STIXMathJax_Arrows-Regular.woff
STIXMathJax_DoubleStruck-Bold.woff
STIXMathJax_DoubleStruck-BoldItalic.woff
STIXMathJax_DoubleStruck-Italic.woff
STIXMathJax_DoubleStruck-Regular.woff
STIXMathJax_Fraktur-Bold.woff
STIXMathJax_Fraktur-Regular.woff
STIXMathJax_Latin-Bold.woff
STIXMathJax_Latin-BoldItalic.woff
STIXMathJax_Latin-Italic.woff
STIXMathJax_Latin-Regular.woff
STIXMathJax_Main-Bold.woff
STIXMathJax_Main-BoldItalic.woff
STIXMathJax_Main-Italic.woff
STIXMathJax_Main-Regular.woff
STIXMathJax_Marks-Bold.woff
STIXMathJax_Marks-BoldItalic.woff
STIXMathJax_Marks-Italic.woff
STIXMathJax_Marks-Regular.woff
STIXMathJax_Misc-Bold.woff
STIXMathJax_Misc-BoldItalic.woff
STIXMathJax_Misc-Italic.woff
STIXMathJax_Misc-Regular.woff
STIXMathJax_Monospace-Regular.woff
STIXMathJax_Normal-Bold.woff
STIXMathJax_Normal-BoldItalic.woff
STIXMathJax_Normal-Italic.woff
STIXMathJax_Operators-Bold.woff
STIXMathJax_Operators-Regular.woff
STIXMathJax_SansSerif-Bold.woff
STIXMathJax_SansSerif-BoldItalic.woff
STIXMathJax_SansSerif-Italic.woff
STIXMathJax_SansSerif-Regular.woff
STIXMathJax_Script-BoldItalic.woff
STIXMathJax_Script-Italic.woff
STIXMathJax_Script-Regular.woff
STIXMathJax_Shapes-Bold.woff
STIXMathJax_Shapes-BoldItalic.woff
STIXMathJax_Shapes-Regular.woff
STIXMathJax_Size1-Regular.woff
STIXMathJax_Size2-Regular.woff
STIXMathJax_Size3-Regular.woff
STIXMathJax_Size4-Regular.woff
STIXMathJax_Size5-Regular.woff
STIXMathJax_Symbols-Bold.woff
STIXMathJax_Symbols-Regular.woff
STIXMathJax_Variants-Bold.woff
STIXMathJax_Variants-BoldItalic.woff
STIXMathJax_Variants-Italic.woff
STIXMathJax_Variants-Regular.woff
 
可以看到,MathJax 的 STIX 字体分割得非常详细,与 KaTeX 的字体差别较大,因此不能完整地替换。使用 FontCreator 软件对两种字体的字模进行分析对比后,我发现 STIXMathJax_Main-Regular 和 STIXMathJax_Main-Italic 的字模足以覆盖 KaTeX_Main-Regular 和 KaTeX_Math-Italic 两个文件,且字符的内部名称一致,替换后可能出现的问题最少。
因此,在替换原有的字体文件后,再将 CSS 中的 KaTeX_Main 和 KaTeX_Math 指向同一文件。
@font-face {font-family: KaTeX_Main;src: url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype");font-weight: 400;font-style: normal
}
@font-face {font-family: KaTeX_Math;src: url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype");font-weight: 400;font-style: italic
}
 
公式渲染效果

行内公式(圆)
对于一般的圆 $x^2 + y^2 + Dx + Ey + F = 0$,其圆心坐标为 $\left(-\cfrac{D}{2}, -\cfrac{E}{2}\right)$,半径为 $\cfrac{\sqrt{D^2 + E^2 - 4F}}{2}$
 

等号换行对齐(二倍角公式)
$\begin{aligned} \sin 2\theta & = 2\sin \theta \cos \theta \\ & = \cfrac{2 \tan \theta}{1 + \tan^2 \theta} \end{aligned}$
 

分段函数、含中文(概率密度函数)
$f(x) = \left\{ \begin{array}{ll} \lambda e^{-\lambda x}, & x > 0 \\ 0, & 其它 \end{array} \right. (\lambda > 0)$
 

矩阵(矩阵定义)
$A_{m,n} = \begin{pmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,n} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m,1} & a_{m,2} & \cdots & a_{m,n} \end{pmatrix}$
 

含积分、行列式等复杂应用(斯托克斯公式)
∬Σ∣cosαcosβcosγ∂∂x∂∂y∂∂zPQR∣dS=∮ΓPdx+Qdy+Rdz\iint_{\Sigma}\begin{vmatrix} \cos \alpha & \cos \beta & \cos \gamma \\ \cfrac{\partial}{\partial x} & \cfrac{\partial}{\partial y} & \cfrac{\partial}{\partial z} \\ P & Q & R \end{vmatrix}dS = \oint_{\Gamma}Pdx + Qdy + Rdz∬Σcosα∂x∂Pcosβ∂y∂Qcosγ∂z∂RdS=∮ΓPdx+Qdy+Rdz

引用 mhchem 模块实现化学方程式
$\ce{x Na(NH4)HPO4 ->[\Delta] (NaPO3)_x + x NH3 ^ + x H2O}$
 
xNa(NH4HPO4) →Δ(NaPO3)x+xNH3↑+xH2Ox\text{Na(NH}_4\text{HPO}_4\text{) } \xrightarrow{\Delta} \text{(NaPO}_3\text{)}_x + x \text{NH}_3 \uparrow + x \text{H}_2\text{O}xNa(NH4HPO4) Δ(NaPO3)x+xNH3↑+xH2O
顺便一提,B 站专栏的公式编辑器也支持 \ce 化学方程式,功能强大且实用。
在轻前端网页显示数学公式 - 使用 KaTeX
darkthread 2025-02-16 10:46 AM
目前主流的 Markdown 编辑软件、套件或程序库几乎都支持内建功能。我的博客平台是自行开发维护的,因此需要自行实现支持功能。
研究后发现,目前 LaTeX 主流的 JavaScript 程序库有两套:MathJax 和 KaTeX。
二者的主要差异如下:
- MathJax:程序库体积较大,渲染速度较慢,但支持完整的 LaTeX 语法,并且与 React、Vue、Angular 等框架的整合性较好。
 - KaTeX:程序库较为轻巧,渲染速度较快,但仅支持部分 LaTeX 语法。
 
KaTeX 官网 提供了二者速度对比的动态展示,效果令人印象深刻。我个人偏好简单轻巧的解决方案,且由于不会使用过于复杂的语法,因此选择了 KaTeX。
要在既有网页中使用 KaTeX,只需引用 katex.min.css 和 katex.min.js。KaTeX 官网提供了针对在浏览器直接引用的 完整说明,对轻前端开发者非常友好。
以下示例展示了如何直接使用 CDN 并添加几行代码来生成数学公式:
<!DOCTYPE html>
<html><head><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css"><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.js"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/contrib/auto-render.min.js"onload="renderMathInElement(document.body);"></script><script></script>
</head><body><p>函式、根號 \(f(x) = \sqrt[3]{2x} + \sqrt{x-2}\),极限 \(\lim_{x \to 0^+} \dfrac{1}{x} = \infty\) (Inline 形式)</p>无穷级数 (Block 形式,使用 <code>\[ \]</code> 或 <code>$$ $$</code>)$$\mathrm{e} = \sum_{n=0}^{\infty} \dfrac{1}{n!}$$微分\[\frac{d}{dx} x^2 = 2x\]积分$$\int_a^b y \: \mathrm{d}x$$矩阵$$M =\begin{bmatrix}\frac{1}{2} & 0 \\0 & -1\end{bmatrix}\begin{bmatrix}1 & 0 \\0 & 1\end{bmatrix}$$矩阵(...)$$A_{m,n} =\begin{pmatrix}a_{1,1} & a_{1,2} & \cdots & a_{1,n} \\a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\\vdots & \vdots & \ddots & \vdots \\a_{m,1} & a_{m,2} & \cdots & a_{m,n}\end{pmatrix}$$
</body></html>
 

 官方范例使用 defer 异步加载,再呼叫社群链接库(auto-render.min.js)的 renderMathInElement() 扫描网页中的 LaTeX 语法,自动转成数学公式。识别依据是寻找用 $$...$$ 或 \[ ... \] 包夹的文字转成区块,用 \(...\) 包夹的内容则会以 Inline 方式穿插在原有文字内容中。另一种常见的 Inline 标示法 $...$ 因为太容易误判,预设不启用。而扫描范围会排除 script, noscript, style, textarea, pre, code, option 等元素。要完整掌握 renderMathInElement() 行为模式,最好的做法是看原始码,所有的疑问马上都能获得解答:
const renderMathInElement = function(elem, options) {if (!elem) {throw new Error("No element provided to render");}const optionsCopy = {};// Object.assign(optionsCopy, option)for (const option in options) {if (options.hasOwnProperty(option)) {optionsCopy[option] = options[option];}}// default optionsoptionsCopy.delimiters = optionsCopy.delimiters || [{left: "$$", right: "$$", display: true},{left: "\\(", right: "\\)", display: false},// LaTeX uses $…$, but it ruins the display of normal `$` in text:// {left: "$", right: "$", display: false},// $ must come after $$// Render AMS environments even if outside $$…$$ delimiters.{left: "\\begin{equation}", right: "\\end{equation}", display: true},{left: "\\begin{align}", right: "\\end{align}", display: true},{left: "\\begin{alignat}", right: "\\end{alignat}", display: true},{left: "\\begin{gather}", right: "\\end{gather}", display: true},{left: "\\begin{CD}", right: "\\end{CD}", display: true},{left: "\\[", right: "\\]", display: true},];optionsCopy.ignoredTags = optionsCopy.ignoredTags || ["script", "noscript", "style", "textarea", "pre", "code", "option",];optionsCopy.ignoredClasses = optionsCopy.ignoredClasses || [];optionsCopy.errorCallback = optionsCopy.errorCallback || console.error;// Enable sharing of global macros defined via `\gdef` between different// math elements within a single call to `renderMathInElement`.optionsCopy.macros = optionsCopy.macros || {};renderElem(elem, optionsCopy);
};
 
由于我是在 Markdown 转出结果套用 KaTeX,有机会透过特定语法格式控制转换范围,比自动扫描有效率并可避免误判。我设计的做法是用 `` 或 ````包夹公式,配合 $ 及 $$ 卷标,范例如下
<!DOCTYPE html>
<html><head><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css"><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.js"></script><script>function parseCodeBlockLaTeX() {document.querySelectorAll('code').forEach((block) => {let tex = block.textContent.replace(/^\s+|\s+$/g, '');if (tex.match(/^\$\$.*\$\$$/s) || tex.match(/^\$.*[^$]\$$/s)) {tex = tex.replace(/^\${1,2}|\${1,2}$/g, '');let el = document.createElement('span');katex.render(tex, el);block.parentNode.replaceChild(el, block);}});}document.addEventListener('DOMContentLoaded', parseCodeBlockLaTeX);</script>
</head><body><p>函式、根號 <code>$f(x) = \sqrt[3]{2x} + \sqrt{x-2}$</code>,极限 <code>$\lim_{x \to 0^+} \dfrac{1}{x} = \infty$</code></p><p>无穷级数 <code>$$\mathrm{e} = \sum_{n=0}^{\infty} \dfrac{1}{n!}$$</code></p><p>矩阵</p><p><code>$$M =\begin{bmatrix}\frac{1}{2} & 0 \\0 & -1\end{bmatrix}\begin{bmatrix}1 & 0 \\0 & 1\end{bmatrix}$$</code></p><p>不转换</p><p><code>X$f(x)$</code>、<code>$f(x)$X</code>、<code>$$f(x)$</code>、<code>$f(x)$$</code>        </p>
</body></html>
 

掌握以上技巧后,我们便可以在网页上轻松显示数学公式了。
via:
- 动手微调KaTeX,让你的博客完美显示数学公式(上) - 哔哩哔哩
https://www.bilibili.com/opus/489781998672601418/ - 动手微调KaTeX,让你的博客完美显示数学公式(下) - 哔哩哔哩
https://www.bilibili.com/opus/492751393031974929/ - 在輕前端網頁顯示數學公式 - 使用 KaTeX-黑暗執行緒
https://blog.darkthread.net/blog/katex/ - Markdown 文件寫作實務 - 數學公式、流程圖-黑暗執行緒
https://blog.darkthread.net/blog/markdown-latex-mermaid/- Supporting LaTeX on hugo
https://blog.juny.wang/posts/support-latex/ 
 - Supporting LaTeX on hugo
 - Markdown and LaTeX introduction
https://ashki23.github.io/markdown-latex.html - Auto-render Extension · KaTeX
https://katex.org/docs/autorender.html 
