TeX中汉字处理的快与慢
汉字排版需要哪些东西呢?大概是:汉字字体,汉字编码,汉字的一些排版基本要求。
汉字字体的事情,前几天也说了,只是一个够用和不够用的问题。汉字编码的问题也不是特别大。那么剩下的就是排版需求,无外乎:行首行末禁则,标点处理,孤行处理。
行首行末禁则,就是那些标点不能出现在行首或者行末,这一般靠加penalty解决。这个penalty就是TeX中常见的概念(即断开的可能性),在处理汉字及相关的标点的时候,加在前面或者后面,或者都加。
标点处理。我没有使用“标点挤压”或者“标点压缩”的概念。因为,这个标点处理,实际上既不是挤压也不是压缩。而是加glue,一种可以伸缩的排版元素。铅字排版时代的标点,基本上都是按最窄的宽度设计的,而OpenType,汉字字体的标点大多做成一个汉字宽度。那么问题就是:OpenType中的标点glyph就有多余的空白,即pre space+ glyph + post space。那么标点处理,从两个标点的情况说,理论上的情况是glyph + glue + glyph,实际的情况就变成(pre space + glyph + post space) + glue + (pre space + glyph + post space)。
所以在处理的时候,标点处理怎么都要处理这些多出来的space,日本的ptex系基本上是按JIS中定义的标点位置和宽度来处理,在TeX上处理就是glyph + glue + glyph,这些多出来的space基本都是在输出的时候计算的。而那个超长的式子,基本上就是国内处理标点需要算的,也就是按一个汉字宽度算之间应该具体是多少glue。这个情况的出现,主要是国内生产的字体的标点位置等,没有一个实际的标准来约束。
孤行处理,其实和禁则类似,处理手法也类似。
我当初选择了用ptex来做我自己的TeX,到现在来看其实也没太大的问题。是能够保证速度的。无论是任何的TeX,扩展基本上都不会改核心算法的。任何TeX想要让汉字之间断开,都是需要加微小的glue的。而pTeX也是这么干的,但是略有不同,它会把连续出现的汉字看作一个整体,这个整体都对应一个glue定义,不用实际加进去。也就是说,ptex处理n个汉字,其实就是要处理n + 1个元素,那个1就是汉字之间的glue。而其他的汉字处理方案,则需要2n - 1个元素。
所以快慢就是这么来的。就好比常人正常跑步,和负重跑步,肯定还是正常跑步要快一点。
还有一个遗留的问题,就是在Unicode之中,标点是放在General Punctuation区的,比如说引号,实际上是没有限制宽度的,在西文字体中基本上是最小宽度,在中文字体中是一个汉字宽度。也就是说,这种字符的宽度是暧昧的。在某些系统和浏览器中,这个引号的宽度就很暧昧。这玩意实际上是能靠状态机解决的。TeX中处理汉字,其实也是用的状态机。
但是理论上能做的事,能不能真做出了,有时候有一些工程上的困难。这个我就无能为力了。因为我很长时间以来,只负责自己的软件行为正常就够了。状态机是个好东西,要是人人都掌握就好了。