在博客中展示数学公式

在博客中展示数学公式

最近写的一系列文章中需要时不时插入一些数学公式,也就不得不接触一些LaTeX相关内容,另外由于要发到博客上,还需要让博客能够正确解析LaTeX语法。

Hexo 插入数学公式起步

Hexo 博客框架默然使用的Markdown解析插件是hexo-renderer-marked, 我同时使用了Next主题。

首先要说明的是,Hexo 默认Markdown是不支持LaTeX语法的,但是,Next的主题默认已经支持MathJax,也就是说不需要再在网页的header中引入如下代码:

<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>

只需要在主题下的配置文件_config.yml中启用相关设置即可

# MathJax Support
mathjax:
enable: true
per_page: true
cdn: //cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML

在需要启用MathJax的post中进行设置

---
title: 统计学基础与R-2
mathjax: true
---

这么几步下来,网页上其实已经可以显示一部分公式了。但是在MathJax中,包含_(下划线)的下标表示语法还是不能正确识别。

尝试不同的 Markdown 插件

为了解决部分MathJax语法不能正确编译的问题,我在Google上大致搜了搜,主要意见都是一劳永逸的更换Hexo的Markdown插件。

第一种可供更换的插件是hexo-renderer-pandocpandoc可以说是最牛最全的Markdown渲染引擎,R Markdown 用的就是它。

首先在电脑上安装pandoc

然后在hexo中进行如下操作

npm un hexo-renderer-marked --save
#卸载旧的
npm install hexo-renderer-pandoc --save
安装新的

然后在后期渲染的过程中,报错了。

INFO Start processing FATAL Something’s wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.html

Error: [pandoc warning] YAML header is not an object “source” (line 67, column 1)
at ChildProcess. (/Users/sean10/Code/sean10.github.io/node_modules/hexo-renderer-pandoc/index.js:73:20)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:877:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)

在pandoc解析的过程中,渲染出现了问题,很可能是我有些文章写得Markdown语言并不完全符合pandoc, 排查这么多篇文章中的错误太浪费时间,于是放弃。

随后,又找到了另一个插件,hexo-renderer-markdown-it-plus 这个插件支持各种各样的Markdown扩展语法,尤其是支持katex。于是我使用后发现确实解决了部分语法不识别的问题,但是所有数学公式除了渲染输出外还会在输出一遍原始格式。迫于无奈,这个方法也放弃了。

修改默认插件语法规则

更换插件的尝试失败后,回顾问题所在其实是默认搜索引擎的下划线语法和mathjax的下标语法冲突。也就是说当我在一个公式中出现了两次下标,输入两次_后,默认会把两个下划线之间的部分解析为斜体

如果不想修改默认语法规则,需要在数学公式中使用\__进行转义,这么做实在是有点麻烦。干脆修改原始的默认语法规则,不让_斜体_转义为斜体字,而是只采用*斜体*的方式。

找到配置文件node_modules\marked\lib\marked.js,对escape,strong和em进行如下修改

var inline = {
//escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
escape: /^\\([`*{}\[\]()# +\-.!_>])/,
autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
url: noop,
tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
link: /^!?\[(inside)\]\(href\)/,
reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
//strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
strong: /^\*\*([\s\S]+?)\*\*(?!\*)/,
//em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
br: /^ {2,}\n(?!\s*$)/,
del: noop,
text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
};

保存之后,清空hexo 缓存,重新部署一次就可以了。最后的效果,可以参考文章统计学基础与R-2

后续

配合默认Markdown渲染引擎和MathJax使用,其实还有一个问题,支持行内公式,但是即便修改了源代码也没有实现多行书写(\\换行),比如


$$
H=-\sum_{i=1}^N (\sigma_{i}^x \sigma_{i+1}^x+g \sigma_{i}^z)
$$

## 用 \\ 没有正常换行

$$
f(n) = \begin{cases}
\frac{n}{2},
& \text{if } n\text{ is even}
\\ 3n+1, & \text{if } n\text{ is odd}
\end{cases}
$$

## 用\\\ 代替正常的\\ 实现换行

$$
f(n) = \begin{cases}
\frac{n}{2},
& \text{if } n\text{ is even}
\\\ 3n+1, & \text{if } n\text{ is odd}
\end{cases}
$$

$$f(x): \begin{cases} x, x>0 \\\ -x,x<0 \end{cases}$$

目前下面的所有公式都能正常显示,是因为我已经解决了上文提到的问题。可以看最下面的解决方法。

$$
H=-\sum_{i=1}^N (\sigma_{i}^x \sigma_{i+1}^x+g \sigma_{i}^z)
$$

$$
f(n) = \begin{cases}
\frac{n}{2},
& \text{if } n\text{ is even}
\ 3n+1, & \text{if } n\text{ is odd}
\end{cases}
$$

$$
f(n) = \begin{cases}
\frac{n}{2},
& \text{if } n\text{ is even}
\\ 3n+1, & \text{if } n\text{ is odd}
\end{cases}
$$

$$f(x): \begin{cases} x, x>0 \\ -x,x<0 \end{cases}$$

但是hexo-renderer-markdown-it-plus是可以解决这个问题,在一篇博客中有比较详细的介绍hexo-renderer-markdown-it-plus plugin demo,可能未来还是需要弄清楚我安装这个插件时出现重复显示的原因。


最终更新

上面提到在使用hexo-renderer-markdown-it-plus时,遇到了公式重复渲染的问题,目前这个方式已经解决,解决方法如下。

npm un hexo-renderer-marked --save
#卸载旧的默认Markdown插件
npm install hexo-renderer--markdown-it-plus --save
安装新的增强型插件

卸载就插件之后,之前修改的marked.js文件已经被随之删除。现在,我们最需要的是hexo-renderer-markdown-it-plus中的Katex插件,为了使用katex需要在主题中的网页中引入相关CSS文件。

Next主题中,专门为用户准备了一个自定义文件,即themes\next\layout\_custom\header.swig文件。在这个自定义header文件中写入如下内容

<link href="https://cdn.bootcss.com/KaTeX/0.7.1/katex.min.css" rel="stylesheet">
# 不要引入最新的katex文件,显示效果和插件并不兼容

紧接着在Hexo的配置文件中进行配置(可选项)

#markdown设置
markdown_it_plus:
highlight: true
html: true
xhtmlOut: true
breaks: true
langPrefix:
linkify: true
typographer:
quotes: “”‘’
plugins:
- plugin:
name: markdown-it-katex
enable: true
- plugin:
name: markdown-it-mark
enable: false

因为该插件调用的是$\KaTeX$, 因为可以将主题配置文件修改为

# MathJax Support
mathjax:
enable: false
per_page: false
cdn: //cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML

同时新的文章头部也不再需要添加mathjax=true


本文作者:思考问题的熊

版权声明:本博客所有文章除特别声明外,均采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×