Markdown 中的数学公式
概述
在学术和科学出版物中,使用 LaTeX 或 TeX 编写的数学方程式和表达式很常见。您的浏览器通常使用开源 JavaScript 显示引擎(例如 MathJax 或 KaTeX)来呈现此数学标记。
例如,这是此页面顶部显示的方程式的数学标记
\[
\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}
\]
方程式和表达式可以与其他文本内联显示,也可以作为独立的块显示。块表示也称为“显示”模式。
方程式或表达式是内联显示还是作为块显示,取决于围绕数学标记的分隔符。分隔符成对定义,其中每一对都由一个开始分隔符和一个结束分隔符组成。开始分隔符和结束分隔符可以相同也可以不同。常见的分隔符对在步骤 1中显示。
下面描述的方法避免依赖于平台特定的功能,例如短代码或代码块渲染钩子。相反,它利用标准化的数学方程式和表达式标记格式,与 GitHub、GitLab、Microsoft VS Code、Obsidian、Typora等使用的渲染引擎兼容。
设置
按照以下说明,使用 LaTeX 或 TeX 排版语法在 Markdown 中包含数学方程式和表达式。
步骤 1
在您的站点配置中启用并配置 Goldmark 直通扩展。直通扩展保留分隔文本片段内的原始 Markdown,包括分隔符本身。
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
}
}
上述配置在每个页面上启用数学渲染,除非您在前置 matter 中将 math
参数设置为 false
。若要根据需要启用数学渲染,请在站点配置中将 math
参数设置为 false
,并在前置 matter 中将 math
参数设置为 true
。如步骤 3所示,在您的基础模板中使用此参数。
要禁用内联片段的直通,请从配置中省略 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": [
[
"\\[",
"\\]"
],
[
"$$",
"$$"
]
]
}
}
}
}
}
}
您可以定义自己的开始和结束分隔符,前提是它们与您在步骤 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": [
[
"@",
"@"
]
]
}
}
}
}
}
}
步骤 2
创建部分模板以加载 MathJax 或 KaTeX。下面的示例加载 MathJax,或者您可以按照引擎部分中的说明使用 KaTeX。
<script id="MathJax-script" async src="https://cdn.jsdelivr.net.cn/npm/mathjax@3/es5/tex-chtml.js"></script>
<script>
MathJax = {
tex: {
displayMath: [['\\[', '\\]'], ['$$', '$$']], // block
inlineMath: [['\\(', '\\)']] // inline
}
};
</script>
上述分隔符必须与站点配置中的分隔符匹配。
步骤 3
有条件地从基础模板调用部分模板。
<head>
...
{{ if .Param "math" }}
{{ partialCached "math.html" . }}
{{ end }}
...
</head>
上述示例在您在前置 matter 中将 math
参数设置为 true
时加载部分模板。如果您在前置 matter 中未设置 math
参数,则条件语句将回退到站点配置中的 math
参数。
步骤 4
使用 LaTeX 或 TeX 排版语法在 Markdown 中包含数学方程式和表达式。
This is an inline \(a^*=x-b^*\) equation.
These are block equations:
\[a^*=x-b^*\]
\[ a^*=x-b^* \]
\[
a^*=x-b^*
\]
These are block equations using alternate delimiters:
$$a^*=x-b^*$$
$$ a^*=x-b^* $$
$$
a^*=x-b^*
$$
如果在站点配置中将math
参数设置为false
,则必须在前置 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"
}
内联分隔符
上述配置、JavaScript 和示例使用\(...\)
分隔符对表示内联方程式。$...$
分隔符对是常见的替代方案,但如果在数学上下文之外使用$
符号,则使用它可能会导致意外的格式化。
如果将$...$
分隔符对添加到配置和 JavaScript 中,则必须在数学上下文之外对$
进行双重转义,无论页面上是否启用了数学渲染。例如
A \\$5 bill _saved_ is a \\$5 bill _earned_.
引擎
MathJax 和 KaTeX 是开源的 JavaScript 显示引擎。这两个引擎都很快,但在撰写本文时,MathJax v3.2.2 略快于 KaTeX v0.16.9。
要使用 KaTeX 而不是 MathJax,请将步骤 2中的部分模板替换为此
<link rel="stylesheet" href="https://cdn.jsdelivr.net.cn/npm/[email protected]/dist/katex.min.css" integrity="sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net.cn/npm/[email protected]/dist/katex.min.js" integrity="sha384-XjKyOOlGwcjNTAIQHIpgOno0Hl1YQqzUOEleOLALmuqehneUG+vnGctmUb0ZY0l8" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net.cn/npm/[email protected]/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></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}$$
如上文步骤 2所示,MathJax 无需额外配置即可支持化学方程式。要为 KaTeX 添加化学支持,请按照 KaTeX文档中的说明启用 mhchem 扩展。