当前位置 : 首页 » 文章分类 :  开发  »  Hexo博客(13)添加MathJax数学公式渲染

Hexo博客(13)添加MathJax数学公式渲染

手动将 CSDN 博客迁移到Hexo的过程中,发现研究生期间写的很多博客中有大量数学公式,在 CSDN 上一直用截图显示公式,在 Hexo 中肯定不能用这么 low 的方法。稍微一搜索了解到 Hexo 中基本都是用 MathJax 做公式渲染,试了试我用的 free2mind 主题中并没有添加对 MathJax 公式渲染的支持,遂自己手动加上,下面介绍如何在 Hexo 博客中添加 MathJax 数学公式渲染。

MathJax 公式书写示例见 MathJax数学公式


Hexo博客中安装MathJax

通过hexo-math插件安装MathJax

有个叫 hexo-math 的插件,可以给 Hexo 博客添加 MathJax 公式支持,GitHub 地址为 https://github.com/hexojs/hexo-math
安装方法可其他 hexo 插件一样,在博客根目录执行 npm install hexo-math --save 安装,配置见 GitHub 说明页,这里我没有通过这种方式安装,而是直接在主题配置中添加MathJax的js来安装的,一来能够对内部引用机制有更多了解,二来备份博客源码时直接就将添加的内容备份了,换电脑的时候不用再去多装这一个插件。

在主题中手动添加js安装MathJax

类似所有第三方js插件,js加载方式有两种:

  • 第一种,通过连接 CDN 加载 js 代码。好处是省了本地配置 js 代码,并且每次加载都是最新的,缺点是一旦连接的 CDN 出问题,可能卡住页面的 js 加载。
  • 第二种,将 js 代码下载下来,放到主题的 js 文件夹中,通过本地相对目录加载。优缺点和第一种方法正相反。

这里我选择通过CDN加载,因为把代码下载下来后发现有好多js,搞不清楚其中的引用关系,还是直接用官方给出的通过CDN加载的简便方法吧:
Getting Started with MathJax
http://docs.mathjax.org/en/latest/web/start.html
又综合了网上其他人给出的一些配置,最终代码如下。

在 themes/free2mind/layout/_partial 目录中新建 mathjax.ejs,填入如下js代码:

<!-- MathJax配置,可通过单美元符号书写行内公式等 -->
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        "HTML-CSS": {
            preferredFont: "TeX",
            availableFonts: ["STIX","TeX"],
            linebreaks: { automatic:true },
            EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50)
        },
        tex2jax: {
            inlineMath: [ ["$", "$"], ["\\(","\\)"] ],
            processEscapes: true,
            ignoreClass: "tex2jax_ignore|dno",
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        },
        TeX: {
            equationNumbers: { autoNumber: "AMS" }, <!-- 2017.6.30,masikkk新增,MathJax公式添加编号支持 -->
            noUndefined: { attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "90%" } },
            Macros: { href: "{}" }
        },
      messageStyle: "none"
    });
</script>

<!-- 给MathJax元素添加has-jax class -->
<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<!-- 通过连接CDN加载MathJax的js代码 -->
<script type="text/javascript" async
  src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML">
</script>

只在有公式的页面才加载MathJax

只在有公式的页面才加载MathJax是一个很重要的优化,没有公式的页面没必要加载MathJax的js代码,影响页面加载速度。
在所有有公式的文章的front-matter中增加一项配置mathjax: true,例如:

---
title: Hexo博客(13)添加MathJax数学公式渲染
toc: true
mathjax: true
date: 2017-06-18 10:51:00
updated: 2017-06-18 23:33:44
categories: 开发
tags: [Hexo,GitHub]
---

然后在themes/free2mind/layout/_partial/footer.ejs 中通过此配置变量决定是否加载 mathjax.ejs

<!-- 根据页面mathjax变量决定是否加载MathJax数学公式js -->
<% if (page.mathjax){ %>
<%- partial('mathjax') %>
<% } %>

解决MarkDown与MathJax渲染冲突

添加MathJax后写几个公式发现渲染出了很多问题,原因是Hexo默认先使用hexo-renderer-marked引擎渲染MarkDown,然后再交给MathJax渲染。hexo-renderer-marked会把一些特殊的markdown符号转换为相应的html标签,比如在markdown语法中,下划线_代表斜体,会被转化为<em>标签,\\也会被转义成一个\。而类Latex格式书写的数学公式下划线_表示角标,\\表示公式换行,有特殊的含义,所以MathJax引擎在渲染数学公式的时候就会出错。

解决方法有人提出更换Hexo的MarkDown渲染引擎,用hexo-renderer-kramed 替换默认的hexo-renderer-marked引擎,但我看了下hexo-renderer-kramed的文档说明,如果用这个引擎的话,要改变我的MarkDown书写习惯,还是不用了,并且换了这个引擎还是没有完全解决问题。

最终我的解决方法是参考一篇博文中修改hexo-renderer-marked渲染引擎的js脚本,去掉对_\\的转义。
Hexo默认的MarkDown渲染引擎hexo-renderer-marked会调用marked模块的marked.js脚本进行最终的解释,这个脚本在Hexo安装后的node_modules\marked\lib\目录中。
有两点修改:

  • 针对下划线的问题,取消_作为斜体转义,因为marked.js中*也是斜体的意思,所以取消掉_的转义并不影响使用markdown,我平时一般不用斜体,就是用也更习惯用*作为斜体标记。
  • 针对marked.js与Mathjax对于个别字符二次转义的问题,我们只要不让marked.js去转义\\,\{,\}在MathJax中有特殊用途的字符就行了。

编辑 node_modules\marked\lib\marked.js 脚本,
第一步,找到如下代码

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

替换为

escape: /^\\([`*\[\]()# +\-.!_>])/,

这一步取消了对\\,\{,\}的转义(escape)

第二步,找到em的符号

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

替换为

em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,

这一步取消了对斜体标记_的转义

这样带来一个问题就是,以后每次更换电脑,在新电脑上安装完Hexo环境后,都要手动修改marked.js文件。

hexo-renderer-marked升级到1.0.1后的解决方法

上面说的都是老版的解决方法,网上也千篇一律都是这种方法。
hexo 3.9.0 中默认将 hexo-renderer-marked 升级到了 1.0.1 后,对应的 marked 也升级了,代码已经不是上面这样了,我也不太懂js,不敢随便改。
自己试了下:
1、公式中的_下划线貌似没问题,可以显示为下标。
2、公式中双反斜线 \\ 换行不好用,改为4个反斜线 \\\\ 换行即可。
其他的不需要改就行了,目前我博客的 hexo-renderer-marked 已升级到1.0.1,可以看我后面的公式书写举例,都是ok的。

搭建一个支持LaTEX的hexo博客
http://blog.csdn.net/emptyset110/article/details/50123231

在 Hexo 中完美使用 Mathjax 输出数学公式
http://lukang.me/2014/mathjax-for-hexo.html

在Hexo中渲染MathJax数学公式
http://www.jianshu.com/p/7ab21c7f0674


解决公式过长会超出页面问题

使用默认的配置,行内公式超长时会超出文章宽度,非常难看。

增加如下 css

/* 解决 mathjax 长公式超出页面范围 */
.MathJax_Display {
overflow-x: auto;
overflow-y: hidden;
}

上一篇 Python-科学计算环境搭建

下一篇 Hexo博客(12)使用google-code-prettify代码高亮

阅读
评论
1,720
阅读预计7分钟
创建日期 2017-06-18
修改日期 2020-03-12
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论