当前位置: 代码迷 >> 综合 >> i18n和i10n:国际化本地化--gettext
  详细解决方案

i18n和i10n:国际化本地化--gettext

热度:3   发布时间:2024-01-18 11:10:17.0
[正文 ]
  1. froward
软件编写和文档通常使用英文,这便于世界各地的 程序员交流,但是并非所有用户都懂英文,所以程序能显示为用户的母语,能使软件用户群更大,且方便了普通用户。
过去我们讲“汉化”,在有了“ Internationalization(国际化 )”和“ localization(本地化 )”的概念和技术之后,“汉化”这个词要进入博物馆了  
本文介绍 GNU工程中重要的工具 gettextintltool
  1. i18n and l10n introduction
首先介绍两个术语 I18NL10N,经常也写成小写 i18nl10n
I18N/L10N 是什么?
开发人员把 internationalization简写成 I18N,中间的数字 18是前后两个字母 in之间的字母个数。  L10N依据“ localization”使用同样的命名规则。  I18N/L10N方法、协议和应用结合在一起,允许用户使用他们自己所选择的语言。
I18N应用程序使用 I18N工具来编程。它允许开发人员写一个简单的文件,就可以将显示的菜单和文本翻译成本地语言。我们非常鼓励程序员遵循这种规则。
为什么要使用 I18N/L10N?
I18N/L10N标准能够很好地支持您查看、输入或处理非英语语言。
I18N支持哪些语言?
I18NL10N不是 Linux特有的。当前,它能支持世界上绝大部分主力语言,包括但不限于:中文,德文,日文,朝鲜文,法文,俄文,越南文等等。
本地化设置需要具备三个条件:
  1. a. 语言 代码  (Language Code)
    b. 国家代码  (Country Code)
    c. 编码 (Encoding)
  • 本地名字可以用下面这些部分来构造:
    语言代码 _国家代码 .编码 比如( zh_CN.UTF-8, en_US等)
locale的别名表见  /usr/lib/X11/locale/locale.alias(以Debian GNU/Linux为例)
  1. gettext and intltool introduction and l10nize this program by gettext manually with autotool
gettext GNU Translation Project上的重要一步,从它基础上可以构建其他步骤。 gettext提供了一个帮助产生多语言 message的框架:包括一组关于程序改如何编写以支持 message种类的约定, message种类相关的一个目录和文件命名组织,一个支持获取已翻译 message的运行时库,一些独立的程序(可以在终端运行如下命令查看  dpkg -L gettext | grep "/usr/bin/" | cut -d'/' -f4)。
intltool包含一些方便的命令,可以通过 dpkg -L intltool | grep “/usr/bin/” | cut -d'/' -f4查看。
  1. building a i18n program step by step

描述:编写一个提供zh_CN支持的程序。

按照软件开发的惯例,最初的软件只有英文版本,根据需要,作者再把软件界面和文档翻译成不同国家、地区的语言版本。但是由于实现翻译的途径、翻译的工作效率、翻译的可重用性等因素各不相同,使翻译工作面临很大困境,也阻碍了软件的推广和应用。为了方便地将软件翻译成不同语言的版本,就需要一套翻译规范和通用工具,这就导致了“国际化”机制的出现。仅仅翻译是不够的,同一种语言在不同国家、地区可能存在多个支系,它们在表达习惯、语法结构甚至文字种类和编码上都有不同,方言更是千奇百怪,通用的翻译其质量肯定是不高的。涉及到计算机领域,还存在操作习惯上的差别,而且对某种语言提供完美的输入、显示、打印、保存、传输并非一件轻而易举的事,这就导致了“本地化”机制的出现。简而言之,“国际化”是“本地化”的一部分,主要是指国际化的实现机制和翻译工作, “本地化”包含“国际化”,是对“国际化”的补充和完善,它还包括为实现对某种特定语言良好的支持而进行的有针对性的翻译调整以及对软件进行的打补丁工作。

I18N 和 L10N 的国际组织是 Openi18n 组织,其前身是 li18nux 组织。它原来是制定 GNU/Linux 自由操作系统上软件全球化标准的国际计划,后来扩充到 GNU/Linux 之外所有开放源代码的技术领域,因而更名为 Open Internationalization Initiative,由非营利组织 Free Standards Group 赞助,并为世界各大厂商所支持,对于 GNU/Linux 系统上的多国语言文字处理技术和环境有决定性的影响。各个开源软件开发组织通常都有负责“国际化”和“本地化”工作的分支机构。

I18N 主要使用 gettext 软件包使软件实现国际化支持。事实上它是一整套 I18N 解决方案。

i18n是internationalization的缩写,意思指i和n之间有18个字母。/etc/sysconfig/i18n里面存放着系统的区域语言设置,可以使linux系统支持国际化信息显示。就是支持多种字符集的转换,避免出现乱码。同一时间i18n只能是英文和一种选定的语言,例如英文+中文、英文+德文、英文+韩文等等。

使用locale查看系统当前locale环境变量

  1. [root@localhost swap]# locale  
  2. LANG=zh_CN.GB18030  
  3. LC_CTYPE="zh_CN.GB18030"  
  4. LC_NUMERIC="zh_CN.GB18030"  
  5. LC_TIME="zh_CN.GB18030"  
  6. LC_COLLATE="zh_CN.GB18030"  
  7. LC_MONETARY="zh_CN.GB18030"  
  8. LC_MESSAGES="zh_CN.GB18030"  
  9. LC_PAPER="zh_CN.GB18030"  
  10. LC_NAME="zh_CN.GB18030"  
  11. LC_ADDRESS="zh_CN.GB18030"  
  12. LC_TELEPHONE="zh_CN.GB18030"  
  13. LC_MEASUREMENT="zh_CN.GB18030"  
  14. LC_IDENTIFICATION="zh_CN.GB18030"  
  15. LC_ALL=  

查看/etc/sysconfig/i18n配置(这个是修改后的配置)

  1. [root@localhost swap]# more /etc/sysconfig/i18n  
  2. LANG="zh_CN.GB18030"  
  3. SUPPORTED="zh_CN.GB18030:zh_CN:zh:en_US.UTF-8:en_US:en"  
  4. SYSFONT="latarcyrheb-sun16"  

按照上面的配置修改/etc/sysconfig/i18n文件,就可以支持中文显示了。

i18n的初始配置如下:

  1. LANG="zh_CN.UTF-8"  
  2. SUPPORTED="zh_CN.UTF-8:zh_CN:zh"  
  3. SYSFONT="latarcyrheb-sun16"  

第一行表示当前系统的语言环境变量设置,这里是zh_CN.UTF-8

第二行表示系统支持哪些字符集,没有设置的语言字符集类型会出现乱码

第三行表示系统终端字符的字体,设置的是latarcyrheb-sun16

The  /etc/sysconfig/i18n  file sets the default language, any supported languages, and the default system font.



setlocale和bindtextdomain函数的用法


这两个函数都是linux实现i18n需要用到的。
其中setlocale用来设定locale,比如LC_ALL,LC_CTYPE等,一般用法是:setlocale(LC_ALL, "")
这用来设置LC_ALL,第二个参数是一个空字符串表示使用环境变量中定义的LC_ALL的值。

然后就是用bindtextdomain,比如:bindtextdomain("libgammu", LOCALE_PATH);
Linux i18n中,每个资源文件是.mo文件,这个文件是二进制的,用工具针对一个文本生成(作成二进制应该是考虑了性能)。所以,上面的代码 中,LOCALE_PATH指定的就是寻找mo文件的一个路径,一般的,如果调用了上面的代码,那么gettext library就会在这个地方寻找mo文件:
/usr/share/locale-langpack/<locale>/LC_MESSAGES/libgammu.mo

此 外,还有textdomain函数,比如:textdomain("gammu"); 这个函数的作用是设置当前需要使用的text domain(这些text domain之前都要使用bindtextdomain来设定好以便能让gettext library找到那个mo文件)。如果我们的程序用到了多个mo文件,那就需要bindtextdomain多次,然后用textdomain来指定当 前需要使用哪个。比如gammu中,gammu命令行程序使用的就是gammu这个text domain,libgammu这个库使用的就是libgammu.mo

附上gammu中使用这两个函数的代码:

Code:  Select all
#ifdef GETTEXTLIBS_FOUND
void GSM_InitLocales(const char *path) {
   /* setlocale, locale is "" means all locale settings are
      depend on the environment setting. */
   setlocale(LC_ALL, "");
   if (path == NULL || strlen(path) == 0) {
#if defined(LOCALE_PATH)
      bindtextdomain("libgammu", LOCALE_PATH);
#else
      bindtextdomain("libgammu", ".");
#endif
   } else {
      /* bindtextdomain, libgammu is the catalog, path is the
         message file root path. E.g: if path is /usr/share/locale-langpack,
         then all messages represented by gettext will by found in:
         /usr/share/locale-langpack/<locale>/LC_MESSAGES/libgammu.mo
         Refer to manual of bindtextdomain for more details. */
      bindtextdomain("libgammu", path);
   }
}
#else
void GSM_InitLocales(const char UNUSED *path) {
   setlocale(LC_ALL, "");
}
#endif



  相关解决方案