其实这个东西早就该写了,只不过我既是一个懒人,也是一个看不惯不完美东西的人,所以一直不好意思去写。
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 爱好者和我一同来完成这个工作,:)
听说teTex不再继续开发了,XeTex中文处理能力听你这么一说,似乎还不太成熟吧。teTeX的维护者建议使用TeXlive,不知道老兄有和高见?
您可能对 TeX 不大了解。tetex、XeTeX 和 TeXLive 三者,无论在概念和功能上都不是对等的东西。(我在 newsmth 的 TeX 版写过一篇《小谈 TeX 系统的结构与发行版的选择》,可以参考)。
tetex 是一套发行版,TeXLive 也是一套发行版,但其最大的区别不在于核心程序的不同,事实上,发行版只存在维护的问题,而不存在开发的问题,因为所有的程序,包括核心的 tex, etex, pdftex, web2c 到外围的 ps driver, pdf driver 都不是发行版作者开发的,发行版作者只负责编译和打包工作。所以只要核心程序的开发人员仍在开发,那我们的 TeX 就还能用下去。
(XeTeX 正是属于和 tex, etex 对等的核心程序)
前面说了,tetex 和 TeXLive 最大的区别不在程序,那在哪里呢?主要在于对外围宏包、字体、文档等 CTAN 上内容的打包和发布方式的区别。
至于说中文处理能力,现在当然不成熟,但预处理的方法如果仅仅针对中文 (和英文),那还是不难做到完善的,事实上,预处理的方法也是比现在的 CJK 这种 LaTeX 宏包的方式更简洁优雅,也效率更高的方式。
Scribus 中怎样使用复合字体呢,一直没找到。我试着用 fontconfig 来替换某些中文字体的英文部分但是没有效果,应该是思路错了,我 Linux 基础太浅。恳请 Jjgod 指点一下,谢谢。
再次打扰了…… 还是没有搞定 Scribus 的复合字体,唉……
@Bodhi: 抱歉,我自己不用 Scribus,所以这个问题帮不上忙了…
@jjgod: 好的,仍然感谢 jjgod。