在写作博文的时候,有时候需要输入一些数学公式,如果公式过长,我们通常希望把方程分成多行显示,在 LaTeX 中,我们可以使用 aligned
环境来书写多行公式,但是写出来的 Markdown 经过 Hexo 的处理以后显示不正确,原因何在?原来这与 Hexo 的渲染引擎有关系。
开启公式支持#
Hexo 的自带的 Markdown 引擎并不支持 LaTeX 公式。 但是 MathJax 支持,因此首先要启用 MathJax 才能渲染 LaTeX 公式。如果你已经安装了 NexT theme,开启 MathJax 支持非常容易,在最新版的NexT 主题的 _config.yml
文件里,找到 MathJax 相关部分,使用以下配置,
math:
enable: true
# Default(true) will load mathjax/katex script on demand
# That is it only render those page who has 'mathjax: true' in Front Matter.
# If you set it to false, it will load mathjax/katex srcipt EVERY PAGE.
per_page: false
engine: mathjax
但是,由于 LaTeX 中的一些符号在 Markdown 也中有特殊含义,例如 两个 _
在 Markdown中用来表示斜体(italic),因此两者的配合使用会产生一些问题。
从一个例子说起#
假如我们想要显示下面的方程,
如果使用如下的 LaTeX 代码
\begin{align}
x &= a +b+c+d\\
&= e +f\\
&= g
\end{align}
使用 Hexo 渲染以后,得到的结果如下图所示,
可以看到,换行并未起作用,这是因为 Hexo 对 Markdown 文件的处理实际上分为两个步骤:
- Hexo 中的 Markdown 引擎把 Markdown 变为 html 文件
- MathJax 负责解释 html 的数学公式
第一步中,由于 backslash 在 Markdown 属于特殊字符,用于字符转义,所以两个 backslash 经过 Markdown 引擎处理,只剩下一个,等到 MathJax 引擎处理时,实际上 MathJax 只看到一个 backslash,MathJax 把它当作 LaTeX 中的空格,因此我们见到了上图所示的渲染结果。
知道了渲染错误的原因,解决办法也很简单,就是用四个 backslash 代替两个 backslash,确保 MathJax 的引擎看到的是两个 backslash,也就是把上述代码变成
\begin{align}
x &= a +b+c+d\\\\
&= e +f\\\\
&= g
\end{align}
这时产生的公式如下图所示,
如果想要去掉公式的编号,在 LaTeX 中,我们通常会选择加星号的 align
环境,但是注意到星号 (star)在 Markdown 也有特殊含义(一对单星号表示斜体,一对双星号表示粗体),因此必须对星号进行转义,才能确保 MathJax 见到星号,正确的代码是
\begin{align\*}
x &= a +b+c+d\\\\
&= e +f\\\\
&= g
\end{align\*}
如果按照上面的方法在 Markdown 文件中写公式,我们将会十分痛苦,并且写出来的 LaTeX 公式不能被标准的 LaTeX 处理引擎识别,因此这个解决办法是非常糟糕的解决办法。有没有更好的办法?答案是:有的!
解决方法#
我试用了多款号称能够解决这个问题的 hexo renderer,例如 hexo-renderer-markdown-it-plus
以及 hexo-math
,效果都差强人意。最后发现使用 hexo-renderer-pandoc 十分靠谱。使用这个 renderer 之前请确保你已经安装了Pandoc,然后卸载 Hexo 自带的 renderer,安装 Pandoc renderer:
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-pandoc --save
注意事项#
如果你使用这款 Pandoc renderer,那么书写 Markdown 时候需要遵循 Pandoc 对 Markdown 的规定。
有一些比较明显的需要注意的事项:正常的文字后面如果跟的是list
, table
或者quotation
,文字后面需要空一行,如果不空行,这些环境将不能被 Pandoc renderer 正常渲染。
另外,文中的 URL 使用 Pandoc 渲染以后是普通的文本格式,不能点击,可以通过用<>
包围 URL 的方式把 URL 变成可点击的 URL。