Markdown 中的数学公式

你是否好奇过 Markdown 为什么能够渲染出支持 Tex/LaTeX 语法的数学公式?如果没有,而你又恰好是 Markdown 的重度使用者亦或是有打算在未来搭建一个自己的博客,你应该好奇一下;如果有,那么恭喜你,这篇文章应该能够解决你的部分疑惑。

那么接下来,欢迎进入属于 Markdown 的魔法世界!

Markdown 的由来

首先,先来看看 Markdown 语言,它是由约翰·格鲁伯(John Gruber)在 2004 年发明的一种轻量级标记语言,约翰·格鲁伯自己是这么形容 Markdown 语言的,

Markdown is a text-to-HTML conversion tool for web writers. Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML)1.

从约翰·格鲁伯(John Gruber)对 Markdown 语言的描述当中,不难得出这样的结论,Markdown 的设计目的是为了简化 HTML 的写作过程,使文档可以使用普通文本格式编写,同时又能通过一些简单的语法实现格式化内容,方便转换成 HTML 或其他格式。对于 Markdown 有两层含义:

  1. 一种纯文本格式语法;
  2. 一种用 Perl 编写的软件工具,用于将纯文本格式转换为 HTML。

所以 Markdown 设计哲学就是作为一种网络写作格式,让阅读、写作和编辑散文变得更容易。

注意,Markdown 并非 HTML 的替代品,HTML 是一种出版格式,而 Markdown 是一种写作格式。Markdown 的格式化语法只解决可以用纯文本表达的问题。

从约翰·格鲁伯对 Markdown 的语法描述中2,并没有找到关于 Markdown 可以编写数学公式这样说法的影子,反倒是证实了一点 Markdown 确实是在足够易读易写的基础上,又能够足够方便地将其转换成 HTML 文档,继续接着前面说,既然设计之初,Markdown 并没有用来编写数学公式的打算,那为何到了现在 Markdown 语言被人们广泛的用来编写数学公式,这其间究竟发生了什么?

TeX/LaTeX-排版系统

聊到了数学公式,就不得不提 TeX/LaTeX34。TeX 作为最高级的数字排版系统之一,是排版复杂数学公式的流行手段,在学术界被广泛使用,尤其是在数学、物理学和计算机科学等等。当然,TeX 能够被广泛使用还有一个重要的原因是它是一个开源软件(开源万岁!!)。它也被用于许多其他的排版任务,特别是以 LaTeX、ConTeXt 和其他宏包的形式。TeX 的设计有两个主要目标:

  1. 允许任何人以最小的努力制作高质量的书籍;
  2. 提供一个在任何时间点都能在所有计算机上产生完全相同结果的系统;

从第一点上来看,TeX/LaTeX 更类似于 Markdown,都想设计一种简单易用,同时最后能够输出高质量作品的东西。比如:TeX/LaTeX 最后的作品被用来印刷书籍,而 Markdown 最后的作品用来生成网页,现实与虚拟交相呼应。

关于第 2 点可太重用了,没有一个被 Word 排版给折磨过的人会不喜欢这一点!!关于 TeX/LaTeX 的部分在这里就不细说了,有时间再写文章详细说说 TeX/LaTeX。

如果用过 Markdown 编写过公式的人都应该或多或少的了解,Markdown 编写公式时使用的 TeX/LaTeX 的语法,其实不单单是 Markdown,就连在 Word 中插入公式,除了使用可视化操作,进行点点点之外,也支持用 TeX/LaTeX 的语法转换公式。Markdown 和 TeX/LaTeX 除了设计初衷相同外,看上去感觉完全是两个八竿子打不着的东西,前者用于网络写作,生成网页,后者用作实体书籍的排版,二者究竟是因何而结缘的呢?

当然除了 TeX/LaTeX 之外,还有另外两种数学公式的标记语言 MathML 和 AsciiMath。其中国,MathML(Mathematical Markup Language)是基于 XML 的标准化语言,它由 W3C 制定,旨在让数学公式可以通过 Web 浏览器等工具展示。而 AsciiMath 是一种简洁的文本方式表示数学公式的标记语言,适合快速输入和展示。简单总结一下就是,LaTeX 提供了最强大的功能和复杂的语法,适合处理高级的数学公式;MathML 是标准化的 XML 格式,注重结构化与语义化;AsciiMath 则简洁直观,适合快速书写。

虽然如此,但是不得不说,如果真要论起排版复杂数学公式,TeX/LaTeX 还是当仁不让的,在这一点上无论是微软的办公软件套组,还是 Markdown 中的公式编辑都不得不承认它的好。确实,只要有需要排版数学公式的地方,好像或多或少都能看到 TeX/LaTeX 的影子。

数学公式渲染引擎

如何在 Markdown 中能够使用 TeX/LaTeX 处理数学公式排版的问题,数学公式渲染引擎它不就来了吗?

前面介绍 Markdown 时提到过,Markdown 设计之初就是为了网络写作而生的,所以用 Markdown 写的文档能够很方便,也很容易的转换成 HTML 格式。考虑到 Markdown 最终的展现形式大多是 HTML,那么要解决在 Markdown 中的数学公式排版问题,很自然就会想到可以在 HTML 上做文章。而 Javascript 就是答案。

MathJax 就是这样是一个开源 JavaScript 显示引擎,用于解决所有现代浏览器中 LaTeX、MathML 和 AsciiMath 符号的显示问题。它的设计目标是将网络技术的最新进展整合到一个单一、明确的网络数学平台中,支持主要浏览器和操作系统,包括移动设备上的浏览器和操作系统5

由于 Markdown 和 HTML 的关系,所以借助于 MathJax 引擎,在 Markdown 中很容易实现数学公式的表示。 只需要配置好 MathJax,告诉它要使用哪种数学标记语言,以及在使用时要如何表示数学知识即可。

比如:以 TeX/LaTeX 为例,MathJax 对 TeX 和 LaTeX 的支持包括两个功能6,第一个功能是在网页中查找数学公式(用数学定界符如 $$...$$ 予以区分)并标记数学公式以便 MathJax 稍后处理;第二个功能是将 TeX 符号转换为 MathJax 的内部格式,然后由 MathJax 的输出处理器在网页中显示。

顺便提一句,除了 MathJax 之外,还有一个以轻量、快速著称的数学公式渲染 KaTeX,但是由于 KaTeX 的发布要晚于 MathJax,并且为了追求轻量和快速,使得 KaTeX 在兼容性以及对 TeX/LaTeX 符号的支持上不如 MathJax。实际使用中,具体选择哪一个引擎,需要根据生产环境的情况灵活决定。

当然,即使是 MathJax ,与真正的 TeX/LaTeX 系统相比,在输入上也存在一些差异。因为 MathJax 仅仅只是用作网络渲染的,而 TeX 是一种真正意义上的印刷排版引擎,又怎能对 MathJax 要求太多(毕竟,蝴蝶飞不过沧海,谁又忍心会去责怪?!)。对于 MathJax 实际支持的 TeX/LaTeX 命令可以看这里

一些具体实例

像是很多人喜欢的 Markdown 编辑器 Typora(也是笔者写这篇文章时正在使用的编辑器),它对于数学公式的支持使用的就是 MathJax 引擎,具体可见官网7

Typora supports rendering normal mathematics using Tex/LaTeX syntax. The rendering process is processed by MathJax.

当然,除了 Typora 之外,还有像是 VSCode,在优化在其上的 Markdown 数学公式编辑体验时所用到的扩展,比如:Markdown+Math8,它用到的数学公式渲染的引擎就是 KaTeX,

mdmath allows to use Visual Studio Code as a markdown editor capable of typesetting and rendering TeX math.K, In fact it now reuses the built in markdown viewer. KaTeX works inside as a fast math renderer.

还有就是静态博客框架 Jekyll,它使用的 Markdown 解析器 Kramdown,对于公式的展示,也是通过引入数学公式渲染引擎(比如:MathJax)实现的。

写在最后

不知不觉唠了那么多,在文章的结尾来讲点干货。如果能从头到尾看到这(说明你是真的闲,开个玩笑,哈哈)的朋友,也许自然也明白这些东西的作用。但我还是讲讲对于我而言它们的用处,还是从我自身的经历出发,之前在用 GitHub 编辑文档时曾经遇到过部分数学公式无法正常渲染的情况,当时就怎么也调整不好,甚至一度把它当成一种玄学。但现在有了这些知识,其实解决这个问题很简单,这无非就是去看 GitHub 所使用的数学公式渲染引擎是哪一款,然后在相应按照其要求的规范去书写就行了。当然,这只是其中一个例子,就像文章开头我说的,如果你碰巧还是一个博客主,那么了解这些知识对于你今后博客上数学公式的使用肯定也有所裨益。

OK,就说那么多,下一篇文章很快再见!

参考资料

  1. Daring Fireball-Markdown: https://daringfireball.net/projects/markdown/ 

  2. Daring Fireball-Markdown Syntax Documentation: https://daringfireball.net/projects/markdown/syntax 

  3. TeX - Wikipedia: https://en.wikipedia.org/wiki/TeX 

  4. LaTeX - Wikipedia: https://en.wikipedia.org/wiki/LaTeX 

  5. What is MathJax?-MathJax 3.2 documentation: https://docs.mathjax.org/en/latest/basic/mathjax.html 

  6. TeX and LaTeX Support - MathJax 3.2 documentation: https://docs.mathjax.org/en/latest/input/tex/index.html 

  7. Math and Academic Functions - Typora Support: https://support.typoraio.cn/Math/ 

  8. Markdown+Math - Visual Studio Marketplace: https://marketplace.visualstudio.com/items?itemName=goessner.mdmath 

分类:

更新时间:

留下评论