平时记录笔记过程中遇到数学公式在所难免,使用 MathJax 可以方便地在网页中渲染这些公式,可一旦公式较多,页面加载起来就异乎寻常的慢。于是乎,就找来了替代工具:KATEX。
KaTeX
KaTeX 是一个支持在网页上显示 Tex 公式的 JavaScript 库,相较于 MathJax,KaTeX 最大的特点是渲染速度快。到底有多大差别,可以通过 KaTeX and MathJax Comparison Demo 比较一下两者的渲染速度,我使用 Chrome 浏览器渲染同一页面,两者的速度分别为 142 ms 和 3600 ms,高下立见。当然,为了达到这样的速度是有所牺牲的,KaTeX 支持的符号相对少一些,某些公式的渲染质量也不如 MathJax,这就看个人取舍了。
在 Jekyll 中使用 KaTeX
添加依赖文件
使用 KaTeX 很简单,可以下载其库文件(KaTeX.min.js
, KaTeX.min.css
及字体)自行托管,也可以使用 CDN:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.css">
<script src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.js"></script>
当然,并不是每个页面都需要加载它们,所以可以在每篇文章的页首中加个变量如:math: true
作为判断有选择的调用。
kramdown 与 KaTeX
kramdown 默认使用 MathJax 引擎。Markdown 转换后的 HTML 中将数学公式包含在 <script type="math/tex">
标签中,改用 KaTeX 的时候,需要使用 JavaScript 转换一下:
<script>
$("script[type='math/tex']").replaceWith(function() {
var tex = $(this).text();
return KaTeX.renderToString(tex, {displayMode: false});
});
$("script[type='math/tex; mode=display']").replaceWith(function() {
var tex = $(this).html();
return KaTeX.renderToString(tex.replace(/%.*/g, ''), {displayMode: true});
});
</script>
将上面代码(这里使用了 jQuery)放在页面底部 </body>
之前(jQuery 和 katex.min.js
之后),当网页加载时交给 KaTeX 引擎处理。当然,后面我会介绍另一种方法,在 Jekyll 生成 HTML 的就处理这些公式。
接下来,是在 markdown 文件中使用 Tex。只需将 Tex 公式包含在两个 $$
之间就行,行内公式和公式块都使用这种格式。
例如,行内公式:∫udxdvdx=uv−∫dxduvdx。
直接将 $$ \int u \frac{dv}{dx}\,dx=uv-\int \frac{du}{dx}v\,dx $$
置于正文中就可以了。
再如,行间公式块:
∫udxdvdx=uv−∫dxduvdx x˙y˙z˙=σ(y−x)=ρx−y−xz=−βz+xy就像代码块一样,将公式置于新段落中:
$$ \int u \frac{dv}{dx}\,dx=uv-\int \frac{du}{dx}v\,dx $$
$$
\begin{aligned}
\dot{x} & = \sigma(y-x) \\
\dot{y} & = \rho x - y - xz \\
\dot{z} & = -\beta z + xy
\end{aligned}
$$
对于简单的数学公式,KaTeX 是够够的。好了,来个麦克斯韦方程组做结束吧。
∇⋅E∇⋅B∇×E∇×B=4πρ=0=−c1∂t∂B=c1(4πJ+∂t∂E)$$
\begin{aligned}
\nabla \cdot \mathbf{E} &= 4 \pi \rho \\
\nabla \cdot \mathbf{B} &= 0 \\
\nabla \times \mathbf{E} &= - \frac{1}{c} \frac{\partial \mathbf{B}}{\partial t} \\
\nabla \times \mathbf{B} &= \frac{1}{c} ({4 \pi} \mathbf{J} + \frac{\partial \mathbf{E}}{\partial t})
\end{aligned}
$$
使用 SsKaTeX
kramdown 最近更新了 SsKaTeX 数学引擎,可以直接在 Jekyll 生成静态文件的时候处理 KaTeX,而不需要后期再使用 JavaScript 将 MathJax 格式转换。
要使用新的 SsKaTeX 数学引擎需要添加以下工具:
- Ruby gem: sskatex
- Ruby gem: execjs
- A Javascript engine supported by ExecJS (选一个就行,我用的 duktape)
katex.min.js
from KaTeX.
将以上 gem 添加到 Gemfile 中,然后 bundle
,之后在 _config.yml
中设置:
markdown: kramdown
kramdown:
math_engine: sskatex
math_engine_opts:
katex_js: './assets/scripts/katex.min.js'
当然,你依然需要将 katex.min.js
和 katex.min.css
添加到网页相应位置。
更新:我现在需要使用的 gem 如下,sskatex
更新为 kramdown-math-sskatex
:
group :jekyll_plugins do
gem "kramdown-math-sskatex"
gem "execjs"
gem "duktape"
end
在 Gemfile
中添加上述插件,然后再使用 bundler 安装更新一下就好了。
小更新:
如果你更新了最新的 katex 的 js (v0.13.xx),有可能在 jekyll build
的时候就会出错 😮💨。我也没找到什么原因~
暂时的解决办法就是在 _config.yml
设置中提供一个 v0.12.xx 的 JavaScript 文件,而在网页端可以继续使用最新的 v0.13.xx 的 JS 和 CSS,看起来没啥问题,有问题再解决吧~