HUGO
Menu
GitHub 87548 stars Mastodon

Hugo Markdown 中的數學

使用 LaTeX markup 在 Markdown 中包含數學方程和表達式。

概述

LaTeX 編寫的數學方程和表達式在學術和科學出版物中很常見。你的瀏覽器通常使用開源 JavaScript 顯示引擎(如 MathJaxKaTeX)來渲染這種數學 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}
\]

渲染為:

KL(y^y)=c=1My^clogy^cycJS(y^y)=12(KL(yy+y^2)+KL(y^y+y^2)) \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 模板替換為以下內容:

layouts/_partials/math.html
<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}$$
Cp[HX2O(l)]=75.3 JmolKC_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}

如上面 Step 2 所示,MathJax 無需額外配置即可支持化學方程。要為 KaTeX 添加化學支持,按照 KaTeX documentation 中的描述啟用 mhchem 擴展。


Last updated: January 1, 0001
Improve this page