将博客从Wordpress迁移到Typecho之后,开始用markdown做一些课程笔记然后放上来,作为工科生笔记里当然就有不少的公式,会运用到LaTex。因为原生的编辑器和渲染实在是太简陋了,买了Handsome主题之后想都没想就开启了vditor,并且让vditor.js接管前台渲染。

因为在线编辑每次修改后都会将整个文件重新渲染一遍,公式一多卡顿就明显,我会先在Typora做编辑,然后将整个源代码复制到后台编辑器,然后检查一些小错误的地方(比如在冒号之后的加粗符号,不加空格直接继续写的话,加粗不渲染,前台只看到两个星号),发布之后再在前台看效果。然后就发现vditor在渲染多行公式的时候有问题,在Typora可以正常显示的公式,在博客上就没法正常显示,但是后台编辑器上是可以正常渲染的,因而就没法在检查的时候发现。

问题

对于下面这段LaTeX代码(在markdown写作里,align换成aligned效果几乎相同):

\begin{align}
a&=line1\\
&=line2\\
&=line3
\end{align}

正常的效果应该是:

$$ \begin{align} a&=line1\\ &=line2\\ &=line3 \end{align} $$

而对于下面这段LaTeX代码:

a=line1\\
b=line2\\
c=line3

正常的效果应该是:

$$ \begin{gather} a=line1\\ b=line2\\ c=line3 \end{gather} $$

对于第一个例子,后台编辑器上能够正常渲染并显示,但在发布之后,前台实际上是一片空白;

对于第二个例子,后台编辑器和前台均不能正常换行。

检查与解决

align问题

一开始的确是百思不得其解,认为是LaTeX和Markdown结合时的兼容性问题。后面发布文章的时候,如果是连在一起但没有关系的多个公式(性质之类的),都使用了多个数学块表示。而对于连续的推演运算,那就没办法了,毕竟是写给自己看的,先用Typora写再发布到博客也是为了有个存档,网站都是次要的。但这么个问题放在那里实在是听膈应人的。

写这篇文章那天突然灵光一闪觉得会不会是vditor的问题,于是去vditor的Github页面去看了一下说明,发现渲染引擎是可以换的,默认的渲染引擎是KaTeX,可以改为MathJax。会不会就是KaTeX的问题导致align块没有办法被正常渲染呢?原本vditor项目说明表明是可以通过api修改渲染引擎的,但在typecho里调用api是插件做的事情,我不会修改插件,就只能直接修改vditor默认的引擎。

查找Handsome主题插件(注意是插件)的文件,发现有editor.min.js以及index.min.js两个文件,editor.min.js文件开头的注释就说明这是接管后台编辑器的脚本。至于index.min.js,一打开就看见大大的vditor几个大字,猜测应该就是通过这个js文件对前台进行渲染。在这个文件内搜索KaTeX,第一个结果存在于以下代码中:

e.MATH_OPTIONS = { engine: "KaTeX", inlineDigit: !1, macros: {} }

所有结果中,唯独这个存在OPTIONS字样,尝试将它改成:

e.MATH_OPTIONS = { engine: "MathJax", inlineDigit: !1, macros: {} }

备份旧文件为index.min.js.bak,上传修改后的文件到服务器,重新打开文章,所有的align块都可以正常渲染了。

换行符问题

在Typora里面,双反斜线作为数学块中的换行符是可以正常工作的,但在Typecho中反斜线没有起到作用。在前台查看TeX代码,发现双反斜线只渲染了一条,应该是html渲染的问题。既然两条线的时候渲染一条,那想要实现双反斜线应该只要写四条线?尝试之后发现,在编辑的时候输入四条反斜线,确实可以在前台渲染出两条反斜线,但这两条反斜线也没有发挥应有的作用,公式依旧没有换行。另外,在align块中,双反斜线就成功的实现了换行。是不是MathJax里,双反斜线只能在多行公式的集合块中发挥作用?答案应该是肯定的了。

对于需要多行对齐的公式,一般使用align块,在需要对齐的地方加一个&号:

\begin{align}
\int_{-\infty}^{+\infty}\frac{e^{ix}}{x^2+a^2}
&=2\pi i\text{Res}[f(z),ai]\\
&=2\pi i\lim_{z\to ai}(z-ai)\frac{e^{iz}}{z^2+a^2}\\
&=2\pi i\frac{e^{-a}}{2ai}=\frac{\pi e^{-a}}{a}
\end{align}

上述代码的效果是:

$$ \begin{align} \int_{-\infty}^{+\infty}\frac{e^{ix}}{x^2+a^2} &=2\pi i\text{Res}[f(z),ai]\\ &=2\pi i\lim_{z\to ai}(z-ai)\frac{e^{iz}}{z^2+a^2}\\ &=2\pi i\frac{e^{-a}}{2ai}=\frac{\pi e^{-a}}{a} \end{align} $$

而对于不需要多行对齐,只是要放在一块写的公式,可以不使用align,而使用gather环境

\begin{gather}
a+b=b+a\\
a(b+c)=ab+ac\\
ab=ba
\end{gather}

上述代码的效果是:

$$ \begin{gather} a+b=b+a\\ a(b+c)=ab+ac\\ a^2+b^2=c^2 \end{gather} $$

结论

align问题:修改vditor的渲染引擎

由于index.min.js比较大,建议下载到本地修改后再重新上传:

  • 下载/your/path/to/typecho/usr/plugins/Handsome/js/index.min.js到本地
  • 在文件中搜索KaTeX,将:
e.MATH_OPTIONS = { engine: "KaTeX", inlineDigit: !1, macros: {} }

修改为:

e.MATH_OPTIONS = { engine: "MathJax", inlineDigit: !1, macros: {} }
  • 保险起见,可以将服务器上的index.min.js备份为index.min.js.bak
  • 将修改后的文件重新上传到服务器

align问题解决方法二:不接管前台渲染

如果没有很复杂的脑图、流程图之类,可以直接在前台使用Typecho原生渲染,Handsome主题中可以开启自带的代码高亮和MathJax功能。只要在Handsome插件设置的前台渲染选项中选择原生渲染,然后在主题增强功能设置中开启代码高亮和MathJax即可。

用这个方法还可以解决代码块和公式块同时出现时公式块不渲染的奇怪问题。

换行符问题:在多行公式块中使用

  • 对于有对齐需要的公式,可以使用align块包裹
  • 对于没有对齐需要的公式,可以使用gather块包裹
  • 对于同时有多个公式,其中部分需要对齐的,如果全部用align块包住会出现很奇怪的对齐,为避免麻烦建议分开几个数学块来写。

啊,LaTeX真麻烦(

如果你想请我喝可乐,请随意赞赏