//zxx: 本文在Firefox或者Safari浏览器下浏览会有更好的体验。
一、MathML简介
MathML指“数学标记语言”,是XML语言的一个子集,用来在web网页,甚至部分软件中显示数学公式。
简言之,就是使用特殊的类似HTML的标记在网页中显示数学公式。
因为有些数学公式很复杂,普通HTML根本没法驾驭,例如下面这个公式:
都有哪些MathML标记呢?可以看下面的定义列表说明(非原文访问会数学公式排版异常):
1. 按类别分类的MathML表现元素
顶级元素
<math>
用在最外部包裹,表示里面的都是数学公式。例如,就一个变量x
,则有:
<math><mi>x</mi></math>
效果是:x
记号元素
<mglyph>
有些现存的Unicode字符是不可用的,此时就可以使用<mglyph>
替换显示,可以理解为MathML世界中的图片元素,支持width
,height
以及alt
等属性。例如:
<math><mi><mglyph src="my-glyph.png" alt="my glyph"/></mi></math>
<mi>
mi
是’math identifier’的缩写,字面意思数学标识符,多指函数名,变量或者符号常量。示意(下面标识符之间无任何关联,仅仅示意语义):
<math> <mi> y </mi> <mi> sin </mi><mi mathvariant="monospace"> x </mi><mi mathvariant="bold"> π </mi></math>
效果是:ysinxπ
<mn>
mn
是’math number’的缩写,表示数值,支持各种数值。示意(仅示意,无关联):
<math> <mn> 0 </mn><mn> 1.337 </mn><mn> twelve </mn><mn> XVI </mn><mn> 2e10 </mn> </math>
效果是:01.337twelveXVI2e10
<mo>
mn
是’math operators’的缩写,表示数学操作符,例如加减乘除,各种括号,分号等。示意:
<math><mrow><mn>5</mn><mo>+</mo><mn>5</mn></mrow> <mrow><mo> [ </mo> <mrow><mn> 0 </mn><mo> ; </mo> <mn> 1 </mn></mrow><mo> ) </mo></mrow></math>
效果是:5+5[0;1)
<ms>
ms
是’math string literal’的缩写,表示一个字符串文字,这个字符串需要由编程语言和计算机代数系统来解释。默认情况下,字符串文字显示为用双引号括起来("
); 通过使用lquote
和rquote
属性,您可以设置要显示的自定义字符。示意:
<math><ms lquote="„" rquote="“"> abc </ms></math>
效果是:abc
<mspace>
mspace
是’math space’的缩写,表示空白间距,其尺寸可以通过width
,height
以及depth
等尺寸控制。示意:
<math><mi>x</mi><mspace width="40px"></mspace><mi>y</mi></math>
效果是:xy
<mtext>
MathML<mtext>
元素用于呈现没有符号含义的任意文本,例如注释或注解。示意:
<math> <mtext> 毕达哥拉斯定理 </mtext> <mtext> /* 在这里注释 */ </mtext></math>
总体布局
<menclose>
MathML<menclose>
元素用来把内容封闭在指定的记号中(通过设置notation
属性)。示意一个根号效果:
<math> <menclose notation="radical"><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup></menclose></math>
在支持的浏览器,例如Firefox浏览器中,表现会如后面这样:
<menclose>
元素支持的封闭符合非常多,款式各种各样,让人大开眼界,有兴趣可以看MDN这个文档。
<merror>
MathML<merror>
元素用来标记这个计算公式或者表达式是错误的,浏览器会通过边框和背景色样式加以明显区分。示意:
<merror><mrow><mtext>除以0:</mtext><mfrac><mn> 1 </mn><mn> 0 </mn></mfrac></mrow></merror></math>
当前浏览器实时效果是:除以0:10
Firefox浏览器截图效果是:
<mfenced>
MathML<maction>
元素可以添加自定义的对称闭合符号(如括号),以及自定义分隔符(如逗号)。示意:
<math><mfenced open="{" close="}" separators=";;,"> <mi>a</mi> <mi>b</mi> <mi>c</mi> <mi>d</mi> <mi>e</mi> </mfenced> </math>
当前浏览器实时效果是:abcde
在支持的浏览器下面会这样呈现:
<mfrac>
MathML<mfrac>
指'math fraction'
,表示分数,也即是除法。示意:
<math> <mfrac bevelled="true"><mfrac><mi> a </mi><mi> b </mi></mfrac><mfrac><mi> c </mi><mi> d </mi></mfrac></mfrac></math>
当前浏览器实时效果是:abcd
在支持的浏览器下面会这样呈现:
<mpadded>
MathML<mpadded>
元素用来给封闭内容增加格外的padding一遍进行位置和尺寸的调整。
<mphantom>
Phantom这个单词是幻影的意思。因此MathML<mphantom>
表示当前元素是个“幻影”,也就是不可见,但是位置尺寸都保留,类似CSS世界中的visibility:hidden
。示意:
<math><mrow><mi> x </mi><mo> + </mo> <mphantom><mi> y </mi><mo> + </mo></mphantom><mi> z </mi></mrow></math>
当前浏览器实时效果是:x+y+z
在支持的浏览器下面会这样呈现:
<mroot>
MathML<mroot>
元素表示根号。示意:
<math><mroot><mi>x</mi><mn>3</mn></mroot> </math>
当前浏览器实时效果是:x3
在支持的浏览器下面会这样呈现:
<mrow>
MathML<mrow>
元素用于对子表达式进行分组,子表达式通常包含一个或多个运算符及其各自的操作数(例如和)。 此元素水平呈现。上面很多案例已经有示意,这里不重复演示。
<msqrt>
MathML<msqrt>
元素表示开平方根。示意:
<math><msqrt><mi>x</mi></msqrt> </math>
当前浏览器实时效果是:x
<mstyle>
MathML<mstyle>
元素用于更改其子项的样式。例如设置颜色为茶色:
<math> <mstyle displaystyle="true" mathcolor="teal"><mrow><mi>i</mi><mo form="infix">=</mo><mn>1</mn></mrow></mstyle></math>
在支持的浏览器下面会这样呈现:
脚本和限制元素
<mmultiscripts>
MathML<mmultiscripts>
元素允许你创建一个类似张量对象。“张量”(tensor)理论是数学的一个分支学科,在力学中有重要应用。张量是一个定义在的一些向量空间和一些对偶空间的笛卡儿积上的多重线性映射,其坐标是|n|维空间内,有|n|个分量的一种量, 其中每个分量都是坐标的函数, 而在坐标变换时,这些分量也依照某些规则作线性变换。
这个元素的理解难度已经超出我的能力范畴,溜了溜了……
<mover>
MathML<mover>
元素用来在表达式的上方添加重音或限制。示意:
<math><mover accent="true"><mrow><mi> x </mi><mo> + </mo><mi> y </mi><mo> + </mo><mi> z </mi></mrow><mo> ⏞ <!--上花括号--> </mo></mover> </math>
当前浏览器实时效果是:x+y+z⏞
在支持的浏览器下面会这样呈现:
<msub>
MathML<msub>
好理解,表示下标。示意:
<math><msub><mi>X</mi><mn>1</mn></msub></math>
当前浏览器效果:X1
<msubsup>
MathML<msubsup>
元素表示同时上标和下标。示意:
<math displaystyle="true"> <msubsup><mo> ∫<!-- 积分 --> </mo><mn> 0 </mn><mn> 1 </mn></msubsup></math>
当前浏览器实时效果是:∫01
在支持的浏览器下面会这样呈现:
<msup>
MathML<msup>
表示上标,参见下标<msub>
<munder>
MathML<munder>
元素和<mover>
对立,表示在表达式下方强调或者限制。示意:
<math><munder accent="true"><mrow><mi> x </mi><mo> + </mo><mi> y </mi><mo> + </mo><mi> z </mi></mrow><mo> ⏟ <!--下花括号--> </mo></munder> </math>
当前浏览器实时效果是:x+y+z⏟
在支持的浏览器下面会这样呈现:
<munderover>
MathML<munderover>
元素表示同时出现在上面和下面。示意:
<math displaystyle="true"> <munderover ><mo> ∫ <!--积分--> </mo><mn> 0 </mn><mi> ∞ <!--无穷--> </mi></munderover></math>
当前浏览器实时效果是:∫0∞
在支持的浏览器下面会这样呈现:
表格数学
<mlabeledtr>
MathML<mlabeledtr>
元素用于表示行内label标签,要么在左侧要么在右侧(由<mtable>
元素上的side
属性决定)。<mlabeledtr>
的子元素必须是<mtd>
元素。 第一个子节点是label标签,而所有其他子节点表示行内容,并且与<mtr>
元素的子节点相同。根据我在Firefox浏览器下的测试,应当作为label标签的第一个子节点并未显示。
<mtable>
MathML<mtable>
元素可以理解为HTML届的<table>
元素,虽然属性出入较大,但排版布局表现很类似。
<mtd>
MathML<maction>
元素可以理解为HTML届的<td>
元素,表示单元格,两者排版效果很类似。
<mtr>
MathML<maction>
元素可以理解为HTML届的<tr>
元素,表示表格行,两者排版布局效果很类似。
未分类元素
<maction>
MathML<maction>
元素可以添加交互行为,例如展现的是表达式,点击一下出现的是表达式计算结果。示意一个1+1=2的效果:
<math><maction actiontype="toggle"><mrow><mn>1</mn><mo>+</mo><mn>1</mn></mrow><mrow><mo>=</mo><mn>2</mn></mrow> </maction></math>
效果如下GIF:
2. 语义注释
在MathML中,有两种标记数学的方法:Presentation MathML用于控制数学方程或表达式的布局,也就是用户看到的外观(上面介绍的部分),而Content MathML用于使数学方程或表达式更语义化,便于计算机理解。 MathML元素<semantics>
,<annotation>
和<annotation-xml>
用于联合展示和内容标记,以及提供数学表达式的布局信息和语义。
<annotation>
MathML<annotation>
表示注解与说明。
<annotation-xml>
MathML<annotation-xml>
指明函数或表达式结构。
<semantics>
MathML<semantics>
表示里面含有语义化信息。
上面3元素看下面一个案例就能知道大概作用了:
<math><semantics><!-- Presentation MathML --><mrow><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mi>y</mi></mrow><!-- Content MathML --><annotation-xml encoding="MathML-Content"><apply><plus/><apply><power/><ci>x</ci><cn type="integer">2</cn></apply><ci>y</ci></apply></annotation-xml><!-- 图像注解 --><annotation encoding="image/png" src="some/path/formula.png"/><!-- TeX注解 --><annotation encoding="application/x-tex">x^{2} + y </annotation> </semantics></math>
其他
可以看到都以MathML标记都是字母m
开头。上面所有展示的MathML代码效果都可以在这个页面看到,您可以狠狠地点击这里:MathML示意demo
二、浏览器的兼容处理
首先看下兼容性,Chrome浏览器在版本24的时候曾经昙花一现支持了下,不过很快就取消了支持,据说是出于安全考虑。
据说IE浏览器可以安装MathPlayer插件支持下,不过我个人觉得最终效果尔尔。
至于Chrome浏览器,我查找了下,有个名叫mathml.css的项目:/fred-wang/mathml.css
针对Chrome这类不支持的浏览器使用CSS进行了公式布局的模拟。使用方法可以是直接引入下面JS代码:
<script src="//fred-wang.github.io/mathml.css/mspace.js"></script>
这个mspace.js会检测当前浏览器是否支持MathML,如果不支持,就会加载mathml.css文件做兼容,但也只是一定程度上的兼容,根据我的实际使用测评,很多标签和属性功能并不支持,然后,最终呈现的排版效果和原本支持的浏览器(如Firefox)相差甚远,只能说凑合使用。
补充于-03-13
外面的世界总有不确定性,于是我把上面项目demo自己服务器上也迁移了一份,顺便优化了下显示的字体,主要针对Chrome浏览器显示。
mathml.css效果的demo演示
字体设置:
math {font-family: Cambria Math, Latin Modern Math;}
Cambria Math是Windows系统,Latin Modern Math是macOS系统。
三、在线生成MathML的工具介绍
从第一段的介绍就可以看出MathML非常复杂,是个完整的XML语言体系,其中还有茫茫多的XML属性还没介绍,由于对于复杂公式,我们想要完全手写出来,呵呵,估计要废掉大半的血条。
好在有现成的工具,可以直接生成MathML代码。经过自己一番实践,发现下面这个工具是极好的!
手写公式自动变MathML
例如,我在画布中写个x2+y2=z2,结果右上角MathML代码就出来了,实在太牛了!
四、小众语言,总会有用的
MathML这么语言,虽然小众,但总归有用的,举例来说,我之前写了很多动画相关的文章,例如抛物线运动,矩阵变换介绍等,都需要用到数学公式,如果得到精美的自己想要的公式代码呢?经过这几天学习,我就知道该怎么玩了。
先打开上面介绍的在线生成MathML的工具,手写数学公式,然后把生成的MathML代码在Firefox浏览器中显示,然后截图,一个精致的数学公式效果图就出来了!
要是没有对MathML的学习和研究,肯定不会知道原来还可以这么玩,对吧?
学习呢,不要功利心太强,就算当下看不到效益,但在将来某一天,总会给你带来雪中送炭般的帮助的。
感谢阅读,欢迎交流!