作为C ++应用程序的构建步骤(使用CMake作为构建系统),我需要创建一些模板文件,其中应包含本地化的字符串。
字符串已经可以通过gettext .po文件的形式从翻译器中获得(与用于翻译应用程序本身的字符串相同)。
因此,我需要一种从.po文件中提取翻译成给定英语源字符串的方法(通过Bash / shell或通过CMake)
到目前为止,我想到的是以下内容
translated_string=$(
msggrep --msgid -e "^${untranslated_string}$" ${po_file} \
| msgattrib --no-fuzzy \
| grep -A 1 'msgid "${untranslated_string}$"' \
| sed -n 's/msgstr "\(.*\)"/\1/p'
)
显然,这些都是对“简单”函数的大量调用:
msggrep
输出的.po文件只有我想要的字符串msgattrib
确保翻译不“模糊”(即需要更新),因为我不能使用这些翻译grep
和sed
手动提取翻译我想必须有更好的方法吗?毕竟gettext确实使在运行时转换我的应用程序变得容易,但是在构建时似乎有点不灵活...
答案 0 :(得分:1)
.po
文件供翻译人员使用。软件应使用已编译的.mo
文件来检索翻译。
GNU gettext附带了一个二进制gettext
,用于对shell脚本进行国际化。您可以按以下目的使用它:
$ mkdir -p de/LC_MESSAGES 2>/dev/null
$ msgfmt --verbose --statistics de.po -o de/LC_MESSAGES/package.mo
$ TEXTDOMAINDIR=. LANGUAGE=de LANG=de_DE.UTF-8 LC_MESSAGES=de_DE.UTF-8 gettext package 'Hello, world!'
用您的文本域“ Hello,world!”替换“ package”。使用您的消息ID和de
使用您选择的语言。请注意,这要求在构建系统上安装选定的语言环境-在这种情况下为de
语言环境。
有关更多信息,请参见gettext(1)
和msgfmt(1)
。
答案 1 :(得分:-1)
按照Guido Flohr在https://stackoverflow.com/a/54707280/2514664中的建议,使用二进制.mo文件并从那里提取字符串是一种可行的解决方案。
但是,按照原始答案中的建议,使用本地gettext
可执行文件最终提取字符串的结果却具有太多含义(毕竟,它旨在在最适合的语言环境中提取用户可见的字符串)为用户从现有消息目录中提供,而不是作为“仅”必须从特定文件中以特定语言提取单个字符串的构建工具)。对于要在多个平台上运行的构建系统而言,它最终太脆弱了。
我原来使用Python,它的自定义gettext module效果更好,并且可以节省很多工作(特别是如果您对Python感到满意的话)。
按照链接的答案中的建议,可以从.po文件生成.mo文件:
mkdir -p locale/de/LC_MESSAGES
msgfmt de.po -o locale/de/LC_MESSAGES/package.mo
用Python进行翻译并不像
那样简单。import gettext
translation = gettext.translation('package', localedir='locale', languages=['de'])
translated_string = translation.gettext('unstranslated_string')
顺便说一句。解决我自己的问题后,我发现我的Python发行版的“ / Tools / i18n”文件夹中还有一个msgfmt.py
和pygettext.py
,它们应该提供与msgfmt
相同的功能,并且gettext
自己。两者都可能很有趣,可以直接使用,也可以查看它们的实现来创建新的东西(例如,msgfmt.py包括一个简单的.po文件解析器)。