Hexo-NexT MathJax 配置

前言

因為 Hexo 本身的 markdown 語法不能使用 LaTeX 進行數學式的編寫,需要額外安裝插件,也就是 MathJax,基本上跟 LaTeX 語法是一模一樣的。 另外,本篇幾乎皆取自官方說明,有興趣可以自行參閱,接下來我會根據以下三點,一一進行介紹。

  1. 安裝
  2. 修改設定
  3. 範例

安裝

安裝 / 卸載套件

這邊載的是渲染網頁的套件,因為 hexo 本來就有自己的渲染工具了,所以要將其解除安裝並下載新的渲染工具,另外這裡也要注意一下如果你之前有安裝過 hexo-mathhexo-katex 要把他們解除安裝,不然也有可能會發生衝突

1
2
npm un hexo-renderer-marked
npm i hexo-renderer-pandoc

本機安裝 pandoc

這一點非常重要,我因為這個坑花了一個多小時,最後才在 github 上的討論找到解決方法,需要額外安裝 pandoc 在本機,其實官方的文檔裡面有寫,但我沒看到🥲 各個作業系統安裝方式不一,我就一一整理打在底下,記得挑選符合自己作業系統的複製執行喔

1
2
3
4
5
6
7
8
9
10
11
12
13
#Windows(這裡需要有chocolatey,如果沒有安裝的話可以去搜尋一下安裝方式,整體過程並不複雜,而且未來用到機會很高)
choco install pandoc

#macOS(這裡需要有homebrew,如果沒有安裝的話可以去搜尋一下安裝方式,整體過程並不複雜,而且未來用到機會很高)
brew install pandoc

#Linux(基本上原本電腦裡應該都有Pandoc,不過也還是可以下載更新到最新版本)
#先到 https://github.com/jgm/pandoc/releases/latest 下載安裝檔,然後再執行指令安裝,$DEB是安裝檔路徑
sudo dpkg -i $DEB

#Chrome(這個需要chromebrew,我沒有用過,但看起來應該不是很麻煩)
crew install pandoc

這邊是 pandoc 官方安裝教學

修改設定

到主題中的 config.yml 找到 math 的位置,並修改成以下內容

theme/NexT/_config.yml
1
2
3
4
5
6
7
8
9
10
11
math:
# 如果是true就代表不用特別設定要不要使用MathJax,所有頁面都會套用,除非設定false
# 如果是false就代表不用特別設定要不要使用MathJax,所有頁面都不會套用,除非設定true
every_page: true

mathjax:
# 就是說要取用mathjax
enable: true
# tag後面會講到,就先選ams
# Available values: none | ams | all
tags: ams

後來發現 mathjax 好像有可能會造成一些跑版的問題,像下圖 mathjax算式跑版 可以執行以下指令,好像就能解決了 (但又會出現標籤沒辦法用的問題,詳見下文)

1
2
3
npm un hexo-renderer-marked
npm un hexo-renderer-pandoc
npm i hexo-renderer-pandoc

這裡需要注意一件事,hexo-renderer-pandoc 和原先的 hexo-renderer-marked 是兩個不同的渲染器(應該是這樣翻吧),所以說生成的結果會與原先不同,目前我遇到的問題就是如果之前的文章換行是直接按 Enter 的話,生成出來的會沒有成功換行,需要重新手動調整在每行後面多加兩個空格。另外還有一個就是文章標題的網址會跑掉(例如說 header 123 原先生成的網址會是 https://example.com/myarticle/#header-123,但用這個渲染出來的會是 https://example.com/myarticle/#header123)。最後還有對使用比較有影響的就是標題最後面的迴紋針符號也會不見(headerlink),於是我到 github 上開 issue 求救,然後就有厲害的大神告訴我怎麼做了 >_<
就是這個會不見 熱心大神的解答

總之,就是到 themes/Your-Theme-Name/script 開一個 javascript腳本,然後把底下的東西貼進去
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// FILE: scripts/fix-header-link.js
const { stripHTML } = require('hexo-util');

// When using hexo-renderer-marked, the header link is generated as follows:
// <h3 id="Filter-Coordinate"><a href="#Filter-Coordinate" class="headerlink" title="Filter Coordinate"></a>Filter Coordinate</h3>
// However, the header link generated by hexo-renderer-pandoc is:
// <h3 id="filter-coordinate">Filter Coordinate</h3>
// There are themes that rely on the "headerlink" element to show the anchor icon.
// So we need to mimic the behavior of hexo-renderer-marked.

hexo.extend.filter.register('after_post_render', (data) => {
// https://github.com/hexojs/hexo-renderer-marked/blob/master/lib/renderer.js#L59
data.content = data.content.replace(
/<h([1-6]) id="(.+)">(.+?)<\/h[1-6]>/g,
(match, level, id, content) => {
const title = stripHTML(content);
return `<h${level} id="${id}"><a href="#${id}" class="headerlink" title="${title}"></a>${content}</h${level}>`;
}
);

return data;
});

後來其中一個作者說用正則表達式不太好,建議用 Pandoc filter,然後隔了超久之後我就自己改了一個出來了。

  • ./source/_data 下新增一個 header-link-filter.lua 檔案,內容如下
1
2
3
4
5
6
7
8
9
10
-- header-link-filter.lua
function Header(el)
-- Create a link
local link = pandoc.Link("", "#" .. el.identifier, "", pandoc.Attr("", {"headerlink"}))

-- Insert the link into the header content
table.insert(el.content, pandoc.Space())
table.insert(el.content, link)

return el
  • ./_config.yml 最後新增以下內容
1
2
3
4
5
6
7
8
9
pandoc:
args:
- "-f"
- "markdown"
- "-t"
- "html"
- "--mathjax"
- '--lua-filter'
- './source/_data/header-link-filter.lua'

然後應該就完成了~

範例

這邊有一些範例可以試試看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$$
A = \begin{bmatrix}
a_{11} & a_{12} & ... & a_{1n}\\
a_{21} & a_{22} & ... & a_{2n}\\
a_{31} & a_{22} & ... & a_{3n}\\
\vdots & \vdots & \ddots & \vdots\\
a_{n1} & a_{n2} & ... & a_{nn}\\
\end{bmatrix} , b = \begin{bmatrix}
b_{1} \\
b_{2} \\
b_{3} \\
\vdots \\
b_{n} \\
\end{bmatrix}
$$

$$
\begin{aligned}
a &= b + c \\
&= d + e + f + g \\
&= h + i
\end{aligned}
$$

$$
e=mc^2
$$

$$
C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}
$$

實際的效果大概就是長這樣 \[ A = \begin{bmatrix} a_{11} & a_{12} & ... & a_{1n}\\ a_{21} & a_{22} & ... & a_{2n}\\ a_{31} & a_{22} & ... & a_{3n}\\ \vdots & \vdots & \ddots & \vdots\\ a_{n1} & a_{n2} & ... & a_{nn}\\ \end{bmatrix} , b = \begin{bmatrix} b_{1} \\ b_{2} \\ b_{3} \\ \vdots \\ b_{n} \\ \end{bmatrix} \]

\[ \begin{aligned} a &= b + c \\ &= d + e + f + g \\ &= h + i \end{aligned} \]

\[ e=mc^2 \]

\[ C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K} \]

可以發現最後這個還是化學式,沒錯,MathJax 也可以撰寫化學式,詳細語法可以看這邊

最後就是標籤的功能,前面在設定 tag 我們選了 ams,那他的功能就是可以讓我們給每一個式子一個編號,例如像這樣

1
2
3
$$\begin{equation} \label{eq1}
e=mc^2
\end{equation}$$

\[\begin{equation} \label{eq1} e=mc^2 \end{equation}\]

在後文中就可以使用 $\eqref{eq1}$ 來引用式子,像這樣 \(\eqref{eq1}\)

另外如果想用其他文字來編號的話可以用 \tag{} 來標記方程式,使用 \label{} 當作引用時的標前,例如說以下這個式子

1
$$x+1\over\sqrt{1-x^2} \tag{i}\label{eq_tag}$$

\[x+1\over\sqrt{1-x^2} \tag{i}\label{eq_tag}\]

而要引用時要使用 \label{} 括號中的內容,以上面的為例就是 $\eqref{eq_tag}$,實際的樣子應該就是像這樣 \(\eqref{eq_tag}\)

結語

現在可以自由輸入各種漂亮的式子了~如果有問題或者發現我有哪裡講錯,歡迎大家到底下留言區跟我討論喔~

其他功能

  1. 側邊欄

    基礎配置 (關於、標籤、分類、歸檔、搜尋、頭像、個人相關連結)切換語言

  2. 頁底

  3. utterances 留言板

  4. Google Analytics 統計網站資訊

  5. 日 / 夜模式

  6. live2d 角色(就是網頁右下角那隻可愛的狗狗)

  7. SEO:搜尋引擎最佳化 (Search Engine Optimization)

  8. 剩下的一些小工具

  9. 自訂網域