Hexo公式渲染问题

参考解决方案:hexo next主题解决无法显示数学公式

问题

Markdown 编辑器通常都会集成 Mathjax,用来渲染文档中的类 Latex 格式书写的数学公式。

Hexo 默认使用 hexo-renderer-marked 引擎渲染网页,该引擎会把一些特殊的 markdown 符号转换为相应的 html 标签。比如在 markdown 语法中,下划线 _ 代表斜体,会被渲染引擎处理为 <em> 标签。类似的语义冲突的符号还包括 *, {, }, \\ 等。

解决方案

更换 Hexo 的 markdown 渲染引擎,将 hexo-renderer-marked 替换成 hexo-renderer-kramed

1
2
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save

换引擎后行间公式可以正确渲染了,但行内公式的渲染还是有问题,因为 hexo-renderer-kramed 引擎也有语义冲突问题。

来到博客根目录下,找到 node_modules\kramed\lib\rules\inline.js,对第11行的 escape 变量和第20行的 em 变量的值做相应的修改:

1
2
//escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/,
escape: /^\\([`*\[\]()#$+\-.!_>])/,

[ escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/ ]:用于检测并捕获在特定字符前面的反斜杠,从而实现转义功能,使这些字符在后续处理中被视为普通字符。

  • //:表示中间的是正则表达式
  • ^: 表示字符串的开始
  • \\: 由于反斜杠在正则表达式中是一个转义字符,所以用两个反斜杠来表示实际的一个反斜杠。
  • ([\\*{}\[\]()#$+\-.!_>]): 这是一个捕获组,用来匹配一组特定的字符。这些字符是:
    • \\: 反斜杠
    • *: 星号
    • {}: 花括号
    • []: 方括号
    • (): 圆括号
    • #: 井号
    • $: 美元符号
    • +: 加号
    • -: 减号
    • .: 点
    • !: 感叹号
    • _: 下划线
    • >: 大于号

[ escape: /^\\([`*\[\]()#$+\-.!_>])/ ]:与上一个正则表达式类似,但是不包含反斜杠(\)和花括号({})

1
2
//em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,

[ em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/ ]:用于匹配用下划线或星号包围的文本,以实现强调或加粗的效果。例如:

  • _italic_ 会被匹配为斜体
  • *bold* 会被匹配为加粗

其中匹配下划线部分 ^\b_((?:__|[\s\S])+?)_\b

  • ^: 表示字符串的开始
  • \b: 单词边界
  • _: 下划线字符
  • ((?:__|[\s\S])+?): 捕获组,匹配下划线之间的内容
    • (?:__|[\s\S]): 非捕获组,匹配两个下划线 (__) 或者匹配任意字符,包括换行符 ([\s\S])。
    • +?: 非贪婪匹配,尽可能少地匹配前面的模式
  • _: 下划线字符
  • \b: 单词边界。

匹配星号的部分 |^\*((?:\*\*|[\s\S])+?)\*(?!\*)

  • ^: 表示字符串的开始
  • \*: 星号字符
  • ((?:\*\*|[\s\S])+?): 捕获组,匹配星号之间的内容
    • (?:\*\*|[\s\S]): 非捕获组,匹配两个星号 (**) 或者匹配任意字符,包括换行符 ([\s\S])
    • +?: 非贪婪匹配,尽可能少地匹配前面的模式
  • \*: 星号字符
  • (?!\*): 负向前瞻,确保星号后面不是另一个星号

[ em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/ ]:与上一个正则表达式类似,但只匹配星号包围的文本。

重新启动 hexo,查看公式是否能够正常渲染

1
2
3
hexo clean
hexo g
hexo d

如果问题仍未解决的话,检查主题配置文件中的 mathjax 是否打开,以 butterfly 主题为例。

来到博客根目录下,找到主题配置文件 themes\butterfly\_config.yml

mathjax 下的 enable 设置为 true

1
2
3
4
5
6
7
8
9
10
11
12
# Math (數學)
# --------------------------------------
# About the per_page
# if you set it to true, it will load mathjax/katex script in each page (true 表示每一頁都加載js)
# if you set it to false, it will load mathjax/katex script according to your setting (add the 'mathjax: true' in page's front-matter)
# (false 需要時加載,須在使用的 Markdown Front-matter 加上 mathjax: true)

# MathJax
mathjax:
enable: true
per_page: false

根据注释,如果将 mathjax 下的 per_page 设置为 true,则对每个文章都进行渲染;如果将 per_page 设置为 false,则需要在需要渲染的文章的 Front-matter 里打开 mathjax 开关,如下:

1
2
3
4
5
6
---
title: test
tags: test
categories: test
mathjax: true
---