The attached script adds a function that allows you to have a separate translation file that can be used to provide alternate translations for a javascript tool. The idea is based on a function in wordpress that has similar functionality.
I named the file somewhat cryptic '1ang.js' to try to get it to load before all other scripts. This may or may not work - seems OK on my system but let me know.
To use, extract the zip file and put the contents in the javascripts folder and restart PDF-XChange. It includes a sample translation file.
It adds a single global function __(textToLocalize, domain, params...) -- the function name is a double underscore -- which you use on a plain string in your code.
Code: Select all
// Instead of writing
app.alert("Hello World!");
// make the alert translateable with the 'sample' translation domain
app.alert( __("Hello World!", "sample") );
- textToLocalize is the text you want to output to the user and be translateable. It must exactly match text in the translation file (including case, punctuation, etc).
domain refers to the name of the translation file that will be used
params... are optional strings you want to substitute back into the text after it's been translated. They are referred to in the textToLocalize as %n where n is parameter number: %1 for the first parameter, %2 for the second, etc. This is useful for adding dynamically generated content that would otherwise prevent the translation string from matching. Use %%1 if you want to literally output %1.
The included translation file has translations for the following two phrases to German and Italian, using domain 'sample':
- Hello World!
- There are %1 options.
Code: Select all
__("Hello World!", 'sample')
Code: Select all
Salve, mondo!
Code: Select all
__("There are %1 options.", 'sample', 12)
Code: Select all
Es gibt 12 Optionen.
Code: Select all
There are 12 options.
There is rudimentary support for adding plurals to translations. Whether it is plural is based on the %1 parameter. The format is to put the list of plural options inside square brackets:
Code: Select all
"ENU": {
# Example of using plurals - last one is default
"There are %1 options.": ["There is only one option.", "There are two options.", "There are three options.", "There are %1 options."]
}
Code: Select all
__("There are %1 options.",'sample',1);
// There is only one option.
__("There are %1 options.",'sample',3);
// There are three options.
Code: Select all
__("There are %1 options.",'sample',12);
// There are 12 options.
__("There are %1 options.",'sample',"ten");
// There are ten options.
- I was having some trouble with non-ASCII unicode characters. I think the problem may have been related to text file encoding (must be encoded UTF-8 I think), but if someone who works in an alphabet with extended unicode (such as accents, and other letters like Eszett in German, or Chinese/Japanese/Korean/... characters) has time to try it, I'd like to figure it out.
- The function must load before you can use it. This is generally going to always be fine for menus, but if you have app.addToolButton() at the beginning of a tool that loads before this function, you may have problems trying to localize the displayed text in the tool button. I don't know how PXE determines the order that files are loaded in the Javascripts folder - I assume it's alphabetically and it's working for me that way - but this may be random luck.
Filename must be "translationData.<domain>.json" and saved in the javascripts folder. <domain> should be a unique text string to your script. Set the encoding to 'UTF-8' (I think -- someone more knowledgeable should confirm this).
This file must be formatted as a JSON file except that lines starting with # are stripped out before processing: Use that to add comments as needed.
"Language" is three letter code as output from app.language. The following are listed in the API but there may be more. You can find your language by running app.language in the javascript console:
"Original Text" is case sensitive and must match exactly including punctuation!
Translation File Format:
Code: Select all
{
"Language": {
"Original Text": "Translated Text",
# optional comments must be on their own line
"Original Text 2": "Translated Text 2"
},
"Language 2": {
"Original Text": "Translated Text in Language 2"
# Not all items need to be translated in every language
},
"Language 3": {
# Plurals from v1.0 onwards
"Original Text": ["Translated Singular", "Translated Plural"]
}
I made a tool to both help with editing the translation files, and extracting textToLocalize strings from the javascript file directly.
- The first page has a field you can paste the textToLocalize strings into so you can edit them with the tool.
- The second page has form fields that allow you to edit the translations in a more user friendly manner. I've added some buttons to upload the strings to google translate, but it still requires some copy and pasting.
- The last page is a tool that allows you to extract the textToLocalize strings from a Javascript file.
Notes
To avoid having to repeat the domain every time this function is called, one could define a function within the script that substitutes in the domain; something like:
Code: Select all
function yourMenuFunction() {
// function to be used inside a script for domain 'sample'
const _ = (text, ...args) => __(text, 'sample', ...args);
// used thus:
_("Text to be translated.");
...
}