gettext 的替换

Posted

技术标签:

【中文标题】gettext 的替换【英文标题】:Replacements for gettext 【发布时间】:2009-10-08 12:36:47 【问题描述】:

我们在产品中使用 gettext 进行翻译,但遇到了很多问题:

除非系统支持,否则无法使用某种语言。

在 Solaris 9 Sparc 上,如果我们将环境重置为各种英语语言环境,如果机器没有相应的语言环境,消息仍然不会被翻译。翻译文件存在,但我们无法访问它。

使用环境来制定语言

这会导致想要将消息翻译成不同语言的服务器出现问题。从理论上讲,这可能是一个完全线程安全、可并行化的操作——但 gettext 意味着我们必须对翻译进行全局锁定。

无法设置默认语言

我的意思不是代码中的文本。我们在代码中使用 MsgID,所以如果当前环境定义语言不可用,我想要的是能够指定一个备用翻译去。但是 gettext 不允许这样做 - 我必须尝试,然后重置环境,然后它才能查看不同的翻译。 (使用 MsgID 不是我的选择 - 我想遵循 gettext 标准并使用英语作为 ID,但我被否决了,现在要更改它会做很多工作)

返回的编码在 UTF-8 和当前本地编码之间有所不同。

我指的不是 .po 文件——它们都是 UTF-8 格式(烦人的是 msgfmt 不处理 BOM,但无论如何)。我的意思是 gettext ngettext 等的输出,它们在 AIX 和 HPUX 上是 UTF-8(不考虑本地/终端编码),但在 Solaris/Linux/FreeBSD 上是本地编码,尽管这可能是由于 iconv 问题?

在任何情况下,不必为不同平台提供特殊代码会很好 - 我将不得不调查是否可以得到bind_textdomain_codeset(domain,codepage); 来帮助解决这个问题。


有人知道提供更有用界面的开源翻译库吗?

【问题讨论】:

【参考方案1】:

我们正在使用ICU resource bundles 并且对它非常满意。 ICU 界面并不“现代”,但功能强大,基本原理合理,资源打包(使用 genrb 工具)非常灵活。它的message formatting 功能也不错。

关于您的特定 cmets:

除非系统支持,否则无法使用语言。

我不明白这个。这可能是因为我对 gettext 的唯一“经验”是阅读了它的文档。

使用环境来制定语言

ICU 界面采用Locale 作为输入,因此您可以完全控制。如果对您更方便的话,它还有一个“默认语言环境”的概念。

无法设置默认语言

ICU 有一个精心设计的fallback mechanism,涉及一个“默认”捆绑

返回的编码在 UTF-8 和当前本地编码之间有所不同。

字符串ResourceBundles(也可以是其他数据类型)始终表示为UnicodeString,其内部编码为UTF-16。带有 UnicodeString 的 UTF-32 非常简单,因为它的接口公开了几种允许在代码点级别对其进行操作的方法。对于其他编码,code conversion 是可能的。

【讨论】:

我以前没有看到 ICU 翻译的东西 - 我以为它只是在转换编码......绝对有趣,因为我认为 ICU 可能在某个时候成为我们的依赖项。 关于 gettext 的系统依赖 - 例如除非系统区域设置 ja_JP.UTF-8 受支持,否则您无法将消息翻译成日语,即使您在 UTF-8 系统中运行,并且很可能能够显示日语。 甚至是希望能够生成日语的服务器,例如对于电子邮件,要求区域设置仅用于获取翻译消息。【参考方案2】:

1。除非系统支持,否则无法使用语言。

错了。您可以手动指定语言。使用 LANGUAGE 环境变量

int main()

      setlocale(LC_ALL,"");
      setenv("LANGUAGE","foo");

即使语言环境不存在,这也有效(你见过语言 foo 吗?)

2。使用环境来解决语言

这有什么问题?这为用户提供了更多控制权。

3。无法设置默认语言

错了,见上文。

4。返回的编码在 UTF-8 和当前本地编码之间有所不同。

错了,见bind_textdomain_codeset(domain,codepage);

我的强烈建议 - 使用 gettext。它是最受支持和最好的工具之一。翻译者会很感激使用正常且有用的工具。

还有一点很重要:对复数形式的支持非常好,但在非基于 gettext 的工具中支持很差。


gettext 只有 1 个限制——每个进程不能使用超过一种语言。切换语言不是线程安全的。幸运的是,大多数与人类互动的程序都使用一种语言。

这可能只是多线程服务的限制。

编辑:但这也不是真正的问题。我已经为我的项目实现了一次线程安全的 gettext 版本。参见http://art-blog.no-ip.info/cppcms/blog/post/16,基于mo 文件阅读器。

【讨论】:

mo 文件不是问题 - 用于访问它们的库是。所以我会饶有兴趣地看看你的图书馆——这正是我所追求的。【参考方案3】:

您还可以将 ICU 资源包与基于 XML 的 XLIFF 格式相互转换以进行翻译。

【讨论】:

一种方法是使用:.mo 到 .po:weblogtoolscollection.com/archives/2007/03/06/… .po 到 xliff:translate.sourceforge.net/wiki/toolkit/xliff2po 也许不是我们想要的。您可能会在 ICU 提交错误。【参考方案4】:

Google Chrome 浏览器的语言切换非常巧妙。程序运行时可以在语言之间切换。我不知道他们使用什么系统,但它可能值得研究,因为它是一个开源浏览器。

【讨论】:

【参考方案5】:

除非系统支持,否则无法使用语言。

这与 GNU gettext 无关——因为它只处理翻译部分。但确实,如果系统无法显示任何汉字,那么您将遇到中国问题。

使用环境来制定语言

这是一个不错的选择,但您始终可以自己设置语言,覆盖环境。这样,您可以根据自己的选择使用任何语言。

无法设置默认语言

这是不正确的 - 默认语言始终是内置语言,如果您想使用另一种语言,只需切换到它。简直不能比一行代码简单。

返回的编码在 UTF-8 和当前本地编码之间有所不同。

如果您可以选择国际化工具,那么您也可以选择您想为文本使用的字符编码。有些项目对所有语言都使用 utf-8(我的偏好),有些项目使用语言环境编码。

有人知道提供更有用界面的开源翻译库吗?

不,抱歉 - 我看不到 GNU gettext 有任何问题 :-)

【讨论】:

也许你应该问如何解决你的问题而不是跳过这个工具......你可能会惊讶它有多好。 当您说默认是内置语言时-您是指放入代码中的文本?我们在代码中使用 MsgID,所以如果当前环境定义语言不可用,我想要的是能够指定一个备用 translation 去。但是 gettext 不允许这样做 - 我必须尝试,然后重置环境,然后它才能查看不同的翻译。 使用环境来计算语言对于命令行程序来说很好,但对于服务器来说就失败了。如果内置文本不是默认语言,则会失败。 编码:我指的不是 .po 文件——它们都是 UTF-8 格式(烦人的是 msgfmt 不处理 BOM,但无论如何)。我的意思是 gettext ngettext 等的输出,它们在 AIX 和 HPUX 上是 UTF-8(不管本地/终端编码),但在 Solaris/Linux/FreeBSD 上是本地编码,尽管这可能是由于 iconv 问题? 后备语言:这样做没有错: if (filedoesnotexist('fr/LC_MESSAGES/default.mo')) SetLanguage ('de'); - 这样,如果法语不存在,它会选择使用德语翻译。

以上是关于gettext 的替换的主要内容,如果未能解决你的问题,请参考以下文章

Android知识点:getText().toString()

getAttribute 或 getText [重复]

php动态加载模块gettext

textout.getText() 导致“可能产生'java.lang.NullPointerException'”消息

JavaScript 中的翻译就像 PHP 中的 gettext?

EditText.getText().toString() 崩溃