修复Mathjax行内显示公式的问题

hugo-theme-next 的主题默认便是可支持使用mathjaxkatex两种不同组件,通过它们来实现对数学公式的渲染输出显示。只不过自己对数学公式的使用了解的也比较少,测试时直接就是复用网上的文章来验证数学公式渲染是否正常。结果当遇到真正的数学“专家”用户时,便是暴露出在了无法在同行文字内显示数学公式的问题 Issue#90 ,趁此便是参考评论区大家提供的建议尝试修复这“千年老🐛”。

修复问题

针对需要在行内显示数学公式的需求,乍一看用户提供的修复参考示例代码,觉得hugo-theme-next主题中的代码应该是没有问题才对,因为明显也是有相同的配置项设置,此时真是丈二和尚摸不着头脑啦。接下来只能是花点时间和耐心直接扒拉下评论中的参考代码进行调试,通过分析后确实也是找到根本原因,主要是如下两点:

  • Mathjax的配置项并非是等待其脚本加载完成后再触发,反而是要先于脚本加载前准备好
  • 加载脚本的script标签需要添加id属性,而且名称也是固定的MathJax-script不可修改

那么接下来只要按上面的问题原因,调整下/assets/js/third-party/others/math.js中的部分代码即可,修复后的代码参考如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
const render_js = NexT.utils.getCDNResource(NexT.CONFIG.page.math.js);
const mathjaxCfg = `
  window.MathJax = {
    // 自定义内联数学公式的分隔符号
    tex: {
      inlineMath: [['$', '$'], ['\\(', '\\)']]
    },
    // SVG 渲染配置为全局共享字体缓存
    svg: {
      fontCache: 'global'
    },
    // 排除特定的HTML标签,避免过度渲染
    options: {
      skipHtmlTags: ["script", "noscript", "style", "textarea", "pre", "footer"],
    }
  };
`;
NexT.utils.getScript(null, { textContent: mathjaxCfg });
NexT.utils.getScript(render_js, { attributes: { id: "MathJax-script", "async": true }});

中间在修复过程中还遇到了件“有趣”的现象,在文章底部的打赏区设置有个字符表情,原则上是不符合Mathjax语法标准的,但不知为何还是受到了影响,导致此表情无法正常显示,于是在上述的配置项中又增加了HTML标签排除来避免整个页面渲染。

效果展现

然后就是来见证奇迹发生的时刻,在行内用不同的语法写个二次元方程的数学公式进行验证,具体的数学公式和效果如下:

1
2
3
4
5
## 支持不同的行内语法标记
一元二次方程:$ax^2+bx+c=0$ 的求解公式为:\( x={-b\pm\sqrt{b^2-4ac} \over 2a} \) 

## 就是这个字符表情会被mathjax识别进行渲染,有点坑
ヾ(^▽^*)))

渲染后的实际效果: 一元二次方程:$ax^2+bx+c=0$ 的求解公式为:( x={-b\pm\sqrt{b^2-4ac} \over 2a} )

其他补充

另外也发现当前主题使用的Mathjax脚本文件是tex-mml-chtml组件,它是通过不同的字体来支持显示数字公式的,为此需要在页面加载时下载诸多使用到的字体库。而另一个组件tex-svg是把公式转换为SVG矢量图形输出,则不需要下载字体的操作。经过思索一番后,决定还是转向使用tex-svg组件来渲染数学公式,减少了资源下载的同时,也是支持更高质量的数学公式显示。

此次修复过程中也是参考了不少其他的资料学习,感兴趣的童靴可以点击下方的参考资源深入了解一二,也欢迎更多的用户使用反馈,提升 hugo-theme-next 主题对数学公式渲染的支持力度。😀