区域设置一词指的是程序环境的一组属性,这些属性取决于用户的语言和文化环境。 其中包括关于哪些字符是字母以及它们的排序顺序、日期和时间的显示方式、十进制数字记录中分隔符的选择(逗号或句点)、货币符号以及程序给用户的消息等信息。
与 POSIX 标准兼容的系统上的国际化和本地化编程接口在 ISO/IEC 9899 标准(ISO C 编程语言)和 IEEE 1003.2 (POSIX.2) 中定义。 与本地化相关的信息分为六个类别:
LC_CTYPE
(表示字母表的字符)LC_COLLATE
(字母表中字符的排序顺序)LC_TIME
(日期和时间的显示)LC_NUMERIC
(数值的显示)LC_MONETARY
(货币符号的显示)LC_MESSAGES
(与用户的通信)LC_ALL
涵盖了所有这六个类别。 虽然 GNU 项目在前五个类别的实现中忠实地遵循了标准,但在第六个类别中,它决定扩展标准。 这是因为标准化委员会无法就消息翻译的处理达成一致,因此标准在这一点上实际上是无法使用的:它仅指定了“是”和“否”的翻译。 因此,GNU 项目开发了自己的方法,即 GNU gettext
包。 gettext
机制使用的已翻译消息目录通常位于 /usr/share/locale/ 目录的子目录中。
以下是一些斯洛文尼亚语系统响应的示例。 这些示例取自 HP-UX,因为 Linux 的本地化目前仍在进行中——GNU libc 2.0 库和后续衍生版本虽然已经提供了本地化的框架,但实现目前仍然滞后,因此目前还不能用 textutils
、fileutils
等软件包中的程序来说明这个概念。
通过将 LANG
变量设置为斯洛文尼亚语区域设置,所有属性都会更改
~> date
Sat Oct 19 22:32:04 METDST 1996
~> LANG=sl_SI.iso88592 date
Sob, 19 okt 1996 22:32:04
我们也可以单独更改它们中的每一个。 如果我们希望保留英文输出、日期格式、十进制句点等,但希望字母的排序遵循斯洛文尼亚语字母表,我们只需更改 LC_COLLATE
即可
~> sort abc.tex
abc
abca
abd
abc
~> LANG=C LC_COLLATE=sl_SI.iso88592 sort abc.tex
abc
abca
abc
abd
当然,LC_COLLATE
并不能解决与排序相关的所有问题。 例如,在对卡斯蒂利亚国王进行排序时,我们希望阿方索九世排在阿方索八世之后,阿方索十世之前。 但这可能已经是人工智能的问题了...LANG
变量通常具有以下形式
LANG=语言[_国家[.字符集]]
其中 语言 是 ISO 639 标准 ISO 639 定义的两位字母语言代码,国家 是 ISO 3166 标准 ISO 3166 定义的两位字母国家代码。 因此,以 ISO 8859-2 字符集书写的斯洛文尼亚语(在斯洛文尼亚使用)的示例是LANG=sl_SI.iso88592
国家和字符集的指定是可选的(当然,这对于在多个国家/地区使用的语言很重要;作者不知道在国外斯洛文尼亚人使用哪种区域设置),因此我们可以简写为LANG=sl
GNU gettext
包提供了一些用于本地化的工具
xgettext
,用于从源代码中提取消息msgcmp
,用于比较两个消息目录msgmerge
,将旧的已翻译消息目录与新的未翻译消息目录合并msgfmt
,将可移植消息目录转换为二进制形式msgunfmt
,与 msgfmt
相反让我们用一个简短的例子来说明如何使用 GNU gettext
包编写本地化程序。
#include <locale.h> #include <stdio.h> #include <libintl.h> #define PACKAGE "zgled" #define LOCALEDIR "/usr/local/share/locale" char main() { setlocale (LC_MESSAGES, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); printf("%s\n", gettext("This is a short example.")); printf("%s\n", gettext("Author: Primoz Peterlin")); return(0); }
xgettext
从源代码中提取屏幕输出xgettext zgled.c
这样我们就创建了一个文件 messages.po。 这是一个普通的文本文件,其中包含消息翻译的框架。# Slovenski prevod zgleda # Primoz Peterlin, <primoz.peterlin@biofiz.mf.uni-lj.si> # msgid "" msgstr "" "Project-Id-Version: zgled 1.0\n" "POT-Creation-Date: 1998-12-06 14:05:53+0100\n" "PO-Revision-Date: 1998-12-06 15:00:00+0100\n" "Last-Translator: Primoz Peterlin <peterlin@biofiz.mf.uni-lj.si>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" "Xgettext-Options: \n" "Files: zgled.c\n" #: zgled.c:13 msgid "This is a short example." msgstr "To je kratek zgled." #: zgled.c:14 msgid "Author: Primoz Peterlin" msgstr "Avtor: Primoz Peterlin"
msgfmt -v -o zgled.mo messages.po
gettext
将会找到它的目录中mv zgled.mo /usr/local/share/locale/sl/LC_MESSAGES
gcc -o zgled zgled.c -lintl
LANG=C ./zgled
LANG=sl ./zgled
LC_ALL=sl ./zgled
LC_MESSAGES=sl ./zgled
LC_CTYPE=sl ./zgled
LC_ALL=sl_SI.iso88592 ./zgled
在第一个和最后一个示例中,消息以英语输出,在倒数第二个示例中,可能也是英语。 第一个示例是因为我们显式要求了区域设置“C”,最后一个示例是因为我们要求了区域设置“sl_SI.iso88592”,其中没有消息翻译——因为消息翻译存在于区域设置“sl”中。 在倒数第二个示例中,我们使用了正确的区域设置,但使用了不相关的类别 LC_CTYPE
而不是使用的 LC_MESSAGES
。还有两点说明:移动消息目录的目录必须与源代码中指定的 LOCALEDIR
目录匹配。 本文作者通过在 /usr/local/share/locale 目录中创建一个符号链接解决了 GNU gettext
将 “sl” 和 “sl_SI.iso88592” 理解为不同区域设置的问题
ln -s sl sl_SI.iso88592
GNU 项目的国际化正在进行中(GNU 项目中的程序构成了整个 Linux 系统的重要部分,以及最终用户面对的大部分内容)。 目前,以下 GNU 软件包的消息已被翻译成斯洛文尼亚语:enscript
、fileutils
、gettext
、grep
、hello
、recode
和 tar
。 通过设置环境变量
LANG=sl
来自这些软件包的程序将输出斯洛文尼亚语消息而不是英语消息。关于 GNU 项目斯洛文尼亚语本地化的讨论正在电子列表 <sl@li.org>
的订阅者之间进行,您可以通过向 sl-request@li.org 发送一行
subscribe
在邮件正文中来订阅该列表。非常欢迎志愿者帮助翻译其余的软件包,或者只是承诺维护已经翻译的软件包。 欢迎加入!