Hugo Markdown 中的數學
概述
用 LaTeX 編寫的數學方程和表達式在學術和科學出版物中很常見。你的瀏覽器通常使用開源 JavaScript 顯示引擎(如 MathJax 或 KaTeX)來渲染這種數學 markup。
例如,此 LaTeX markup:
\[
\begin{aligned}
KL(\hat{y} || y) &= \sum_{c=1}^{M}\hat{y}_c \log{\frac{\hat{y}_c}{y_c}} \\
JS(\hat{y} || y) &= \frac{1}{2}(KL(y||\frac{y+\hat{y}}{2}) + KL(\hat{y}||\frac{y+\hat{y}}{2}))
\end{aligned}
\]渲染為:
方程和表達式可以與其他文本內聯顯示,或作為獨立塊顯示。塊顯示也稱為"display"模式。
方程或表達式是內聯顯示還是作為塊顯示,取決於圍繞數學 markup 的分隔符。分隔符成對定義,每對由一個開始和一個結束分隔符組成。開始和結束分隔符可以相同,也可以不同。
你可以配置 Hugo 使用 MathJax 或 KaTeX 顯示引擎在客戶端渲染數學 markup,或者在構建站點時使用 transform.ToMath 函數渲染 markup。
下面介紹第一種方法。
設置
按照以下說明使用 LaTeX markup 在 Markdown 中包含數學方程和表達式。
- Step 1
- 在站點配置中啟用並配置 Goldmark passthrough extension。passthrough 擴展保留原始 Markdown 在 delimited 文本片段中,包括分隔符本身。
markup: goldmark: extensions: passthrough: delimiters: block: - - '\[' - '\]' - - $$ - $$ inline: - - '\(' - '\)' enable: true params: math: true[markup] [markup.goldmark] [markup.goldmark.extensions] [markup.goldmark.extensions.passthrough] enable = true [markup.goldmark.extensions.passthrough.delimiters] block = [['\[', '\]'], ['$$', '$$']] inline = [['\(', '\)']] [params] math = true{ "markup": { "goldmark": { "extensions": { "passthrough": { "delimiters": { "block": [ [ "\\[", "\\]" ], [ "$$", "$$" ] ], "inline": [ [ "\\(", "\\)" ] ] }, "enable": true } } } }, "params": { "math": true } }上面的配置在每個頁面上啟用數學渲染,除非你在 front matter 中將
math參數設置為false。要按需啟用數學渲染,在站點配置中將math參數設置為false,並在 front matter 中將math參數設置為true。在基礎模板中使用此參數,如 Step 3 所示。上面的配置排除了使用
$...$分隔符對作為內聯方程。雖然你可以將此分隔符對添加到配置和 JavaScript 中,但你必須在數學上下文之外使用時雙轉義$符號以避免意外格式。參見 inline delimiters 部分了解詳情。
要禁用內聯片段的 passthrough,從配置中省略
inline鍵:markup: goldmark: extensions: passthrough: delimiters: block: - - '\[' - '\]' - - $$ - $$[markup] [markup.goldmark] [markup.goldmark.extensions] [markup.goldmark.extensions.passthrough] [markup.goldmark.extensions.passthrough.delimiters] block = [['\[', '\]'], ['$$', '$$']]{ "markup": { "goldmark": { "extensions": { "passthrough": { "delimiters": { "block": [ [ "\\[", "\\]" ], [ "$$", "$$" ] ] } } } } } }你可以定義自己的開始和結束分隔符,只要它們與你在 Step 2 中設置的分隔符匹配。
markup: goldmark: extensions: passthrough: delimiters: block: - - '@@' - '@@' inline: - - '@' - '@'[markup] [markup.goldmark] [markup.goldmark.extensions] [markup.goldmark.extensions.passthrough] [markup.goldmark.extensions.passthrough.delimiters] block = [['@@', '@@']] inline = [['@', '@']]{ "markup": { "goldmark": { "extensions": { "passthrough": { "delimiters": { "block": [ [ "@@", "@@" ] ], "inline": [ [ "@", "@" ] ] } } } } } } - Step 2
- 創建 partial 模板來加載 MathJax 或 KaTeX。下面的示例加載 MathJax,或者你可以使用 KaTeX,如 engines 部分所述。
layouts/_partials/math.html
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@4/tex-mml-chtml.js"></script> <script> MathJax = { tex: { displayMath: [['\\[', '\\]'], ['$$', '$$']], // block inlineMath: [['\\(', '\\)']] // inline }, loader:{ load: ['ui/safe'] }, }; </script>上面的分隔符必須與站點配置中的分隔符匹配。
- Step 3
- 從基礎模板有條件地調用 partial 模板。
layouts/baseof.html
<head> ... {{ if .Param "math" }} {{ partialCached "math.html" . }} {{ end }} ... </head>上面的示例如果你在 front matter 中將
math參數設置為true,則加載 partial 模板。如果你沒有在 front matter 中設置math參數,條件語句回退到站點配置中的math參數。 - Step 4
- 如果你在站點配置中將
math參數設置為false,你必須在 front matter 中將math參數設置為true。例如:--- date: 2024-01-24T18:09:49-08:00 params: math: true title: Math examples ---+++ date = 2024-01-24T18:09:49-08:00 title = 'Math examples' [params] math = true +++{ "date": "2024-01-24T18:09:49-08:00", "params": { "math": true }, "title": "Math examples" } - Step 5
- 使用 LaTeX markup 在 Markdown 中包含數學方程和表達式。
content/math-examples.md
This is an inline \(a^*=x-b^*\) equation. These are block equations: \[a^*=x-b^*\] \[ a^*=x-b^* \] \[ a^*=x-b^* \] These are also block equations: $$a^*=x-b^*$$ $$ a^*=x-b^* $$ $$ a^*=x-b^* $$
內聯分隔符
上面的配置、JavaScript 和示例使用 \(...\) 分隔符對作為內聯方程。$...$ 分隔符對是常見的替代方案,但如果你在數學上下文之外使用 $ 符號,使用它可能導致意外格式。
如果你將 $...$ 分隔符對添加到配置和 JavaScript 中,你必須在數學上下文之外使用時雙轉義 $ 符號以避免意外格式。例如:
I will give you \\$2 if you can solve $y = x^2$.如果你使用 $...$ 分隔符對作為內聯方程,並且偶爾在數學上下文之外使用 $ 符號,你必須使用 MathJax 而不是 KaTeX 以避免 this KaTeX limitation 導致的意外格式。
引擎
MathJax 和 KaTeX 是開源 JavaScript 顯示引擎。
如果你使用 $...$ 分隔符對作為內聯方程,並且偶爾在數學上下文之外使用 $ 符號,你必須使用 MathJax 而不是 KaTeX 以避免 this KaTeX limitation 導致的意外格式。
參見 inline delimiters 部分了解詳情。
要使用 KaTeX 而不是 MathJax,將 Step 2 中的 partial 模板替換為以下內容:
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.16.25/dist/katex.min.css"
integrity="sha384-WcoG4HRXMzYzfCgiyfrySxx90XSl2rxY5mnVY5TwtWE6KLrArNKn0T/mOgNL0Mmi"
crossorigin="anonymous"
>
<script
defer
src="https://cdn.jsdelivr.net/npm/katex@0.16.25/dist/katex.min.js"
integrity="sha384-J+9dG2KMoiR9hqcFao0IBLwxt6zpcyN68IgwzsCSkbreXUjmNVRhPFTssqdSGjwQ"
crossorigin="anonymous">
</script>
<script
defer
src="https://cdn.jsdelivr.net/npm/katex@0.16.25/dist/contrib/auto-render.min.js"
integrity="sha384-hCXGrW6PitJEwbkoStFjeJxv+fSOOQKOPbJxSfM6G5sWZjAyWhXiTIIAmQqnlLlh"
crossorigin="anonymous"
onload="renderMathInElement(document.body);">
</script>
<script>
document.addEventListener("DOMContentLoaded", function() {
renderMathInElement(document.body, {
delimiters: [
{left: '\\[', right: '\\]', display: true}, // block
{left: '$$', right: '$$', display: true}, // block
{left: '\\(', right: '\\)', display: false}, // inline
],
throwOnError : false
});
});
</script>上面的分隔符必須與站點配置中的分隔符匹配。
化學
MathJax 和 KaTeX 都支持化學方程。例如:
$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$如上面 Step 2 所示,MathJax 無需額外配置即可支持化學方程。要為 KaTeX 添加化學支持,按照 KaTeX documentation 中的描述啟用 mhchem 擴展。