I want to have error messages, warnings and other user feedback from my package available in multiple languages. (R can translate the contents of message
, warning
, stop
, gettext
, and ngettext
.)
There is advice on how to do this in these documents:
The mgcv
and Rcmdr
(po dir) packages have translations, providing examples of how to do things.
Nevertheless, I'm struggling to get things working. Here's a reproducible package example:
On Windows you need to download and extract gettext-tools, and add the location to your Windows PATH
environment variable.
library(roxygen2)
library(devtools)
library(tools)
# Create the directories to hold the package content
Vectorize(dir.create)(c("test", "test/R", "test/man", "test/po"))
# Write the package DESCRIPTION file
cat(
'Package: test
Title: Test pkg
Description: Investigate how to translate content
Version: 0.0-1
Date: 2015-03-17
Author: Richard Cotton
Maintainer: Richard Cotton <[email protected]>
License: Unlimited',
file = "test/DESCRIPTION"
)
# Create a function go to into the package, plus its documentation
cat(
"#' Translatable messages
#' Some strings to be translated.
#' @param n A natural number.
#' @export
translatable <- function(n)
{
message('faucet')
cat(gettext('napkin'), '\n')
cat(ngettext(n, 'one', 'many', domain = 'R-test'), '\n')
}",
file = "test/R/translatable.R"
)
# Create the master translation file (American English)
xgettext2pot("test", "test/po/R-test.pot")
# Alter the master file to make British English and French translations
en <- readLines("test/po/R-test.pot")
en_gb <- en
en_gb[which(en_gb == 'msgid "faucet"') + 1] <- 'msgid "tap"'
en_gb[which(en_gb == 'msgid "napkin"') + 1] <- 'msgid "serviette"'
writeLines(en_gb, "test/po/R-en_GB.po")
fr <- en
fr[which(fr == 'msgid "faucet"') + 1] <- 'msgid "robinet"'
fr[which(fr == 'msgid "napkin"') + 1] <- 'msgid "serviette"'
fr[which(fr == 'msgid "one"') + 2] <- 'msgstr[0] "un"'
fr[which(fr == 'msgid_plural "many"') + 2] <- 'msgstr[1] "beaucoup"'
writeLines(fr, "test/po/R-fr.po")
# Build and install the package
pkg_file <- build("test")
install.packages(pkg_file, repos = NULL, type = "source")
Change your OS locale to English (United States)
(under Windows 7, it's in Control Panel -> Region and Language -> Formats -> Format) and restart R.
You should see the default text:
library(test)
translatable(1)
## faucet
## napkin
## one
translatable(2)
## faucet
## napkin
## many
Now change your locale to English (United Kingdom)
or to French (France)
, restart R, and rerun the example. I expected the text to change, but it doesn't.
Sys.getlocale()
reports a change in my locale, so that is definitely working.
capabilities("NLS")
returns TRUE
, so natural language support is switched on.
With a French locale, this example adapted from the mgcv::bam
help page gives me a French error message, so the problem is with how I've generated the package.
library(mgcv)
dat <- gamSim(1,n=25000,dist="normal",scale=20)
bs <- "cr";k <- 12
b <- bam(
y ~ s(x0,bs=bs)+s(x1,bs=bs)+s(x2,bs=bs,k=k)+s(x3,bs=bs),
data = dat,
family = list(family = NULL)
)
## Erreur dans bam(y ~ s(x0, bs = bs) + s(x1, bs = bs) + s(x2, bs = bs, k = k) + :
## famille non reconnue
What am I doing wrong?
In your browser, go to Google Translate. At the top, click Documents. Choose the languages to translate to and from. To automatically set the original language of a document, click Detect language.
Translating a webpage on any Android device is as simple as using Google Translate in the built-in Chrome browser. Open the Chrome app and when visiting a webpage in another language select “More” and then the target language at the bottom of the page.
A translation package is a ZIP file containing the service structure's XLIFFs and dynamic documents that are set to the proper preference value of Preparation State, one for each target language selected in Package Languages.
You haven't taken the step to compile and install your translations. And your .po files have problems.
Here's a working R-fr.po
file for your example:
msgid ""
msgstr ""
"Project-Id-Version: R 3.1.2\n"
"Report-Msgid-Bugs-To: bugs.r-project.org\n"
"POT-Creation-Date: 2015-03-17 09:46\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
msgid "faucet"
msgstr "robinet"
msgid "napkin"
msgstr "serviette"
msgid "one"
msgid_plural "many"
msgstr[0] "un"
msgstr[1] "beaucoup"
Note that you had msgid
where you should have msgstr
. You also did not specify the language, or the plural forms, and the "charset" variable threw an error during compilation.
Once you have the correct file, follow the directions under "preparing and installing a translation". Specifically, from the command line do the following:
mkdir test/inst/po/fr/LC_MESSAGES
msgfmt -c --statistics -o test/inst/po/fr/LC_MESSAGES/R-test.mo R-test.po
This will throw some errors and warnings if there are problems. If not, it should give a confirmation message.
Then rebuild the package and install it, and then try everything again:
library("test")
translatable(1)
## faucet
## napkin
## one
translatable(2)
## faucet
## napkin
## many
Sys.setenv(LANG = "fr")
translatable(1)
## robinet
## serviette
## un
> translatable(2)
## robinet
## serviette
## beaucoup
Note, you don't need to change your OS language. You can just set the LANG
environment variable to get the message translations.
On a related note, I find this process really annoying, so it's on my medium-term to-do list to create a package (this one, specifically) that I hope will simplify the process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With