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()
textout.getText() 导致“可能产生'java.lang.NullPointerException'”消息