Hexo+Next: 使用 Latex 公式这篇文章中我发现在使用Pandoc作为 Hexo 的渲染引擎时,Hexo 的标签功能会有问题,具体表现为 Hexo 的标签内部的内容会输出 markdown 源码,而非渲染后的 html。

1 问题研究

经过我的研究,这是因为hexo-render-pandoc在注册自己的renderer时,只注册了异步渲染的 renderer,而没有注册同步渲染的 renderer,而 Hexo 的标签中主要是用同步 renderer。以当时我使用的 NexT 的 note 标签为例。其实现代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
"use strict";

function postNote(args, content) {
return `<div class="note ${args.join(" ")}">
${hexo.render
.renderSync({ text: content, engine: "markdown" })
.split("\n")
.join("")}
</div>`;
}

hexo.extend.tag.register("note", postNote, { ends: true, async: true });
hexo.extend.tag.register("subnote", postNote, { ends: true, async: true });

由于没有注册同步渲染器,这里的hexo.render.renderSync渲染会失败,从而返回的是content中的原本内容,也即 Markdown 形式的源码。

2 解决办法

彻底的解决办法,自然是在hexo-render-pandoc中同时注册同步渲染器。不过我自己尝试之后发现作为同步渲染器,pandoc和 Hexo 使用模板引擎貌似有冲突。更细致深入的修改最好还是由原作者来进行(我已经提交了Issue)。

这里我给出一个临时的解决办法:既然hexo-render-pandoc只注册了异步渲染代码,那么我们在 Tag 的实现代码中调用异步渲染的接口就可以了。仍然以 NexT 主题的 note 标签为例,可以将代码修改成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"use strict";

function postNote(args, content) {
return hexo.render
.render({ text: content, engine: "markdown" })
.then(function (res) {
return `<div class="note ${args.join(" ")}">
${res.split("\n").join("")}
</div>`;
});
// return `<div class="note ${args.join(' ')}">
// ${hexo.render.renderSync({text: content, engine: 'markdown'}).split('\n').join('')}
// </div>`;
}

hexo.extend.tag.register("note", postNote, { ends: true, async: true });
hexo.extend.tag.register("subnote", postNote, { ends: true, async: true });

经过这样修改就可以了。不过这种方法仍然只是权宜之计,要是去修改每个 Tag 的实现,就太繁琐了。