QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 7845|回复: 4

转贴“国际化、本土化和中文输出入”

[复制链接]
发表于 2002-10-26 02:04:04 | 显示全部楼层 |阅读模式
国际化、本土化和中文输出入

谢东翰


当我们在发展程序时可能会遇到如下的问题:当一个程序已按照该地区惯用的编码系
统发展完成,已经可以顺利处理该地区的文字语言了。如果这时国外,或使用其它语
文的地区发觉这个程序很好用,而要将它改成适用于他们地区的语文时,一个很常见
的做法就是设法取得该程序的原始码,然后逐行去改,将隐藏在原始码中的文字处理、
讯息显示等部分全部改成当地的语文与编码系统,最后还要重新编译程序,才能让它
上路。

在这里很明显我们见到一个问题,要让一个程序可以适用于当地的语文与编码系统,
必须直接去改程序代码。万一该程序正持续发展中,未来出新版本时,整个修改工作势
必又要从头来过一遍,相当费时费力,同时也很不容易追赶程序原作者的发展脚步。

为了解决此问题,在 UNIX 的世界中,便逐步形成了「程序国际化」与「数据本土化」
的标准,让世界各地的程序开发者得以遵循。在此标准之下,程序代码只要写过一遍,
就可以适用于所有的语文与编码系统,只要系统有支持该语文与编码系统所需的「本
土数据」即可。简而言之,这里所采取的概念就是「程序」与「数据」分离并分开维
护的方式。

「程序国际化」简称 I18N,其意为 InternationalizatioN 一字中头尾字母 "I" 与
"N" 中间夹 18 个英文字母,故名。它是在系统底层的函式库 (即 libc 函式库) 中
实作一组标准的函式接口,可以让程序存取该地区语系的种种信息。有了这些信息,
程序本身不仅可以不需要修改,就足以处理各国的语文,同时程序本身甚至连各地区
语文的各项细节 (如编码方式 .... 等) 都不需要知道,因为这些全部都是由系统函
式库提供的。

「资料本土化」简称 L10N,其意为 LocalizatioN 一字中头尾字母 "L" 与 "N" 中间
夹 10 个英文字母,故名。它是将地区语文的各项细节数据分门别类,安装在系统底
层的数据库中,以便让系统函式库存取,以提供给上头的应用程序使用。这些用来描
述各地区语文的数据,我们称之为「地区环境数据库 (locale)」,或简称「地区环境」
它们包括以下的类别 (categories):

   1. LC_COLLATE: 该地区文字排序规则,以及正规化表示式 (regular expression)
      的比对依据。

   2. LC_CTYPE: 该地区所使用的编码系统、字集、与文字分类、转换等信息。

   3. LC_MESSAGES: 各应用程序区域化的讯息显示。

   4. LC_MONETARY: 该地区所通行的货币格式。

   5. LC_NUMERIC: 该地区所通行的数字表示格式。

   6. LC_TIME: 该地区所通行的时间、日期表示格式。

对于同一个地区语文而言,除了 LC_MESSAGES 之外,其它所有的类别都是固定的,不
会随应用程序的不同而有改变。故这些类别的数据就只需准备一份即可,它们是由系
统底层函式库直接提供,可以让所有的应用程序分享。至于 LC_MESSAGES 讯息显示的
部分,由于各应用程序的讯息都不同,故这部分的数据是由应用程序提供。

在这些类别中,决定一个程序是否在该地区已「本土」化的最重要因素,一是 LC_CTYPE,
二是 LC_MESSAGES。前者赋与程序处理该地区文字的能力,后者赋与程序用该地区的
语文来显示的能力,故底下我们就针对这两个类别作更进一步介绍。

   1. LC_CTYPE 类别:

      LC_CTYPE 与文字处理有关,它让程序可以在不知道该地区所采用的编码细节之
      下,进行文字的处理。它包括以下的信息:

         * 该地区所使用的字集。所谓「字集」就是指一群文字符号的集合,换言之
           就是该地区会用到的所有文字符号。

         * 该字集所采用的编码方式。一般而言,一个编码方式所能容纳的字数是固
           定的,故当我们谈到某个编码系统时,会自然而然将它所代表的字集联想
           在一起。但稍后我们将看到,其实二者的观念是分开的,特别是在 GNU/Linux
           的系统中 (使用 glibc-2.2.X)。

         * 该字集中每个字的分类与转换。这一点其实在使用拼音文字的语系中比较
           有意义,而在使用象形文字的地区 (如亚洲语系) 则意义比较不那么大。
           这里指的是拼音文字中字母大小写的转换、是不是数字 (阿拉伯数字或十
           六进位数字)、是不是标点符号、是否可以印出、是否为计算机句柄 ....
           等等。由于计算机的发展起源于使用拼音文字的西方世界,故当他们在制定
           C 语言等标准函式库接口时就特别将这一点列入考虑。显然这些分类转换
           规则会随着地区语系的不同而不同。而在使用象形文字的地区,也许没有
           所谓大小写的分别,但仍然可以大至依既定的规则填入分类表中。

         * 多字节字符与宽字符的转换。这是特别为亚洲地区,使用大量非拼音文
           字的地区而制定的。因为这些地区所使用的文字符号数目,大大超越了单
           一一个字节 (即 8 位) 所能表示的范围,因而往往需要依一定的编
           码规则,将多个字节合起来代表一个字。然而,在程序中往往不会有这
           些编码规则的信息,这使得该程序无法从一个字节串行中辨认出一个一
           个的文字。因此系统就提供了这一组多字节字符与宽字符的转换机制。
           由于每个宽字符所占的字节数是固定的,因而一个宽字符就代表一个文
           字,不管它原先在多字节字符形式时是由几个字节所组成的。因此,
           程序本身可以完全不需要知道各地区的编码方式,就能采这种方式逐字处
           理文字,而这些详尽的编码辨识与转换工作就全部交由系统底层函式库来
           完成了。这正是程序国际化最重要的关键。

   2. LC_MESSAGES 类别:

      此类别与程序讯息显示有关。由于各程序会显示的讯息都不相同,故这些讯息
      必须由程序本身提供,而不能像其它类别一样由系统函式库提供。在一个国际
      化的程序中,程序讯息的部分是与程序代码本身分开维护。在实作上,我们将程
      式所有的讯息集中放在一个文件档中,而该文件文件的讯息开始时只会用程序原
      作者惯用的语言来表示。如果我们希望该程序也能显示其它语文的讯息时,我
      们只需要去做翻译的工作即可,而不必真的去修改程序代码本身。因此,讯息翻
      译与程序维护可以分头进行,翻译的工作不需要由程序原作者、或有经验的程
      式设计师来做,只需他熟悉该语文,并对该程序有一定的熟悉度即可。故基本
      上,任何人都可以参与翻译的工作。

      当程序编译安装完成后,已翻译成各国语文的讯息文件也会一并安装入系统的区
      域化数据库中。当程序启动,需要做讯息显示时,它会呼叫系统提供的函式介
      面,依目前的语系设定 (见后述) 来正确抓取该语文的讯息并显示出来。万一
      目前的语系设定找不到相对应的讯息翻译文件时,则程序会自动以其原始的语系
      来显示。




地区环境数据库名称和语系设定

各地区所属的地区环境数据库名称格式如下:

        {语系名}_{地区名}[.{编码系统名}]

其中 [.{编码系统名}] 有时候会省略。以我们台湾地区所使用的为例:

        zh_TW.Big5

其意即为「中文语系」(zh)「台湾地区」(TW)「使用 Big5 编码系统」。如果将后头
的 [.{编码系统名}] 省略掉,就是这个样子

        zh_TW

那这样的地区环境数据库是用什么样的编码系统呢?就依不同的 UNIX 系统而有不同
了。在大部分早期的 UNIX 系统中,用的可能是 EUC-TW 编码系统,即 ISO11643,而
在 GNU/Linux 系统中,用的则是 Big5,原因是 Big5 是目前台湾地区使用最广泛的
编码。

如果我们不特别做语系的设定,则程序在启动时,会以系统预设的语系来运作,一般
而言其地区环境数据库名就是 "C" 或 "POSIX",也就是原始 C 语言所采用的编码系
统 (ASCII) 与英文讯息等等。如果我们希望改变程序运作的语系,则我们必须在程序
启动前先做好环境语系的设定,也就是设好各类别的环境变量。例如:

        LC_CTYPE=zh_TW.Big5;    export LC_CTYPE
        LC_MESSAGES=zh_TW.Big5; export LC_MESSAGES

经过如上的设定后,则之后我们在此 shell 下启动程序时,程序就可以处理台湾地区
的 Big5 文字,同时讯息显示也会是台湾地区 Big5 中文。万一我们希望程序可以处
理 EUC-TW 的文字,但仍以 Big5 中文显示讯息时,就这样设定:

        LC_CTYPE=zh_TW.euctw;   export LC_CTYPE
        LC_MESSAGES=zh_TW.Big5; export LC_MESSAGES

而其它类别的设定方式依此类推。

在很多情况下,我们通常会希望一口气将所有的类别设定成相同的语系,也就是让我
们的整体环境全部处于同一个语系下。当然我们可以用上述的方式一个个类别分别设
定,但除此之外系统还提供了另外两个环境变量,以方便我们的作业。一是 LANG,另
一个是 LC_ALL。例如我们这样设:

        LC_ALL=zh_TW.Big5; export LC_ALL

其效果就完全等价于将所有的类别全部设定了。而 LANG 的用法也是一样,所达到的
效果也类似,但意义稍有不同,这里要留意优先级的差别。一般系统对这些环境变
数的优先级是:

        LC_ALL > LC_* > LANG

也就是说,任何一个 LC_ 类的变量设定后,会使 LANG 的设定的相对应类别失效。
如果我们完全不设任何的 LC_ 类的环境变量,只单单这么设

        LANG=zh_TW.Big5; export LANG

则所有的类别都会以 LANG 的设定来运作,除非我们特别去设了某个 LC_ 的环境变
数,如此这个类别就会以新的设定来运作 (但其它的类别不变)。相似的道理,如果
我们设了 LC_ALL 的环境变量,则所有的类别设定,包括 LANG 的设定全部会失效,
而改以 LC_ALL 的设定来运作。




GNU/Linux 下的实作方式

长久以来,中文化的问题一直是两岸三地 GNU/Linux 使用者所面临的一大挑战。在过
去我们所谓「中文化」的方式,就是将需要处理中文的程序,如终端机、文字编辑器、
邮件程序等的原始码拿来,一行行改,改成可以处理我们的 Big5 码。然而之前我们
也提过,这样的方式相当费时费力,而且每个程序都要修改,也难以跟上国外程序发
展团队的脚步。

直到近两三年来,GNU/Linux 的 I18N 与 L10N 环境发展开始起步,我们也才能依循
这些标准,逐步建构我们的中文环境。我们认为,遵循这样的标准来建构中文环境,
才是彻底的解决之道,我们不能自己关起门来,自行实作一套独特中文环境,因为这
不仅事倍功半,同时国外的程序开发团体也无法直接支持我们。只要按照 I18N 的标
准来发展程序,不仅可以马上使用我们的中文,而且也可以在别的语系下使用。

GNU/Linux 的 I18N 环境的发展,到了去年中 glibc-2.2 系列正式问世后,才算完全
成熟。它不仅完全支持 Unicode 环境,同时在 I18N 与 L10N 方面还拥有许多先进的
特色,兹简述如后:

   1. glibc 内部的编码转换系统 (iconv) 拥有共同的「基底字集」,该基底字集采
      用 UCS4 编码,目前仍持续扩编当中,理论上将可以函盖世界上所有已知的编
      码系统的转换对应。透过基底字集,可以达到完善的转码机制。同时,由于在
      各语系下其多字节编码转成宽字符时,其实就是转成 UCS4,这在将来 Unicode
      通行时,将有利于数据的处理。

   2. glibc 内部拥有数量庞大的编码转换表,大部分是各编码系统与 UCS4 的转换
      用,也有一些是用于不同编码间直接转换。所有的转换表皆采动态模块加载的
      方式供应用程序使用,故只有在需要时系统才会自动加载所需的转换表来执行,
      使用完毕后可以卸下,不会浪费内存空间。

   3. glibc 拥有完整的 I18N 过程调用接口,以及完整的 Unicode 输出入与处理的
      呼叫接口。

   4. 在地区环境方面,glibc 将「字集」与「编码」的概念分开。一个地区环境资
      料库有一个明确的字集,代表这个地区语文可能会使用到的所有文字符号,而
      这个字集可以自由选择一个编码系统来套用。例如我们台湾地区的字集包含所
      有的中文字 (简繁体都有),如果我们选用 Big5 编码,则地区环境数据库名
      称就是 zh_TW.Big5;若我们选用 EUC-TW 编码,则名称就是 zh_TW.euctw;
      当然我们甚至可以选用 GB2312 或 Unicode 等编码来套用。

      然而,要注意的是,由于各编码所能包含的字数是固定的,同时它们也只能包
      含特定的字集,因此,仅管我们的中文字集包含了所有的中文字,但一旦选定
      编码系统后,其所能使用的中文字自然仅限于该编码系统所包含的范围。因此,
      假如我们选用了 Big5,就表示在此环境下我们无法使用简体字;反之若选用
      GB2312 亦然。

   5. glibc 中各地区环境预设的编码系统与传统的 UNIX 系统稍有不同。所谓的
      「预设编码系统」指的是在 "{语文名}_{地区名}" 这样的地区环境数据库名称
      中,所采用的编码系统。传统的 UNIX 系统中所采用的预设编码系统多半是依
      照官方或业界的标准,例如在台湾地区就是 EUC-TW。而在 glibc 中,则是以
      当地最广泛流通的编码系统做为预设,故在台湾地区就是 Big5。

      更进一步地,glibc 会自动将未登录的编码系统名称,改以其地区环境的预设
      编码系统来取代。例如我们将语系环境设定为 zh_TW.euctw,由于 "euctw"
      在 glibc 内部已有登录,故它就会采用 EUC-TW 做为此环境下的编码系统。万
      一我们将语系环境设定为 zh_TW.unknown,由于 "unknown" 一字没有登录,故
      glibc 会自动以 zh_TW 预设的编码系统 Big5 来取代。

   6. 在讯息显示方面,各应用程序的讯息翻译只需依各语文地区分别保留一份即可,
      不需要分别为不同的编码系统都保留一份。以台湾地区中文为例,我们只需要
      一份 zh_TW 的讯息即可,至于它是用 Big5 写成的,或 EUC-TW 写成的都没关
      系。假如它原来是以 Big5 写成的,但我们却希望以 EUC-TW 来显示时,glibc
      会自动为我们做好转码的工作。

      也许有人会问,那我们只需要保留一份 zh (即中文) 的讯息就好了嘛,这样岂
      不是两岸三地都可使用了?然而这么做并不恰当,原因是两岸三地因历史背景
      与文化的隔阂,使得它们各自发展成独特的语文,或称「地区性方言」,对同
      一个句子的翻译,可能两岸三地的翻法都各自不同。故我们不能单纯用转码的
      方式,直接将台湾地区的翻译转成简体字供对岸使用,而必须为他们分别保留
      一份他们自己的讯息翻译。

   7. 在讯息翻译的维护工作,以及系统函式的呼叫接口上,各 UNIX 系统的实作方
      式都不尽相同。而在 glibc (或所有的 GNU 系统、程序) 中,则统一使用 GNU
      gettext,以方便程序撰写以及后续的翻译维护。

   8. 在地区环境数据库中,除了上述那几个传统的类别之外,新一代的 glibc-2.2
      还扩增了以下的类别:

        LC_PAPER,
        LC_NAME,
        LC_ADDRESS,
        LC_TELEPHONE,
        LC_MEASUREMENT,
        LC_IDENTIFICATION

      这些是根据 ISO/IEC JTC1/SC22/WG20 N690 (1999/06) 的新规范而来,用以描
      述更多的地区性惯例,如住址格式、电话号码格式、抬头称位 .... 等等。




X Window 的国际化环境 (Xi18n)

Libc 的国际化与本土化是整个 UNIX 系统的语文处理的基础,其它应用程序都是以此
基础出发往上延伸发展,图形接口的 X Window 系统亦是如此。同样的,X Window 系
统所面临的课题也是在于文字处理与讯息显示这两大方面。就讯息显示方面而言,过
去在 libc 的 I18N 与 L10N 标准尚未确立前,曾一度使用资源档 (X Resources) 来
存放讯息的翻译,唯此方式普及率不高。现在有了 I18N 与 L10N,只要使用 LC_MESSAGES
类别,就能达到所需的目标。

但在文字处理方面就复杂许多,主要是文字的输出与输入两方面。在图形接口中,不
同的文字需要不同的字形来显示,故为了要完整显示一个地区所有的文字符号,往往
需要同时使用许多不同的字型才能达成。故在 X Window 的地区环境定义中就多了一
个字型集 (FontSet) 的定义。以我们的 zh_TW.Big5 地区环境为例,在使用 XFree86
的 X Window 系统中 (包括 GNU/Linux),我们的字型集就包括了一个 ISO8859-1 的
字型,以及一个 BIG5-0 的字型,分别用于显示英文与 Big5 中文。但在其它使用非
XFree86 的 UNIX 系统中,其字型集的定义则各有不同。

有了字型集的定义,X Window 系统就会依据 libc 的 LC_CTYPE 编码辨识与分析机
制,自动从字型集中挑选适当的字型来显示各个文字。因此, X Window 的应用程序
同样也不需要知道各语文的编码细节,使用字型集就能自动完整地显示出该语文中所
有的文字符号。因而程序可以国际化。

至于文字的输入方面比起文字显示还要更复杂些,这里牵涉到各语系的输入法问题,
故在此 X Window 系统特别定义了一个 XIM (X Input Method) 的协议来做处理,它
同样是以 libc 的 LC_CTYPE 类别为基础运作的。有关这方面的细节,请参阅下一节
「中文输入」的说明。

参考数据:

1. man setlocale, man locale
2. info libc
3. ISO/IEC JTC1/SC22/WG20 N690: [187]
4. Unicode: [188]
5. Xlib Programming Manual, 作者: Adrian Nye,
   出版者: O'Reilly, ISBN 1-56592-002-3




中文输入法

由于一般计算机键盘上的字键数目有限,多半 (远) 少于地区语文所需的文字或符号的
数目,使得在很多情况下无法做到一个按键就对应一个「字」或符号。对于使用拼音
语系的地区而言,由于基本的拼音字母较少,因此可以藉由功能键改变键盘状态,让
同一个字键在不同状态下输出不同的字母。例如在我们一般的键盘中, CapsLock 关
闭的情况下可以打出小写英文字母,反之可以打出大写英文字母。

然而,到了非拼音语系的地区,特别是亚洲语系的国家,光是藉由上述方式也不足已
打出所有的文字与符号了,故在这些地区中通常需要藉助「输入法程序」来完成文字
输入的工作。一个输入法程序主要的工作是拦截使用者所敲入的字键序列,经由查表
或其它方式将这些字键序列转换成该地区文字符号,然后才输出至应用程序。而字键
序列与文字符号之间的对应关系,就形成了各式各样的输入法。而逐一将字键序列组
合出一个个文字符号的过程,就称之为「组字」。

大体而言,我们的「中文输入」就是以上述的方式达成的。以下我们就针对 GNU/Linux
系统来谈中文输入的解决方案。

1. 纯文字模式下的中文输入:

      在早期计算机的内存与运算能力仍十分有限的时候,若要执行 X Window 系统
      多半无 法达到令人满意的效能,故那时候的操作环境多半是在纯文字模式之
      下,而纯文字模 式下的中文输入方案也应需求而一一出现。

      在此模式下,由于一般的文字终端机只能显示英文,故刚我们尝试用中文输入
      法程序来输入中文时,我们必须连带要设法让文字终端机也能显示中文,如此
      才有意义。因此,在此模式下的输入法程序通常会与一个可以显示中文的文字
      终端机连在一起,启动它后就等于进入了一个「中文输入输出」的环境。而且,
      一个能显示中文字的中文终端机程序,往往比输入法本身还要重要。

      一般而言,文字模式下的输入法并没有特殊的规范或协议,程序所要做的,只
      有取得使用者的字键输入,再将中文输出到「标准输出 (standard out)」管
      道,系统自然会将这些文字喂入应用程序中。只要应用程序能够接受并处理 8
      位字符码,则不会有任何问题。

      这类文字模式下的中文输入法与中文终端机程序种类很多,早期以王佑中先生
      所发展的 chdrv 为主要的代表,它是一个 GNU/Linux 下的中文终端机、输入
      法的程序。另一个在同时期的类似程序为 yact, 它与 chdrv 的不同点在于 chdrv
      是直接去控制 tty 装置以仿真出中文终端机,而 yact 却是以显示卡绘图函
      式库 svgalib 为基础,将纯文字模式的终端机转为图形模式以显示中文字。
      这些早期的中文输入系统各自有其缺点,而随着时间的流逝也渐渐没有在维护
      了,但其它类似的中文软件却相继出现。它们或是以早期的中文输入系统为基
      础,针对其缺点加以修正,或是引进新的设计概念,使其有较好的功能与较多
      的输入法支持。这类的软件包括 bcs16、jmce、jmcce .... 等。至于 FreeBSD
      系统上,有早期常见的 big5con,以及后来出现的可显示、输入 GB 码的中文
      终端机程序 cce .... 等。

      这类用于纯文字模式下的中文输入系统,由于需要将原本的文字显示转为图形
      显示,如此才能画中文字。然而转换成图形显示的方式可能依系统的不同而有
      不同,例如同样在 x86 系统下执行的 GNU/Linux 与 FreeBSD 系统,它们在
      处理终端机程序的方式不尽相同,而且对硬件显示卡的控制方式也有差异,这
      使得分别针对这些系统所设计的中文终端机程序不容易移植到其它系统上去,
      甚至同样在 GNU/Linux 平台上,为 x86 系统所设计的也无法在其它硬件平台
      上编译后执行。这一点与以下将介绍的 X Window 环境下的中文输入法程序有
      很大的不同。尽管如此,这些不同的中文输入系统仍在原始码的层次上互相截
      长补短,彼此吸收对方的优点。例如最近才出现的 jmcce, 它就是改进自 bcs16、
      cce、与 jmce 等中文输入系统,而这也正是自由软件世界中分享、互惠精神
      的一个很好的范例。


2. X Window 下的中文输入:

  2.1. XIM 协定:

      由于近来计算机硬件的进步,使得执行 X Window 系统渐渐可以达到令人满意的
      效能,同时在一般情况下使用图形操作接口往往比纯文字的操作接口方便,故
      有越来越多的使用者转向使用 X Window 的环境,使用 X Window 下的中文终
      端机程序与中文输入法。因此在相对上,纯文字模式的中文输入法使用者较少
      了,而 X Window 下的输入法发展则日渐蓬勃起来。

      在 X Window 的图形接口底下,由于各程序间的交互作用是以「窗口」为单位,
      它们可以藉由标准的 X 协议达到彼此间的沟通,故我们自然而然地可以将中文
      终端机程序与输入法本身分开发展,而不再需要像纯文字模式下将二者绑在一
      起 (然而在早期的确有将二者绑在一起的解决方案,如 cxterm,它是直接自 X
      Window 的标准终端机程序 xterm 修改而来),如此在一个图形桌面上只需执行
      一个中文输入法,就可以对许多中文终端机程序提供中文输入的服务,不但节
      省系统资源,同时模块化的开发模式也让后续维护工作容易得多。

      然而,在 X Window 下的输入法所面临的问题却比纯文字下要复杂许多。由于
      考虑到程序国际化等方面的问题,故 X Window 定义了一组标准的输入法协议,
      称之为 XIM (X Input Method) 协定。此协议是架构在程序国际化 (I18N) 与
      系统的地区环境 (locale) 之上的,故只要遵守此协议,则应用程序就可以在
      不需修改程序代码的原则下,接受来自各种语系输入法程序的文字输入。

      与纯文字输入方式不同的是,在这里输入法程序不预先拦截使用者的字键输入。
      而应用程序与输入法程序之间的关系,就好像客户端与伺服端一样,应用程序
      提出输入请求,则输入法程序提供输入服务。因此,当我们对一个窗口做中文
      输入时,实际上敲入的字键是直接送往应用程序本身,而应用程序在处理它之
      前,会先经由 XIM 协议将这些字键序列送往输入法程序,然后由输入法程序那
      边取得中文字。故在此协议下,应用程序又称之为 ``XIM client'',而输入法
      程序又称之为 ``XIM server''。

      在一个 ``X Window 的显示设备 (display)'' 中 (这里意指一个屏幕、一个键
      盘,再加一个鼠标,也就是一个 X Window 终端桌上环境),可以同时执行好几
      个 XIM server,它们可以输出不同语系的文字 (例如有的可以用来打中文,有
      的可以打日文),或其中有几个可以输出相同语系的文字。而 XIM client 要选
      那一个 XIM server 来使用,必须透过以下两个环境变量的设定:

        export LC_CTYPE={地区环境数据库名称}
        export XMODIFIERS="@im={XIM server 名称}"

      其中前者指定了语系环境,后者指定了要用那一个输入法程序。所有的 XIM client
      在启动之前必须先有上述的环境变量设定,启动后才能接受该 XIM server 的输
      入。

      一般 XIM server 所显示的信息可以分成以下三类:

         A. 组字信息: 显示于 XIM server 组字的过程中。
         B. 状态信息: 显示 XIM server 目前的状态。
         C. 其它辅助信息: 例如菜单选单或在线文件说明等。

      其中依组字与状态信息显示的位置不同,就形成了各种操作接口 (input style),
      供使用者方便使用。其中包括:

         A. Root: 此二信息都显示在 XIM server 的主窗口内。
         B. OverTheSpot: XIM server 会在 XIM client 的输入光标附近开启一个
                  小窗口,以显示组字信息。如此使用者在打字过程中眼睛就不需
                  要时时去看 XIM server 主窗口的组字信息。
         C. OffTheSpot: XIM client 会在自己的窗口中开出一块区域,让 XIM server
                  来显示其组字信息。此区域通常是在 XIM client 窗口的底下。
         D. OnTheSpot: XIM server 提供必要的数据给 XIM client,让它用自己的
                  方法来画 XIM server 的组字信息。这通常是给有特别需求的 XIM
                  client 选用。

      其中 Root 模式是最简单的方式,一般而言所有的 XIM server 与 XIM client
      都会支持,至于其它的模式则不一定。必须 XIM server 与 XIM client 都同
      时支持的模式才能使用。如果二者同时支持几种模式,则当二者开始连系,准
      备让使用者输入时,它们就会先协调好,以挑选最佳的模式来用。当然,很多
      时候使用者也可以在 XIM client 这边指定要使用那一种模式。

      由于 X Window 环境下有较好的人机接口,因此大部分的输入法程序都是在 X
      Window 下运作的。早期的输入法程序可能不支持 XIM 协议,但近年来新发展
      的输入法程序几乎都支持 XIM 协议,以下就几种常见、可以做中文输入的输入
      法程序稍作介绍。


2.2. XCIN (X Chinese INput method):

XCIN (http://xcin.linux.org.tw) 可能是台湾地区最普及的一个输入法程序。它最
早期是由 刘德华 (Edward Der-Hua Liu) 先生发展的 (1994 年 10 月),那时它并不
支持 XIM 协议,直到 1999 年全新改写后才开始支持。历经多年的延革,并加入了多
位网友的贡献,使它逐渐成为一个稳定且功能齐备的输入法程序, 目前由作者维护。
其特色包括:

   A. 支持 BIG5, BIG5HKSCS, 与 GB2312 等多种编码方式。使用时只要在不同的
      地区环境 (LC_CTYPE) 下启动它,即可自动采用该语系的编码来做输入。

   B. 支持动态外挂式输入模块,让我们可以依需要开发不同的输入法模块,
      以支持不同的输入法。目前 XCIN 套件内含三个输入法模块:

         i. zh_hex:    内码输入模块。
        ii. gen_inp:   一般性输入法模块,以查表方式进行组字,适用于字根类
                       型的输入法。
       iii. bimsphone: 自动猜字注音输入法。它以 libtabe 做为猜字引擎,经由
                       字词的分析辞库查询完成自动猜字动作。

      除此之外,由其它计划所发展的 XCIN 输入法模块计有:

         i. 酷音中音输入法 (http://chewing.oio.cx/)
            它是由中研际信息所徐赞升博士指导、龚律全与陈康本所设计的输入法
            模块。它也是一个自动猜字的注音输入法,拥有比 bimsphone 更方便的
            功能,使用 上与 Microsoft 平台上常见的自然输入法很接近。

   C. 支持多种输入法。除了上述的内码输入与自动猜字注音输入法以外,还支持了:

         1. 仓颉输入法 (BIG5, BIG5HKSCS, GB2312)
         2. 行列 30 输入法 (BIG5)
         3. 拼音输入法 (BIG5, GB2312)
         4. 简易输入法 (BIG5)
         5. 一般注音输入法 (BIG5, GB2312)
         6. 双拼输入法 (GB2312)
         7. 五笔输入法 (GB2312)

         另外,一些商业公司也提供了适当的输入法表格,在其特定的版权限制下,
         可以在 XCIN 底下使用。其中包括了大易输入法、呒虾米输入法 .... 等等。

   D. 支持 Xi18n, XIM 协议与 Root 和 OverTheSpot 输入模式。

   E. 拥有丰富多样使用者自定选项。

   F. 可以跨平台编译执行,其中包括 GNU/Linux, FreeBSD 与 HP-UX。

当然,XCIN 仍不是一个完美的程序,未来仍有相当大的改善空间,主要包括: Unicode
与更多编码系统的支持、输入法模块功能改进、可同时处理多个地区环境 XIM client
的请求、更多 UNIX 平台的移植等等。



2.3. Chinput

这是一个针对 GB 编码与大陆地区使用者习惯而设计的中文输入法,其设计者为于明
俭先生。它是以 cxterm 为基础发展出来的。它同样支持 XIM 协议,与 XCIN 相较,
它具备较佳的拼音输入功能,有较好的图形操作接口,同时也支持 GB、Big5、JIS
(一种日文的编码) 与 KS (一种韩文的编码) 等编码方式,以及许多常见的输入法表
格和方便的输入功能,是一支相当优秀的中文输入法程序。

参考数据:

   1. Xlib Programming Manual
   2. XCIN 发展计划.
   3. libtabe 计划.
   4. 酷音输入法计划.
   5. Chinput.
   6. 中文 HOTWO.




中文输出


简介

本小节的重点,主要在中文文件的排版与打印方面。在 UNIX 世界中,长久以来已不
乏排版与打印的工具,例如功能强大的幕后排版系统 TeX/LaTeX,用以预览、显示、
以及打印的文件图形化语言 Postscript,以及在自由软件世界中常见的 Postscript
解译器 Ghostscript 及其附带的打印机与其它外围装置的驱动程序 .... 等等。

然而,要让这些排版与打印工具可以处理中文 (或其它多字节的文字) 却是一项难
题,主要是在于文字的编码方式以及字型方面。就以中文为例,由于在一般的计算机装
置 (如打印机) 或计算机软件并不内建数量庞大而且笔画复杂的中文字型,故当我们要
做中文输出时,必须要有特别的处理方式。例如我们希望在印一份纯文字的中文文件,
我不能直接将它送交纯文字打印机去打印,因为这些打印机多半认不得中文编码,也
没有字型可用,故它最多只能将送来 的中文编码拆成一个个连续的 ASCII 或 ISO8859-1
的编码,再用其内建的 ASCII 或 ISO8859-1 字型印出来,结果就是印出一连串的乱
码。

为了解决此问题,通常当我们要做打印时,不论是印已编排好的文件或纯文字,我们
多半要做如下的处理: 辨认出文件内的所有文字,中文字的部分就去找适当的字型,
将代表该字的字型 (或说该字的「图案」) 画在该文件内,最后处理完后原本的文件
(或文字文件) 就成为一个「图形文件」,最后才将该「图形文件」送印。因此,在很多情况
下,印一篇中文的文本文件,其实是印一份内嵌了中文字型的图形档案。图形文件的格
式有许多种,但在自由软件的世界中,其最终输出的格式通常是 Postscript。故以下
我们就以此为中心,简介自由软件世界的中文输出方案。


图形输出格式: Postscript 与 PDF

Postscript 是早年 Adobe 公司与频果计算机公司所合作开发的一种描述式语言。该档
案的内容看起来就是一大堆奇奇怪怪的语法与关键词 (也就是说,它看起来像一个纯
文字文件),描述了一张纸上那个坐标要画一个点、那里要画一条线、线的粗细、颜色、
还有那里要摆一个文字 (这里指多半的是 ISO8859-1 的文字)、字的大小、形状、字
型 .... 等等。而这些描述式的语言,必须要由懂得此语言的程序或外围设备来读,
才能从中组合出一幅完整的图案。之所以用 Postscript 做为最终的送印图档格式,
我认为主要是因为它有很好的可移植性 (因为它在一般人或程序看来只是纯文字文件,
而不是二进制文件),而且其语法有很高的弹性与延展性,使得我们可以轻易将图案缩
放而不至于失真。同时,Postscript 也是业界文件输出格式的重要标准,早期有许
多学术论文与排版印刷工作的最终输出都是 Postscript,甚至有许多打印机直接就
可以读懂 Postscript, 故它们可以直接打印 Postscript 的文件,而不需要额外的
驱动程序。

另一个让自由软件世界采用 Postscript 为最终输出形式的重要理由,是因为
Ghostscript 软件。它是一个可以读懂 Postscript 语言的解译器,更重要的是它内
含许多驱动程序,可以将 Postscript 文件转换成各种形式输出,包括许多打印机的
驱动程序,使得这些不懂 Postscript 语言的打印机得以顺利打印文件。除此之外,
Ghostscript 还有 X Window 的绘图模块,可以让 ghostview、gv 等程序在 X Window
的环境下显示 Postscript 的文件;它还有可以将 Postscript 转换成其它图档格式
(jpeg, png, tiff, ....)、甚至可以送交传真的 faxg3 格式 .... 等等 (因此,当
我们要用 modem 传真文件时,我们可以先将该文件的 Postscript 档案准备好,经由
Ghostscript 程序转换后送出)。故 Ghostscript 可以说是一个功能相当强大的
Postscript 转换引擎。

由于 Postscript 只是一种图档格式而已,除非我们熟悉它的语法,否则我们很难直
接编写、修改 Postscript 的文件,也无法轻易在 Postscript 文件中搜寻文字,更
难以用鼠标剪贴的方式将 Postscript 文件中的文字剪贴到别的窗口中。为了弥补这
些缺点,故近年来 Adobe 公司又另外发展了一套称为 PDF 的文件。它同样包含了
Postscript 所有的优点 (然而它是个二进制文件,而非纯文字文件,这一点与 Postscript
格式不同),也弥补了 Postscript 的不足,其中包括:

   1. 由于 PDF 的文件有压缩过之故,使得它的大小比起相同的 Postscript
      文件要小得多。
   2. 在 PDF 浏览器 (如 xpdf) 中显示 PDF 文件时,速度比起用 Postscript
      浏览器 (如 gv) 来显示 Postscript 要加快不少。
   3. 用 PDF 编辑器可以很容易地直接修改 PDF 文件,也可以直接将 PDF
      文件中的文字直接剪贴到别的窗口中。
   4. PDF 文件还支持索引、hyper-reference、及 bookmark (目录) 的功能。

由于这些优点,故在这一两年来它的普级率迅速上升,许多原本采用 Postscript 的
学术文件也逐渐改采 PDF 了,连近年来新版的 Ghostscript 软件也能读懂 PDF 的
格式。 然而在自由软件世界中,现阶段 PDF 仍然不是最终输出的格式,特别是在印
表方面, 很多时候仍然要先转换成 Postscript 之后才能送印,而许多绘图程序的
打印输出也多 半还是 Postscript 而非 PDF,我想主要是因为对自由软件世界而言
它还太新,还需要一段时间才会有完整的支持。



中文字型的转换与内嵌

不论是 Postscript 文件或 PDF 文件,都可以直接内嵌所需的字型,也可以只提示所
需的字型名称与每个字在字型文件中的编码索引等。后者的档案大小当然比前者来得小,
但前提是文件内所使用的字型名与字型规格要有一个通用的标准,如此该份文件才能
在各种环境下阅读与打印。故一般只包含 ASCII 或 ISO8859-1 文字的 Postscript
文件是不内嵌字型的,但是一份中文文件在目前常见的情况下是必须内嵌字型的,其
原因正是目前还没有通用的中文字型与规格。

在早期 (也许 PDF 格式尚未问世的时候),用做内嵌的中文字型来源是一种名为 HBF
的点阵字型,当时有许多程序可以将 HBF 字型转换成 Postscript 可以使用的格式,
然而这类的点阵字型分辨率有限,故内嵌在 Postscript 文件中往往不够美观,特别
是当我们要做有限度的文字缩放时更是惨不忍睹。后来,由于 TrueType 字型逐渐普
及,同时可以处理 TrueType 字型的引擎 -- freetype 函式库的问世,许多基于该函
式库的 TrueType 字型转换程序一一开发出来,使得它成为 Postscript 与 PDF 内嵌
字型的最重要来源。内嵌了 TrueType 转换字型的文件不但比起过去要美观许多,且
由于 TrueType 本身就具有可缩放的特性,故我们可以轻易产生高分辨率的转换字型,
使得文件在有限度的缩放下仍不失真。同时由于文鼎公司对自由软件世界的支持,慷
慨地捐赠了两套 TrueType 中文字型供大家自由使用,让我们在中文文件输出的问题
上得以彻底解决。

然而,最近我们开始慢慢体认到,使用内嵌字型的文件输出仍然不是最佳的解决方案
(然而,对许多人或许多应用场合而言,它已经是相当不错的解决方案了)。最佳的解
决方案仍然是希望以不需内嵌中文字型的方式,其优点除了可以让输出的文件档变小
以外, 同时还可以保证在任何尺度上的缩放而不失真。由于内嵌在文件中的字型在很
多情况下是将 TrueType 字型转成点阵字型之后,才进行内嵌 (例如在 CJK-LaTeX 所
编译的文件中内嵌了由 TrueType 转成 PK 的点阵字)。仅管由转换过来的字型有相当
高的分辨率,但再高的分辨率也是有限的,故在做大尺度的缩放时仍然会失真。还有
一点就是,就目前的测试结果,若在 PDF 文件中使用内嵌字型则无法自 PDF 文件中
剪贴文字到别的窗口或文件中,其原因可能不单纯,也有可能是 PDF 文件中的字型编
码没有符合 Adobe 的规格所至。要做到真正不内嵌中文字型于文件中,有许多工作要
做,其中包括:

   1. 要有一套统一的字型名称与规格: 这可能是最令人头疼的部分,因为这里卡到
      了授权问题。由于 Postscript 与 PDF 文件格式是 Adobe 公司开发的,故其
      所用的字型名称都会灌上 Adobe 之名,而这些名称是否能在自由软件世界中,
      以自由软件的游戏规则来运行,将会是个问题,其中尤以 PDF 最为严重。同时,
      在定这些名称与规格时,我们不能关起门来自己定,必须同时与许多团体谈,
      可能包括 Adobe 公司、TeX/LaTeX 开发团队、Ghostscript 开发团队、甚至其
      他与排版、字型相关的计划与 商业公司等。

   2. 要有一个字型的来源: 这一点在现阶段已有初步成果,目前我们已有将 TrueType
      字型转换成 Postscript 所需的 Type1 字型的工具程序,例如 ttf2pt1 或 chpfb,
      ttf2pfb 等。除此之外,另外还有一套称为 t1lib 的函式库,可以用来进一步
      处理 Type1 字型,例如将字缩放、旋转,或将它转换成点阵的格式以用于其它
      的用途 .... 等等。

   3. 如果我们有了 Type1 的字型,我们还可以进一步地将它合成 Type0 的 CID-Keyed
      字型,可用于 Postscript 与 PDF 的文件中。这一点目前仍在讨论阶段,但相
      当具有可行性。理论上,只要透过字型名的 alias (别名) 机制,我们也许就
      可以用此技术直接显示 Adobe 做出的不内嵌中文的 pdf 檔了。而如何定订此
      alias 的标准,仍需进一步讨论。

   4. 我们的文件转换引擎: Ghostscript 要能处理多字节编码、并利用这些字型:
      这一点目前也正积极开发中,例如下一代的 Ghostscript 就有处理多字节编
      码的能力,除了迎接未来的中文 Type1 字型以外,它还内含了一个可直接使用
      TrueType 字型的模块,可以做到不需要字型的内嵌,就可以使用 TrueType 字
      型来显示文件,其原 理是将 TrueType 字型仿真成 Type0 CID-Keyed 字型来
      用。但这可能会面临可移植性 的问题,万一将此文件拿到其它没有安装此 TrueType
      字型的系统下就无法读了。因 此,它目前也同时在开发直接内嵌 TrueType 字
      型的技术,做为因应此问题的配套措施。



中文 Postscript 与 PDF 文件的产生

在 UNIX 或自由软件的世界中,有许多与文书处理与绘图有关的程序可以产生 Postscript
的文件,因为当文件要送印时就需要 Postscript。至于 PDF,在自由软件世界中则比
较少,主要见于文书排版方面。以下就以中文文件的输出为中心,兹简介如下:


纯文字的转换

目前较通用的纯文字文件转 Postscript 格式的程序为由 python 语言所写成的 bg5ps
程序,它所产生的 Postscript 文件采内嵌中文字型的方式,而中文字型的来源即为
TrueType 字型。其实,bg5ps 还有许多其它功能,包括简单的格式化与排版的指令、
同时可以在未内嵌中文字型的 Postscript 中加入内嵌字型。其中后者在早期的中文
打印尤为有用。早期有些应用程序如 Netscape,它可以在窗口中显示中文,让我们观
看中文文件。但当它要将文件输出成 Postscript 格式时,因为没有标准的字型可用,
而它也不会去产生内嵌字型,故最后的输出结果就是将每个中文字拆成一个个连续的
ASCII 或 ISO8859-1 的字符,也就是一堆乱码。这时,bg5ps 程序就可以扮演一个过
滤器的角色,它在这些乱码的 Postscript 文件中安插入内嵌字型,于是一份可正常
显示中文的文件就产生了。可做到类似 bg5ps 的功能的程序还有许多,在此就不一一
详列。

至于将纯文字文件转成 PDF 格式,有一个很类似 bg5ps 的程序 -- bg5pdf,它一样也
是以 python 语言写成的 (外加 PDFLib 函式库),然而与 bg5ps 不同的是,它在文
件中只标示了中文字型的名称 (为不内嵌的 Acrobat Reader 的中文 CID Keyed 字
型),故由它产生的文件可以享有 PDF 文件所有的好处。而在现阶段,它所产生的文
件可以用 xpdf 程序来浏览,只要经过适当的设定,xpdf 会自 X Window 系统中抓取
适当的字型来做显示,故可以避开没有 CID Keyed 字型的问题。但长远来看,我们仍
然需要一套完整的 CID Keyed 字型,如此才能完整解决中文 PDF 文 件的显示问题。


CJK-LaTeX

TeX/LaTeX 是一套功能相当强大的幕后排版系统,它使用类似程序语言的方式,来格
式化并编排文件,并配合 Postscript 的输出,可以轻易达到高品质文件的输出要求。
特别是它容易处理数学符号的特性,使得它特别适于学术文件、书籍、出版的排版工
作。要让 LaTeX 能处理中文,必须在 LaTeX 系统上额外加装一套 CJK-LaTeX 的宏。
顾名思议,此宏可以付与 LaTeX 处理中文、日文、韩文等编码系统的能力,而它也
渐渐成为 LaTeX 的标准之一。而它最后在产生 Postscript 文件时,是采用内嵌中文
字型的方式,其字型来源也是 TrueType。它利用 freetype 函式库的衍生工具 ttf2tfm、
ttf2pk 将 TrueType 字型转换成 TFM 与 PK 点阵字型,前者用于前段的排版工作,
后者则用于最后的字型内嵌。

以 LaTeX 编排的文件也可以转换成 PDF 格式,有两种方式: 一为 pdftex, 它是
TeX/LaTeX 程序的变形,专门用来输出 PDF 格式。另一种方式为使用 dvipdfm 程序,
它可以将 TeX/LaTeX 编排过程的中间产物 -- DVI 档转换成 PDF 格式。所谓 DVI 意
指 DeVice Independent,它是 TeX/LaTeX 编排之后的输出,可以用来转换成各种所
需的格式,包括显示的屏幕上预览 (使用 xdvi 程序)、转换成 Postscript 格式 (使
用 dvips 程序)、或丢给特定打印机的驱动程序送印 .... 等等。不论是 pdftex 还
是 dvipdfm,现阶段所产生的 PDF 文件都是内嵌字型的文件。其内嵌的字型可以是
PK 字型、或 TrueType 字型、或者是 Type1 字型 (若内嵌了 PK 字型则会有大尺度
缩放失真的问题,因为 PK 字型是点阵字型,但若内嵌其它二者则不会)。其中 dvipdfm
目前内嵌 TrueType 字型还不够成熟,相信在不久的将来就会有成果。



LaTeX 的外衣 -- LyX

LyX 是一个以 LaTeX 为基底的一个图形化排版系统,让我们不必须记一大堆 LaTeX
的排版指令,可以直接可视化地在窗口内编排我们的文件,而最后的排版输出才交由
LaTeX 处理。它的中文支持目前正慢慢发展中,包括支持 XIM 协议,使得我们可以
用 XIM server 输入法程序直接在它的窗口内打中文。而它的 CJK-LaTeX 指令的部
分在经过少许的修正后也能正确地搭配使用。



各应用程序与打印系统的整合

如前所述,由于 Ghostscript 可以正确处理 Postscript 与 PDF 的文件,并且可以
将它们转换成各种格式输出,包括许多打印机的打印格式。故使用 Ghostscript 正是
最标准且一致的打印解决方案。除了上述可以产生 Postscript/PDF 文件的程序以外,
事实上还有许多与文书工作相关的应用程序,如办公室软件 KOffice/AbiWord 等,或
绘图软件 gimp、xfig、gnuplot .... 等,它们在做打印输出时都可以产生 Postscript
的格式 (未来也许会有 PDF 格式),故只要经过适当的整合,就能顺利 解决打印的问
题。

至于未来当我们慢慢转形使用「不内嵌」中文字型的文件时,还要再注意各应用程序
所用的字型名称是否与 Ghostscript 所用的一致,这些都需要更进一步的协调与整合
的工作。


参考文献:

   1. A First Guide to Postscript [196]
   2. Adobe PostScript 3 [197]
   3. PDF [198]
   4. Ghostscript [199]
   5. Other resources [200]
   6. TrueType [201]
   7. Freetype project [202]
   8. 李果正
      CJK-LyX 中使用中文 [203]
      CJK/LaTeX enviroment 中文 Type1 及 TTF 的使用 [204]
   9. 字型与文件转换工具
      bg5ps[205]、 bg5pdf[206]、 chpfb[207]、 ttf2pt1[208]、 pdfTeX[209]、 dvipdfm[210]。
  10. t1lib [211,212]
  11. jmcce [213]

致谢: 本文内容感谢李果正先生的参与讨论与帮忙校对 :-))
发表于 2005-12-6 15:41:01 | 显示全部楼层
这个太好了。
回复

使用道具 举报

发表于 2005-12-6 15:54:11 | 显示全部楼层
请问是在哪儿转的? 我想再转,所以需要原地址。谢谢
回复

使用道具 举报

发表于 2005-12-8 09:57:17 | 显示全部楼层
好贴,收了。
回复

使用道具 举报

发表于 2006-9-9 11:28:46 | 显示全部楼层
强文,收藏,认真学习!! :D
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-29 05:20 , Processed in 0.051109 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表