About
RSS

Bit Focus


软件翻译与 locale

    看了一篇会 "吐核" 的终端, 了解到 wget 还有烦人的 "eta(英国中部时间)" 提示, 看来软件翻译这档子事还真是很能产生喜感的.

    在 Linux 环境下, 主流的软件翻译方法是通过工具抓取源代码中的需翻译字符串到外部文本文件, 形成一个字典, 翻译之后在运行期加载. 更专业一点就是, 从软件本身要能国际化 (internationalization, 一般简写为 i18n, 因为 i 和 n 之间有 18 个字符), 支持从源代码中提取字符串来翻译; 而翻译这个步骤则成为本地化 (localization, 简称 l10n).
    要让软件具备国际化属性, 这必须程序员们亲自努力, 为需翻译字符串附加一些修饰. 如下面这个程序
int main(int argc, char* argv[])
{
    if (1 == argc || 0 == strcmp("hello", argv[1]))
    {
        puts("Hello");
    }
    else
    {
        puts("World");
    }
    return 0;
}
是很难具备国际化能力的, 因为文本扫描程序无法区分哪些字符串是需要翻译的.
    要加上区分信息很简单, 比如
#define TRANSLATE_THIS(x) x

int main(int argc, char* argv[])
{
    if (1 == argc || 0 == strcmp("hello", argv[1]))
    {
        puts(TRANSLATE_THIS("Hello"));
    }
    else
    {
        puts(TRANSLATE_THIS("World"));
    }
    return 0;
}
    将文件保存为 hello.c, 使用 xgettext 工具提取字符串
$ xgettext hello.c --keyword=TRANSLATE_THIS -o hello.po
那么 xgettext 将提取被宏 TRANSLATE_THIS 所包括的所有字符串到 hello.po 纯文本文件中.
    在 po 文件中, 每个被提取的字符串是一个 msgid, 而翻译则是接下来一行中的 msgstr, 现在所有的 msgstr 都空着, 在 po 文件中直接写入翻译结果并保存即可. 此外还要指定 po 文件头部有文件编码等信息.
    翻译完成后, 在本地创建 locale 相关目录, 再使用 msgfmt 工具编译 po 文件为二进制文件, 并放入 locale 目录中
$ mkdir -p $LANG/LC_MESSAGES && msgfmt hello.po -o $LANG/LC_MESSAGES/hello.mo
这个目录的意义待会儿再解释.
    使用纯文本编辑器盯着 po 文件翻译条目是很累很无趣的事情, 好在有许多工具可以选取. 比较流行的有 poEditQt Linguist. 接下来继续讨论程序的事情.

    到此为止, 程序本身还不具备本地化的能力, 因为宏 TRANSLATE_THIS 什么也没干, 程序本身的逻辑并没有变化, 也不知道如何导入翻译目标字符串替换原有字符串. 现在将宏定义换掉, 使用 locale 中的组件来完成本地化工作

Permanent Link: ?p=208 Load full text

Post tags:

 Locale Programming
 l10n
 Tutorial
 C
 i18n


. Back to Bit Focus
NijiPress - Copyright (C) Neuron Teckid @ Bit Focus
About this site