有没有办法让 GNU gettext(或类似的东西)处理 scala 文件?
Is there any way go get GNU xgettext (or something similar) to work with scala files?
我们正在使用 GNU gettext utilities 直接从我们的代码库创建 PO 文件。然而,问题是我们的一些代码库是用 Scala 编写的(大部分是 Java)。我们正在使用 gradle 进行构建和部署。
据我所知,根据 xgettext 文档,Scala 不是受支持的语言:
5.1.3 Choice of input file language
‘-L name’
‘--language=name’
Specifies the language of the input files.
The supported languages are C, C++, ObjectiveC, PO, Shell, Python, Lisp, EmacsLisp, librep, Scheme, Smalltalk, Java, JavaProperties, C#, awk, YCP, Tcl, Perl, PHP, GCC-source, NXStringTable, RST, RSJ, Glade, Lua, JavaScript, Vala, GSettings, Desktop.
有什么方法可以对 Scala 文件使用 xgettext 吗?我发现 this sbt compiler plugin 可以满足我们的需求,但不幸的是我们使用的是 gradle 而不是 sbt.
Perl 模块 Locale::XGettext 允许您为几乎所有文本格式编写自己的 xgettext 变体。您只需为能够提取字符串的 language/format 提供解析器。
可以用最少的 Perl 样板代码在 Java 中编写解析器。我在博客中描述了这个过程 post Extending Xgettext With Locale::XGettext. A sample extractor in Java is available at https://github.com/gflohr/Locale-XGettext/tree/master/samples/Java
免责声明:本人是上述所有软件和文档的作者!
如果与 Perl 代码交互听起来太复杂,您也可以只用您选择的语言为 Scala 编写一个解析器,运行 该解析器在 xgettext 之前,并将所有可翻译的字符串转储为您可以使用的格式xgettext
的版本可以理解,例如 C:
gettext("Hello, world!");
gettext("Another string.");
然后您只需使用生成的虚拟源文件作为 xgettext
的输入以及构建设置中的其他源文件。
可能值得注意的是 xgettext
将始终将 .po
和 .pot
文件识别为输入,即使您使用 --language=java
调用它也是如此。这意味着,如果您找到生成 .po
/.pot
文件的方法,那么 .po
或 .pot
文件最适合从 Scala 文件中转储可翻译字符串。
最后,gettext 工具的源代码被设计为可扩展的。如果您能够用 C 编写字符串提取器和格式检查器,则可以添加 Scala 语言。但是,您不能在 运行 时添加对另一种语言的支持,但您必须编译自己的版本xgettext
或将您的提取器贡献给 GNU gettext 项目。
我使用了一个非常简单的解决方案,我将 Vala 指定为 xgettext 的语言。它在转义文字和函数调用语法方面非常接近 Scala。这不是一个严格的解决方案,但在我的实践中它对我来说已经足够好了。
我有一个 Po
class 保存消息目录,并允许我通过几个简单的方法执行翻译:
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 在遇到它们时警告 "unterminated literal",但无论如何都会进行。
IIRC,甚至 -c
命令行参数也可以用来支持对翻译消息的评论,这对翻译人员来说非常有用。
实践中的一些观察结果并未直接回答原始问题:
- 如果我再次执行此操作,方法
t
、tc
、... 将不会 return 直接转换为字符串,而是一些 LocalizableMessage
封装原始字符串和扩展参数,稍后可以通过适当的目录进行延迟翻译。
- 我不使用方法
tn
(处理复数的 gettext 方式)。我建议使用更通用的 ICU 消息扩展库或类似的东西。
我们正在使用 GNU gettext utilities 直接从我们的代码库创建 PO 文件。然而,问题是我们的一些代码库是用 Scala 编写的(大部分是 Java)。我们正在使用 gradle 进行构建和部署。
据我所知,根据 xgettext 文档,Scala 不是受支持的语言:
5.1.3 Choice of input file language
‘-L name’
‘--language=name’ Specifies the language of the input files.
The supported languages are C, C++, ObjectiveC, PO, Shell, Python, Lisp, EmacsLisp, librep, Scheme, Smalltalk, Java, JavaProperties, C#, awk, YCP, Tcl, Perl, PHP, GCC-source, NXStringTable, RST, RSJ, Glade, Lua, JavaScript, Vala, GSettings, Desktop.
有什么方法可以对 Scala 文件使用 xgettext 吗?我发现 this sbt compiler plugin 可以满足我们的需求,但不幸的是我们使用的是 gradle 而不是 sbt.
Perl 模块 Locale::XGettext 允许您为几乎所有文本格式编写自己的 xgettext 变体。您只需为能够提取字符串的 language/format 提供解析器。
可以用最少的 Perl 样板代码在 Java 中编写解析器。我在博客中描述了这个过程 post Extending Xgettext With Locale::XGettext. A sample extractor in Java is available at https://github.com/gflohr/Locale-XGettext/tree/master/samples/Java
免责声明:本人是上述所有软件和文档的作者!
如果与 Perl 代码交互听起来太复杂,您也可以只用您选择的语言为 Scala 编写一个解析器,运行 该解析器在 xgettext 之前,并将所有可翻译的字符串转储为您可以使用的格式xgettext
的版本可以理解,例如 C:
gettext("Hello, world!");
gettext("Another string.");
然后您只需使用生成的虚拟源文件作为 xgettext
的输入以及构建设置中的其他源文件。
可能值得注意的是 xgettext
将始终将 .po
和 .pot
文件识别为输入,即使您使用 --language=java
调用它也是如此。这意味着,如果您找到生成 .po
/.pot
文件的方法,那么 .po
或 .pot
文件最适合从 Scala 文件中转储可翻译字符串。
最后,gettext 工具的源代码被设计为可扩展的。如果您能够用 C 编写字符串提取器和格式检查器,则可以添加 Scala 语言。但是,您不能在 运行 时添加对另一种语言的支持,但您必须编译自己的版本xgettext
或将您的提取器贡献给 GNU gettext 项目。
我使用了一个非常简单的解决方案,我将 Vala 指定为 xgettext 的语言。它在转义文字和函数调用语法方面非常接近 Scala。这不是一个严格的解决方案,但在我的实践中它对我来说已经足够好了。
我有一个 Po
class 保存消息目录,并允许我通过几个简单的方法执行翻译:
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 在遇到它们时警告 "unterminated literal",但无论如何都会进行。
IIRC,甚至 -c
命令行参数也可以用来支持对翻译消息的评论,这对翻译人员来说非常有用。
实践中的一些观察结果并未直接回答原始问题:
- 如果我再次执行此操作,方法
t
、tc
、... 将不会 return 直接转换为字符串,而是一些LocalizableMessage
封装原始字符串和扩展参数,稍后可以通过适当的目录进行延迟翻译。 - 我不使用方法
tn
(处理复数的 gettext 方式)。我建议使用更通用的 ICU 消息扩展库或类似的东西。