數學標記語言MathML簡介、工具及相容
byzhangxinxu from ofollow,noindex" target="_blank">https://www.zhangxinxu.com/wordpress/?p=8108
本文可全文轉載,個人網站無需授權,只要保留原作者、出處以及文中連結即可,任何網站均可摘要聚合,商用請聯絡授權。
//zxx: 本文在Firefox或者Safari瀏覽器下瀏覽會有更好的體驗。
一、MathML簡介
MathML指“數學標記語言”,是XML語言的一個子集,用來在web網頁,甚至部分軟體中顯示數學公式。
簡言之,就是使用特殊的類似HTML的標記在網頁中顯示數學公式。
因為有些數學公式很複雜,普通HTML根本沒法駕馭,例如下面這個公式:
都有哪些MathML標記呢?可以看下面的定義列表說明(非原文訪問會數學公式排版異常):
1. 按類別分類的MathML表現元素
頂級元素
- <math>
x
,則有:
<math><mi>x</mi></math>
效果是:
記號元素
<mglyph>
替換顯示,可以理解為MathML世界中的圖片元素,支援
width
,
height
以及
alt
等屬性。例如:
<math> <mi><mglyph src="my-glyph.png" alt="my glyph"/></mi> </math>
mi
是’math identifier’的縮寫,字面意思數學識別符號,多指函式名,變數或者符號常量。示意(下面識別符號之間無任何關聯,僅僅示意語義):
<math> <mi> y </mi> <mi> sin </mi> <mi mathvariant="monospace"> x </mi> <mi mathvariant="bold"> π </mi> </math>
效果是:
mn
是’math number’的縮寫,表示數值,支援各種數值。示意(僅示意,無關聯):
<math> <mn> 0 </mn> <mn> 1.337 </mn> <mn> twelve </mn> <mn> XVI </mn> <mn> 2e10 </mn> </math>
效果是:
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>
效果是:
ms
是’math string literal’的縮寫,表示一個字串文字,這個字串需要由程式語言和計算機代數系統來解釋。預設情況下,字串文字顯示為用雙引號括起來(
"
); 通過使用
lquote
和
rquote
屬性,您可以設定要顯示的自定義字元。示意:
<math> <ms lquote="„" rquote="“"> abc </ms> </math>
效果是:
mspace
是’math space’的縮寫,表示空白間距,其尺寸可以通過
width
,
height
以及
depth
等尺寸控制。示意:
<math> <mi>x</mi> <mspace width="40px"></mspace> <mi>y</mi> </math>
效果是:
<mtext>
元素用於呈現沒有符號含義的任意文字,例如註釋或註解。示意:
<math> <mtext> 畢達哥拉斯定理 </mtext> <mtext> /* 在這裡註釋 */ </mtext> </math>
總體佈局
<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>
元素用來標記這個計算公式或者表示式是錯誤的,瀏覽器會通過邊框和背景色樣式加以明顯區分。示意:
<merror> <mrow> <mtext>除以0:</mtext> <mfrac> <mn> 1 </mn> <mn> 0 </mn> </mfrac> </mrow> </merror> </math>
當前瀏覽器實時效果是:
Firefox瀏覽器截圖效果是:
<maction>
元素可以新增自定義的對稱閉合符號(如括號),以及自定義分隔符(如逗號)。示意:
<math> <mfenced open="{" close="}" separators=";;,"> <mi>a</mi> <mi>b</mi> <mi>c</mi> <mi>d</mi> <mi>e</mi> </mfenced> </math>
當前瀏覽器實時效果是:
在支援的瀏覽器下面會這樣呈現:
<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>
當前瀏覽器實時效果是:
在支援的瀏覽器下面會這樣呈現:
<mpadded>
元素用來給封閉內容增加格外的padding一遍進行位置和尺寸的調整。
<mphantom>
表示當前元素是個“幻影”,也就是不可見,但是位置尺寸都保留,類似CSS世界中的
visibility:hidden
。示意:
<math> <mrow> <mi> x </mi> <mo> + </mo> <mphantom> <mi> y </mi> <mo> + </mo> </mphantom> <mi> z </mi> </mrow> </math>
當前瀏覽器實時效果是:
在支援的瀏覽器下面會這樣呈現:
<mroot>
元素表示根號。示意:
<math> <mroot> <mi>x</mi> <mn>3</mn> </mroot> </math>
當前瀏覽器實時效果是:
在支援的瀏覽器下面會這樣呈現:
<mrow>
元素用於對子表示式進行分組,子表示式通常包含一個或多個運算子及其各自的運算元(例如
<msqrt>
元素表示開平方根。示意:
<math> <msqrt> <mi>x</mi> </msqrt> </math>
當前瀏覽器實時效果是:
<mstyle>
元素用於更改其子項的樣式。例如設定顏色為茶色:
<math> <mstyle displaystyle="true" mathcolor="teal"> <mrow> <mi>i</mi> <mo form="infix">=</mo> <mn>1</mn> </mrow> </mstyle> </math>
在支援的瀏覽器下面會這樣呈現:
指令碼和限制元素
<mmultiscripts>
元素允許你建立一個類似張量物件。“張量”(tensor)理論是數學的一個分支學科,在力學中有重要應用。張量是一個定義在的一些向量空間和一些對偶空間的笛卡兒積上的多重線性對映,其座標是|n|維空間內,有|n|個分量的一種量, 其中每個分量都是座標的函式, 而在座標變換時,這些分量也依照某些規則作線性變換。
這個元素的理解難度已經超出我的能力範疇,溜了溜了……
<mover>
元素用來在表示式的上方新增重音或限制。示意:
<math> <mover accent="true"> <mrow> <mi> x </mi> <mo> + </mo> <mi> y </mi> <mo> + </mo> <mi> z </mi> </mrow> <mo> ⏞ <!--上花括號--> </mo> </mover> </math>
當前瀏覽器實時效果是:
在支援的瀏覽器下面會這樣呈現:
<msub>
好理解,表示下標。示意:
<math> <msub> <mi>X</mi> <mn>1</mn> </msub> </math>
當前瀏覽器效果:
<msubsup>
元素表示同時上標和下標。示意:
<math displaystyle="true"> <msubsup> <mo> ∫<!-- 積分 --> </mo> <mn> 0 </mn> <mn> 1 </mn> </msubsup> </math>
當前瀏覽器實時效果是:
在支援的瀏覽器下面會這樣呈現:
<msup>
表示上標,參見下標
<msub>
<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>
當前瀏覽器實時效果是:
在支援的瀏覽器下面會這樣呈現:
<munderover>
元素表示同時出現在上面和下面。示意:
<math displaystyle="true"> <munderover > <mo> ∫ <!--積分--> </mo> <mn> 0 </mn> <mi> ∞ <!--無窮--> </mi> </munderover> </math>
當前瀏覽器實時效果是:
在支援的瀏覽器下面會這樣呈現:
表格數學
<mlabeledtr>
元素用於表示行內label標籤,要麼在左側要麼在右側(由
<mtable>
元素上的
side
屬性決定)。
<mlabeledtr>
的子元素必須是
<mtd>
元素。 第一個子節點是label標籤,而所有其他子節點表示行內容,並且與
<mtr>
元素的子節點相同。根據我在Firefox瀏覽器下的測試,應當作為label標籤的第一個子節點並未顯示。
<mtable>
元素可以理解為HTML屆的
<table>
元素,雖然屬性出入較大,但排版佈局表現很類似。
<maction>
元素可以理解為HTML屆的
<td>
元素,表示單元格,兩者排版效果很類似。
<maction>
元素可以理解為HTML屆的
<tr>
元素,表示表格行,兩者排版佈局效果很類似。
未分類元素
<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>
表示註解與說明。
<annotation-xml>
指明函式或表示式結構。
<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的專案: https://github.com/fred-wang/mathml.css
針對Chrome這類不支援的瀏覽器使用CSS進行了公式佈局的模擬。使用方法可以是直接引入下面JS程式碼:
<script src="//fred-wang.github.io/mathml.css/mspace.js"></script>
這個mspace.js會檢測當前瀏覽器是否支援MathML,如果不支援,就會載入mathml.css檔案做相容,但也只是一定程度上的相容,根據我的實際使用測評,很多標籤和屬性功能並不支援,然後,最終呈現的排版效果和原本支援的瀏覽器(如Firefox)相差甚遠,只能說湊合使用。
三、線上生成MathML的工具介紹
從第一段的介紹就可以看出MathML非常複雜,是個完整的XML語言體系,其中還有茫茫多的XML屬性還沒介紹,由於對於複雜公式,我們想要完全手寫出來,呵呵,估計要廢掉大半的血條。
好在有現成的工具,可以直接生成MathML程式碼。經過自己一番實踐,發現下面這個工具是極好的!
例如,我在畫布中寫個x 2 +y 2 =z 2 ,結果右上角MathML程式碼就出來了,實在太牛了!
四、小眾語言,總會有用的
MathML這麼語言,雖然小眾,但總歸有用的,舉例來說,我之前寫了很多動畫相關的文章,例如拋物線運動,矩陣變換介紹等,都需要用到數學公式,如果得到精美的自己想要的公式程式碼呢?經過這幾天學習,我就知道該怎麼玩了。
先開啟上面介紹的線上生成MathML的工具,手寫數學公式,然後把生成的MathML程式碼在Firefox瀏覽器中顯示,然後截圖,一個精緻的數學公式效果圖就出來了!
要是沒有對MathML的學習和研究,肯定不會知道原來還可以這麼玩,對吧?
學習呢,不要功利心太強,就算當下看不到效益,但在將來某一天,總會給你帶來雪中送炭般的幫助的。
感謝閱讀,歡迎交流!