我使用了一个非常简单的解决方案,我将 Vala 指定为 xgettext 的语言。在转义文字和函数调用语法方面,它与 Scala 非常接近。这不是一个严格的解决方案,但在我的实践中,它对我来说已经足够好了。
我有一个Po
类保存消息目录,并允许我通过几个简单的方法执行翻译:
def t(singular: String): String = lookupSingular(None, singular)
def tf(singular: String, parameters: Any*): String = format(t(singular), Array(parameters: _*))
def tc(ctx: String, singular: String): String = lookupSingular(Some(ctx), singular)
def tcf(ctx: String, singular: String, parameters: Any*): String = format(lookupSingular(Some(ctx), singular), Array(parameters: _*))
def tn(singular: String, plural: String, n: Long): String = lookupPlural(None, singular, plural, n)
def tcn(ctx: String, singular: String, plural: String, n: Long): String = lookupPlural(Some(ctx), singular, plural, n)
t
代表 Translate,f
代表 Formatted(有参数),c
代表 Context(意思是 gettext 上下文,以及将其与具有相同文本的其他消息区分开来的消息的附加信息),n
代表指定 N 的复数。你可以编自己的名字。
这些方法既可用作执行翻译的方法,又可用作 xgettext 的标记,以.pot
从源代码中提取文件。
我使用这样的:
new JMenuItem(po.t("Copy to clipboard"))
new JButton(po.tc("errorDialog", "Copy to clipboard"))
po.tf("Camera {0}", number),
等等
通过这个设置,我像这样运行 xgettext:
xgettext \
--package-name="xxx" \
-ktc:1c,2 \
-ktcf:1c,2 \
-ktnc:1c,2,3 \
-ktf \
-kt \
-ktn:1,2 \
-o "output.po" \
$(find "DIRECTORY" -name *.scala) 2>&1 | grep -v "extension 'scala' is unknown; will try C"
重要的部分是-k
参数,它将自定义 xgettext 关键字直接映射到我的方法名称。这样,xgettext 可以配置为使用自定义关键字。
但是,不支持 Scala 的三引号。xgettext 在遇到它们时会警告“未终止的文字”,但无论如何都会进行。
IIRC,甚至-c
命令行参数也可以用来支持对已翻译消息的评论,这对翻译者来说非常有用。
实践中的一些观察结果并没有直接回答原始问题:
- 如果我再次实现它,方法
t
, tc
, ... 将不会直接返回翻译后的字符串,而是一些LocalizableMessage
封装原始字符串和扩展参数的方法,稍后可以通过适当的目录懒惰地翻译。
- 我不使用这些方法
tn
(gettext 处理复数的方式)。我建议使用更通用的 ICU 消息扩展库或类似的东西。