我的朋友之中,有曾经研究过ConTeXt的。所以他们一度顺理成章地研究过Luatex。和XeTeX相比,LuaTeX曾经在理论上有非常高的自由度和开放性。

LuaTeX项目的起源,大概是要从一个大学的阿拉伯语项目说起。但是,从排版技术难度上来说,其实是不必专门造一个引擎的。因为阿拉伯语排版,固然是复杂语言排版(Complex Text Layout),但是它只比西文和汉字排版复杂一点的。简单的说(以后有机会详细说,做成视频应该更有意思),阿拉伯语的字符只有一个排版输出方向上的变化和字符的位置变体,说人话就是,阿拉伯语是从右往左排字,字在词中的位置会有变体。

所以呢,“骗”经费这事,大概是的。但是呢,我们可以看Knuth在TeXbook里面写的:

My work at Stanford has been generously supported by the National Science Foundation, the Office of Naval Research, the IBM Corporation, and the System Development Foundation.

所以说啊,立项了,基本上就是走流程了,能出结果就好。

LuaTeX它做了些什么呢?我们先从最简单的说起:

sin(2)=\directlua{tex.print(math.sin(2))} \bye

lua源码是什么语言(LuaTeX它是由什么构成的)(1)

\directlua整个东西实际上和TeX的扩展很相似,即\input的管道输入,举例:

\input|"extractbb --version" \bye

lua源码是什么语言(LuaTeX它是由什么构成的)(2)

但是呢,\directlua实际上是在LuaTeX内部创建一个buffer,所有计算的结果,只要想存到这里面,都需要使用类似tex.print的函数调用。当然,你在\directlua里面也使用io.popen,这也是使用管道。

\directlua的应用,使用最广泛的例子其实是TiKZ的LuaTeX后端,比如说它实现了一些图形学的算法来排布特定格式的图的元素(如谱系树的排法)。

除此之外,LuaTeX的核心排版部分,加了不少允许挂Lua代码钩子的地方,这是LuaTeX的迷人之处,当然也是脑瓜仁疼的来源。毕竟,能做出一些好玩的排版效果但是效率低。这个效率低体现在:他们最后不得不上了LuaJIT。但是用LuaJIT也没缓解慢的问题。非要强加一个理由的话,那可能是排版这事,就是那么复杂,挂钩子的效率就是不高。

更重要的,现在人讲的很少的,其实是Omega部分。这个东西,我以前水文章的时候写过一点。这个引擎做了三件事,第一个是把8位支持直接修改成了十六位;第二个是增加了多方向排版(就是“骗”经费的公能);第三个是OTP或者OCP。

但实际上,很长时间里面,LuaTeX的多方向排版,是假的。或者说,它的这一部分功能实际上是处于不怎么维护的状态。也就是这几年,这一块的代码是进入了可用状态的。当然,不可用的话,可以强行可用,比如LuaTeX-ja用代码模拟的:

lua源码是什么语言(LuaTeX它是由什么构成的)(3)

这里面顺便提一句,有人说XeTeX也支持竖排。这是不确切的。XeTeX支持的功能很简单,就是把glyph转90度,看起来像是竖排,但其实不是。竖排这事,如果是输出到图上,那还好说。但是稍微想要带一些语义,可能还得做特殊处理,比如在PDF中要控制嵌入的字体的CMAP。所以说,竖排这事,也是分层的,图像上看着像只是第一步,但是还有几步走。

这里该轮到将OTP和OCP了。这里熟悉Erlang的朋友不要误会,Omega中的OTP不是Open Telecom Platform的意思,而是Omega Translation Processes。OCP就是编译之后的OTP。在Omege的语境下,这个translation其实包含了transliteration,也就是转写。那么什么是转写呢?比如我们见到泰语的สวัสดี,用拉丁字母写可以是sa wa dee。这就是一种直接的转写。转写这东西,在输入法比较难搞定的情况下,其实能解决不少事情。在九十年代,Omega面对的就是类似的情况。所以Omega的强项其实也是这个,所以社区做了阿拉伯语,梵语,孟加拉语,高棉语等等的OTP文件。

OTP这东西,语法很像flex,但是不太支持复杂的正则表达式,也能做编码转换。这也就是我很久之前提到的,Omega的纯文本文件可以输入多种不同的编码文本块。OTP技术虽然很强,但是技术太强有时候也是包袱,就会导致难学。就像我在别的地方揶揄Apple的AAT技术,强是强,但是设计师看了想打人。

话说回到LuaTeX这边。LuaTeX直接把OTP部分功能删掉了。这有几方面的考虑,比如说LuaTeX只支持Unicode,那么编码转换之类的东西其实就没用了。这确实没什么遗憾的。不过,OTP这东西确实依旧很好玩。因为它的设计模式在一定程度上,和Harfbuzz相似。但是显而易见的是,OTP比Harfbuzz要出现的早。所以,OTP曾经是我在思考复杂语言处理时候,研究的一个具体对象。

LuaTeX的核心钩子的那部分,太庞杂了。我暂时就不讲了。

,