MathML 的纯 HTML 后备方案

Sor*_*455 4 html mathml

MathML是一种用于编写数学的 Web 标准,无需像素化即可轻松缩放(就像 SVG 一样)、复制和粘贴以及由屏幕阅读器读取。

Chrome 拒绝实现它,因为存在 JavaScript polyfill。(我没有骗你。) Edge 的支持“目前没有计划”。因此,只有 Safari 和 Firefox(以及一些 EPub 阅读器)支持 MathML。

鉴于实施情况参差不齐,后备内容是 100% 必要的。通常的解决方案是MathJax;但这对于禁用 JavaScript 或更有可能损坏 JavaScript 的用户来说不起作用。

我们生活在一个 HTML 轻松允许后备内容而无需 JavaScript 的时代(请参阅<picture><audio><video>标签)。MathML 有什么办法可以做到这一点吗?

Sor*_*455 5

据我所知,没有纯 HTML 的方法来检测对 MathML 的支持。

然而,一种 SVG 方式。

SVG<switch>元素呈现其自身的第一个直接子元素,其中该子元素的某些布尔属性要么缺失,要么计算结果为 true。一个这样的属性是requiredExtensions属性,它要求用户代理必须支持特定的扩展来呈现指示的元素。

因此,如果您有一个带有set 的SVG<foreignObject>元素(用于在 SVG 中嵌入非 SVG 元素) ,然后将其放入元素内,则如果支持 MathML,则将渲染该元素,如果支持 MathML,则下一个元素将是不是。requiredExtensions="http://www.w3.org/1998/Math/MathML"<foreignObject><switch><math>

因此,对于一个基本的 MathML 示例:<math xmlns="http://www.w3.org/1998/Math/MathML"><mn>1</mn><mo>+</mo><mn>1</mn><mo>=</mo><mn>2</mn></math>MathML 表示 1 + 1 = 2。

一个基本的 SVG 后备是<svg xmlns="http://www.w3.org/2000/svg" width="65" height="23"><text y="15" font-size="16">1 + 1 = 2</text></svg>(可以使用Mathjax-Node生成更复杂的后备)。

因此,具有后备功能的完整 MathML 表达式将是:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="40">
  <switch>
    <foreignObject requiredExtensions="http://www.w3.org/1998/Math/MathML" width="120" height="40">
      <math xmlns="http://www.w3.org/1998/Math/MathML">
        <mn>1</mn><mo>+</mo><mn>1</mn><mo>=</mo><mn>2</mn><mtext>MathML</mtext>
      </math>
    </foreignObject>
    <text y="15" font-size="16">1 + 1 = 2 (SVG)</text>
  </switch>
</svg>
Run Code Online (Sandbox Code Playgroud)

我已经在 Firefox(渲染 MathML)、Edge、IE11 和 Chrome(渲染 SVG)中测试了上述内容。我没有测试过 Safari,因为我没有 Mac。

编辑:Safari 9 呈现 MathML。

但我想支持IE8!

为什么?

因为!

美好的。

如果您想保留复制+过去数学的能力,则不能使用标签<picture>来嵌入 SVG/MathML 混合体 - 请改用<object>

(我在这里使用 DataUrl,但您可以轻松地将 SVG 保存为外部文件):

<object typemustmatch type="image/svg+xml" data="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTIwIiBoZWlnaHQ9IjQwIj4NCiAgPHN3aXRjaD4NCiAgICA8Zm9yZWlnbk9iamVjdCByZXF1aXJlZEV4dGVuc2lvbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aC9NYXRoTUwiIHdpZHRoPSIxMjAiIGhlaWdodD0iNDAiPg0KICAgICAgPG1hdGggeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aC9NYXRoTUwiPg0KICAgICAgICA8bW4+MTwvbW4+PG1vPis8L21vPjxtbj4xPC9tbj48bW8+PTwvbW8+PG1uPjI8L21uPjxtdGV4dD5NYXRoTUw8L210ZXh0Pg0KICAgICAgPC9tYXRoPg0KICAgIDwvZm9yZWlnbk9iamVjdD4NCiAgICA8dGV4dCB5PSIxNSIgZm9udC1zaXplPSIxNiI+MSArIDEgPSAyIChTVkcpPC90ZXh0Pg0KICA8L3N3aXRjaD4NCjwvc3ZnPg==">
  1 + 1 = 2 (You don't support SVG)
</object>
Run Code Online (Sandbox Code Playgroud)

(如果您确实需要,您可以使用CloudConvert或类似工具将 SVG 渲染为 PNG ,然后将其放入对象内部。)

所以就这样吧。进行一点预渲染,您就可以得到不需要 JavaScript 或 CSS - 只需 HTML 的 MathML 后备。

编辑:我制作了一个 NPM 包来自动创建 MathML、SVG 和 PNG。在这里能找到它。