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