凌云的博客

行胜于言

MathML 实用教程

分类:html| 发布时间:2025-01-27 17:40:00

什么是 MathML

数学标记语言(MathML)是一种基于 XML 的,用于描述数学符号的语言。

MathML 最初被设计为用于浏览器、办公套件、计算机代数系统、EPUB 阅读器和基于 LaTeX 的生成器的通用规范。 然而,这种方法并不非常适用于 Web:专注于语义的子集从未在浏览器中实现,而专注于数学布局的子集导致了不完整和不一致的浏览器实现。

MathML Core 是一个基于 LaTeX 和开放字体格式规则的增加了实现细节的子集。 它专门为浏览器量身定制,并设计成与其他 Web 标准(包括 HTML、CSS、DOM、JavaScript)良好配合。

通过 <math> 元素在 HTML 中插入公式

MathML 使用与 HTML 相同的语法来表示元素和属性的树形结构。 特别地,每个数学公式都由一个 <math> 元素表示,该元素可以放置在 HTML 页面中。 在下面的文档中,它位于一个段落文本中:

<!doctype html>
<html lang="zh-CN">
  <head>
    <title>我的第一个数学页面</title>
  </head>
  <body>
    <p>
      分数
      <math>
        <mfrac>
          <mn>1</mn>
          <mn>3</mn>
        </mfrac>
      </math>
      不是十进制数。
    </p>
  </body>
</html>

<mfrac> 元素指定了一个分数,其中分子是它的第一个子元素,分母是它的第二个子元素。 以下是它在浏览器中的呈现方式:

分数 1 3 不是十进制数。

警告: 如果你只看到“1 3”而不是一个分数,那么你的浏览器可能不支持 MathML。 请查看 浏览器兼容性表格 获取进一步的详细信息。

display 属性

请注意,在前面的示例中,公式与段落文本在一行上。 然而,通常情况下,我们会将大的数学公式居中显示在独立的行上,如下所示。 为了实现这一点,你需要在 <math> 元素上附加一个 display="block" 属性。

分数 1 3 不是十进制数。

你可能还会注意到一些细微的外观变化:分数的文本和垂直间距变大了一点。 没有 display="block" 属性,高度会被最小化,以避免干扰周围文本的流畅性。 使用 display="block" 属性时,优先考虑的是数学公式的易读性。

使用 <mrow> 元素进行分组

实际上,<math> 元素可以包含任意数量的子元素,并且将它们在一行内呈现。 例如,简单的公式“1 + 2 + 3”在 MathML 中的编码如下:

<math>
  <mn>1</mn>
  <mo>+</mo>
  <mn>2</mn>
  <mo>+</mo>
  <mn>3</mn>
</math>

显示如下:

1 + 2 + 3

<mrow> 元素是一个通用容器,可以执行类似的布局,但可以放置在 MathML 子树的任何位置。 它可以将多个元素组合在一起。 例如,下面的分数的分子部分(它的第一个子元素)是“一加二”。

<math>
  <mfrac>
    <mrow>
      <mn>1</mn>
      <mo>+</mo>
      <mn>2</mn>
    </mrow>
    <mn>3</mn>
  </mfrac>
</math>

显示如下:

1 + 2 3

数学符号的 Unicode 字符

数学公式涉及许多特殊字符,例如希腊字母(例如 Δ)、弗拉克图尔字母(例如 𝔄)、双线字母(例如 ℂ)、二元运算符(例如 ≠)、箭头(例如 ⇒)、积分符号(例如 ∮)、求和符号(例如 ∑)、逻辑符号(例如 ∀)以及括号(例如 ⌊)等等。 维基百科的文章 数学运算符和符号的 Unicode 提供了这些字符的概述。

由于这些字符大多不属于基本拉丁 Unicode 块,因此建议指定你的文档字符编码,并使用适当的 Web 字体。以下是一个使用 UTF-8 编码和 Latin Modern Math 字体的基本模板:

<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <title>带数学字符的页面</title>
    <link
      rel="stylesheet"
      href="https://fred-wang.github.io/MathFonts/LatinModern/mathfonts.css" />
  </head>
  <body>
    <p style="font-family: Latin Modern Math">∀A∊𝔰𝔩(n,𝔽),TrA=0</p>
  </body>
</html>

一些语义

MathML 公式中的文本被包裹在特定的容器元素中,例如 <mn><mo>。 一般而言,MathML 公式中的所有文字都必须包含在这类容器元素中,这类元素被称为标记(token)元素。 此外,MathML 提供了多种标记元素,以区分文字内容的不同含义。

  • <mi> 元素表示“标识符”,其可以是符号名称或任意文本。 例如:<mi>x</mi>(变量)、<mi>cos</mi>(函数名)和 <mi>π</mi>(符号常量)。
  • <mn> 元素表示“数值文字”或其他应呈现为数值文字的数据。 例如:<mn>2</mn>(整数)、<mn>0.123</mn>(小数)或 <mn>0xFFEF</mn>(十六进制值)。
  • <mo> 元素表示运算符或任何应呈现为运算符的内容。 例如:<mo>+</mo>(二元运算符)、<mo>≤</mo>(二元关系符),<mo>∑</mo>(求和符号)或 <mo>[</mo>(括号)。
  • <mtext> 元素用于表示任意文本。例如公式中的短词,如 <mtext>if</mtext><mtext>映射到</mtext>

<mi> 的自动斜体化

在数学中的一种排版惯例是使用斜体字母表示变量。 为了帮助实现这一点,仅具有单个字符的 <mi> 元素会自动呈现为斜体。 请比较以下公式中两个 <mi> 元素的渲染效果:

<math>
  <mi>sin</mi>
  <mi>x</mi>
</math>

显示为:

sin x

要想阻止 元素的自动斜体化,可以在该元素上附加 mathvariant="normal" 属性。 例如:

<math>
  <mi>sin</mi>
  <mi mathvariant="normal">x</mi>
</math>

显示为:

sin x

<mo> 的运算符属性

MathML 包含一个 运算符字典,其根据 <mo> 元素的内容和其在容器中的位置(前缀、中缀或后缀),定义了默认属性。 例如:

<table>
  <tr>
    <td>前缀加号</td>
    <td>
      <math>
        <mo>+</mo>
        <mi>i</mi>
      </math>
    </td>
  </tr>
  <tr>
    <td>中缀加号</td>
    <td>
      <math>
        <mi>j</mi>
        <mo>+</mo>
        <mi>i</mi>
      </math>
    </td>
  </tr>
  <tr>
    <td>前缀求和符号</td>
    <td>
      <math>
        <mo>∑</mo>
        <mi>i</mi>
      </math>
    </td>
  </tr>
</table>

显示为:

前缀加号 + i
中缀加号 j + i
前缀求和符号 i

前缀加号没有间距,中缀加号有一些间距,前缀求和符号有一些较小的间距。

可伸缩运算符

操作符词典定义了一些操作符的默认可伸缩属性以及相应的伸缩轴。 例如,操作符可以默认垂直伸展,以覆盖其 <mrow> 容器中非可伸缩兄弟节点的最大高度。

比如:

<math display="block">
  <mrow>
    <mo>|</mo>
    <mfrac>
      <mn>1</mn>
      <mi>x</mi>
    </mfrac>
    <mo>|</mo>
  </mrow>
</math>

显示为:

| 1 x |

部分操作符可以支持横向伸展,比如:

<math display="block">
  <mrow>
    <munder>
      <mrow>
        <msub>
          <mi>z</mi>
          <mn>1</mn>
        </msub>
        <mo>+</mo>
        <msub>
          <mi>z</mi>
          <mn>2</mn>
        </msub>
      </mrow>
      <mo>⎵</mo>
    </munder>
  </mrow>
</math>

显示为:

z 1 + z 2

分数 <mfrac>

<mfrac> 元素被渲染为一个分数:第一个子元素(分子)被绘制于第二个子元素(分母)的上方,并由一条水平线分隔。

<math display="block">
  <mfrac>
    <mtext>child1</mtext>
    <mtext>child2</mtext>
  </mfrac>
</math>

显示为:

child1 child2

有些数学概念有时会使用类似分数的表示法,例如二项式系数或勒让德符号。 对于这种不绘制横线的类似分数的表示法,可以在 <mfrac> 元素上附加 linethickness="0" 属性进行标记:

<math display="block">
  <mrow>
    <mo>(</mo>
    <mfrac linethickness="0">
      <mn>3</mn>
      <mn>2</mn>
    </mfrac>
    <mo>)</mo>
  </mrow>
  <mo>=</mo>
  <mn>3</mn>
  <mo>≠</mo>
  <mfrac>
    <mn>3</mn>
    <mn>2</mn>
  </mfrac>
</math>

显示为:

( 3 2 ) = 3 3 2

平方根 <msqrt>

<msqrt> 被渲染为一个平方根:其子元素呈现为一个 <mrow>,前缀为根号√,并完全被一条横线覆盖。

<math display="block">
  <msqrt>
    <mtext>child1</mtext>
    <mtext>child2</mtext>
    <mtext>...</mtext>
    <mtext>childN</mtext>
  </msqrt>
</math>

显示为:

child1 child2 ... childN

n 次方根 <mroot>

<mroot> 元素被渲染为一个 n 次方根:第一个元素被根号符号覆盖,而第二个元素被用作根的次数,并作为前缀上标呈现。

<math display="block">
  <mroot>
    <mtext>child1</mtext>
    <mtext>child2</mtext>
  </mroot>
</math>

显示为:

child1 child2

下标 <msub>

<msub> 元素的第二个子元素作为其第一个子元素的下标

<math display="block">
  <msub>
    <mtext>child1</mtext>
    <mtext>child2</mtext>
  </msub>
</math>

显示为:

child1 child2

上标 <msup>

<msup> 元素的第二个子元素作为其第一个子元素的上标

<math display="block">
  <msup>
    <mtext>child1</mtext>
    <mtext>child2</mtext>
  </msup>
</math>

显示为:

child1 child2

下标和上标同时存在 <msubsup>

<msubsup> 元素的第二个和第三个子元素分别作为其第一个子元素的下标和上标

<math display="block">
  <msubsup>
    <mtext>child1</mtext>
    <mtext>child2</mtext>
    <mtext>child3</mtext>
  </msubsup>
</math>

显示为:

child1 child2 child3

正下标 <munder>

<munder> 元素的第二个子元素作为其第一个子元素的正下标

<math display="block">
  <munder>
    <mtext>child1</mtext>
    <mtext>child2</mtext>
  </munder>
</math>

显示为:

child1 child2

正上标 <mover>

<mover> 元素的第二个子元素作为其第一个子元素的正上标

<math display="block">
  <mover>
    <mtext>child1</mtext>
    <mtext>child2</mtext>
  </mover>
</math>

显示为:

child1 child2

正下标和上标同时存在 <munderover>

<munderover> 元素的第二个和第三个子元素分别作为其第一个子元素的正下标和正上标

<math display="block">
  <munderover>
    <mtext>child1</mtext>
    <mtext>child2</mtext>
    <mtext>child3</mtext>
  </munderover>
</math>

显示为:

child1 child2 child3

MathML 表格

MathML 表格元素与 HTML 表格的元素类似:<mtable> 元素表示数学表格,它的子元素是 <mtr> 元素(表示行),每个 <mtr> 元素都有 <mtd> 元素作为其子元素(表示单元格)。 <mtable> 元素可以在 MathML 公式的任何位置插入。 <mtd> 元素可以包含任意数量的 MathML 子元素,并将它们布局为 <mrow> 容器。

<math display="block">
  <mrow>
    <mo>(</mo>
    <mtable>
      <mtr>
        <mtd>
          <mi>a</mi>
        </mtd>
        <mtd>
          <mi>c</mi>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <msub>
            <mi>t</mi>
            <mi>x</mi>
          </msub>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mi>b</mi>
        </mtd>
        <mtd>
          <mi>d</mi>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <msub>
            <mi>t</mi>
            <mi>y</mi>
          </msub>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>1</mn>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>1</mn>
        </mtd>
      </mtr>
    </mtable>
    <mo>)</mo>
  </mrow>
</math>

显示为:

( a c 0 t x b d 0 t y 0 0 1 0 0 0 0 1 )

总结

  • <math> 用于在 HTML 中插入数学公式
  • <mfrac> 用于插入分数
  • <msqrt> 用于插入平方根
  • <mroot> 用于插入 n 次方根
  • <msub> 用于插入下标
  • <msup> 用于插入上标
  • <msubsup> 用于下标和上标同时存在的情况
  • <munder> 用于插入正下标
  • <mover> 用于插入正上标
  • <munderover> 用于正下标和正上标同时存在的情况
  • <mrow> 用于分组
  • 数学公式的表格类似 HTML 的表格 <mtable> 类似 <table><mtr> 类似 <tr><mtd> 类似 <td>