Scaposer is a GNU gettext po file parser written in Scala. It's strange that there's not many JVM libraries of this kind, see the discussion on Stackoverflow.
To extract i18n strings from Scala source code files, use Scala xgettext.
Presentation: I18nize Scala programs à la gettext
Discussion group: https://groups.google.com/group/scala-xgettext
See Scaladoc.
val po = """ msgid "Hello" msgstr "Bonjour" """ val result = scaposer.Parser.parse(po) // => An Either, // Left(scaposer.ParseFailure) or // Right(Seq[scaposer.Translation])
Use t
methods to get the translations:
val translations = result.right.get val i18n = scaposer.I18n(translations) i18n.t("Hello") // => "Bonjour"
If there's no translation, or the translation is an empty string (not translated yet), the original input is returned:
i18n.t("Hi") // => "Hi"
val po = """ msgid "Hello" msgstr "Bonjour" msgctxt "Casual" msgid "Hello" msgstr "Salut" """ val translations = scaposer.Parser.parse(po).right.get val i18n = scaposer.I18n(translations) i18n.tc("Casual", "Hello") // => "Salut"
If there's no translation for the context, the translation without context is tried:
i18n.tc("Missing context", "Hello") // => "Bonjour"
Your po file must define Plural-Forms
exactly as at:
- http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html#Plural-forms
- http://www.gnu.org/software/gettext/manual/html_node/Translating-plural-forms.html#Translating-plural-forms
Scaposer does not evaluate the plural
expression, which is in C language.
It just removes spaces in the expression and performs string comparison. See
evaluatePluralForms.
val po = """ msgid "" msgstr "Plural-Forms: nplurals=2; plural=n>1;" msgid "I have one apple" msgid_plural "I have %d apples" msgstr[0] "J'ai une pomme" msgstr[1] "J'ai %d pommes" """ val translations = scaposer.Parser.parse(po).right.get val i18n = scaposer.I18n(translations) i18n.tn("I have one apple", "I have %d apples", 1) // => "J'ai une pomme" i18n.tn("I have one apple", "I have %d apples", 2) // => "J'ai 2 pommes" i18n.tcn("A context", "I have one apple", "I have %d apples", 3) // => "J'ai 3 pommes"
You can merge multiple ``I18n``s together.
val i18n4 = i18n1 ++ i18n2 ++ i18n3
Just like when you merge maps, translations in i18n3 will overwrite those in i18n2 will overwrite those in i18n1.
Supported Scala versions: 2.11.x, 2.10.x
build.sbt example:
libraryDependencies += "tv.cntt" %% "scaposer" % "1.7"
Scaposer is used in Xitrum web framework.