渲染 Hexo 博客里的 latex 公式

当初打算建一个Hexo博客的原因之一,是可以方便地添加latex支持。前些天写nlp的课程笔记,需要写公式时,才发现事情要更加复杂。

next主题的latex支持

我目前用的next主题,是可以直接配置公式支持,可选择mathjax和katex两种主流插件。

mathjax使用js动态渲染用$标记的latex代码,提供一些交互操作。

katex有js版和css版,next主题支持的是后者。显然,需要先把latex公式渲染成katex对应的html代码,公式才能正确显示。好处是,网页里公式的加载速度更快。另外,相较于mathjax,katex的对latex的语法支持更有限。

markdown渲染器的不足

然而事情没有这么简单,接下来的问题是,hexo的默认渲染器hexo-renderer-marked不支持latex语法,一些latex中的符号会被误认为是markdown语法,比如\_*,这让mathjax不能正确地渲染(katex需要渲染器支持,根本不能工作)。粗暴的办法是,写latex公式时,对冲突符号添加markdown转义符号\,这个方法很糟糕,公式书写不便,可移植性也差。或者修改渲染器代码里的正则表达式,改动语法规则,例如去掉markdown里用*强调的语法,参考这篇文章,我也不喜欢这个办法。

我看了不少讨论解决方案的文章,next主题的文档写得最清晰。

办法就是替换Hexo的渲染器,比如在博客目录下执行:

1
2
npm un hexo-renderer-marked --save
npm i hexo-renderer-pandoc --save # or hexo-renderer-kramed

事情也没有到此为止,切换渲染器并不是无痛的。

对于mathjax,可以选择hexo-renderer-pandoc或hexo-renderer-kramed。

hexo-renderer-pandoc用的是pandoc渲染器,需要先额外地安装它。pandoc是一种特别设计的markdown语法,用它写的文档可以转换成五花八门的格式,该语法天然支持latex。这也意味着pandoc与markdown语法不全相同。

hexo-renderer-kramed渲染器也有缺点,它不支持行内latex公式。解决办法是有的——和上面一样,要么在行内自己加上转义符号,要么修改渲染规则。渲染器作者建议是用`把公式标注成代码块,参见此处

对于katex,可以用hexo-renderer-markdown-it-plus或者hexo-renderer-markdown-it。 看其他人的使用感受也是不如人意。。。

所见即所得的方案

我研究到这里的时候简直心累,然后想到了我用的markdown编辑器HexoEditor,公式渲染得挺好的,如果博客上也用这个,岂不是做到了所见即所得。

我去翻github。HexoEditor继承自Moeditor,在Moeditor作者的仓库里真的有一个Hexo渲染器hexo-renderer-moemark-pygments,这个是利用katex的。用npm从git仓库安装依赖很方便:

1
2
npm un hexo-renderer-marked --save
npm i https://github.com/Moeditor/hexo-renderer-moemark-pygments.git

配置next主题启用katex支持后,博客的渲染效果就和HexoEditor里的一致了,是很让我满意的方案了。

这里有个小坑。next的配置里有个perpage选项,打开后,只对开头声明了mathjax: true的文章启用数学支持。我在换用katex引擎后,声明了katex: true,没有用,还是要写成mathjax: true。。

选择与妥协

最后再说几句方案选择的想法。我目前用的是hexo-renderer-moemark-pygments渲染器搭配katex。缺点是katex的数学支持比mathjax弱,而且渲染器支持的是katex 0.7,而最新版已经到了0.10,据next的那篇文档说,Hexo的渲染器都只支持到0.7。

其它一些mathjax的方案也是值得考虑的(用katex的都有同样的问题):

  • 用hexo-renderer-pandoc,需要额外安装pandoc,而且语法与markdown有差异。
  • 用hexo-renderer-kramed,把行内数学公式写在代码块里。

为了保证博客与编辑器一致,所见即所得,没遇到问题的话,我会继续用当前的方案。我也给HexoEditor的作者提了issue,建议编辑器直接利用Hexo的渲染器,实现起来可能有点复杂,但这更符合Hexo编辑器的定位:)

看了许多篇解决Hexo公式渲染的博文,这篇可能是目前最详细、最深究的吧,哈哈。可惜现有方案都存在着一些妥协,希望有大神写一个完美支持latex公式的Hexo渲染器。