数学公式网页可视化 | KaTeX 在网页中显示数学公式的应用与优化

注:本文为 “KaTeX 在网页中显示数学公式的应用” 相关合辑。
图片清晰度受引文原图所限。
略作重排,未整理去重。
如有内容异常,请看原文。


动手微调 KaTeX,让你的博客完美显示数学公式(上)

晓雾喵
2021年02月09日 20:44

为数学公式头疼的攻城狮和理科生

对于理科生而言,数学公式常常构成一项挑战。从视觉上看,公式结构复杂;在书写时,过程繁琐;而在电脑上显示公式,更是面临诸多技术难题。与普通文字按顺序排列不同,公式中的字符需要通过不同的位置来表示从属关系,例如右下角、右上角、符号上方等。以表示求和的 Σ \Sigma Σ 符号为例,其尺寸比普通字符大得多,且可以在符号的上方和下方添加其他符号。此外,仔细观察可以发现,数学公式中的括号高度各不相同。

img

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

img

铅字时期(上世纪)排版数学公式

理工科学生在撰写报告、论文以及参加数学建模比赛时,不可避免地要处理各种数学公式。因此,如何在电脑上高效地编辑和显示公式,成为了一个亟待解决的问题。

制订互联网标准的国际组织 W3C 在很久之前设计了 MathML 标准,用于在网页上显示公式。MathML 标准使用 XML 格式,将公式中的各个数字、字母和符号通过 XML 表示其从属关系,生成一段非常长且复杂的代码,然后通过浏览器渲染成人们可以识别的公式。然而,这一标准在实际应用中并未得到广泛推广。

img

MathML 排版数学公式,效果欠佳

1977 年,斯坦福大学的 Donald E. Knuth 开发了一套排版系统 TeX。之后,Leslie Lamport 在 TeX 的基础上进行了改进,开发出了现代最常用的排版系统 LaTeX。LaTeX 使用各种指令代码来控制排版,描述数学公式,并通过其引擎将文本文件转换成如 pdf 这样的可以交付印刷的格式。然而,LaTeX 在使用时需要记住许多命令和符号,因此学习难度较大。大多数人更习惯使用 MathType、Office 自带公式编辑器这类可以点选符号的工具。

MathType 的原理是将绘制的矢量图格式以图片的形式嵌入文档中。如果需要编辑,双击公式,调用 MathType 程序进行修改。这样绘制的公式放大后不会失真,公式的样式符合标准,但编辑起来较为麻烦。尤其是当文档中嵌入大量公式时,需要一一双击修改,且与文字混排时不易对齐,较长的公式也无法换行等。

微软的 Office 从 2010 版本开始提供了自带的公式编辑器,可以编辑一些相对简单的公式。与 MathType 相比,微软自带的公式编辑器可以换行、批量选中更改大小和字体,使用起来非常方便。

img

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 表示。

img

普通样式的符号和书本上常见的 slanted(倾斜)样式

如果更倾向于倾斜的风格,可以使用 \geqslant\leqslant 指令。

分式扁扁的……

在 LaTeX 中,表示分式使用 \frac{a}{b} 指令,其中 a a a 是分子, b b b 是分母。使用 \frac 指令时,有时会看到分式被压扁的情况。

img

分式被压扁

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

img

使用 \cfrac,分式不会被压扁

建议使用 \dfrac{}{} 指令代替 \frac{}{},因为 \dfrac 表示 display(显示),而 \cfrac 表示 continued(连分式)。二者效果相同,但语义不同。

2022-04-19 09:38

方程组、换行等号不对齐

在 LaTeX 中,换行使用两个斜线 \\ 表示,前后用 \begin{aligned} {公式} \end{aligned} 包裹起来可以让换行后的公式自动对齐。然而,仔细观察下图可以发现,第一行和第二行的等号并没有完全对齐。

img

等号没有对齐

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

img

注意黄色标注的 & 符号

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

img

Word 中还提供有许多公式供参考

可以看到,这个公式在 n n n 为偶数或奇数的条件处并没有对齐。

img

注意到 n n n 偶数前的灰色竖线了吗

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

img

对齐

MathJax?KaTeX?哪个更好用

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

img

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 风格字体,因为这种字体严肃、干净,装饰较少,在显示器这种分辨率较低的设备上显示较为清晰。

img


动手微调 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&#34 ; rel="stylesheet"><\script src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/katex.min.js&#34 ;>
<\script src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/auto-render.min.js&#34 ;></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&#34 ;><\script defer src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/auto-render.min.js&#34 ;>

在 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 代码。

img

你以为选中的是一堆字符?不,其实是 LaTeX 代码

只需在网页中加入以下 CSS 文件和脚本即可。

<\link href="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/copy-tex.css&#34 ; rel="stylesheet"><\script src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/copy-tex.js&#34 ;>

如果用户是化学相关专业的从业人员、学生或教师,可以使用 mhchem 扩展。

该扩展不受 LaTeX 语法的束缚,可以用最简明的代码写出规范的化学方程式

img

− > -\gt > 表示箭头,元素下标不用 _ \_ _ 表示,大大简化了代码

同样,只需在网页中加入以下脚本即可。

<script src="https://cdn.bootcdn.net/ajax/libs/KaTeX/0.12.0/contrib/mhchem.min.js&#34 ;>

更换 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
}

公式渲染效果

img

行内公式(圆)

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

img

等号换行对齐(二倍角公式)

$\begin{aligned} \sin 2\theta & = 2\sin \theta \cos \theta \\ & = \cfrac{2 \tan \theta}{1 + \tan^2 \theta} \end{aligned}$

img

分段函数、含中文(概率密度函数)

$f(x) = \left\{ \begin{array}{ll} \lambda e^{-\lambda x}, & x > 0 \\ 0, & 其它 \end{array} \right. (\lambda > 0)$

img

矩阵(矩阵定义)

$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}$

img

含积分、行列式等复杂应用(斯托克斯公式)

∬ Σ ∣ cos ⁡ α cos ⁡ β cos ⁡ γ ∂ ∂ x ∂ ∂ y ∂ ∂ z P Q R ∣ d S = ∮ Γ P d x + Q d y + R d z \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αxPcosβyQcosγzR dS=ΓPdx+Qdy+Rdz

img

引用 mhchem 模块实现化学方程式

$\ce{x Na(NH4)HPO4 ->[\Delta] (NaPO3)_x + x NH3 ^ + x H2O}$

x Na(NH 4 HPO 4 )  → Δ (NaPO 3 ) x + x NH 3 ↑ + x H 2 O x\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 options
    optionsCopy.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>

img

掌握以上技巧后,我们便可以在网页上轻松显示数学公式了。


via:

【电能质量扰动】基于ML和DWT的电能质量扰动分类方法研究(Matlab实现)内容概要:本文研究了一种基于机器学习(ML)和离散小波变换(DWT)的电能质量扰动分类方法,并提供了Matlab实现方案。首先利用DWT对电能质量信号进行多尺度分解,提取信号的时频域特征,有效捕捉电压暂降、暂升、中断、谐波、闪变等常见扰动的关键信息;随后结合机器学习分类器(如SVM、BP神经网络等)对提取的特征进行训练分类,实现对不同类型扰动的自动识别准确区分。该方法充分发挥DWT在信号去噪特征提取方面的优势,结合ML强大的模式识别能力,提升了分类精度鲁棒性,具有较强的实用价值。; 适合人群:电气工程、自动化、电力系统及其自动化等相关专业的研究生、科研人员及从事电能质量监测分析的工程技术人员;具备一定的信号处理基础和Matlab编程能力者更佳。; 使用场景及目标:①应用于智能电网中的电能质量在线监测系统,实现扰动类型的自动识别;②作为高校或科研机构在信号处理、模式识别、电力系统分析等课程的教学案例或科研实验平台;③目标是提高电能质量扰动分类的准确性效率,为后续的电能治理设备保护提供决策依据。; 阅读建议:建议读者结合Matlab代码深入理解DWT的实现过程特征提取步骤,重点关注小波基选择、分解层数设定及特征向量构造对分类性能的影响,并尝试对比不同机器学习模型的分类效果,以全面掌握该方法的核心技术要点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值