分類: 網頁開發

使用 MathJax 把 LaTeX 或 MathML 數學式子放進網頁

MathJax 這個 JavaScript 工具可以讓你直接使用 LaTeX、MathML 或 AsciiMath 的語法把數學式子寫進網頁中,它會自動幫你排版並產生 HTML、SVG 或是 MathML 的方程式,讓各種瀏覽器都可以看,效果幾乎跟傳統上的 LaTeX 一樣,非常厲害。

傳統上如果要在網頁上顯示專業排版的數學式子,大概都只能靠 LaTeX 排版之後,透過一些編譯工具把 LaTeX 轉成圖片檔,再放進網頁中,雖然有很多線上編譯 LaTeX 的工具可以使用,但是最終還是需要自己內崁圖檔,並不是很方便。


現在有了 MathJax 這個工具,使用起來既方便效果又好,下面這個就是使用 MathJax 所排版出來的效果:

When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

A Cross Product Formula:

$$\mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix}
\mathbf{i} & \mathbf{j} & \mathbf{k} \\
\frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\
\frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0
\end{vmatrix}$$

An Identity of Ramanujan:

$$\frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} =
1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}}
{1+\frac{e^{-8\pi}} {1+\ldots} } } }$$

這些都是將原始的 LaTeX 直接寫在網頁中的,在這些數學式子上點右鍵,還可以直接看到該式子的原始 LaTeX 程式碼:

選擇「TeX Commands」打開之後,就會看到程式碼:

如果想使用 MathJax 的話,主要有有幾種方式,你可以直接使用 cdn.mathjax.org 上面提供的連結,或是將 MathJax 的 JavaScript 檔直接下載下來,放在自己的網頁伺服器中使用,或是放在自己的電腦中使用(在沒有連上網路的時候)。以下是各種情況的教學。

使用 MathJax Content Delivery Network(CDN)

要使用 MathJax 最直接的方式就是直接使用 CDN 所提供的服務,只要在自己的網頁加入 MathJax 函式庫的連結就可以直接使用,以下是設定步驟。

首先在網頁的 header 部分加入載入 MathJax JavaScript 的程式碼,也就是在 <head></head> 之間加入:

<script type="text/javascript"
  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>

而這段 JavaScript 也可以加在 <body> 之中,但一般來說都會把他放在 <head> 的部份,除非不想更動 <head> 的時候,才會改放在 <body> 之中(下面會介紹這樣的狀況)。

引入這段 MathJax 的 JavaScript 程式碼之後,它會自動從分散式的伺服器上載入最新版的 MathJax,然後使用預設的設定值將網頁中的 TeX 或 MathML 語法轉換為 MathML(在瀏覽器支援的情況下)或 HTML 與 CSS 來顯示數學式子,這是完全沒有做任何設定時,預設會執行的動作,這對於大部份的使用者而言,應該是很夠用了,而如果需要的也可以自己加入額外的參數設定,設定方式可參考 Loading and Configuring MathJax

使用加密的 CDN

上面這個方式是透過一般的 HTTP 連線從 cdn.mathjax.org 抓取 JavaScript 程式碼,這個方式有潛在的安全性風險,有可能會遭受 man in the middle 的攻擊。如果想避免這個風險,則可以透過 HTTPS 加密的連線來使用 MathJax CDN 伺服器,而使用方式只是簡單的將 src 的內容改一下而已:

<script type="text/javascript"
  src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>

安裝自己的 MathJax

在一般的狀況下建議是以上述的 CDN 方式來使用 MathJax,但你也可以直接把 MathJax 的 JavaScript 函式庫直接安裝在自己的伺服器上,或是放在本機使用。

若要把 MathJax 安裝在自己的機器上使用,基本上有下面幾個步驟:

  1. 將 MathJax 下載後放在自己的伺服器或電腦上。
  2. 依據自己的需求設定 MathJax。
  3. 將 MathJax 連結至要使用數學式子的網頁中。
  4. 把數學式子放上網頁。

取得與安裝 MathJax

MathJax 函式庫可以從 MathJax 的官方網站直接下載,下載下來的檔案大概會是一個類似 mathjax-MathJax-v2.1-X-XXXXXXXX.zip 的壓縮檔,這個壓縮檔中包含了 MathJax 的原始程式碼與網頁字型,其中已經包含所有你所需要的東西。(舊版的 MathJax 會有些差異,若在 1.0 版以前,網頁字型與程式碼是分開的)

將下載下來的壓縮黨解壓縮之後,在自己的網頁伺服器上選擇一個地方將 MathJax 資料夾放上去,當然這個放置的位置要可以被其他網頁引入的才行,例如放在網頁的最上層目錄中的話,則在伺服器上的網頁要引入 MathJax 的時候,URL 位址就寫成 /MathJax/MathJax.js

上面這個方式是最簡單的使用方法,然而還有其他更好的方式可以讓你自己伺服器中的 MathJax 版本自動更新,例如使用 Git 或是 Subversion 進行自動更新,這部分可參考 Installing MathJaxInstalling MathJax via SVN

當安裝好 MathJax 之後,你可以使用 MathJax/test 目錄中的檔案進行測試,如果你是將 MathJax 放置在伺服器中,則可開啓瀏覽器瀏覽其中的 index.html,瀏覽的時候網址要輸入類似 http://192.168.0.1/MathJax/test/index.html 類似這樣以 http:// 開頭的網址,不要用 file:// 的,如果安裝正確,應該會看到正常的畫面,如果有問題的話,就要檢查在檔案放置的過程是否有出錯,或是檔案權限是否有設定正確等,另外亦可檢查伺服器的記錄檔看看是否有出現什麼問題。

設定自己的 MathJax

在預設的狀況下,加入 MathJax 的網頁會載入 config/TeX-AMS-MML_HTMLorMML.js,而這個 JavaScript 會自動載入一般最常用的 MathJax 模組,讓網頁可以呈現以 TeX、LaTeX 或 MathML 表示的數學式子,如果瀏覽器支援的話,他會產生 MathML 的格式,否則就會使用傳統的 HTML 加上 CSS 的方式來顯示。

在 MathJax 中有許多已經預先寫好的設定組態,你可以直接使用,或是使用 config/default.js 這個預設值,再加以修改,詳細說明可參考 Common ConfigurationsConfiguration Options

連結自己的 MathJax 至網頁中

若要將自己安裝的 MathJax 連結至網頁中,做法跟上面使用 CDN 的方式很像,在在 <head></head> 之間加入下面這段程式碼:

<script type="text/javascript" src="path-to-MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

其中 path-to-MathJax 要替換成自己的 MathJax 安裝路徑,如果你是將 MathJax 安裝在網頁的最上層目錄中的話,就會是這樣:

<script type="text/javascript" src="/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

在網頁中加入數學式子

如果想在網頁中使用加入可以讓 MathJax 處理的數學式子,可以使用 TeX、LaTeX、MathML 或是 AsciiMath 這幾種方式,甚至將這幾種表示方式在網頁中混合使用也可以,上面範例的設定是設定讓 MathJax 處理 TeX 與 MathML 兩種,如果要使用其他的方式,你必須先設定好要使用的方式,以下介紹各種不同的方式如何設定。

TeX 與 LaTeX

在 TeX 與 LaTeX 中的數學式子是使用其專用的數學分隔符號(math delimiters)來與一般文字區隔的,只要是被數學分隔符號包起來的部分就會被 MathJax 視為是一個數學式子,然後它就會對這部分進行數學的排版。

一般數學式子分為兩種,一種是出現在文章中間的 in-line 數學式子,一種是獨立於一般文字,自己一行的 displayed 數學式子,如果要顯示 in-line 數學式子的話,可以使用 \(...\),而 displayed 數學式子則可使用 $$...$$\[...\],這裡要注意一下,一般在 TeX 與 LaTeX 中常用的 $...$ 這種 in-line 方式,在 MathJax 中不支援,原因是一般的文字出現錢字號($)的機會很高,如果支援這樣的表示法常常會造成一些不是數學式子的文字被 MathJax 誤判為數學式子,但如果你還是很想使用這個語法的話,也可以更改設定檔,啟用這樣的語法:

<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
</script>
<script type="text/javascript" src="path-to-mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

下面這個是一個完整的 TeX 範例:

<!DOCTYPE html>
<html>
<head>
<title>MathJax TeX Test Page</title>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
</script>
<script type="text/javascript"
  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</head>
<body>
When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
</body>
</html>

因為這個 TeX 表示法也是網頁內容的一部分,在輸入數學式子時,要小心不要輸入到一些 HTML 的關鍵字,尤其是在輸入小於符號(<)的時候,記得要在前後都留一個空白,避免瀏覽器將其誤判為 HTML 標籤,詳細說明可參考 TeX and LaTeX support

若你是在部落格、Wiki 或是類似的 CMS(content management system)的系統中使用 MathJax,這些環境中所使用的語法可能會與 MathJax 衝突,如果發生類似的問題,可以參考 TeX and LaTeX support

在使用 TeX-AMS-MML_HTMLorMML 這個設定時,有一些用於 TeX 處理的擴充功能會自動載入,包含:

  • TeX/AMSmath.js:定義一些 AMS 的數學環境與巨集(macros)。
  • TeX/AMSsymbols.js:定義一些 msam10 與 msbm10 字型中的符號。
  • TeX/noErrors.js:在無法正常顯示數學式子時,顯示原始的 TeX 程式碼。
  • TeX/noUndefined.js:當碰到未定義的巨集時,顯示紅色的巨集名稱,避免產生錯誤訊息。

其餘的擴充功能在需要的時候,也會自動載入,關於其餘的擴充功能可以參考 TeX and LaTeX support

MathML

如果是想以 MathML 來表示數學式子,你可以使用標準的 <math> 標籤,<math display="block"> 表示 displayed 的數學式子,而 <math display="inline"> 或是 <math> 則代表 in-line 的數學式子。

在使用 <math> 標籤時,建議加入 xmlns="http://www.w3.org/1998/Math/MathML" 這個屬性,這樣可以增加其相容性。

以下是完整的範例:

<!DOCTYPE html>
<html>
<head>
<title>MathJax MathML Test Page</title>
<script type="text/javascript"
  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</head>
<body>

<p>
When
<math xmlns="http://www.w3.org/1998/Math/MathML">
  <mi>a</mi><mo>&#x2260;</mo><mn>0</mn>
</math>,
there are two solutions to
<math xmlns="http://www.w3.org/1998/Math/MathML">
  <mi>a</mi><msup><mi>x</mi><mn>2</mn></msup>
  <mo>+</mo> <mi>b</mi><mi>x</mi>
  <mo>+</mo> <mi>c</mi> <mo>=</mo> <mn>0</mn>
</math>
and they are
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
  <mi>x</mi> <mo>=</mo>
  <mrow>
    <mfrac>
      <mrow>
        <mo>&#x2212;</mo>
        <mi>b</mi>
        <mo>&#x00B1;</mo>
        <msqrt>
          <msup><mi>b</mi><mn>2</mn></msup>
          <mo>&#x2212;</mo>
          <mn>4</mn><mi>a</mi><mi>c</mi>
        </msqrt>
      </mrow>
      <mrow> <mn>2</mn><mi>a</mi> </mrow>
    </mfrac>
  </mrow>
  <mtext>.</mtext>
</math>
</p>

</body>
</html>

在一般的 HTML 網頁中如果使用 MathML 的表示法,所有的數學元素都要以成對的標籤來表示,不可以使用 self-closing 的標籤,例如:

<mspace width="5pt"></mspace>

不可以使用 <mspace width="5pt" /> 來取代,如果你使用這樣的 self-closing 標籤的話,有一些瀏覽器會無法建立正確的樹狀結構,導致 MathJax 接收到的數學式子結構錯誤,最後也就無法顯示正確的數學式子。由於這樣的問題是因為瀏覽器的解析錯誤造成的,所以 MathJax 也無能為力,唯一的解決方式就是按照這個規則來使用它。

在 MathJax 中負責處理 MathML 的擴充功能是 mml2jax,而這個功能只有一些少量的參數可以設定,設定時可以參考 config/default.js,或是查閱 mml2jax configuration optionsMathML

AsciiMath

MathJax 2.0 版之後加入了一個新的數學式子表示方式:AsciiMath,其語法是將數學式子以反引號包起來,就像這樣:`...`

下面是一個完整的範例:

<!DOCTYPE html>
<html>
<head>
<title>MathJax AsciiMath Test Page</title>
<script type="text/javascript"
  src="../MathJax.js?config=AM_HTMLorMML-full"></script>
</head>
<body>

<p>When `a != 0`, there are two solutions to `ax^2 + bx + c = 0` and
they are</p>
<p style="text-align:center">
  `x = (-b +- sqrt(b^2-4ac))/(2a) .`
</p>

</body>
</html>

處理 AsciiMath 語法的擴充功能是 asciimath2jax,設定時可以參考 config/default.js,或是查閱 asciimath2jax configuration optionsAsciiMath support

G. T. Wang

個人使用 Linux 經驗長達十餘年,樂於分享各種自由軟體技術與實作文章。

Share
Published by
G. T. Wang
標籤: 數學

Recent Posts

光陽 KYMCO GP 125 機車接電發動、更換電瓶記錄

本篇記錄我的光陽 KYMCO ...

2 年 ago

[開箱] YubiKey 5C NFC 實體金鑰

本篇是 YubiKey 5C ...

3 年 ago

[DIY] 自製竹火把

本篇記錄我拿竹子加上過期的苦茶...

3 年 ago