54.1. 给翻译者

54.1.1. 需求
54.1.2. 概念
54.1.3. 创建并维护消息目录
54.1.4. 编辑 PO 文件

PostgreSQL程序(服务器和客户端)可以用你最喜欢的语言发出它们的消息 — 如果消息已经被翻译过。常见和维护已翻译的消息集需要以该语言为母语并且愿意为PostgreSQL做贡献的人们的帮助。要做这些你根本不需要成为一个程序员。本节将解释如何来帮助我们。

54.1.1. 需求

我们将不会判断你的语言技巧 — 这一节是关于软件工具。理论上,你只需要一个文本编辑器。但是这仅仅是最少见的情况:你不想试验你的已翻译好的消息。当你配置你的源代码树时,一定要使用--enable-nls选项。这将也会检查libintl库和msgfmt程序,这些是所有终端用户将会需要的。要试验你的工作,请按安装指导的相应部分进行。

如果你想开始一个新的翻译工作或想做一次消息目录合并(在后面描述),你将分别需要程序xgettextmsgmerge的 GNU 兼容的实现。稍后,我们将试着安排它这样如果你使用一个打包好的源代码发布,你将不需要xgettext(如果使用来自 Git 的发布,你仍将需要它)。我们目前推荐GNU Gettext 0.10.36或更高版本。

你的本地 gettext 实现应该有其自身的文档。其中的某些可能与接下来的内容重复,但是你应该看看来了解更多细节。

54.1.2. 概念

原始(英语)消息和它们(可能的)已翻译等价物组成的对被保持在消息目录中,每个程序(尽管相关程序可以共享一个消息目录)以及每个目标语言一个目录。消息目录有两种文件格式:第一种是PO文件(用于可移植对象),它是一个翻译者编辑的具有特殊语法的普通文本文件。第二种是MO文件(用于机器对象),它是从相应的 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-格式,它指示该消息是一个printf-风格的格式模板。这意味着翻译也应当是一个格式字符串,其中有相同个数和相同类型的占位符。有工具能验证这点,它会切断该 c-格式标志。

54.1.3. 创建并维护消息目录

好,那么我们如何创建一个空的消息目录呢?首先,进入到包含你希望翻译其消息的程序的目录中。如果那里有一个文件nls.mk,那么这个程序就已经准备好被翻译了。

如果已经有某些.po文件,那么有些人已经完成了一些翻译工作。这些文件被命名为语言.po,其中语言 ISO 639-1 双字符语言代码(小写形式),例如法语是fr.po。如果真的对于一种语言有需要多个翻译任务那么这些文件也可以被命名为语言_区域.po,其中region ISO 3166-1 双字符国家代码(大写形式),例如巴西的葡萄牙语是pt_BR.po。如果你找到了你想要的语言,你就可以开始在那个文件上工作了。

如果你需要开始一项新的翻译工作,那么首先运行命令:

make init-po

这将创建一个文件 程序名.pot.pot用来把它与在生产中的 PO 文件区分开。T表示template)。将这个文件拷贝到语言.po并编辑它。要让让人知道新语言可用,还要编辑文件nls.mk并且增加该语言(或语言与国家)代码到如下的行中:

AVAIL_LANGUAGES := de fr

(当然可以出现其他的语言)。

如果底层程序或库改变,消息可能会被程序员改变或增加。在这种情况中,你不需要从头开始。相反,运行命令:

make update-po

它将创建一个新的空白消息目录文件(你从其开始的 pot 文件)并且将把它合并到现有的 PO 文件中。如果合并算法不确定一个特定的消息,它会把该消息标记为如上所释的fuzzy。新的 PO 文件会被保存为一个.po.new扩展名。

54.1.4. 编辑 PO 文件

PO 文件可以用一个常规文本编辑器编辑。翻译者应该只改变 msgstr 指令之后引号之间的区域、增加注释并且修改 fuzzy 标志。Emacs 有一个 PO 模式(不出意料),我们觉得它非常有用。

PO 文件不需要被完全填充。如果无翻译(或一个空翻译)可用,该软件将自动回退到原始的字符串。提交一个未完成的翻译包含到源码树中不存在问题,那样可以让其他人有机会继续你的工作。不过,我们鼓励你在做完合并之后优先移除模糊项。记住模糊项将不会被安装,它们只作为什么可能是正确翻译的参考。

这里有一些在编辑翻译时要记住的事情:

  • 确定如果原始消息以一个新行结束,那么翻译后的消息也要保持一样。制表符等也类似。

  • 如果原始消息是一个printf格式字符串,翻译消息也需要是那样。翻译也需要保留相同顺序的格式指示符。有时语言的自然规则让这样做不可能或者至少很尴尬。在那样的情况下,你可以这样修改格式指示符:

    msgstr "Die Datei %2$s hat %1$u Zeichen."

    那么第一个占位符将实际上使用列表中的第二个参数。digits$需要在任何其他格式操纵符之前紧跟 %(这个特性真实地存在于printf函数族中。你可能之前没有听说过它,因为除消息国际化之外很少会用到它)。

  • 如果原始字符串包含一个语法错误,报告它(或者在程序源码中自己修复它)并且正常进行翻译。更正过的字符串可以在程序源码已被更新时合并。如果原始字符串包含一个事实错误,报告它(或自己修复它)并且不要翻译它。相反,你可以在 PO 文件中对该字符串标注一个注释。

  • 保持原始字符串的风格和语气。特别地,不是句子的消息(cannot open file %s)可能不以一个大写字母开始(如果你的语言区分字母大小写)或者一个句号结尾(如果你的语言使用标点符号)。阅读第 53.3 节可能有所帮助。

  • 如果你不知道一个消息的含义,或者如果它是模棱两可的,在开发者邮件列表中询问其正确含义。如果说英语的终端用户可能也无法理解它或者发现它是模棱两可的,那么最好改进该消息。