解决 hexo-renderer-kramed 渲染冲突的部分问题

【阅读建议】因 hexo-renderer-marked 不支持数学公式的渲染,其他渲染器又有一些问题,如 hexo-renderer-pandoc 过于沉重,hexo-renderer-markdown-it 对 NexT 主题支持不佳,因此选用 hexo-renderer-kramed 渲染器。本文解决了该渲染器在渲染 Markdown 及数学公式时遇到的部分问题。

【原文地址】:https://corecabin.cn/2021/08/14/solve-some-problems-of-hexo-renderer-kramed-rendering-conflicts/

1 hexo-renderer-kramed 不能渲染 Todo List 的问题

原来的渲染器 hexo-renderer-marked 是支持 Todo List 的,翻了下 hexo-renderer-marked 的 GitHub 仓库 的 Pull Request。发现在这个 PR 里,hexo-renderer-marked 加入了对 Todo List 的支持,那就拷贝这个 PR 中 lib/renderer.js 里新增的代码:

1
2
3
4
5
6
7
8
9
// Support To-Do List
Renderer.prototype.listitem = function(text) {
if (/^\s*\[[x ]\]\s*/.test(text)) {
text = text.replace(/^\s*\[ \]\s*/, '<input type="checkbox"></input> ').replace(/^\s*\[x\]\s*/, '<input type="checkbox" checked></input> ');
return '<li style="list-style: none">' + text + '</li>\n';
} else {
return '<li>' + text + '</li>\n';
}
};

加入到本地的 hexo 文件夹的 /node_modules/hexo-renderer-kramed/lib/renderer.js 的第 19 行中。

保存后重新hexo cleanhexo g,就渲染成功了。

其实这个解决方案不是我翻 PR 找到的,而是我在 GitHub 乱搜索时 在这里 找到的。本来并不指望解决这个问题的,又学到一招。

2 hexo-renderer-kramed 渲染 MathJax 时与 Markdown 语法冲突

关于如何修改语义冲突,网上的教程讲得很详细了,比如:

但网上找到的教程通常只讲述了如何修改下划线 _ 和反斜杠 \\ 的冲突。我将遇到的所有问题一一整理如下。

下文的问题通常是行内公式的问题,目前看来公式块受到的影响比较小。

2.1 行内公式与行内代码冲突

问题描述:把行内公式作为行内代码输入时(如下),会显示异常。例如:

1
`$ a+b $`

翻一下 hexo-renderer-kramed 的文档,发现作者写在这里了:

所以要想输入行内代码中的公式,在$前后加上空格就行了:

1
` $ a+b $ `

2.2 下划线_被转义为斜体而非 LaTeX 下标

问题描述:当公式中出现多个下划线时,会被 kramed 渲染为 Markdown 斜体,导致公式显示异常。

Markdown 本身的语法是支持*_都被转义为_斜体_的,所以可以取消掉 kramed 对_的转义。

打开本地hexo文件夹下的/node_modules/kramed/lib/rules/inline.js,找到第 20 行如下代码:

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

修改为:

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

就取消了对下划线_的转义。

以后使用斜体的话只用*符号就够了。如果 LaTeX 要使用大量*符号,可用\ast代替。

2.3 反斜杠\\被转义为\而非 LaTeX 换行

问题描述:当公式中出现\\表示换行时,会被 kramed 渲染为\,导致公式显示异常。

取消掉对\\的转义就行了。

同上,找到inline.js中第 11 行如下代码:

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

修改为:

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

就取消了对反斜杠\\的转义。

2.4 LaTeX 紧贴符\!不被转义

问题描述:当公式中出现\!表示紧贴符号时,会被 kramed 渲染为!,导致公式显示异常。

同上,把escape:后的正则表达式中的!去掉即可,取消掉对\!的转义。

2.5 反斜杠加竖线\|被转义为|而非 LaTeX 双竖线

问题描述:当公式中出现\|表示紧贴符号时,会被 kramed 渲染为|,导致公式显示异常。

真是个困扰了半天的 bug,上面的escape:后面也没有|啊。

找了我 n 个小时,原来还是inline.js代码的问题。

找到第 64 行如下代码:

1
escape: replace(inline.escape)('])', '~|])')(),

修改为:

1
escape: replace(inline.escape)('])', '~])')(),

就取消了对\|的转义。

执行完以上步骤后,记得hexo cleanhexo g走一波。

总结:哪里被 kramed 转义就检查escape对应的部分。

3 总结

  • 多上 GitHub 看看原仓库的文档、issues、PR,会有收获的,实在不行直接搜,比百度好使。
  • 熟悉流程,Hexo 的原理是根据渲染器,把 Markdown 语法转为 HTML 语法。所以一些显示 bug 不一定是主题的问题,而很有可能是渲染器的问题。所以看看渲染器的源码总是有收获的。