這個問題自己很早以前便碰到了,用MathJax語法寫的一些公式,在本地Markdown編譯器上渲染是沒問題的,可是部署到hexo博客中就出現問題了,之前我是使用圖片代替公式應付過去了,今天從網上找了一下資料,發現了其問題所在,同時也解決了這個問題。
問題
hexo默認使用hexo-renderer-marked引擎去渲染網頁,它會把利用Markdown語法寫的文本去轉換為相應的html標簽。在利用Markdown寫MathJax公式的時候,經常會用到下划線_
表示下標,但是下划線_
會被hexo的默認引擎hexo-renderer-marked渲染成html中的<em>
標簽,表示斜體,這樣一來,我們寫的MathJax公式就被錯誤渲染了,也就沒辦法正確顯示出來。
例如:
在我寫的KMP算法這篇文章中,沒有解決問題之前,出現着各種渲染錯誤,而當你仔細觀察那些錯誤之處時,會發現你寫的MathJax公式中的下划線_
會莫名其妙地消失。
下圖是我利用Markdown編譯器寫的文本
是表格的一部分,在Markdown編譯器預覽是正確的,如下圖
但是部署到hexo博客后,便出現了錯誤,呈現的效果如下圖
我們發現公式沒有渲染成功,仔細觀察這個式子特征,發現它和我之前寫的相比,少了部分_
,打開該網頁源代碼,定位到這里,如下圖
會發現缺少的_
其實是被hexo的渲染引擎渲染成了html中的<em>
標簽,這樣一來,這個公式就不完整了,那么也就不能正確顯示了。
解決方法
從上面的分析,我們可以知道問題或許出在hexo的渲染引擎上,如果渲染引擎不把公式中的一些特殊字符渲染成html標簽,也就避免了這個問題。當然已經有人意識到了這個問題,並且對原先的渲染引擎進行了改進,生成了新的hexo-renderer-kramed引擎,這里是它的Github頁面,所以我們只需要卸載默認引擎,並安裝這個新的渲染引擎即可。
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save
我之前寫有一篇KMP算法,就是在這里發現的渲染出錯問題,當我把渲染引擎更換之后,發現大部分公式都正確渲染了,而從網上其他人的敘述中,也同樣提到了這個問題,即是行間公式都沒有問題,但是個別行內公式還會出現渲染出錯,從網上找到了一個方法,解決了這一問題。
定位到你的博客根目錄,找到../node_modules/kramed/lib/rules/inline.js文件,
進行部分修改:
//escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/, 第11行,將其修改為
escape: /^\\([`*\[\]()#$+\-.!_>])/,
//em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, 第20行,將其修改為
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
它取消了該渲染引擎對\,{,}
的轉義,然后再hexo clean、hexo g
重新部署,即可解決問題。
另外需要注意一點,對於需要用到MathJax公式的文章,要在Front-matter中打開MathJax開關,例如:
---
date: 2017/8/3 18:20:00
tags: hexo
mathjax: true
title: hexo博客MathJax公式渲染
---
MathJax公式語法
下面呢,我整理總結了一番比較常用的MathJax公式語法,同時也可以用來測試一下渲染效果。
符號 | 釋義 | 測試用例 | 最終效果 |
---|---|---|---|
^ | 上標 | x^{y^z}=(1+e^x)^{-2xy^w} | $ x^{y^z}=(1+e^x)^{-2xy^w} $ |
_ | 下標 | CO_2 | $ CO_2 $ |
\frac{分子}{分母} or 分子 \over 分母 | 分數 | f(x,y,z)=3y^2z(3+\frac{7x+5}{1+y^2}) | $ f(x,y,z)=3y^2z(3+\frac{7x+5}{1+y^2}) $ |
\sqrt[根指數,省略時為2]{被開方數} | 開方 | \sqrt{2}、\sqrt[3]{9} | \(\sqrt{2} 、\sqrt[3]{9}\) |
\ldots | 與文本底線對齊的省略號 | x_1x_2{\ldots}x_n | \(x_1x_2{\ldots}x_n\) |
\cdots | 與文本中線對齊的省略號 | x_1x_2{\cdots}x_n | \(x_1x_2{\cdots}x_n\) |
\int_積分下限^積分上限(被積表達式) | 積分 | \int_1^n{x^2}dx | $ \int_1^n{x^2}dx $ |
\sum_{下標表達式}^{上標表達式} {累加表達式} | 累加 | \sum_{i=1}^n \frac{1}{i^2} | $ \sum_{i=1}^n \frac{1}{i^2} $ |
\, or ; or \quad or \qquad | 不同寬度的空格 | a , b \mid a ; b \mid a \quad b \mid a \qquad b | $ a , b \mid a ; b \mid a \quad b \mid a \qquad b $ |
\color{顏色}{文字} | 更改文字顏色 | \color{red}{紅色} | $ \color{red}{紅色} $ |
上面的一些基本語法使用了行內公式, 渲染效果沒有問題,下面再利用行間公式寫一些較為復雜的公式。
分段函數
分段函數格式為f(x)=\begin{cases}語句1\\語句2\\...\end{cases}
\text{文字}
中仍可以使用$公式$
去插入其他公式,所以可以將其結合分段函數一起使用。
實例:
md文本
$$
f(n)=\begin{cases}
n/2, & \text{如果$ x<=2 $}\\
3n+1, & \text{如果$ x>2 $}
\end{cases}
$$
最終效果
大括號和小括號
()、[]、{}
表示的即是符號本身,使用\{\}
來表示{}
。但是如果要顯示大號的括號時,需要使用\left
和\right
命令。
實例:
- 正常括號
md文本
$$
f([\frac{1+\{x,y\}}{(\frac{x}{y}+\frac{y}{x})(u+1)}+a]^{3\2})
$$
最終效果
- 大括號
md文本
$$
f\left(
\left[
\frac{
1+\left\{x,y\right\}
}{
\left(
\frac{x}{y}+\frac{y}{x}
\right)
\left(u+1\right)
}+a
\right]^{3\2}
\right)
$$
最終效果
添加刪除線
使用刪除線功能必須使用行間公式,刪除線分為片段刪除線和整段刪除線,樣式比較多,在這里我只列舉一種比較常用的水平刪除線,它屬於整段刪除線的一種。
整段刪除線使用\require{enclose}
來顯示,聲明整段刪除線后,使用\enclose{刪除線效果}{字符}
來實現刪除線效果,而水平刪除線效果用關鍵字horizontalstrike
。
實例:
md文本
$$
\require{enclose}\begin{array}{}
\enclose{horizontalstrike}{x+y}\\
\enclose{horizontalstrike}{x*y}\\
\end{array}
$$
最終效果
注意事項
我在更換hexo的渲染引擎的時候,還出了一點問題,當我卸載了原先的渲染引擎,安裝新的時,出了錯誤,如下圖:
它顯示我的npm
版本為v4.2.0
,我將npm
更新到了最新版本,再次安裝,便沒有問題了。
通過這篇文章和KMP算法,里面也涉及了較多的MathJax公式,從效果上來看,都沒有出現什么問題,這也說明了該方法還是有一定的效果的。