本节描述如何在程序或属于PostgreSQL发行版库的程序中实现母语支持。当前,它只适用于C程序。
添加NLS支持到程序
在程序的启动序列中插入此代码
#ifdef ENABLE_NLS #include <locale.h> #endif ... #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain("progname
", LOCALEDIR); textdomain("progname
"); #endif
(实际上progname
可以自由选择.)
在找到适合翻译的消息处,需要调用gettext()
。例如。
fprintf(stderr, "panic level %d\n", lvl);
将更改为
fprintf(stderr, gettext("panic level %d\n"), lvl);
如果未配置 NLS 支持,则将 (gettext
定义为无操作。
这样往往会增加很多混乱。一种常见的简便方法是使用
#define _(x) gettext(x)
如果程序通过一个或几个函数(例如后端的 ereport()
)进行大量通信,则另一种解决方案可行。然后,您使此函数调用内部 gettext
在所有输入字符串上。
在包含程序源的目录中添加一个文件 nls.mk
。此文件将作为 Makefile 读取。此处需要进行以下变量分配
CATALOG_NAME
程序名称,在 textdomain()
调用中提供。
GETTEXT_FILES
包含可翻译字符串的文件的列表,即用 gettext
或替代解决方案标记的文件。最后,这将包括程序的几乎所有源文件。如果此列表太长,您可以使第一个 “文件” 成为 +
,第二个单词成为每行包含一个文件名的新文件。
GETTEXT_TRIGGERS
为翻译人员工作的生成消息目录的工具需要知道哪些函数调用包含可翻译字符串。默认情况下,只知道 gettext()
调用。如果您使用了 _
或其他标识符,则需要在此处列出它们。如果可翻译字符串不是第一个参数,则该项需要为 func:2
(对于第二个参数)的形式。如果您有一个支持复数形式消息的函数,则该项应类似于 func:1,2
(标识单数和复数消息参数)。
创建一个文件 po/LINGUAS
,它将包含提供的翻译列表 - 最初为空。
构建系统将自动负责构建和安装消息目录。
以下是一些编写易于翻译的信息的消息的指南。
不要在运行时构建句子,例如
printf("Files were %s.\n", flag ? "copied" : "removed");
句子中的词序在其他语言中可能不同。此外,即使您记得对每个片段调用 gettext()
,但这些片段可能无法分别很好地翻译。最好复制一点代码,以便要翻译的每个消息成为一个连贯的整体。只应在运行时将数字、文件名和此类运行时变量插入消息文本中。
由于类似的原因,如下操作无效
printf("copied %d file%s", n, n!=1 ? "s" : "");
因为它假定了复数的形成方式。如果您认为可以这样解决它
if (n==1) printf("copied 1 file"); else printf("copied %d files", n):
那么就会失望的。某些语言有多种形式,以及一些奇特的规则。通常最好设计消息来完全避开该问题,比如像这样
printf("number of copied files: %d", n);
如果您真的想构建一条正确复数形式的消息,可以支持这一点,但这有点别扭。当在ereport()
中生成一个主错误消息或详细信息消息时,您可以编写类似如下内容
errmsg_plural("copied %d file", "copied %d files", n, n)
第一个参数是适合英语单数形式的格式字符串,第二个是适合英语复数形式的格式字符串,第三个是确定要使用哪种复数形式的整数控制值。后续的参数根据格式字符串照常设置格式。(通常,复数形式控制值也将是要格式化的值之一,因此必须写入两次。)在英语中,n
是 1 或不是 1 这一点至关重要,但在其他语言中,复数形式可能有许多不同形式。为了能够对 n
的运行时值进行適切选择,译者将这两种英语形式看作一个组,这样才能获得提供多个替代字符串的机会。
如果您需要对不会直接转到 errmsg
或 errdetail
报告的消息进行复数形式处理,您必须使用底层函数 ngettext
。请参阅 gettext 文档。
如果您想向译者传达一些内容,例如有关消息如何与其他输出对齐的方式,请在字符串出现之前加上从 translator
开始的注释,例如
/* translator: This message is not what it seems to be. */
这些注释被复制到消息目录文件中,以便译者可以查看它们。