* 注:本文由一场 Presentation 的 nodePPT 整理而来。
1 什么是 MathJax
MathJax is a cross-browser JavaScript library that displays mathematical notation in web browsers, using MathML, TeX and AsciiMath markup.
MathJax 是一个跨浏览器的 JavaScript 库,可以在网页上显示数学式,使用 MathML, TeX 和 AsciiMath 标记语言编写。
这并没有很好地回答问题。你会接着问,什么是 MathML, TeX 和 AsciiMath ? 什么是 标记语言?
数学式工具小史
- 1969,高德纳 (D. E. Knuth) 的巨著 《计算机程序设计艺术 (The Art of Computer Programming)》 第一卷出版
- 1976,他收到 TACP 第二版,排版质量非常糟糕,他开始寻找高质量的数字排版系统
- 1977,遍寻无果后,他开始自己动手写。 计划 1978 年完成,结果一直写到 1989 年,这就是 TeX 。 由于对 数学式 排版的良好支持,在学术写作中大受欢迎,并影响了日后的排版系统
- 1985,计算机科学家 兰伯特 (L. Lamport) 基于 TeX 开发出宏包 LaTeX ,包含大多数需要的宏,方便一般人使用(注:由于 LaTeX 的流行,网上说 TeX 的时候,有时其实是在说 LaTeX )
- 1999,W3C (万维网联盟) 提出 基于 XML 标准来描述 数学符号 和 公式的标准 MathML ,最新的版本是 2010年 发布的 3.0
- 2009,美国数学学会 (American Mathematical Society) 为首的多个组织发起 MathJax,兼容 TeX, AsciiMath, MathML
( * 没找到 AsciiMath 的出处和年份。 最早可能出自 07 年的一篇论文,目的是为了简化 MathML 书写。简单说,AsciiMath 的设计目标是,只用 Ascii 字符就能写出数学公式。)
换言之,前面出现了几个优秀的 编写 / 排版 数学式 的 语言 / 工具 (LaTeX, MathML, AsciiMath), AMS 发起 MathJax 将它们集成到一起,用不同的语言写,最终都能转换成 MathML 在浏览器显示。
2 做个对比
这些名字长得很像,几乎都带一个 Math,通过对比来区分一下:
例如显示公式
$$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$
MathML
先看 MathML。
MathML 是 XML 的拓展,特点是:冗余 而 精确 。
它可以同时表示 视觉义 和 逻辑义,对读屏软件友好。
首先是显示效果:
然后源码长这样:
|
|
可以留意到,一些视觉上被省略不显示的符号 (典型的例子是 代数间省略的 乘号 InvisibleTimes),在 MathML 中也有对应的转义实体。这些符号的存在,首先保证公式 没有歧义 ;其次,读屏软件 可以识别这些符号并读出来,方便残障人士理解。
不过精确的代价,是相当地冗余。因为它本来就是设计给浏览器解析的。
LaTeX
显示效果:
$$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$
显示效果并不会有区别。浏览器不认识 LaTeX , LaTeX 写的公式到达浏览器,要经一层 js 库 转换成 MathML ,MathML 才是 W3C 制定的浏览器标准。
LaTeX 源码:
|
|
源码比 MathML 精简很多。
打开浏览器的调试模式,可以看到浏览器解析的代码(js 转换后,浏览器解析前):
|
|
LaTeX 经转换后,显示效果一致; 转换得到的 MathML 代码差别也不大,但 不可见符号并不能自动理解并且添加 。
AsciiMath
显示效果不对:
$$x = (-b +- sqrt(b^2 – 4ac)) / (2a)$$
源码:
|
|
生成的MathML:
|
|
写下这些文字时,我是在 nodePPT 里面加载 MathJax。再次进入调试模式,看看加载配置:
|
|
我给不熟悉的读者翻译一下这块代码:
配置并加载 MathJax.js,加载的配置文件(”TeX-AMS-MML_HTMLorMML.js”)意思是,加载 TeX + AMS拓展 + MathML,并使用HTML+MathML 显示。
没有加载 AsciiMath。
我尝试把配置改成这样
|
|
* 翻译:加载 TeX + MathML + AsciiMath
出于未知原因,没有配置文件同时兼容 AMS 拓展 和 AsciiMath (一般这意味着他们之间有冲突,例如同一个符号做了不同用途)
与此同时,查看配置文件后,发现
|
|
* 翻译:AsciiMath 用 反引号 作为起止符
把源码改成
|
|
效果就出来了。(注:为兼容大多数公式,本文加载默认配置,所以 AsciiMath 无法正常显示。其实正常显示也会转换成 MathML ,效果是没有差别的。)
为什么源码多了一个反斜杠?
反引号 ``` 在 Markdown 代码块的起止符(没错这个反引号的代码块本身就是用反引号括起来的。好拗口。),所以需要增加反斜杠引用它本身,避免被识别为代码块(需要识别为数学块)。看来 AsciiMath 不仅跟别的工具冲突,跟 Markdown 也有冲突。
小结
LaTeX
- 科学写作主流
- 键盘有的符号直接输入
- 没有的符号 或者 效果,通过
\关键字
转义,{}
表示起止范围
如: 分数,就是
\frac 分子 分母
,如果 分子 和 分母 只有一个符号,那就直接写,否则就要用花括号括起来MathML
- W3C 标准,精确,同时啰嗦
- 在 MathJax 环境下无论用什么写公式,最终转换成 MathML 显示
- 直接写 MathML,MathJax 会跳过转换,直接渲染
AsciiMath
- nodePPT 的默认配置没有加载
- 纯 Ascii 字符,不用转义符,阅读起来非常自然,理解不费劲; 但无法区分特殊字符和普通字符,会带来一些麻烦(例如:sqrt 究竟是 平方根,还是 4 个代数相乘呢?)
- 跟其他工具有冲突
初步结论
- 大多数情况下用 LaTeX
- 极少数情况,需要用 MathML
- 多种工具混合的环境,AsciiMath 比较容易出冲突,不推荐
3 怎么开始
加载和配置
HTML 里加载 MathJax,官方推荐做法是在 <head>
标签加入
|
|
如果使用 nodePPT, 模板已经加载好
|
|
数学环境
使用 MathJax 时,需要特定标志,将 公式代码 的范围标识出来。在标志中间的部分,就叫做 数学环境 。包括 段模式 (displayed) 和 行内 (inline) 两种。
查看配置或文档,可以发现 LaTeX 默认分隔符是:
|
|
配置可以在加载时重新定义,覆盖默认值。nodePPT 的加载就定义了行内分隔符,不过跟官方定义一样,等于没改。
我猜测,可能早期版本 MathJax 会跟 nodePPT 或 Markdown 的语法冲突,所以改了配置;然后 MathJax 官方也把配置改了,刚好一样。
还是那个经典例子
段模式:
$$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$
|
|
段模式需要独立一段。
我是行内模式: \(x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\)
|
|
行内模式则可以跟其他文字混排。
4 实例
接下来提供一系列实例,展示 常见符号 和 公式 用 LaTeX 的写法。
(注:语法均为LaTeX。为简便源码省略环境分隔符。个别字符在 Markdown 环境会被识别为特殊字符,如果跟 Markdown 混排这些字符要加反斜杠 \
,如一对下划线 _
中间的内容会被识别为强调,所以要用\_
代替。)
重申一遍基本原则:
- 键盘有的直接输入,不能直接输入的反斜杠
\
+ 对应代码 - 一个字符一个块,效果只对紧接的块起效;多个字符要用
{}
包成一个块
下标
x_1
: \(x_1\)
x_{12}
: \(x_{12}\)
特别的是,_强调_
在 Markdown 里表示 强调 ,如果有连续使用下标,下划线可能会被 Markdown 先识别处理
A_{M-1} < A_{M+1}
: \(A{M-1} < A{M+1}\)
可以通过添加反斜杠处理
A\_{M-1} < A\_{M+1}
: \(A_{M-1} < A_{M+1}\)
上标
x^2
: \(x^2\)
x^{2a}
: \(x^{2a}\)
括号 、 分数
() [] 用原来的就好(花括号{}
因为用来分块,所以显示原始花括号要加反斜杠\{\}
)
也可以用转义,区别就是,如果中间的式子特别大,原始符号不会跟着缩放,但是转义的就会
(\frac{n^2}{6} )
: \(( \frac{n^2}{6} )\)
\left( \frac{n^2}{6} \right)
: \(\left( \frac{n^2}{6} \right)\)
根式 、 求和 、 求积 、 积分
\sqrt x
: \(\sqrt x\)
\sqrt[3]{x^2+1}
: \(\sqrt[3]{x^2+1}\)
\sum_1^n {x^2-1}
: \(\sum_1^n {x^2-1}\)
\prod_1^n {x^2-1}
: \(\prod_1^n {x^2-1}\)
\int_1^{\frac{\pi}{2}}{sin(x)}
: \(\int_1^{\frac{\pi}{2}}{sin(x)}\)
其他特殊符号
\pm \times \div
: \(\pm \times \div\)
\lt \gt \le \ge \neq \not\lt
: \(\lt \gt \le \ge \neq \not\lt\)
\alpha \beta \gamma
: \(\alpha \beta \gamma\)
\infty
: \(\infty\)
\forall a \in A
: \(\forall a \in A\)
\exists B \subset A
: \(\exists B \subset A\)
\underbrace{a+b+ \cdots +z} _{26}
: \(\underbrace{a+b+ \cdots +z} _{26}\)
更多参考,见
- MathJax 主页: https://www.mathjax.org
- 官方文档: http://docs.mathjax.org
- 两份我在网上找到的参考
本文为本人原创,采用知识共享 “署名-非商业性使用-相同方式共享” 4.0 (CC BY-NC-SA 4.0)”许可协议进行许可。
本作品可自由复制、传播及基于本作品进行演绎创作。如有以上需要,请留言告知,在文章开头明显位置加上署名(Jayce Chant)、原链接及许可协议信息,并明确指出修改(如有),不得用于商业用途。谢谢合作。
详情请点击查看协议具体内容。