0%

hexo中如何支持公式 mathjax

UPDATE: 2018-08-08: github markdown已经支持公式,

简介

MathJaxKatex

mathjax

Beautiful math in all browsers

A JavaScript display engine for mathematics that works in all browsers.

—— 来自www.mathjax.org

MathJax是一款运行在浏览器中的开源的数学符号渲染引擎,使用MathJax可以方便的在浏览器中显示数学公式,不需要使用图片。目前,MathJax可以解析Latex、MathML和ASCIIMathML的标记语言。 MathJax项目于2009年开始,发起人有American Mathematical Society, Design Science等,还有众多的支持者。

  • 无损缩放,支持多种方式的公式渲染(math-render)。(不采用图片、Flash)
    • CSS引擎:采用CSS生成数学公式
    • SVG引擎:采用SVG生成数学公式
    • MathML引擎
  • 源码拷贝。可以拷贝LaTeX、wiki等;
  • 输入形式可以是MathML、TeX或者ASCIImath

html中使用mathjax

mathjax就是个前端渲染引擎

也可以借鉴 https://kexue.fm/latex.html

或者拷贝以上代码,保存为math.html,双击打开就能看到渲染好的公式。

hexo中使用mathjax

同样很简单,仅需两步。

  1. 加载mathjax的cdn
  2. 博客中按照tex语法写公式即可

示例

markdown中书写:

1
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

首先会被markdown-render渲染到html,成为以下的脚本 (这一步不是必须的,mathjax能直接解析$$符号,而无需该步的转换)

1
<script type="math/tex; mode=display">x = {-b \pm \sqrt{b^2-4ac} \over 2a}.</script>

浏览器加载html页面后,根据script引用加载mathjax.js,然后在浏览器端渲染成以下公式:

$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

1
2
3
4
# 其他方式:
\[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
# 如果存在转义问题,可以采用以下方式
\\[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\\]

hexo中支持公式的markdown插件

  • hexo-renderer-marked
    这是hexo默认的markdown渲染插件,其调用的marked.js渲染引擎这个插件支持公式渲染吗?
  • hexo-math插件
    • 支持math标签
    • 早期版本支持$$$符号,新版不再支持
    • 如果喜欢,推荐使用 (hexo-filter-mathjax)[https://github.com/hexojs/hexo-math/issues/51#issuecomment-677982993]
  • hexo-filter-mathjax
  • 主题自带的公式
    • theme-next 自带mathjax支持 (我用的这个)

markdown渲染引擎

  • marked demo
    • 轻量级,更新活跃
    • jupyter、google-colab、hexo默认采用的marked.js作为渲染引擎
    • hexo模块: hexo-renderer-marked
    • 该模块并不会渲染公式,但是mathjax也能识别,因为mathjax可直接解析$$
  • pandoc 重量级 demo
    • pandoc -f markdown+tex_math_single_backslash –mathjax test.md -o test.html
    • 以上参数的命令可以解决问题
    • hexo模块: hexo-renderer-pandoc
  • kramdowndemo
    • 派生自marked,但是很久没有更新过了
    • cs231n 采用的kramdown
    • hexo模块: hexo-renderer-kramed

存在的问题

公式的转义问题

有时会遇到公式渲染失败,有时也会遇到很多不同的公式写法,比如:

  • $$$
  • \(\)\[\]
  • \\(\\)\\[\\],示例tensorflowcs231n

公式渲染失败,一般是由于不同的markdown引擎的渲染方式不同引起的,以上的\\(这种写法也是为了和markdown渲染引擎作斗争,以致于写个公式变得这么复杂。

举个例子

1
\[ x=1 \]

经过marked引擎解析成以下html:

1
<p>[ x=1 ]</p>

注意: 这里的反斜线\[经过marked引擎后转义丢失,只剩下[。因此mathjax无法识别,以致于公式无法正常显示。

怎么办?既然反斜线丢失,那就多加个反斜线,写成\\[ x=1 \\]。这样就渲染成功了

常见的markdown渲染引擎

  • marked 轻量级 demo
  • pandoc 重量级 也存在同样的问题,demo
    • pandoc -f markdown+tex_math_single_backslash –mathjax test.md -o test.html
    • 以上参数的命令可以解决问题
  • kramdown也存在同样的问题,demo
  1. 多加个反斜线,比如\[要写成\\[ 麻烦
  2. 修改marked源码,取消了对\\,\{,\}的转义(escape) 麻烦
  3. 采用其他markdown引擎,比如kramdown (比如cs231n就采用的kramdown) 发现也不work
  4. 把所有\[替换成$$ 我目前是这样做的

建议:

不要采用 \[\(的格式书写公式,尽量用$$$

  1. 很多引擎不支持\[\( (比如github)
  2. \[中的反斜线经常会被解释成转义符号,造成符号丢失

疑问

雷军
`theme-next`为什么要限定markdown引擎?不应该和markdown引擎无关吗?
雷军
...

公式里的 _ 被渲染成斜体

由于 Markdown 在 MathJax 之前起作用,有时下标记号会被 Markdown 吃掉,变成 HTML 标记 <i><em> 而失去 LaTeX 的下标效果,造成数学公式显示不正常。

有时会被渲染成斜体。$c _ {t-1} $ 和 $ h _ {t-1}$

解决策略:带空格的 _ 不会被渲染成斜体。

$c_{t-1} $ 和 $ h_{t-1}$

$ c_{t-1} $ 和 $ h_{t-1} $

$ c_{t-1} $ 和 $ h_{t-1} $

$ c_{t-1} $ 和 $ h_{t-1} $

参考

  • theme-next中使用mathjax | next官方文档
  • Hexo下mathjax的转义问题
  • 使Marked.js与MathJax共存
  • MathJax 与 Markdown 的冲突