In R there are several ways to support multilingual messages:
You can access translation services that usually require a paid account, such as
deeplr
- a wrapper for the DeepL
Pro API,googleLanguageR
- calls Google’s ‘Natural Language’ API, ‘Cloud Translation’ API and so
on, andgtranslate
- translating between different languages (which does not require a
Google account).There are also key-based approaches such as the translated
library, which is based on JSON files. The stranslate
package also uses a key-based approach, but is based on plain text files
(as a lazy guy, I don’t want to follow the JSON typing rules ;).
stranslate
The first step is to load one or more files with translations
library("stranslate")
file <- system.file("messages", "messages.txt", package="stranslate")
loadMsg(file) # load the translation(s)
and to show what has been loaded
listMsg() # show all loaded keys and domains
#>
#> Current domain : domain
#> Current language: lang -> en
#>
#> Domain: d
#> Language: l
#> COPYRIGHT, LANGUAGE, DOMAIN, CURRENT_LANGUAGE, CURRENT_DOMAIN
#> MISSING_KEYS, UNDEFINED_KEYS, KEY_NOT_FOUND, KEY_LENGTH, DOMAIN_UNIQUE
#> lang, key
#> Language: l
#> COPYRIGHT, LANGUAGE, DOMAIN, CURRENT_LANGUAGE, CURRENT_DOMAIN
#> MISSING_KEYS, UNDEFINED_KEYS, KEY_LENGTH, KEY_NOT_FOUND, DOMAIN_UNIQUE
#> lang, key
#>
#> Domain: d
#> Language: l
#> ROUND, PHOTO, COUNT, STREAM, user, gender
#> Language: l
#> ROUND, PHOTO, COUNT, STREAM, user, gender
We can access from the default
domain some messages
getMsg(ROUND=3)
#> [1] "Round your result to 3 decimal places"
getMsg(ROUND=3, .lang="de")
#> [1] "Runden Sie ihr Ergebnis auf 3 Nachkommastellen"
getMsg(ROUND=1)
#> [1] "Round your result to one decimal place"
getMsg(ROUND=1, .lang="de")
#> [1] "Runden Sie ihr Ergebnis auf eine Nachkommastelle"
Instead of ROUND
you could use 'ROUND'
,
especially if you write a package. Since English is the fallback
language, an English translation must be there.
And a multi-line example:
loadMsg(system.file("messages", "Rdewiki.txt", package="stranslate")) # load the translation(s)
getMsg("Rdewiki", .lang="en")
#> [1] "R is a free programming language for statistical calculations and graphics. It\nwas newly developed in 1992 by statisticians for users with statistical tasks.\nThe syntax is based on the programming language S, with which R is largely\ncompatible, and the semantics are based on Scheme. As a standard distribution,\nR is supplied with an interpreter as a command line environment with reduced\ngraphical buttons. Thus R is currently available on the most important platforms;\nthe environment is also explicitly referred to as R by the developers. R is part\nof the GNU project. RStudio is also offered as an integrated development\nenvironment and to increase R's user-friendliness.\nTranslated with https://www.deepl.com/translator"
getMsg(Rdewiki, .lang="de")
#> [1] "R ist eine freie Programmiersprache für statistische Berechnungen und Grafiken.\nSie wurde 1992 von Statistikern für Anwender mit statistischen Aufgaben neu\nentwickelt. Die Syntax orientiert sich an der Programmiersprache S, mit der R\nweitgehend kompatibel ist, und die Semantik an Scheme. Als Standarddistribution\nwird R mit einem Interpreter als Kommandozeilenumgebung mit reduzierten\ngrafischen Schaltflächen angeboten. So ist R aktuell auf den wichtigsten\nPlattformen verfügbar; die Umgebung wird von den Entwicklern ausdrücklich\nebenfalls als R bezeichnet. R ist Teil des GNU-Projekt. Als integrierte\nEntwicklungsumgebung und um die Benutzerfreundlichkeit von R zu erhöhen, wird\naußerdem RStudio angeboten.\nQuelle: https://de.wikipedia.org/wiki/R_(Programmiersprache)\n"
As you could see a key can have a parameter, also additional parameters are allowed. The current example is taken from Project fluent.
getMsg(PHOTO=5, user="Anne", gender="female")
#> [1] "Anne added 5 new photos to her stream"
getMsg(PHOTO=5, user="Anne", gender="female", .lang="de")
#> [1] "Anne fügt 5 neue Fotos ihrem Stream zu"
getMsg(PHOTO=0, user="Bert", gender="male")
#> [1] "Bert added 0 new photos to his stream"
getMsg(PHOTO=1, user="Bert", gender="male", .lang="de")
#> [1] "Bert fügt ein neues Foto seinem Stream zu"
If you want to know which languages will be used then use
language
.
# use German spoken in South Tirol (Italy)
# but available onby standard german and german spoken in Austria
language('de_IT', c('de', 'de_AT'))
#> [1] "de" "en"
Since de_IT
is not available, de is used first. If a key
is not available in de
, en
is used. This is
the reason why you need to provide an English translation. Although all
languages are equal, English is particularly important in R. Most
commands and functions are based on English words.
A domain separates messages in different subsets. There are two domains:
stranslate
used by the package stranslate
anddefault
the user domain.If you do not want to load messages into the default domain, use
loadMsg(file, .domain="mydomain") # load the translation(s)
listMsg()
#>
#> Current domain : domain
#> Current language: lang -> en
#>
#> Domain: d
#> Language: l
#> COPYRIGHT, LANGUAGE, DOMAIN, CURRENT_LANGUAGE, CURRENT_DOMAIN
#> MISSING_KEYS, UNDEFINED_KEYS, KEY_NOT_FOUND, KEY_LENGTH, DOMAIN_UNIQUE
#> lang, key
#> Language: l
#> COPYRIGHT, LANGUAGE, DOMAIN, CURRENT_LANGUAGE, CURRENT_DOMAIN
#> MISSING_KEYS, UNDEFINED_KEYS, KEY_LENGTH, KEY_NOT_FOUND, DOMAIN_UNIQUE
#> lang, key
#>
#> Domain: d
#> Language: l
#> ROUND, PHOTO, COUNT, STREAM, user, gender
#> Language: l
#> ROUND, PHOTO, COUNT, STREAM, user, gender
#>
#> Domain: d
#> Language: l
#> ROUND, PHOTO, COUNT, STREAM, Rdewiki, user, gender
#> Language: l
#> ROUND, PHOTO, COUNT, STREAM, Rdewiki, user, gender
If you want to use your domain as the default domain, do the following
of use the .domain='mydomain'
parameter in
getMsg
.
txt
fileIn the translation file is the first character in a line important:
#
then a one line comment
starts.<
then you are changing to
this language.?
then condition on the key
starts.# switch to german
< de
# start key with its default message, note that `r ROUND` is replaced by its value
ROUND Runden Sie ihr Ergebnis auf `r ROUND` Nachkommastellen
# if ROUND==0 then use this message
?0 Runden Sie ihr Ergebnis auf eine ganze Zahl
# if ROUND==1 then use this message
?1 Runden Sie ihr Ergebnis auf eine Nachkommastelle
# otherwise use the default message
ATTENTION: All comparison are character comparisons.
If in doubt, make sure you convert your parameters yourself,
e.g. getMsg(ROUND=as.character(3))
.
As you can seem we use the Rmarkdown inline notation for R and
internally is knitr::knit
is used. This allows calculations
with the parameters.
ATTENTION: Neither R code chunks nor other engines than R are supported.
Other parameters given to getMsg
,
e.g. getMsg(ROUND=3, user='Anne')
can be used in a message,
e.g.
You can also call another key in a message with a specific value, e.g.
setLang('en', "R") # choose language and another domain
setMsg('ROUND'='Round your result to `r ROUND` decimal places',
'0'='Round your result to an integer',
'1'='Round your result to one decimal place')
setMsg(PHOTO='`r user` added `r COUNT(PHOTO)` to `r STREAM(gender)` stream')
setMsg(COUNT='`r PHOTO` new photos', '1'='a new photo')
setMsg(STREAM='their', 'male'='his', 'female'='her')
#
setLang('de', 'R')
setMsg(ROUND='Runden Sie ihr Ergebnis auf `r ROUND` Nachkommastellen',
'0'='Runden Sie ihr Ergebnis auf eine ganze Zahl',
'1'='Runden Sie ihr Ergebnis auf eine Nachkommastelle')
setMsg(PHOTO='`r user` fügt `r COUNT(PHOTO)` `r STREAM(gender)` Stream zu')
setMsg(COUNT='`r PHOTO` neue Fotos', '1'= 'ein neues Foto')
setMsg(STREAM='seinem', 'female'='ihrem')
#
getMsg(ROUND=3, .domain="R")
#> [1] "Round your result to 3 decimal places"
stranslate
messages.txt
< de
ROUND Runden Sie ihr Ergebnis auf `r ROUND` Nachkommastellen
?0 Runden Sie ihr Ergebnis auf eine ganze Zahl
?1 Runden Sie ihr Ergebnis auf eine Nachkommastelle
PHOTO `r user` fügt `r COUNT(PHOTO)` `r STREAM(gender)` Stream zu
COUNT `r COUNT` neue Fotos
?1 ein neues Foto
STREAM seinem
?female ihrem
< en
ROUND Round your result to `r ROUND` decimal places
?0 Round your result to an integer
?1 Round your result to one decimal place
PHOTO `r user` added `r COUNT(PHOTO)` to `r STREAM(gender)` stream
COUNT `r COUNT` new photos
?1 a new photo
STREAM their
?male his
?female her
Rdewiki.txt
< de
Rdewiki R ist eine freie Programmiersprache für statistische Berechnungen und Grafiken.
Sie wurde 1992 von Statistikern für Anwender mit statistischen Aufgaben neu
entwickelt. Die Syntax orientiert sich an der Programmiersprache S, mit der R
weitgehend kompatibel ist, und die Semantik an Scheme. Als Standarddistribution
wird R mit einem Interpreter als Kommandozeilenumgebung mit reduzierten
grafischen Schaltflächen angeboten. So ist R aktuell auf den wichtigsten
Plattformen verfügbar; die Umgebung wird von den Entwicklern ausdrücklich
ebenfalls als R bezeichnet. R ist Teil des GNU-Projekt. Als integrierte
Entwicklungsumgebung und um die Benutzerfreundlichkeit von R zu erhöhen, wird
außerdem RStudio angeboten.
Quelle: https://de.wikipedia.org/wiki/R_(Programmiersprache)
< en
Rdewiki R is a free programming language for statistical calculations and graphics. It
was newly developed in 1992 by statisticians for users with statistical tasks.
The syntax is based on the programming language S, with which R is largely
compatible, and the semantics are based on Scheme. As a standard distribution,
R is supplied with an interpreter as a command line environment with reduced
graphical buttons. Thus R is currently available on the most important platforms;
the environment is also explicitly referred to as R by the developers. R is part
of the GNU project. RStudio is also offered as an integrated development
environment and to increase R's user-friendliness.
Translated with https://www.deepl.com/translator
stranslate.txt
< de
COPYRIGHT (C) 2023+ S. Klinke, Humboldt-Universität zu Berlin
LANGUAGE Sprache: `r LANGUAGE`
DOMAIN Domäne : `r DOMAIN`
CURRENT_LANGUAGE Aktuelle Sprache: `r CURRENT_LANGUAGE`
CURRENT_DOMAIN Aktuelle Domäne : `r CURRENT_DOMAIN`
MISSING_KEYS Für die Sprache '`r lang`' fehlt der/die Schlüssel: `r MISSING_KEYS`
UNDEFINED_KEYS Undefinierte Schlüssel: `r UNDEFINED_KEYS`
KEY_LENGTH 'key' muss die Länge 1 haben, vielleicht funktioniert '"key"'
KEY_NOT_FOUND Schlüssel '`r key`' nicht in '`r lang`' gefunden, vielleicht meinten Sie:
DOMAIN_UNIQUE Es muss eine eindeutige Domäne angegeben werden
< en
COPYRIGHT (C) 2023+ S. Klinke, Humboldt-Universität zu Berlin
LANGUAGE Language: `r LANGUAGE`
DOMAIN Domain: `r DOMAIN`
CURRENT_LANGUAGE Current language: `r CURRENT_LANGUAGE`
CURRENT_DOMAIN Current domain : `r CURRENT_DOMAIN`
MISSING_KEYS Missing for language '`r lang`' the key(s): `r MISSING_KEYS`
UNDEFINED_KEYS Undefined key(s): `r UNDEFINED_KEYS`
KEY_NOT_FOUND Key '`r key`' not found in '`r lang`', maybe you meant:
KEY_LENGTH 'key' must have length 1, maybe '"key"' works
DOMAIN_UNIQUE A unique domain must be specified
messages.R
setLang('en') # adds to domain 'default'
setMsg('ROUND'='Round your result to `r ROUND` decimal places',
'0'='Round your result to an integer',
'1'='Round your result to one decimal place')
setMsg(PHOTO='`r user` added `r COUNT(PHOTO)` to `r STREAM(gender)` stream')
setMsg(COUNT='`r PHOTO` new photos',
'1'='a new photo')
setMsg(STREAM='their',
'male'='his',
'female'='her')
#
setLang('de') # adds to domain 'default'
setMsg(ROUND='Runden Sie ihr Ergebnis auf `r ROUND` Nachkommastellen',
'0'='Runden Sie ihr Ergebnis auf eine ganze Zahl',
'1'='Runden Sie ihr Ergebnis auf eine Nachkommastelle')
setMsg(PHOTO='`r user` fügt `r COUNT(PHOTO)` `r STREAM(gender)` Stream zu')
setMsg(COUNT='`r PHOTO` neue Fotos',
'1'= 'ein neues Foto')
setMsg(STREAM='seinem',
'female'='ihrem')