
Hugo 中的数学公式渲染在 Markdown 中使用 LaTeX 标记的完整指南【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo导读本指南面向使用 Hugo 构建学术、科学类网站的开发者讲解如何在 Markdown 内容中嵌入 LaTeX 数学公式与表达式并提供完整的配置与模板方案。读完本文你将掌握基于 Goldmark passthrough 扩展保留原始数学标记、通过 MathJax 或 KaTeX 在前端渲染公式、按页面按需启用数学功能math参数的完整实战流程以及$...$内联分隔符的坑与规避方法。概述为什么需要在 Markdown 中写数学数学公式与表达式以 LaTeX 标记书写在学术与科学出版物中极为常见。浏览器本身并不认识 LaTeX 语法通常需要借助 MathJax 或 KaTeX 这类开源 JavaScript 显示引擎将其渲染为可视化的数学排版。例如下面这段 LaTeX 标记KL 散度与 JS 散度的定义\[ \begin{aligned} KL(\hat{y} || y) \sum_{c1}^{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} \]渲染后的结果就是经典的公式排版效果。公式既可以在文本中行内inline显示也可以作为独立块block显示后者也被称为 display 模式。一个公式是行内还是块级取决于包围数学标记的分隔符delimiters。分隔符成对出现每一对由开始分隔符与结束分隔符组成二者可以相同如$$...$$也可以不同如\[...\]。[!NOTE] 你有两种路线在 Hugo 中渲染数学标记一是配置 Hugo 在客户端使用 MathJax 或 KaTeX 引擎渲染本指南下文详述二是使用transform.ToMath函数在构建项目时完成渲染。前置条件启用 Goldmark passthrough 扩展要保留 Markdown 中被分隔符包裹的原始文本包括分隔符本身不被 Goldmark 的默认解析器改写需要启用 passthrough 扩展。该扩展在 Hugo 源码中位于 markup/goldmark/passthrough/passthrough.go底层基于github.com/gohugoio/hugo-goldmark-extensions/passthrough实现。从源码可以看到扩展在Extend方法中把配置中的行内/块级分隔符逐对转换为passthrough.Delimiters{Open, Close}结构passthrough.go#L44-L72并注册对应的 HTML 渲染器。在项目配置中启用并配置该扩展[markup.goldmark.extensions.passthrough] enable true [markup.goldmark.extensions.passthrough.delimiters] block [[\[, \]], [$$, $$]] inline [[\(, \)]] [params] math true上述配置的要点enable true开启 passthrough 扩展block与inline均为一组「开始/结束」分隔符对的列表格式与源码 goldmark_config/config.go#L247-L257 中DelimitersConfig的注释完全一致每个条目是长度为 2 的字符串列表第一个是开始分隔符第二个是结束分隔符[params] math true用于控制是否加载前端渲染脚本见下文 Step 3。[!NOTE] 上述配置中math true意味着每个页面都会启用数学渲染。若希望按需启用可在项目配置中把math设为false再在需要的页面 front matter 中单独设置math true。[!WARNING] 上面的配置刻意排除了$...$内联分隔符。虽然你可以把$...$同时加进配置与 JavaScript但一旦在非数学语境中使用$符号如美元金额就会引发意外的格式错乱必须对$做双重转义详见下文「Inline delimiters」一节。变体一只保留块级公式如果不需要行内公式的 passthrough省略inline键即可[markup.goldmark.extensions.passthrough.delimiters] block [[\[, \]], [$$, $$]]变体二自定义分隔符你可以定义自己的开始/结束分隔符但必须与前端引擎Step 2中设置的分隔符保持一致。例如用作为块级、作为行内分隔符[markup.goldmark.extensions.passthrough.delimiters] block [[, ]] inline [[, ]]完整配置步骤5 步接入数学渲染Step 1配置 Goldmark passthrough 扩展即上文「前置条件」中的配置。启用扩展后Goldmark 解析器会原样保留分隔符包裹的原始内容含分隔符本身交给前端渲染引擎处理。Step 2创建加载渲染引擎的 partial 模板创建 layouts/_partials/math.html 来加载 MathJax 或 KaTeX。下面的示例加载 MathJaxscript idMathJax-script async srchttps://cdn.jsdelivr.net/npm/mathjax4/tex-mml-chtml.js/script script MathJax { tex: { displayMath: [[\\[, \\]], [$$, $$]], // block inlineMath: [[\\(, \\)]] // inline }, loader:{ load: [ui/safe] }, }; /script这里 JavaScript 中声明的displayMath与inlineMath分隔符必须与项目配置中的分隔符一一对应否则公式无法被识别渲染。Step 3在 base 模板中按条件加载 partial在 layouts/baseof.html 的head中条件调用head {{ if .Param math }} {{ partialCached math.html . }} {{ end }} /head说明若页面 front matter 中设置了math true则加载该 partial若页面 front matter 未设置math则回退读取项目配置中的[params] math值使用partialCached可以避免多页面重复渲染该脚本。Step 4按需启用时在 front matter 中声明如果你在项目配置中把math设为了false则需要在每个需要公式的页面 front matter 中显式开启title Math examples date 2024-01-24T18:09:49-08:00 [params] math trueStep 5在 Markdown 中书写公式以下示例展示了行内与块级公式的完整写法对应文件 docs/content/en/content-management/mathematics.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^* $$可以看到块级分隔符\[...\]与$$...$$均支持「同一行紧凑书写」「带空格的书写」「独占多行书写」三种风格。Inline delimiters\(...\)与$...$的选择上文配置与 JavaScript 示例均使用\(...\)作为行内分隔符。$...$是更常见的备选但在非数学语境中使用$符号时可能引发意外格式化。如果你坚持把$...$加入配置与 JavaScript那么当$出现在数学语境之外时必须双重转义例如I will give you \\$2 if you can solve $y x^2$.[!NOTE] 若你使用$...$行内分隔符且偶尔会在数学语境之外使用$符号就必须选用MathJax 而非 KaTeX以规避 KaTeX 的已知限制该限制会导致未转义的$触发意外格式化。渲染引擎MathJax 与 KaTeX 对比使用MathJax 与 KaTeX 都是开源 JavaScript 显示引擎。二者的取舍除了渲染速度与功能差异外如上文所述若采用$...$行内分隔符且正文会用到$符号则应选用 MathJax。使用 KaTeX 时把 Step 2 的 partial 模板替换为如下内容使用 KaTeX 0.17.0通过 CDN 引入样式、核心脚本与 auto-render 组件link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/katex0.17.0/dist/katex.min.css integritysha384-vlBdW0r3AcZO/HboRPznQNowvexd3fY8qHOWkBi5q7KGgqJF48DceybYmrVbmB crossoriginanonymous script defer srchttps://cdn.jsdelivr.net/npm/katex0.17.0/dist/katex.min.js integritysha384-AtrdNsnxl/75rvBneBVH7DtOvCxSVahR2zWqle1coBKd8DEmLoviqNeJSx64gNAs crossoriginanonymous/script script defer srchttps://cdn.jsdelivr.net/npm/katex0.17.0/dist/contrib/auto-render.min.js integritysha384-bjyGPfbij8/NDKJhSGZNP/khQVgtHUE5exjm4Ydllo42FwIgYsdLO2lXGmRBf5Mz crossoriginanonymous onloadrenderMathInElement(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 }); }); /scriptKaTeX 方案的关键点通过auto-render扩展在DOMContentLoaded后扫描document.body依据delimiters数组中声明的分隔符自动渲染display: true表示块级display模式display: false表示行内模式throwOnError: false确保遇到无法解析的内容时不抛出异常打断页面同样这里的分隔符必须与项目配置保持一致。化学方程式mhchem 支持MathJax 与 KaTeX 都支持化学方程式。例如水的定压热容$$C_p[\ce{H2O(l)}] \pu{75.3 J // mol K}$$渲染结果为标准的化学热力学表达式。如 Step 2 所示MathJax无需额外配置即可支持化学方程式KaTeX 则需要按官方 KaTeX 文档启用mhchem 扩展。原理纵深passthrough 扩展与渲染钩子Hugo 的数学渲染方案可以拆成两层理解构建期Go 端Goldmark passthrough 扩展负责在 Markdown 解析时识别分隔符对将内部原始文本含分隔符原样保留不会像普通 Markdown 解析那样把$、\、_等字符当作格式语法处理。源码 markup/goldmark/passthrough/passthrough.go 中的renderPassthroughBlock会优先查找用户注册的渲染钩子hooks.PassthroughRenderer若未找到则直接输出原始内容passthrough.go#L122-L127。渲染期浏览器端MathJax 或 KaTeX 在页面加载后扫描 DOM把分隔符包围的 LaTeX 文本渲染为数学排版。Hugo 侧的math参数只是控制是否加载引擎脚本真正的排版渲染完全发生在客户端。集成测试 markup/goldmark/passthrough/passthrough_integration_test.go 验证了这条链路配置block [[$$,$$]]、inline [[$,$]]后页面中的$a^*x-b^*$会被渲染钩子输出为Passthrough inline: a^*x-b^*|inline|0:END块级$$a^*x-b^*$$输出为Passthrough block: a^*x-b^*|block|1:END——可见行内与块级 passthrough 共享同一个序号计数器Ordinal且分隔符本身会被裁剪只保留内部的 LaTeX 内容。常见问题与最佳实践公式不渲染优先检查 Step 1 配置与 Step 2/KaTeX partial 中的分隔符是否完全一致其次确认 base 模板的条件判断Step 3与math参数的取值链路。正文中的$引发错乱避免使用$...$行内分隔符改用\(...\)如确需使用对$双重转义并选用 MathJax 引擎。所有页面都加载引擎脚本将[params] math默认设为false仅在需要的页面 front matter 中开启配合partialCached控制脚本重复加载。自定义分隔符只要保证 Hugo 配置与前端引擎两侧的分隔符一一对应就可以使用任意成对字符如/。按上述 5 个步骤完成配置后即可在 Hugo 站点中自由书写行内与块级 LaTeX 数学公式并平滑支持化学方程式兼顾学术写作的严谨性与站点的构建性能。【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考