编写 MathML

本文档说明了如何使用 MathML 语言编写数学公式。MathML 是一种用文本格式描述的标签和属性。就像 HTML 或 SVG 一样,对于复杂的数学内容,这种文本格式可能会非常冗长,因此需要 合适的创作工具,例如从 轻量级标记语言所见即所得 公式编辑器转换的工具。市面上有许多这类工具,无法在此一一列举。因此,本文将重点介绍常见的做法和示例。

使用 MathML

尽管您的 MathML 公式很可能由创作工具生成,但了解一些技巧以将其正确集成到文档中仍然很重要。

HTML 页面中的 MathML

每个 MathML 方程都由一个根 math 元素表示,该元素可以直接嵌入到 HTML 页面中。默认情况下,公式将以内联方式呈现,并进行额外调整以最小化其高度。使用 display="block" 属性可以正常渲染复杂公式,并使其独占一段。

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>MathML in HTML</title>
  </head>
  <body>
    <h1>MathML in HTML</h1>

    <p>
      One over square root of two (inline style):
      <math>
        <mfrac>
          <mn>1</mn>
          <msqrt>
            <mn>2</mn>
          </msqrt>
        </mfrac>
      </math>
    </p>

    <p>
      One over square root of two (display style):
      <math display="block">
        <mfrac>
          <mn>1</mn>
          <msqrt>
            <mn>2</mn>
          </msqrt>
        </mfrac>
      </math>
    </p>
  </body>
</html>

注意:要在 XML 文档(例如 XHTML、EPUB 或 OpenDocument)中使用 MathML,请在每个 <math> 元素上添加一个显式的 xmlns="http://www.w3.org/1998/Math/MathML" 属性。

注意:一些电子邮件或即时消息客户端能够以 HTML 格式发送和接收消息。因此,可以在此类消息中嵌入数学公式,只要 MathML 标签不被标记清理程序过滤掉。

无 MathML 支持的浏览器回退方案

建议为不支持 MathML 的浏览器提供回退机制。如果您的文档仅包含基本的数学公式,那么一个小的 mathml.css 样式表可能就足够了。要条件性地加载它,只需在文档头部插入一行:

html
<script src="https://fred-wang.github.io/mathml.css/mspace.js"></script>

如果您需要更复杂的构造,可以考虑使用更重的 MathJax 库作为 MathML 的 polyfill。

html
<script src="https://fred-wang.github.io/mathjax.js/mpadded-min.js"></script>

或者,您也可以在页面顶部显示一个警告,告知浏览器没有良好的 MathML 支持,并让用户选择上述回退方案中的一个。

html
<script src="https://fred-wang.github.io/mathml-warning.js/mpadded-min.js"></script>

注意:这些小脚本会执行功能检测(检测 mspacempadded 元素),这比 浏览器嗅探 更可取。此外,它们是在开源许可证下分发的,因此您可以随意将其复制到自己的服务器上并根据需要进行调整。

数学字体

正如 MathML 字体文章中所解释的,数学字体对于渲染 MathML 内容至关重要。因此,分享 这类字体的安装说明 或将其作为 Web 字体 提供始终是个好主意。

MathFonts 页面 提供了此类 Web 字体以及相应的样式表。例如,只需在文档头部插入以下行,即可选择 Latin Modern 字体并提供回退 Web 字体:

html
<link
  rel="stylesheet"
  href="https://fred-wang.github.io/MathFonts/LatinModern/mathfonts.css" />

提供了几种字体,您可以选择不同的样式,例如 STIX。

html
<link
  rel="stylesheet"
  href="https://fred-wang.github.io/MathFonts/STIX/mathfonts.css" />

注意:该 MathFonts 页面的字体和样式表是在开源许可证下分发的,因此您可以随意将其复制到自己的服务器上并根据需要进行调整。

从简单语法转换

本节将介绍一些工具,用于将 MathML 从 轻量级标记语言(如流行的 LaTeX 语言)转换为 MathML。

客户端转换

通过这种方法,公式直接编写在网页中,然后一个 JavaScript 库负责将其转换为 MathML。这可能是最简单的方法,但也有一些问题:需要加载和执行额外的 JavaScript 代码,作者必须转义保留字符,Web 爬虫将无法访问 MathML 输出……

可以使用 自定义元素 来托管源代码,并确保通过 shadow subtree 插入和渲染相应的 MathML 输出。例如,使用 TeXZilla<la-tex> 元素,上面的 MathML 示例 可以更简洁地重写如下:

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>MathML in HTML5</title>
    <script src="https://fred-wang.github.io/TeXZilla/TeXZilla-min.js"></script>
    <script src="https://fred-wang.github.io/TeXZilla/examples/customElement.js"></script>
  </head>
  <body>
    <h1>MathML in HTML5</h1>

    <p>
      One over square root of two (inline style):
      <la-tex>\frac{1}{\sqrt{2}}</la-tex>
    </p>

    <p>
      One over square root of two (display style):
      <la-tex display="block">\frac{1}{\sqrt{2}}</la-tex>
    </p>
  </body>
</html>

对于不熟悉 LaTeX 的作者,还有其他输入方法,例如 ASCIIMathjqMath 语法。请务必加载 JavaScript 库并使用正确的定界符。

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>ASCII MathML</title>
    …
    <!-- ASCIIMathML.js -->
    <script src="/path/to/ASCIIMathML.js"></script>
    …
    <!-- jqMath -->
    <script src="https://mathscribe.com/mathscribe/jquery-1.4.3.min.js"></script>
    <script src="https://mathscribe.com/mathscribe/jqmath-etc-0.4.6.min.js"></script>
    …
  </head>
  <body>
    …
    <p>One over square root of two (inline style, ASCIIMath): `1/(sqrt 2)`</p>
    …
    <p>One over square root of two (inline style, jqMath): $1/√2$</p>
    …
    <p>One over square root of two (display style, jqMath): $$1/√2$$</p>
    …
  </body>
</html>

命令行程序

您不必在页面加载时生成 MathML 表达式,而是可以依赖命令行工具。这将生成加载速度更快的静态 MathML 内容的页面。让我们再次考虑一个包含来自 客户端转换 内容的页面 input.html

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>MathML in HTML5</title>
  </head>
  <body>
    <h1>MathML in HTML5</h1>
    <p>One over square root of two (inline style): $\frac{1}{\sqrt{2}}$</p>
    <p>One over square root of two (display style): $$\frac{1}{\sqrt{2}}$$</p>
  </body>
</html>

该页面不包含任何 script 标签。相反,转换通过以下命令行使用 Node.jsTeXZilla 执行。

bash
cat input.html | node TeXZilla.js streamfilter > output.html

运行该命令后,会创建一个名为 output.html 的文件,其中包含以下 HTML 输出。用美元符号括起来的公式已被转换为 MathML。

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>MathML in HTML5</title>
  </head>
  <body>
    <h1>MathML in HTML5</h1>

    <p>
      One over square root of two (inline style):
      <math><semantics><mfrac><mn>1</mn><msqrt><mn>2</mn></msqrt></mfrac><annotation encoding="TeX">\frac{1}{\sqrt{2}}</annotation></semantics></math>
    </p>

    <p>
      One over square root of two (display style):
      <math display="block"><semantics><mfrac><mn>1</mn><msqrt><mn>2</mn></msqrt></mfrac><annotation encoding="TeX">\frac{1}{\sqrt{2}}</annotation></semantics></math>
    </p>
  </body>
</html>

还有更复杂的工具,旨在将任意 LaTeX 文档转换为包含 MathML 内容的文档。例如,使用 LaTeXML,以下命令会将 foo.tex 转换为 HTML 或 EPUB 文档:

bash
latexmlc --dest foo.html foo.tex # Generate a HTML document foo.html
latexmlc --dest foo.epub foo.tex # Generate an EPUB document foo.epub

latexmlc 接受一个 --javascript 参数,您可以使用它来包含上面提到的 回退脚本 之一。

bash
latexmlc --dest foo.html --javascript=https://fred-wang.github.io/mathml.css/mspace.js foo.tex  # Add the CSS fallback
latexmlc --dest foo.html --javascript=https://fred-wang.github.io/mathjax.js/mpadded-min.js foo.tex # Add the MathJax fallback

注意:命令行工具可以在服务器端使用,例如 MediaWiki 通过 Mathoid 执行 LaTeX 到 MathML 的转换。

图形界面

本节将介绍一些提供图形界面的编辑工具。

输入框

一种简单的方法是将 简单语法的转换器 集成到简单的数学输入框中。例如,ThunderbirdSeaMonkey 提供了一个 **插入 > 数学** 命令,该命令会打开一个弹出窗口,其中包含一个 LaTeX 到 MathML 的输入字段和实时 MathML 预览。

LaTeX input box in Thunderbird

注意:您也可以使用 **插入 > HTML** 命令粘贴任何 MathML 内容。

LibreOffice 的公式编辑器(文件 → 新建 → 公式)展示了一种可能的增强:其 StartMath 语法的输入框提供了额外的公式面板来插入预定义的数学构造。

StarMath input box in Libre Office

注意:要获取 LibreOffice 的 MathML 代码,请将文档另存为 mml 格式,然后用您喜欢的文本编辑器打开它。

所见即所得编辑器

其他编辑器在其所见即所得界面中直接集成了数学编辑功能。以下屏幕截图来自 LyXTeXmacs,它们都支持 HTML 导出。

Lyx example

TeXmacs example

注意:默认情况下,Lyx 和 TeXmacs 会在它们的 HTML 输出中使用公式图像。要改用 MathML,请按照 Lyx 的说明进行操作,或者为后者选择 用户偏好设置 > 转换 > 将数学公式导出为 MathML

光学字符识别和手写识别

输入的另一种选择是依赖于 光学字符识别手写识别 的用户界面。其中一些工具支持数学公式,并可以将它们导出为 MathML。以下截图显示了 MyScript 的演示

MyScript