輸入數學公式
1 數學公式的web解決方案
在網頁上顯示漂亮的數學公式,是多年來數學工作者和學者的願望。最容易實現的方式就是使用離線編輯器如word,Latex等編寫完公式,然後截圖作爲圖片在html網頁中顯示。然而這種方式存在很多缺點:
- 無法在線修改,離線修改後必須重新截圖
- 放大顯示會失真,這是位圖的天生缺陷
- 不同的離線編輯器生成的顯示效果不同,很難統一
- 由於無法直接編輯,所以即使看到了公式,也無法在此基礎上進一步修改,不利於交流
當然,位圖顯示公式也有一個最大的優點,那就是兼容所有瀏覽器,不需要任何插件就可以瀏覽。
隨着html, css的持續發展,使用純html+css來顯示公式已經非常可行,於是大名鼎鼎的MathJax出現了。它是一個開源的JavaScript庫,用來把特定格式的公式描述轉換爲html+css或者svg代碼,從而在瀏覽器上顯示數學公式。
2 MathJax渲染過程簡單模擬
2.1 MathJax最簡示例
先來看一個帶公式的最簡網頁實例mathjax.html。
<code class="language-html hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-doctype" style="color: rgb(102, 0, 102); box-sizing: border-box;"><!DOCTYPE html></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">html</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">head</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">title</span>></span>MathJax TeX Test Page<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">title</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">script</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"text/x-mathjax-config"</span>></span><span class="javascript" style="box-sizing: border-box;">
MathJax.Hub.Config({tex2jax: {inlineMath: [[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'$'</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'$'</span>], [<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\\('</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\\)'</span>]]}});
</span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">script</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">script</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"text/javascript"</span>
<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">src</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"</span>></span><span class="javascript" style="box-sizing: border-box;">
</span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">script</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">head</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span>
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}.$$
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">html</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>
在瀏覽器中打開mathjax.html,會顯示如下圖:
其對應的html代碼如下圖:
2.2 模擬MathJax渲染原理
從前面的例子可以看出,MathJax中數學公式是用一些特殊字符串表示的,這些字符串被特定的邊界$ $
和$$
$$
包圍。然後MathJax引擎會根據邊界提取公式表達式,然後把它們替換成用戶顯示公式的html+css代碼。
下面我們來模擬這一過程。用math.js模擬MathJax.js,如下所示:
<code class="language-javascript hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">window.onload = <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>
{</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> body = document.getElementsByTagName(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'body'</span>)[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> oldBody = body.innerHTML;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> newBody = oldBody.replace(<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/[^$]\$([^$]+)\$[^$]/g</span>, <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(str, r1)</span>{</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> MathJax_inline(r1);
});
newBody = newBody.replace(<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/\$\$([^$]+)\$\$/g</span>, <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(str, r1)</span>{</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> MathJax_block(r1);
});
body.innerHTML = newBody;
}
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 把公式內容描述轉換爲顯示描述</span>
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">MathJax_inline</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(r1)</span>
{</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'<span style="color:red">'</span> + r1 + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'</span>'</span>;
}
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-title" style="box-sizing: border-box;">MathJax_block</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(r1)</span>
{</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'<div style="color:red">'</span> + r1 + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'</div>'</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>
html頁面相應修改:
<code class="language-html hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-doctype" style="color: rgb(102, 0, 102); box-sizing: border-box;"><!DOCTYPE html></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">html</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">head</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">title</span>></span>MathJax TeX Test Page<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">title</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">script</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">type</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"text/javascript"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">src</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"math.js"</span>></span><span class="javascript" style="box-sizing: border-box;"></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">script</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">head</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span>
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}.$$
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">html</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
來看看效果:
雖然沒有正確顯示出公式,但是已經識別出了公式邊界,並把公式部分用紅色顯示出來。真正的MathJax是把公式表達式替換成顯示公式的html代碼,而不是簡單的設置爲紅色,但是這其中的處理原理是一致的。
3 CSDN-MarkDown編輯器常用數學公式輸入教程
MathJax支持多種公式輸入輸出規範,輸入格式可以是MathML, TeX,ASCIImath中的任何一種,輸出格式可以是html+css,或svg,或MathML。下面僅對最常用的Tex輸入規範進行說明。
3.1 公式定界符與關鍵字
CSDN-MarkDown編輯器使用的公式定界符爲$
和$$
,單美元符號包圍的是行內公式,雙美元符號包圍的是塊公式。
Tex關鍵字(字符轉義序列)表示特殊顯示符號,如\frac表示分數,其後面可以跟隨參數,參數多少與關鍵字有關。
3.2 上下標
^表示上標,_表示下標,如果上(下)標內容多於一個字符就需要使用{},注意不是( ), 因爲( )經常是公式本身組成部分,爲避免衝突,所以選用了{ } 將其包起來。
示例:$x^{y^z}=(1+e^x)^{-2xy^w}$
效果:xyz=(1+ex)−2xyw
上面輸入的上下標都是在字符的右側,要想在左側或者兩側都寫上下標,那麼需要使用\sideset語法。
示例:$\sideset{^1_2}{^3_4}\bigotimes$
效果:12⨂34
3.3 括號和分隔符
( )和[ ]就是自身了,由於{ } 是Tex的元字符,所以表示它自身時需要轉義。
示例:$f(x,y) = x^2 + y^2, x\epsilon[0,100]$
效果:f(x,y)=x2+y2,xϵ[0,100],y={3,4,5}
有時候括號需要大號的,普通括號不好看,此時需要使用\left和\right加大括號的大小。
示例:$(\frac{x}{y})^8$,$\left(\frac{x}{y}\right)^8$
效果:(xy)8,(xy)8
\left和\right必須成對出現,對於不顯示的一邊可以使用 . 代替。
示例:$\left.\frac{{\rm d}u}{{\rm d}x} \right| _{x=0}$
效果:dudx∣∣x=0
3.4 分數
使用\frac{分子}{分母}格式,或者 分子\over 分母。
示例:$\frac{1}{2x+1}$
或者$1\over{2x+1}$
效果:12x+1 或者 12x+1
3.5 開方
示例:$\sqrt[9]{3}$ 和 $\sqrt{3}$
效果:3√9 和 3√
3.6 省略號
有兩種省略號,\ldots 表示語文本底線對其的省略號,\cdots表示與文本中線對其的省略號。
示例:$f(x_1, x_2, \ldots, x_n)=x_1^2 + x_2^2+ \cdots + x_n^2$
效果:f(x1,x2,…,xn)=x21+x22+⋯+x2n
3.7 矢量
示例:$\vec{a} \cdot \vec{b}=0$
效果: a⃗ ⋅b⃗ =0
3.8 積分
示例:$\int_0^1x^2{\rm d}x $
效果: ∫10x2dx
3.9 極限
示例:$\lim_{n\rightarrow+\infty}\frac{1}{n(n+1)}$
效果: limn→+∞1n(n+1)
3.10 累加、累乘
示例:$\sum_1^n\frac{1}{x^2}$, $\prod_{i=0}^n\frac{1}{x^2}$
效果:∑n11x2, ∏ni=01x2
3.11 希臘字母
希臘字符示例:$$\alpha A \beta B \gamma \Gamma \delta \Delta \epsilon E \varepsilon \zeta Z \eta H \theta \Theta \vartheta \iota I \kappa K \lambda \Lambda \mu M \nu N
\xi \Xi o O \pi \Pi \varpi \rho P \varrho \sigma \Sigma \varsigma \tau T \upsilon \Upsilon \phi \Phi \varphi \chi X \psi \Psi \omega \Omega$$
效果:
α A β B γ Γ δ Δ ϵ Eε ζ Z η H θ Θ ϑι I κ K λ Λ μ M ν Nξ Ξ o O π Π ϖ ρ Pϱ σ Σ ς τ T υ Υϕ Φ φ χ X ψ Ψ ω Ω
3.12 數學符號大彙總
± :\pm
× :\times
÷:\div
∣:\mid
⋅:\cdot
∘:\circ
∗:
\ast
⨀:\bigodot
⨂:\bigotimes
⨁:\bigoplus
≤:\leq
≥:\geq
≠:\neq
≈:\approx
≡:\equiv
∑:\sum
∏:\prod
∐:\coprod
集合運算符:
∅:\emptyset
∈:\in
∉:\notin
⊂:\subset
⊃ :\supset
⊆ :\subseteq
⊇ :\supseteq
⋂ :\bigcap
⋃ :\bigcup
⋁ :\bigvee
⋀ :\bigwedge
⨄ :\biguplus
⨆:\bigsqcup
對數運算符:
log :\log
lg :\lg
ln :\ln
三角運算符:
⊥:\bot
∠:\angle
30∘:30^\circ
sin :\sin
cos :\cos
tan :\tan
cot :\cot
sec :\sec
csc :\csc
微積分運算符:
y′x:\prime
∫:\int
∬ :\iint
∭ :\iiint
∬∬:\iiiint
∮ :\oint
lim :\lim
∞ :\infty
∇:\nabla
邏輯運算符:
∵:\because
∴ :\therefore
∀ :\forall
∃ :\exists
≠ :\not=
≯:\not>
⊄:\not\subset
戴帽符號:
y^ :\hat{y}
\check{y} :\check{y}
y˘ :\breve{y}
連線符號:
a+b+c+d¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯:\overline{a+b+c+d}
a+b+c+d−−−−−−−−−− :\underline{a+b+c+d}
a+b+c1.0+d2.0:\overbrace{a+\underbrace{b+c}_{1.0}+d}^{2.0}
箭頭符號:
↑:\uparrow
↓:\downarrow
⇑ :\Uparrow
⇓:\Downarrow
→:\rightarrow
← :\leftarrow
⇒ :\Rightarrow
⇐ :\Leftarrow
⟶ :\longrightarrow
⟵ :\longleftarrow
⟹:\Longrightarrow
⟸ :\Longleftarrow
3.13 需要轉義的字符
要輸出字符 空格 # $ % & _ { } ,用命令: \空格 # \$ \% \& _ { }
3.14 使用指定字體
{\rm text}如:
使用羅馬字體:text ${\rm
text}$
其他的字體還有:
\rm 羅馬體 \it 意大利體
\bf 黑體 \cal 花體
\sl 傾斜體 \sf 等線體
\mit 數學斜體 \tt 打字機字體
\sc 小體大寫字母