PostgreSQL 的程序(服务器和客户端)可以用您喜欢的语言发出消息 — 前提是这些 消息已经被翻译。创建和维护翻译后的消息集需要既精通自己的语言、又愿意 为 PostgreSQL 事业贡献力量的人的帮助。 要做这件事,您完全不必是一名程序员。本节将介绍如何提供帮助。
我们不会评判您的语言水平 — 本节讨论的是软件工具。理论上您只需
要一个文本编辑器。但这只有在您不想试用自己翻译的消息这种不太可能
发生的情况下才成立。配置源码树时,请务必使用
--enable-nls 选项。它同时会检查
libintl 库和 msgfmt
程序,这些反正也是所有最终用户需要的。要试用您的成果,请按照安装
说明中适用的部分操作。
如果您想开始一项新的翻译工作,或者想做消息目录合并(后文会介绍),
您将分别需要 GNU 兼容实现的 xgettext 和
msgmerge 程序。稍后我们会设法让使用打包源码发行
版的用户不需要 xgettext。(如果使用 Git 源码,
您仍然需要它。)目前推荐 GNU Gettext 0.10.36
或更高版本。
您本地的 gettext 实现应带有自己的文档。其中有些内容可能与下文重复, 但更多细节请查阅那些文档。
原始(英文)消息与其(可能的)译文对保存在 消息目录中,每个程序一份(相关程序可以共用一个 消息目录),每种目标语言一份。消息目录有两种文件格式:第一种是 “PO” 文件(Portable Object,可移植对象),它是译者编辑的 具有特殊语法的纯文本文件。第二种是 “MO” 文件(Machine Object,机器对象),它是由对应的 PO 文件生成的二进制 文件,在国际化程序运行时使用。译者无需处理 MO 文件;实际上几乎没人 处理它。
消息目录文件的扩展名自然是 .po 或
.mo。基础名要么是它所属程序的名字,要么是该文件
对应的语言,视情况而定。这有点令人困惑。例如 psql.po
(psql 的 PO 文件)或 fr.mo(法语的 MO 文件)。
PO 文件的文件格式如下所示:
# comment msgid "original string" msgstr "translated string" msgid "more original" msgstr "another translated" "string can be broken up like this" ...
msgid 行是从程序源代码中提取的。(不一定如此,但这是最常见的方式。) msgstr 行起初为空,由译者填入有用的字符串。字符串可以包含 C 风格的 转义字符,并且可以如图所示跨行书写。(下一行必须从行首开始。)
# 字符引入一条注释。如果 # 字符后紧跟空白,那么这是由译者维护的 注释。也可以有自动注释,它们在 # 后紧跟一个非空白字符。这些注释由 操作 PO 文件的各种工具维护,旨在帮助译者。
#. automatic comment #: filename.c:1023 #, flags, flags
#. 风格的注释提取自使用该消息的源文件。程序员可能在其中插入了给译者
的信息,例如关于预期对齐方式的说明。#: 注释指出消息在源代码中被使用
的确切位置。译者不必查看程序源代码,但如果对正确的翻译存有疑问,可以
去查看。#, 注释包含以某种方式描述消息的标志。目前有两种标志:
fuzzy 表示该消息可能因程序源代码的更改而已过时。
译者随后可以核实这一点,并可能移除 fuzzy 标志。注意 fuzzy 消息不会
提供给最终用户。另一个标志是 c-format,表示该消息
是 printf 风格的格式模板。这意味着译文也应是
一个占位符数量和类型相同的格式字符串。有工具可以对此进行验证,它们
依据 c-format 标志工作。
那么,如何创建一个“空白”消息目录呢?首先,进入包含您想
翻译其消息的程序的那个目录。如果存在文件
nls.mk,则说明该程序已为翻译做好准备。
如果已经存在一些 .po 文件,那么说明已经有人做过
翻译工作。这些文件被命名为
,
其中 language.polanguage 是
ISO 639-1 两位小写语言代码,例如法语为
fr.po。如果确实需要在同一语言下进行不止一项翻译
工作,文件也可以命名为
,
其中 language_region.poregion 是
ISO 3166-1 两位大写国家代码,
例如巴西葡萄牙语为 pt_BR.po。如果您找到了想要的
语言,就可以直接在那个文件上开始工作了。
如果您需要开始一项新的翻译工作,请先运行命令:
make init-po
这将创建一个文件
。
(用 progname.pot.pot 与已经“投入使用”的 PO
文件区分开。字母 T 代表
“template”(模板)。)
把这个文件复制为
并编辑它。
为了让新语言可用这一点被知晓,还要编辑文件
language.popo/LINGUAS,在已列出的语言旁边添加该语言(或
语言和国家)代码,例如:
de fr
(当然还可以出现其他语言。)
随着底层程序或库的变化,程序员可能会修改或新增消息。在这种情况下, 您不需要从头开始,而是运行命令:
make update-po
它会创建一个新的空白消息目录文件(即您起初使用的 pot 文件),并将其
与现有的 PO 文件合并。如果合并算法对某条消息没有把握,它会像前文
解释的那样将其标记为“fuzzy”。新的 PO 文件会以
.po.new 扩展名保存。
PO 文件可以用普通的文本编辑器编辑。也有若干专门针对 PO 文件的编辑器, 它们通过翻译特有的功能来辅助这一过程。 (毫不意外地)Emacs 有一个 PO 模式,相当有用。
译者只应修改 msgstr 指令后引号之间的区域、添加注释以及改变 fuzzy 标志。
PO 文件不必完全填写。当没有译文(或译文为空)时,软件会自动回退到 原始字符串。提交不完整的翻译以便纳入源码树是没有任何问题的;这为 其他人接手您的工作留出了空间。不过,我们鼓励您在执行一次合并之后 优先清除 fuzzy 条目。请记住,fuzzy 条目不会被安装;它们只是作为 可能正确的译文的参考而存在。
编辑译文时需要注意以下事项:
确保如果原文以换行符结尾,译文也要以换行符结尾。制表符等也 类似。
如果原文是一个 printf 格式字符串,译文也必须
是。译文中还必须以相同的顺序包含相同的格式说明符。有时语言的
自然规则使这一点无法实现或至少很别扭。这种情况下,您可以像这样
修改格式说明符:
msgstr "Die Datei %2$s hat %1$u Zeichen."
这样第一个占位符实际上会使用参数列表中的第二个参数。
必须紧跟在
% 之后,位于任何其他格式修饰符之前。
(这个功能确实存在于 digits$printf 函数族中。您
可能以前没听说过它,因为在消息国际化之外很少用到。)
如果原始字符串含有语言性错误,请报告它(或自行在程序源代码中 修复)并正常翻译。程序源代码更新后,修正后的字符串可以在合并时 纳入。如果原始字符串含有事实性错误,请报告它(或自行修复)并且 不要翻译它。此时您可以在 PO 文件中用注释标记该字符串。
保持原始字符串的风格和语气。具体来说,不是完整句子的消息
(cannot
open file %s)大概不应以大写字母开头(如果您的语言区分
大小写)或以句号结尾(如果您的语言使用标点符号)。
阅读 Section 55.3 可能会有帮助。
如果您不知道某条消息的含义,或者它有歧义,请在开发者邮件列表上 询问。很可能以英语为母语的最终用户也不理解它或觉得它有歧义,因此 最好改进这条消息。