pangu.js 做的事很窄
pangu.js 的目标可以用一句话说完:在中日韩文字和半角英文、数字、符号之间,自动插入适当空格,让混排更容易读。
中日韩文字,这里大白话说,就是汉字、日文假名、韩文等常见 CJK 字符。半角字符,这里主要指英文、数字和一些窄符号。pangu.js 不需要知道一篇文章讲什么,它只关心两类字符有没有贴在一起。
这也是它聪明的地方:问题被缩得很小。它不判断审美,不识别语法,不理解品牌策略。它只问:左边是不是 CJK?右边是不是 Latin 或数字?如果是,中间没有空格,那就补一个。
pangu.js 像一把窄刀:不做饭,不摆盘,只负责把最常见的粘连切开。
规则为什么能工作
很多文字处理问题难,是因为机器要理解意思。中英文加空格相对容易,是因为大部分情况只看字符类别就够了。
比如“发布iOS17版本”。这里“布”和“i”贴住,“17”和“版”贴住。即使机器不知道 iOS 是什么,也能看出汉字和半角串的边界。处理后变成“发布 iOS 17 版本”,读者的眼睛轻松很多。
这类规则通常会围绕几组边界展开:
- CJK 字符和英文字母之间。
- CJK 字符和数字之间。
- CJK 字符和某些半角符号之间。
- 已经有空格或标点的地方,不重复添加。
真实实现会比这更细,因为括号、引号、斜杠、百分号、链接、代码片段都可能造成例外。但主干思想就是字符分类和边界替换。
它改的是文本,不只是显示
这里要特别小心。很多 pangu 系工具会直接返回一个带空格的新字符串。也就是说,它不是告诉浏览器“显示时稍微挪开”,而是真的把空格写进内容。
这有好处。结果稳定,任何浏览器、任何平台、任何复制粘贴之后都能看到空格。它也容易接入:博客发布前跑一遍,Markdown 保存前跑一遍,评论显示前跑一遍,都可以。
坏处也正来自这里。只要改文本,就会遇到“这里该不该改”的问题。代码里的变量名、URL、文件路径、邮箱地址、数学表达式、产品固定写法,都可能不希望被插入空格。
所以成熟的用法不会盲目扫全世界。它会限定范围:只处理正文节点,不处理代码块;只处理展示文本,不处理链接地址;只处理用户可读内容,不处理机器要解析的字段。
小工具背后的工程品味
pangu.js 让人着迷,不是因为它复杂,而是因为它克制。它承认自己解决的是一个小问题,然后把小问题做成可靠的管道。
幂等,大白话说,就是你对同一段文本处理一次和处理十次,结果应该一样。加空格工具很需要幂等。如果第一次把“中文English”变成“中文 English”,第二次不应该再变成“中文 English”。
正则表达式,大白话说,是一种用规则匹配字符串的办法。许多这类工具会用正则表达式识别边界。正则的好处是快、直接、容易移植;坏处是规则一多,就会变成一张难读的网。
工程品味就在这里:规则要够多,能覆盖常见场景;又不能多到没人敢维护。它不是写一条“全都加空”的命令,而是在“足够好”和“别误伤”之间反复调位置。
为什么叫盘古
这个名字好。盘古在混沌里开天辟地,而中英文数字粘在一起时,也像一个小混沌。工具跑过,黑字没有变多,意思没有变深,只是中间出现一线白,天地分开了。
但神话感不能遮住工程事实:pangu.js 不是标准,也不是唯一答案。它是一种作者侧、应用侧的补救办法。它存在,恰恰说明底层排版系统没有把这件事自然做好。
如果浏览器、编辑器、操作系统都能在显示层提供稳定、细腻、可关闭的中西文间距,很多场景就不需要把真实空格写进文本。可在那之前,小刀有小刀的价值。
下一章的问题也由此出现:如果工具能自动加空,操作系统和输入法要不要也自动加?它们是在帮用户,还是在擅自改用户的字?