XeTeX Chinese Preprocessor 0.2

#### 两个功能

1. 使用 Python 来对 XeTeX 文档进行处理,进行自动的中文与英文字体的切换。
2. 消除两行连续的中文之间多余的空格。

#### 如何获取

从下面的地址下载:

[http://xcp.googlecode.com/svn/trunk/xcp.py](http://xcp.googlecode.com/svn/trunk/xcp.py)

可以到 [http://code.google.com/p/xcp/](http://code.google.com/p/xcp/) 查看相关信息和提交 Issues。

#### 使用方法

现在这个版本应该可以处理任何包含中文的 XeTeX 文档了。使用方法很简单,在文档的导言区加上:

\usepackage{fontspec}

\setromanfont{Garamond Premier Pro} % 此处指定英文字体

\newfontinstance\zhfont{SimSun} % 此处指定中文字体
\newcommand{\zh}[1]{{\zhfont #1}}

然后调用:

python xcp.py foo.tex > bar.tex

编译得到的 bar.tex 即可。

#### 几点说明

1. 默认接受 UTF-8 格式的文档,如果你使用了其他编码,可以修改 xcp.py 第 5 行的 encoding=’utf-8′ 为你使用的编码,在 [http://docs.python.org/lib/standard-encodings.html](http://docs.python.org/lib/standard-encodings.html) 可以找到 Python 支持的所有编码。

2. 默认在 `\begin{document}` 之后才开始处理,到 `\end{document}` 结束处理,所以记住把 `\title{}` 之类放在这中间,其中的汉字才能被处理。如果你用的不是 LaTeX 而是 ConTeXt,可以相应的改成 `\starttext` 和 `\stoptext`。

3. 需要 Python 2.4。并建议把文件格式转换为 Unix 的。

4. 如果需要避免它处理部分代码,则可以使用 `@{}` 标记,这样 `{}` 中间的内容都不会被处理。比如 `@{中文}` 将被转换为 `{中文}`,而不是 `{\zh{中文}}`。

TeX 系统的构建 (2) – 恐怖的 web2c

自从第一部分贴出以来,受到了很多朋友的鼓励,令我感到非常高兴: 看来尽管我拙于表达,对于 TeX 系统的构建感兴趣的朋友还是不少的。不过有一点需要说明:撰写此文的主要目的并非是“构建一个最小的 TeX 系统”,只不过正巧 web2c 系统符合我们讲解的需要而已,我所希望证明的是,TeX 的构建看似复杂,其实也不过是有许多细小的“砖石”一块块搭成,并无什么神秘的地方,尽管大家的兴趣多数是在 TeX 的基础上撰写宏包,但其实参与到 TeX 系统的开发中去也并非那么困难。

web2c 只是用 YACC 写的一套简单的分析程序,由于无法作复杂的分析,所以类似 autotools 的那套“由 A 生成 B,B 生成 C,C 再生成 D”这样化学反应链一般的恐怖过程便被设计出来。

一开始,因为没法直接从 Pascal 代码中分析出其中的变量与函数,所以不得不在一些称为 .defines 的文件中专门说明这些,比如我们如果要用 web2c 转换 etex.p,就得把 common.defines, texmf .defines 和 etexdir/etex.defines 再加上 etex.p 四个文件连接起来送给 web2c 这个程序的标准输入。

然后编写 web2c 的人发现,就算这样还是不好直接通过 web2c 生成的方式搞定所有 C 程序里需要的定义,还是另外把一些内容写在 .h 头文件里,让生成的 .c 程序 #include 它就好了。于是就有一个叫做 texmf.h 的头文件被 C 程序包含,后来这个包含继续复杂化,变成现在这样,C 程序包含 texd.h, texd.h 除了自己的一部分自动生成的内容之外包含 texmfmp.h 和 texcoerce.h,而 texcoerce.h 的内容则是把 web2c 生成的一部分内容再加上一个通用的 coerce.h 连接起来得到的……实在太麻烦也太恶心了,好在我们不需要细究这个,毕竟我们只希望知道,如果要给 TeX 增加代码,对 web 文件的改动,如果增加了变量、函数、过程,则应该在 .defines 文件里增加内容,如果有额外的 C 程序需要链接在一起,则应该找一个被 texd.h 包含的 .h 文件,往里面添加增加全局变量或者函数声明。

分析 web2c/convert 这个 shell 脚本我们可以发现,这个脚本完成了完整的从 Pascal 转换到 C 的过程,一个 tex.p 被分成了三个部分:

texd.h (被其他 .c 文件包含的头文件),事实上,这个文件主要是从对应 .defines 文件里得来,比如 web2c/texmf.defines 就定义了全局变量和函数原型 (prototypes)。对此的分析可以让我们得出结论:如果我们希望把部分模块单独用 C 语言写好,最后再和原来的 TeX 程序链接起来,是可以做到的,只需要在对应的 .h 文件中增加相应的函数声明,并在 Makefile.in 文件中提供正确的链接选项即可。事实上,虽然 eTeX, pdfTeX, Omega 这些 TeX 的扩展都还是用纯 web 语言编写的,但较新的一些扩展,如 XeTeX 和 LuaTeX,都体现了尽量把代码提取出来用 C/C++ 实现的思路。

texini.c: 这是原来的程序中标记了 INITEX 那一部分的代码, 读过 TeXBook 的朋友知道,TeX 可以采用一种特殊的方式把大量的宏定义转换成一种便于以后快速载入的文件 (很像现在的 C 编译器提供的预编译头文件 PCH 的功能),这种文件就称为 format 文件,而用于生成——在这里叫做 dump——这种 format 文件的程序就是initex。以前 Knuth 的设计是,如果我们把标记了 INITEX 的那部分代码编译进去,生成的程序就叫做 initex,专门用于 dump format,如果不编译进去,就是我们日常运行的 tex,只能载入 format 而不能 \dump。熟悉 C 语言的朋友可以想象成,web2c 里把 `#ifdef INITEX` 和 `#endif` 之间的那部分代码提取出来,形成了 texini.c。

顺便说一下,现在的 tex 程序往往都把这个 texini.c 默认就编译进去,不过一定要指定命令行参数 -initialize (-ini) 才会启用这部分功能,事实上平时我们用于生成 format 文件的 fmtutil 这个脚本就是调用 tex -ini 来创建格式的。如果用 tetex/TeXLive,可以打开 kpsewhich fmtutil.cnf 文件查看不同的格式对应的源文件 (如果用 MikTeX,你可以使用 MikTeX Options->Formats 查看),比如我这里 Plain TeX 格式对应的源文件的内容就是:

\input plain
\dump
\endinput

你同样可以用 etex -ini 启动 TeX 系统,输入上面的内容,手动地生成格式。

tex0.c, tex1.c, tex2.c: 在前面我们提到过,原来的 Pascal 代码足足有 3 万多行,自然,转换出的 C 代码也有 3 万多行,设计 web2c 的时候生怕当时的 C 编译器无法一口啃下这么长的代码,就专门开发了一个叫做 splitup 的程序,把完整的程序切分为三个差不多长度的文件——嗯,叫人很汗的想法。

得到这些文件之后就简单了,只要用 C 编译器编译并链接起来就得到我们平时运行的 TeX 程序。

最后是一幅图,把前边叙述的内容作一小结。下次我们将讨论 TeX 系统中的文件搜索与支持它的核心:Kpathsea。

TeX 系统的构建

FreeType 2.2.1 的一点测试

最近 [FreeType 2.2.1](http://download.savannah.gnu.org/releases/freetype/)
刚刚发布,尽管由于 API 的变化 (许多内部函数被隐藏起来了),多数的 distro
并未把系统使用的 FreeType 升级到这一版本——我相信要过很长一段时间才有可能这
么做。但使用源代码编译的版本,我做了一点小小的对比分析。

因为精力有限,只对 FreeType 2.1.10 (目前绝大多数发行版正在使用的版本)
进行了比较,试图给出基于 FreeType 的程序 (如 fontconfig) 应当如何配置字体
才能获得最好的效果的一点建议。而事实上,font rasterizer (字体光栅化工具)
必须和其他的 rasterizer 比较才能看出明显的区别来,例如 ATSUI, Win32 GDI
等等。

同时,我也只对随 Windows 附的 simsun.ttc 做了测试。如果你有兴趣,欢迎分享
更多的测试结果。

测试的截图在 [flickr](http://www.flickr.com/photos/jjgod/tags/freetype/) 上。

经过比较,我们可以给出这样一些建议:

1. 必须打开 anti-alias,gamma 才会起作用。
2. gamma = 0.0 时启用 sRGB (次像素反锯齿) 模式,这种模式要比默认的
gamma = 1.0 显示得更清晰锐利一些。
3. 绝大多数情况下,打开 hinting 能达到更好的效果。
4. 小于 12px 的情况下,关闭 anti-alias,打开 hinting 能使字体勉强可读,
但仍然建议绝对不要使用这么小的字体。
5. 12px 以上,即 12-16px, 18px 的汉字必须使用嵌入的 bitmap。事实上,AA +
hinting 的汉字要到 28px 以上才可以称为比较可读。

Layout Engine 的文档

真的是.. a mess,估计就像 pango maillist 上有的人说的,有能力使用 layout engine 的人都能够直接看 reference 写程序,没能力的都去用 GUI Toolkit 提供的 high-level API 了。

最近看的几个 layout engine 包括:[Uniscribe](http://www.microsoft.com/typography/developers/uniscribe/), [Graphite](http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&cat_id=RenderingGraphite), [Pango](http://www.pango.org) 和 [ICU](http://icu.sourceforge.net/userguide/layoutEngine.html)。最惨的是它们的定位和功能还不一样,有些相互之间还有牵扯。

就是这样居然还有人能把 Graphite, ICU 和 ATSUI 集成起来[给 TeX 用](http://scripts.sil.org/xetex),考虑到 TeX 还是用 WEB (Pascal 的 literate programming 版本) 语言写成的,这真是让人崇拜得五体投地的[强者](http://www.unicode.org/iuc/iuc22/b051.html)啊。

(看了一下强者的 biography,原来自从我出生开始就在 SIL 工作了.. 那么这样我比较不自卑一点。)

更新:看完这篇 [mail](http://mail.gnome.org/archives/gtk-i18n-list/2004-December/msg00010.html),我又很高兴了 🙂

Markdown 的一点翻译

Markdown 是 John Gruber 精心设计的一套文本标记系统,由 Michel Fortin 转换到 PHP 并提供了 WordPress 的插件。这两天抽空翻译了一下 [Markdown][1] 的[基本功能][2]以备学习。感谢 [hlb][3] 的指点,我想下面要做的大概是翻译完整的 [syntax][4] 文件和 PHP Markdown 的[扩展][5]功能。此外,[MultiMarkdown][6] 也是个有趣的东西。

[1]: http://daringfireball.net/projects/markdown/ “Markdown”
[2]: http://daringfireball.net/projects/markdown/basics “Markdown Basics”
[3]: http://hlb.yichi.org/blog “布丁长辈的 blog”
[4]: http://daringfireball.net/projects/markdown/syntax “Markdown Syntax”
[5]: http://www.michelf.com/projects/php-markdown/extra/ “PHP Markdown Extra”
[6]: http://fletcher.freeshell.org/wiki/MultiMarkdown “MultiMarkdown”

噢对了,翻译后的文件在[这儿](http://opencjk.org/~jjgod/document/markdown/basics.php)。