编写 MathML
本文档说明了如何使用 MathML 语言编写数学公式。MathML 是一种用文本格式描述的标签和属性。就像 HTML 或 SVG 一样,对于复杂的数学内容,这种文本格式可能会非常冗长,因此需要 合适的创作工具,例如从 轻量级标记语言 或 所见即所得 公式编辑器转换的工具。市面上有许多这类工具,无法在此一一列举。因此,本文将重点介绍常见的做法和示例。
使用 MathML
尽管您的 MathML 公式很可能由创作工具生成,但了解一些技巧以将其正确集成到文档中仍然很重要。
HTML 页面中的 MathML
每个 MathML 方程都由一个根 math
元素表示,该元素可以直接嵌入到 HTML 页面中。默认情况下,公式将以内联方式呈现,并进行额外调整以最小化其高度。使用 display="block"
属性可以正常渲染复杂公式,并使其独占一段。
<!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 样式表可能就足够了。要条件性地加载它,只需在文档头部插入一行:
<script src="https://fred-wang.github.io/mathml.css/mspace.js"></script>
如果您需要更复杂的构造,可以考虑使用更重的 MathJax 库作为 MathML 的 polyfill。
<script src="https://fred-wang.github.io/mathjax.js/mpadded-min.js"></script>
或者,您也可以在页面顶部显示一个警告,告知浏览器没有良好的 MathML 支持,并让用户选择上述回退方案中的一个。
<script src="https://fred-wang.github.io/mathml-warning.js/mpadded-min.js"></script>
数学字体
正如 MathML 字体文章中所解释的,数学字体对于渲染 MathML 内容至关重要。因此,分享 这类字体的安装说明 或将其作为 Web 字体 提供始终是个好主意。
MathFonts 页面 提供了此类 Web 字体以及相应的样式表。例如,只需在文档头部插入以下行,即可选择 Latin Modern 字体并提供回退 Web 字体:
<link
rel="stylesheet"
href="https://fred-wang.github.io/MathFonts/LatinModern/mathfonts.css" />
提供了几种字体,您可以选择不同的样式,例如 STIX。
<link
rel="stylesheet"
href="https://fred-wang.github.io/MathFonts/STIX/mathfonts.css" />
注意:该 MathFonts 页面的字体和样式表是在开源许可证下分发的,因此您可以随意将其复制到自己的服务器上并根据需要进行调整。
从简单语法转换
客户端转换
通过这种方法,公式直接编写在网页中,然后一个 JavaScript 库负责将其转换为 MathML。这可能是最简单的方法,但也有一些问题:需要加载和执行额外的 JavaScript 代码,作者必须转义保留字符,Web 爬虫将无法访问 MathML 输出……
可以使用 自定义元素 来托管源代码,并确保通过 shadow subtree 插入和渲染相应的 MathML 输出。例如,使用 TeXZilla 的 <la-tex>
元素,上面的 MathML 示例 可以更简洁地重写如下:
<!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 的作者,还有其他输入方法,例如 ASCIIMath 或 jqMath 语法。请务必加载 JavaScript 库并使用正确的定界符。
<!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
。
<!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.js 和 TeXZilla 执行。
cat input.html | node TeXZilla.js streamfilter > output.html
运行该命令后,会创建一个名为 output.html
的文件,其中包含以下 HTML 输出。用美元符号括起来的公式已被转换为 MathML。
<!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 文档:
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
参数,您可以使用它来包含上面提到的 回退脚本 之一。
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
图形界面
本节将介绍一些提供图形界面的编辑工具。
输入框
一种简单的方法是将 简单语法的转换器 集成到简单的数学输入框中。例如,Thunderbird 和 SeaMonkey 提供了一个 **插入 > 数学** 命令,该命令会打开一个弹出窗口,其中包含一个 LaTeX 到 MathML 的输入字段和实时 MathML 预览。
注意:您也可以使用 **插入 > HTML** 命令粘贴任何 MathML 内容。
LibreOffice 的公式编辑器(文件 → 新建 → 公式)展示了一种可能的增强:其 StartMath 语法的输入框提供了额外的公式面板来插入预定义的数学构造。
注意:要获取 LibreOffice 的 MathML 代码,请将文档另存为 mml
格式,然后用您喜欢的文本编辑器打开它。
所见即所得编辑器
其他编辑器在其所见即所得界面中直接集成了数学编辑功能。以下屏幕截图来自 LyX 和 TeXmacs,它们都支持 HTML 导出。
注意:默认情况下,Lyx 和 TeXmacs 会在它们的 HTML 输出中使用公式图像。要改用 MathML,请按照 Lyx 的说明进行操作,或者为后者选择 用户偏好设置 > 转换 > 将数学公式导出为 MathML
。
光学字符识别和手写识别
输入的另一种选择是依赖于 光学字符识别 或 手写识别 的用户界面。其中一些工具支持数学公式,并可以将它们导出为 MathML。以下截图显示了 MyScript 的演示。