<-- Home |--hugo

Hugo+Mathjax的正确姿势

游戏名称:hugo

把手头的无聊域名用起来之后,就用Hugo搭了一个博客。

感觉整个的使用体验还是很不错很不错的。

安装

安装Hugo的时候,一定要记得是安装hugo-extended版本,好多功能需要这个版本。

这个版本的安装地址:

1export HUGO_VERSION=0.144.2
2wget -o hugo_extended_${HUGO_VERSION}_Windows-amd64.zip https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Windows-amd64.zip

如果是wsl(最好的Linux发行版),可以这样安装:

1export HUGO_VERSION=0.144.2
2wget -o hugo_extended_${HUGO_VERSION}_Linux-amd64.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-amd64.deb
3sudo dpkg -i hugo_extended_${HUGO_VERSION}_Linux-64bit.deb

建立站点

wsl下面安装好就可以访问hugo命令了。在windows下面,需要把解压后的hugo.exe文件移动到某个通过PATH环境变量可以访问的目录下。

之后就可以通过hugo命令,测试是否安装成功,

1hugo version

如果成功安装,会显示hugo的版本号。

然后就可以用hugo new site命令,创建一个新站点。

1hugo new site MyBlog

套用一个模板,入门的一般是ananke

1hugo new site MyBlog --template=ananke

或者

1git init
2git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke

写文章

更新文章的方式

1hugo new posts/hugo/hugo-mathjax.md

本地运行

1hugo server -D

这里的-D表示draft,表示草稿。在新建的文章默认是draft的,所以需要加这个参数。

发布

1hugo build

此时完整的站点就生成在public目录下。可以采用各种方式部署。

当然我们采用GitHub Pages的时候,可以直接只提交public目录到gh-pages分支。也可以采用Github-Actions自动部署。

几个特殊的文件

  • hugo.toml:站点配置文件
  • CNAME:用于设置自定义域名
  • .github/workflows/hugo.yml:Github-Actions自动部署文件

Hugo支持数学的正确方式

测试驱动

下面用Hugo写数学公式为例,看看搞点自己的东西是什么样子的。

我们首先新建一个测试文件:

1hugo new posts/hugo/hugo-mathjax.md

这个文件的内容包括:

 1+++
 2date = '2025-02-22T13:20:35+08:00'
 3draft = true
 4title = 'Mathjax'
 5+++
 6
 7# Block Math
 8
 9$$
10\int_0^\infty \frac{x^3}{e^x} \, dx = \frac{\pi^4}{15}
11$$
12
13
14\[
15\int_0^\infty \frac{x^3}{e^x} \, dx = \frac{\pi^4}{15}
16\]
17
18# Inline Math
19
20$\int_0^\infty \frac{x^3}{e^x} \, dx = \frac{\pi^4}{15}$ 是一个行内公式。\(
21    \int_0^\infty \frac{x^3}{e^x} \, dx = \frac{\pi^4}{15}
22\) 也是一个行内公式。

当然,这个相当于是我们用一个TDD的开发模式,先写一个测试案例,然后逐步开发,达到我们想要的效果。这个时候,测试肯定是通不过的。hugo server -D会显示下面的页面:

hugo-mathjax

第一步

第一步,整一个部分的Html文件增加到Hugo产生的Html文件中。这个文件我们放在themes/ananke/layouts/partials/extend-head.html文件中。

 1{{ if or .Params.math .Site.Params.math }}
 2<script>
 3  MathJax = {
 4    tex: {
 5      inlineMath: [['\\(', '\\)']],
 6      displayMath: [['$$','$$']],
 7      processEscapes: true,
 8      processEnvironments: true
 9    },
10    options: {
11      skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre']
12    }
13  };
14</script>
15<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
16<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
17{{ end }} 

还需要在\themes\ananke\layouts\_default\baseof.html文件中,增加一个extend-head.html文件的引入。

1{{ partial "extend-head.html" . }}

这个应该是增加在<head>标签中。

然后,我们要修改hugo.toml文件,增加math参数,并开启mathjax。 当然,这个math = true/false,可以全站设定,也可以在单个页面中的头部设置。

 1# Site parameters
 2[params]
 3  #  other params
 4  math = true  # Enable math support
 5
 6
 7[markup]
 8  [markup.goldmark]
 9    [markup.goldmark.renderer]
10      unsafe = true  # This allows HTML in markdown

这里有两个部分,一个部分就是要打开math参数,另一个部分是打开unsafe参数。

有第二个参数,才会允许MathJax处理HTML标签。

完成这一步,我们可以看到,有一个公式被处理了,但是其他的公式没有被处理。

hugo-mathjax

第二步

依然没有效果,我们在仔细看看我们的代码中,是不是没有搞对。

首先是,我们注册的公式格式中,只包含了$$\(),修改extend-head.html文件,增加$\的注册。

1      inlineMath: [['\\(', '\\)'], ['$', '$']],
2      displayMath: [['$$', '$$'], ['\\[', '\\]']],

现在,我们再运行hugo server -D,可以看到,用$$$包围的公式已经可以正常显示了。

hugo-mathjax

第三步

我们仔细观察,发现得到的Html文件中,()[]包围的公式没有被处理。

这里还会有一个非常精巧的bug,就是,用$$$包围的公式中,某些_xxxx_会被处理成<em>xxxx</em>,从而造成公式不能正常显示。Hugo的处理流程中,首先会进行Markdown的解析,然后进行HTML的解析。

所以,这里我们应该引入一个条件,来让Hugo解析Markdown的时候,不处理相应的公式。

这一次,我们应该修改hugo.toml文件,增加extensions参数。

这里首先启用markdown的扩展,然后增加一个passthrough的扩展,来处理我们想要的公式。当碰到区块的分隔符和行内分隔符(在下面定义)时,Hugo跳过不进行处理,从而能够把行间公式和行内公式留给后续的Mathjax,产生正确的公式渲染。

 1[markup]
 2  [markup.tableOfContents]
 3    endLevel = 2
 4    startLevel = 2
 5    ordered = true
 6  [markup.goldmark]
 7    [markup.goldmark.renderer]
 8      unsafe = true
 9    [markup.goldmark.extensions]
10      [markup.goldmark.extensions.passthrough]
11        enable = true
12        [markup.goldmark.extensions.passthrough.delimiters]
13          block = [['\[', '\]'], ['$$', '$$']]
14          inline = [['\(', '\)'], ['$', '$']]

大概就是这样,经过这一步,我们就可以看到,所有的公式都可以正常显示了。

hugo-mathjax

这里有一个要记得,定义行间公式时,$$\[\]的前后要留一个空行,不然hugo会忽略任何跟行间公式相连(只有一个换行)的文字。

总结

  1. Hugo的Markdown解析流程中,首先会进行Markdown的解析,然后进行HTML的解析。
  2. Hugo程序命令行提供了站点、文章的创建、运行、发布等操作。
  3. 这里我们提供了一个没有bug的Mathjax的配置,可以让大家在Hugo中愉快地写数学公式,这个问题有一大堆人在用英语问,但是解决方案却很少。

文章标签

|-->hugo |-->mathjax |-->markdown |-->hugo数学公式


GitHub