UP | HOME

使用GetText本地化编程

目录

介绍

GetText 是 GNU 的一个项目,GetText 主页有最丰富的信息。下面大致翻 译一下 GetText 主页的介绍 :

“通常,程序及其文档信息都是用英语语言写的,程序运行时同用户交 互的信息也是英语。这是一个事实,不仅仅 GNU 的软件是这样,其他大 部分私有软件或自由软件也是这样。一方面,对于来自所有国家的开 发者、维护者和用户来说,相互沟通中使用一种通用的语言非常的方便。另一方面,相对于母语来说大多数人并不适应使用英语,而且他 们的日常工作都是尽可能的使用他们自己的母语。多数人都会喜欢他 们的计算机屏幕显示的英语更少,显示的母语更多。"

" GNU 的 'gettext' 是 GNU 翻译项目的一个重要步骤,我们依赖于它 来作很多其他的步骤。这个软件包给程序员、翻译者,或者用户提供 了一套集成工具和文档。详细地说,GNU gettext 提供了一套工具, 能让其他 GNU 软件创建多语言信息。…"

gettext 的工作流程是这样的:比如我们写一个 C 程序,通常 printf 等输 出信息都是 English 的。如果我们在程序中加入 gettext 支持,在需要交 互的字符串上用 gettext 函数,程序运行是就可以先调用 gettext 函数处 理字符串,替换当前的字符串了。注意是运行时替换。

例子

#include <stdio.h>
#include <locale.h>
#include <libintl.h>

/*使用gettext通常使用类似下面的一个带函数的宏定义
  *你完全可以不用,直接使用 gettext(字符串)
*/
#define _(S) gettext(S)

/*PACKAGE是本程序最终的名字(运行时输入的命令)*/
#define PACKAGE "jian_gettext"

int main(int argc, char **argv)
{
/* 下面三个参数都是使用gettext时候需要使用的
  * setlocale
  * bindtextdomain
  * textdomain
*/
  setlocale(LC_ALL,"");
  bindtextdomain(PACKAGE, "locale");
  textdomain(PACKAGE);

  printf(_("Hello,GetText!\n"));
  return 0;
}

使用 gettext 的流程

  1. 头文件包含:

#include <locale.h> #include <libintl.h>

  1. 定义宏定义(完全是为了方便,而且几乎所有程序都这样)

#define _(S) gettext(S)

  1. 设置 locale 和 mo 文件将要存放的路径,关联程序

setlocale(LC_ALL,""); bindtextdomain(PACKAGE, "locale"); textdomain(PACKAGE);

  1. 制作 po 文件(示例程序是:jian_gettext.c)

xgettext -a jian_gettext.c -o jian_gettext.po --from-code=utf-8

  1. 修改生成的 jian_gettext.po 文件,将下面行中的 CHARSET 换成 UTF-8

"Content-Type: text/plain; charset=CHARSET\n"

再翻译其中的 string(其他的 string 不要改):

#: jian_gettext.c:14 #, c-format msgid "Hello,GetText!\n" msgstr "你好,GetText!\n"

  1. 生成 mo 文件,

msgfmt jian_gettext.po -o jian_gettext.mo

  1. 创建存放 mo 文件的目录,(例子使用./locale)

mkdir -pv locale/zh_CN/LC_MESSAGES/ cp -v jian_gettext.mo locale/zh_CN/LC_MESSAGES/

  1. 运行程序,你的程序应该是这样编译好的:

gcc -Wall -o jian_gettext jian_gettext.c

如果没有错误,上面的程序运行结果如下:

# ./jian_gettext 你好,GetText!

细节

setlocale()

setlocale(LC_ALL,"") 的意思是使用环境变量(系统当前的值)

xgettext

  • -k 参数 可以只搜索某些字符串,没有用的信息省略。

xgettext jian_gettext.c -k_ -o jian_gettext.po

  • -l 参数 可以针对某一语言生成 po 文件,中文为例:

msginit -l zh_CN -i jian_gettext.po

上面命令会生成 zh_CN.po 文件,可由此修改生成 mo 文件

多文件的 PO

一个开源项目中,通常有很多源文件,我们都需要翻译其中的字符串。通常步骤 如下:

进入 PO 目录执行(一定要是 PO 目录):

intltool-update -m

得到一个文件列表告诉我应该把它们加入 POTFILES.in 文件.

跳到 PO 目录的父目录,使用新的 POTFILES.in 生成 POT 文件::

xgettext -a -f po/POTFILES.in -o po/xxx.pot

我使用的一个示例:

xgettext -k_ -f po/POTFILES.in -o po/mutter-moblin.pot --from-code="utf-8"
intltool-update —pot             # 生成 pot 文件
intltool-update —maintain

创建 po 文件

创建并进入/po 目录,创建 POTFILES.in,内容为你需要提取源码中有需要翻译的 字符串的源文件列表,每行一个文件,然后执行 intltool-update —pot 产生 pot 文件,如果将来你在维护代码中代码有变化或者在 POTFILES.in 中新增了源文件, 可用 intltool-update —maintain 更新。

有了 pot 文件,现在需要产生各种语言的 po 文件,如 msginit —locale=zh_CN 产生 中文 po 文件,如将来源文件有变化可以 intltool-update zh_CN 更新 zh_CN.po,接 下来翻译的工作就是你自己来做了。

要生成特定语言的 mo 文件,需要维护 configure.ac 中的 ALL_LINGUAS,以空格分隔 就可以了

参考链接

作者: Petrus.Z

Created: 2021-09-01 Wed 00:38