在Markdown文档编写中,我们可以使用$\LaTeX$的语法输入数学公式。常见的Markdown编辑器如Typora都可以方便地渲染数学公式。然而,Hexo在默认设置下部署博客时,并不能渲染数学公式。
原因在于,渲染数学公式需要使用MathJax(一种模块化的JavaScript框架);而Hexo的默认渲染器是hexo-renderer-marked引擎,它并不支持MathJax。
1. 更换渲染引擎
Hexo-renderer-kramed引擎在hexo-renderer-marked渲染引擎的基础上修改了一些bug(“kram”这个名字目测是把“mark”倒过来拼写得到的),支持了MathJax。因此,将渲染引擎改为Hexo-renderer-kramed可以解决数学公式渲染的问题。
使用Git Bash打开自己的博客文件夹,输入下面的代码即可卸载marked、安装kramed:
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save
中国用户还可使用cnpm
命令代替npm
,获得更好体验。cnpm
命令的安装可自行搜索,这里不再赘述。
更换渲染引擎之后,还需要相应地更改一些其他配置。
2. 修改配置文件
诸多网文混淆了站点配置文件和主题配置文件。二者的文件名都是_config.yml
,但文件的位置不同。站点配置文件位于博客的根目录,即.\_config.yml
,管理的是整个博客的全局设置;而主题配置文件则位于对应的主题文件夹之下,例如Ocean主题的配置文件路径为.\themes\ocean\_config.yml
,管理的是与该主题的相关的具体设置。
更换kramed引擎之后,需要在主题配置文件中增加这样几行:
mathjax:
enable: true
cdn: https://cdn.jsdelivr.net/npm/mathjax@2.7.8/MathJax.js?config=TeX-AMS-MML_HTMLorMML
还要在站点配置文件中增加:
math:
engine: 'mathjax'
mathjax:
src: custom_mathjax_source
3. 添加JavaScript脚本
根据一些网文的说法,如果博客使用的是Next主题,那么至此已经可以实现行间公式的渲染。不过,对于有些并未引入MathJax功能的主题,还需要自行增加JavaScript脚本文件。
以Ocean主题为例。首先打开.\themes\ocean\layout
文件夹,如果该目录下没有mathjax.ejs
文件,则新建 mathjax.ejs
文件。可以先新建一个txt文本文档,将后缀更改为.ejs
即可。
在mathjax.ejs
中写入如下内容:
<% if (theme.mathjax.enable){ %>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true,
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
}
});
MathJax.Hub.Queue(function() {
var all = MathJax.Hub.getAllJax(), i;
for(i=0; i < all.length; i += 1) {
all[i].SourceElement().parentNode.className += ' has-jax';
}
});
</script>
<script type="text/javascript" src="<%- theme.mathjax.cdn %>"></script>
<% } %>
此外,还要在.\themes\ocean\layout\post.ejs
中追加如下代码:
<% if (theme.mathjax){ %>
<%- partial('mathjax') %>
<% } %>
4. 打开MathJax开关
如果仍未能正确渲染数学公式,那么可能还需在Markdown文档的顶部配置里打开MathJax开关,即mathjax: true
:
---
title: 文章标题
date: 2021-01-01 00:00:00
mathjax: true
---
$$
e ^ {i\pi} + 1 = 0
$$
即可显示:
这行设置需要在每一篇用到数学公式的文章中手动添加。不添加这行设置,文章就不会加载MathJax,以提高页面渲染的速度。
5. 调整行内渲染设置
Markdown的公式分为行间公式和行内公式。经过上述配置之后,行间公式已经可以正确渲染。但行内公式仍有可能渲染错误。
原因在于Markdown语法和$\LaTeX$数学公式语法有一定冲突。例如,用两个下划线_
或两个星号*
包围的文字,在Markdown语法中都被识别为斜体;但在$\LaTeX$数学公式中,下划线_
用于表示下标。因此,当同一个行内公式中出现两个下标时,下划线_
会被转化为<em>
标签,二者之间的部分就会被渲染为斜体。这就造成了混乱。此外,反斜杠 \
和花括号 {}
也有可能造成渲染错误。
为此,需要更改与行内渲染相关的JavaScript脚本。回到博客根目录,打开.\node_modules\kramed\lib\rules\inline.js
(注意打开node_modules
文件夹之后选择的是kramed
文件夹,而不是hexo-renderer-kramed
文件夹),找到escape
变量,注释掉原来的值,并更新:
// escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/,
escape: /^\\([`*\[\]()#$+\-.!_>])/,
这样就取消了对反斜杠和花括号的转义(escape)。
再找到em
变量,注释掉原来的值,并更新:
// em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
这样就停用了以下划线标注斜体/强调(em)的语法。
此时,形如
$N = P_1 ^ {\alpha _1} P_2 ^ {\alpha _2} \cdots P_n ^ {\alpha _n}$,其中$P_1 < P_2 < \cdots < P_n$,$P_1 , P_2 , \cdots , P_n$为质数。
这样的复杂行内公式,就可以正确渲染了:$N = P_1 ^ {\alpha _1} P_2 ^ {\alpha _2} \cdots P_n ^ {\alpha _n}$,其中$P_1 < P_2 < \cdots < P_n$,$P_1 , P_2 , \cdots , P_n$为质数。
当然,调整行内渲染设置之后,在Markdown文档中就要用星号*
标注斜体文字,因为用下划线_
标注斜体的语法已经被停用了。
参考文献
- Hexo博客支持数学公式. https://blog.csdn.net/qq_38496329/article/details/104065659
- 在Hexo中渲染MathJax数学公式. https://www.jianshu.com/p/7ab21c7f0674
- 让 Hexo 支持 LaTeX 公式. https://blog.xiangfa.org/2020/09/let-hexo-support-latex-formulas/