在Hexo中使用LaTeX语法输入数学公式

引子

作为一款以简洁为宗旨的标记语言,HTML的扩展性并不强,其自身也不具有满足一些特殊需求的功能,要使用HTML渲染出漂亮的数学公式可以说并非轻而易举,因此大多数人使用截图上传的方式实现在网页上展示数学公式。
但前阵子浏览Wikipedia,便偶然想到一个问题此多的数学公式,如果都使用截图上传的方式来展现,岂不是太费力气了。这显然是不现实的。
原来,对于在网页上展示数学公式这个问题,早已经有前辈开发了具有对应功能的插件来解决了,这便是MathJax。

MathJax是一款用以支持在网页中插入数学公式的开源JavaScript插件。支持LaTeX、MathML等多种语言。它负责将网页上指定标签内用这些标记语言的语法输入的数学公式渲染成HTML和CSS代码,使这些漂亮的数学公式不需要复杂的代码便可以在网页中被渲染出来。
在此之前,我在书写博文时也采用传统的截图上传的方式来展示数学公式,这样的方式带来的几个问题便是操作量大、整齐性不佳、加载速度慢。因此在前不久重新开始打理博客时,便产生了使用MathJax的想法。于是着手进行了一番尝试。

在Hexo中启用MathJax

Hexo原生兼容MathJax,且大多数主流主题如醉仙阁所采用的Next都内置了MathJax,此处即以其为例,在Next中启用MathJax只需要一步。在主题目录下找到_config.yml。用文本编辑器找到如下部分:

plain _config.yml
1
2
3
4
5
# MathJax Support
mathjax:
enable: false
per_page: true
cdn: //cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML

将第二行修改为enable: true即可。

如此以来就在Next主题中启用了MathJax支持,但事实上还存在着不少问题:

  • 部分数学公式直接显示为代码的形式
  • 部分数学公式的下标、角标等显示异常
  • 希腊字母字体显示异常

更换渲染引擎

Hexo默认使用hexo-renderer-marked引擎进行网页渲染,其中对许多字符诸如划线、下划线、中括号等定义了转义。因此,在进行网页渲染时,数学公式中的这些字符先通过hexo-renderer-marked进行转义,就发生了歧义,而再通过MathJax渲染出来的数学公式,自然就显示不正常了。
在知道了原因以后,问题也就迎刃而解了,解决方法就是更换Hexo默认的hexo-renderer-marked渲染引擎。hexo-renderer-kramed就是一个不错的选择,它在hexo-renderer-marked的基础上修复了一些Bug,其中就包括取消大部分多余的转义。
安装hexo-renderer-kramed非常简单,只需在Hexo根目录下执行以下命令:

git
1
npm install hexo-renderer-kramed --save

这样就完成了hexo-renderer-kramed的安装,但还有一个容易被忽略的问题是,安装hexo-renderer-kramed的同时并不会自动对hexo-renderer-marked进行停用,数学公式仍要经过hexo-renderer-marked的转义,这样显然没有完全解决问题,故我们还需手动对hexo-renderer-marked进行停用。
在Hexo的根目录下找到package.json文件,用文本编辑器打开它,删除字符串hexo-renderer-marked所在的一行并保存。之所以不直接卸载hexo-renderer-marked,是因为其他重要包极有可能在卸载该包的同时被删除。

修复行内公式的转义字符

在做完工作上面的工作后,行间公式就可以被正确渲染了,但行内公式却还存在着部分问题,这是因为对行间定义的转义字符和对行内定义的转义字符并不相同,还有部分已定义的行间转义字符会与数学公式中可能用到的字符发生冲突,用到这些字符的数学公式在渲染前仍被进行了转义。
修复这一问题的方法是,在根目录下依次打开node_modules\kramed\lib\rules,并找到inline.js文件。
用文本编辑器编辑文件的第11行和第20行:

js inline.js
1
2
3
4
5
6
7
line 11,
// escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/,
-> escape: /^\\([`*\[\]()#$+\-.!_>])/

line 20,
// em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
-> em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/

保存文件。如此一来,所有对数学公式中字符的不合理转义就都被取消了,数学公式的渲染和显示也就正常了。

确保所有公式都被渲染

在条件支持的情况下,MathJax会对页面上的所有位置的标签内都进行渲染;但在条件不允许时,MathJax对数学公式的渲染可能止于页面上的某个位置,其后的数学公式都将不被渲染而直接显示为代码的形式。
这时,就需要在文章的开头font-matter中手动打开MathJax的开关,如下图:

plain _config.yml
1
2
3
4
5
6
---
title: index.html
date: 2016-12-28 21:01:30
tags:
mathjax: true
---

如上,在使用了数学公式的页面上增加一行mathjax: true,这样就能确保页面上所有数学公式都被正确渲染了。


参考资料: