Hexo 博客的中文排版自动修正插件
近期阅读一篇名为《我的博客设计》的文章时,我深受启发。不只是极简设计的诸多考量(见 《博客重构记录》),还让我第一次接触到 《中文文案排版指北》 这套详尽的规范。看来我对排版的一些零散的执念,早就被社区总结成一套系统性的方法论:比方说手动在中英文之间添加空格的习惯。
然而,《指北》中提到的许多其他规范 —— 比如使用直角引号 —— 我就无法坚持下去了。我用的是搜狗输入法,输入直角引号会有点繁琐(最常见的方案是设置自定义短语,但我不喜欢)。不过这种问题,对于一个开发者而言并不是一个难题:既然手动操作繁琐且不全面,何尝不直接让程序为我自动格式化这一切呢?
方案
我的博客网站是使用 Hexo 框架搭建的。作为一个静态网站生成器,它会在我写完 Markdown 文章后,通过 hexo g
命令将它们转换成最终的 HTML 页面。我的目标很明确:在运行 hexo g
命令时,让 Hexo 能自动扫描我的所有文章,并应用《指北》中的排版规则。
幸运的是,Hexo 提供了过滤器系统,它允许开发者在生成过程的特定节点上挂载自定义脚本,对内容进行处理。经过一番研究,我将目标锁定在了 after_post_render
这个钩子上(关于 hexo g
命令更详细的内部流程,我曾在 这篇文章 中进行过探讨)。
after_post_render
会在一篇文章从 Markdown 渲染成 HTML 之后、但写入最终文件之前触发,这正是我们对内容进行拦截和润色的完美时机。确定了技术路径只是第一步。要打造一个可靠的自动化脚本,必须解决两个关键问题:
- 自动化脚本绝对不能破坏文章的结构,尤其是代码块。
const message = "你好world"
这样的代码里就不能添加空格 - 规则必须足够智能,能够正确处理中英文混合的复杂上下文,避免将纯英文内容里的标点也错误地汉化
为了解决这两个问题,我最终采用了一个多阶段、基于 DOM 解析的方案:
- 我先前尝试参考 hexo-pangu 的写法,用
jsdom
。但是这种小任务用jsdom
实在是大材小用,纯正则表达式又太难以维护(我也不太会写),最终还是选择了cheerio
来操作 HTML 内容 - 在进行任何处理之前,脚本会首先识别并保护所有
<pre>
和<code>
标签,确保它们内部的内容不会被后续任何规则触碰到 - 对所有被确认为安全的文本内容,脚本会依次执行专有名词修正、标点符号转换和空格添加等一系列处理流程,确保规则之间不会互相干扰
成果
为了将这个解决方案固化下来,并方便自己和其他人使用,我将其打包成了一个独立的 Hexo 插件:hexo-filter-copywriting。
它是一个轻量、高效且完全可配置的过滤器,可以帮助我们自动完成绝大部分中文排版工作。使用起来也很简单,你可以直接从 npm 安装它(说来这也是我第一次在 npm 上发布包),然后在博客根目录的 _config.yml
中进行配置即可。
自然,这个工具还未完善,有些排版规则没有被添加进去。日后我会逐渐完善它,最近还是太忙了,只能挤出一点点时间在写博客和开发开源小玩意儿上。毋庸置疑,该项目欢迎任何 Issue 或者 PR。
效果展示
为了直观展示插件的效果,并持续验证其健壮性,我创建了一个「排版自动化测试页面」。这个页面包含了各种常见的排版错误,你可以清除地看到插件修正前后的区别。
- 查看最终效果:排版自动化测试页面
- 查看原始 Markdown 文件:README.md on GitHub