其实这个东西早就该写了,只不过我既是一个懒人,也是一个看不惯不完美东西的人,所以一直不好意思去写。
For the impatient: [脚本在这里](http://www.newsmth.net/att.php?s.460.239183.807.py)
[XeTeX](http://scripts.sil.org/xetex) 是 Johnathan Kew 一开始在 Mac OS X 上开发的一套 TeX 系统的扩展,主要的特点是使用 ATSUI 支持了操作系统 native 的字体,而后使用 ICU 加入了对 complex scripts 等多语言排版的直接支持,算是 TeX 世界中很振奋人心的更新,我也一直在关注着,因为没有 Mac 用,所以不大了解详情。
直到最近 Johnathan 公布了 Linux 系统下的 XeTeX,结合 fontconfig 和 freetype、ICU 一起支持了 Linux 系统下的 native fonts 和多语言排版,并在 Jin Wan Cho (dvipdfmx 的作者之一) 的帮助下扩展了 dvipdfmx,支持 xetex 的“.xdv”输出。所以近期在我的 Arch Linux 上,好好把玩了一阵子 XeTeX (中间的经历,在 [newsmth](http://www.newsmth.net/) 的 [TeX](http://www.newsmth.net/bbsdoc.php?board=TeX) 版和朋友们提过),虽然发现有诸多不便,但仍然觉得这是一个很值得发展的东西。
最大的不便在于 mixed scripts typesetting,即所谓多种语言混杂的排版,因为目前 XeTeX (其实 TeX 也是,只不过无论 [CJK](http://cjk.ffii.org/) 还是 [CCT](ftp://ftp.cc.ac.cn/pub/cct/) 都用一种比较特别的方法绕过了这个问题,此处按下不表) 无论是哪一段文字,都只有唯一的一种字体,你无法给它指定一个复合字体 (combined font),而复合字体的概念在 DTP 软件中是很常见的 (比如 FrameMaker, InDesign, Scribus 都支持),这就造成了混杂排版的困难:每当语言变化了,就必须手动切换字体,比如用 XeLaTeX,通常使用的是 Will Robertson 写的 fontspec 来选择字体,设置正文的字体用:
\setromanfont[字体特性]{字体名称}
上面这里推荐使用汉字的字体,才能比较好的处理中文的断行 (考虑标点符号的避头尾)。
\XeTeXlinebreaklocale=”zh”
\XeTeXlinebreakskip=0pt plus 1pt
然后定义一个英文字体,比如:
\newfontinstance\rmfont{Garamond Premr Pro}
\newcommand{\nc}[1]{{\rmfont #1}}
这样在文档中写的时候是:
中文啦啦啦 \nc{blahblahblah} 中文啦啦啦 \nc{blahblahblah}
一行字还不觉得,英文多了就会很麻烦。目前在 XeTeX 的 mail list 上,已经多次有人 (包括我 ^^|) 提到了这个问题,其实反复思考,这真的不是一个很容易处理的问题,尤其是不仅仅考虑中文和英文两种语言,而是数十种相互字符集范围有交叠的语言时,设计就更费斟酌了,Johnathan 表示他在关注这个问题,但还没有到集中力量解决它的时候,所以我才在这里贴这么一个很 dirty 的 script,其实发现这个问题以后,我反复想了几天,即分析了 XeTeX 的源代码,也去信和 CCT 的作者张林波老师讨论了,最后才决定采用预处理这个方法,觉得这是目前最不伤筋动骨,又能迅速解决问题的方法。
这个脚本就是用来处理中英文混杂的排版,在英文前后自动插入 \nc{} 用于切换字体,你可以在 preamble 定义 \nc 代表的字体。处理时,最 tricky 的部分是中文的标点,其实这一部分在 Unicode 中的代码分布是 [Fullwidth Latin Characters](http://www.unicode.org/charts/PDF/UFF00.pdf) 部分,根本不属于汉字部分。
这是用 Python 写的一个很简单的小工具,从 `\begin{document}` 开始处理,到 `\end{document}` 结束,目前还*不支持*任何命令,所以在正文部分如果有 `\title{中文标题}` 这样的东西,别指望它能正确处理。
此外还有一个功能是在两行连续的中文之间插入 % 以保证源文件中的手动换行不会导致输出结果中出现空白。
这还是一个非常非常 experimental 的东西。欢迎测试,我希望有时间认真写一个 tokenizer 作这个处理,现在的处理是基本上不依赖上下文的,所以能力很弱。另外,还可能在以后加上标点符号的 kerning 处理,类似 CJKpunct 的功能。
当然,我很希望有更多中文的 XeTeX 爱好者和我一同来完成这个工作,:)




