... | @@ -17,6 +17,7 @@ The code must be able to handle the following: |
... | @@ -17,6 +17,7 @@ The code must be able to handle the following: |
|
|
|
|
|
The mechanism for specifying the selected language has yet to be determined, but the page author should be able to give a default language, and users should be able to override that if they choose.
|
|
The mechanism for specifying the selected language has yet to be determined, but the page author should be able to give a default language, and users should be able to override that if they choose.
|
|
|
|
|
|
|
|
|
|
## Overview ##
|
|
## Overview ##
|
|
|
|
|
|
A new `Localization` object will be added to the `MathJax` variable to handle localization functions. This will include the data needed for the translations into the selected language, the methods to be called for obtaining those translations, and the methods needed for loading and registering translations.
|
|
A new `Localization` object will be added to the `MathJax` variable to handle localization functions. This will include the data needed for the translations into the selected language, the methods to be called for obtaining those translations, and the methods needed for loading and registering translations.
|
... | @@ -25,6 +26,7 @@ Currently all messages used in MathJax are in English, and the text of these mes |
... | @@ -25,6 +26,7 @@ Currently all messages used in MathJax are in English, and the text of these mes |
|
|
|
|
|
One approach would be to use these message strings as the keys for looking up the translations, but this would make it harder to modify the English messages if rewording were required, or if spelling errors were found. Instead, each message will have an ID string that will be used to identify the phrase so that the English can be changed without requiring all the translation files to be modified to reflect the change. This also has the advantage the the same word or phrase, when used in different ways, can have different identifiers, so "Post" as a verb and "Post" as a noun can be translated differently, if necessary.
|
|
One approach would be to use these message strings as the keys for looking up the translations, but this would make it harder to modify the English messages if rewording were required, or if spelling errors were found. Instead, each message will have an ID string that will be used to identify the phrase so that the English can be changed without requiring all the translation files to be modified to reflect the change. This also has the advantage the the same word or phrase, when used in different ways, can have different identifiers, so "Post" as a verb and "Post" as a noun can be translated differently, if necessary.
|
|
|
|
|
|
|
|
|
|
## Getting a Translated String ##
|
|
## Getting a Translated String ##
|
|
|
|
|
|
The basic means of obtaining the string to use for a message to display to the user is to call the `_()` method of the `MathJax.Localization` object, passing the string id and the English phrase. For example,
|
|
The basic means of obtaining the string to use for a message to display to the user is to call the `_()` method of the `MathJax.Localization` object, passing the string id and the English phrase. For example,
|
... | @@ -47,6 +49,9 @@ The advantage of having both the identifier and the English string together is t |
... | @@ -47,6 +49,9 @@ The advantage of having both the identifier and the English string together is t |
|
2. The English version is available to use as a fallback if the phrase has not been translated into the selected language.
|
|
2. The English version is available to use as a fallback if the phrase has not been translated into the selected language.
|
|
3. The English translation doesn't need to be loaded separately (i.e., you don't need to load two language files, the selected one, plus English for fallback, and English users won't need to download any language files at all).
|
|
3. The English translation doesn't need to be loaded separately (i.e., you don't need to load two language files, the selected one, plus English for fallback, and English users won't need to download any language files at all).
|
|
|
|
|
|
|
|
|
|
|
|
### Id's and Domains ###
|
|
|
|
|
|
Using short identifiers can lead to collisions if not handled carefully. To help avoid this, we introduce identifier *domains* that are used to isolate collections of identifiers for one component of MathJax from those for another component. For example, each input jax could have its own domain, as could each extension. This means you only have to worry about collisions within your own domain, and so can more easily manage the uniqueness id's in use.
|
|
Using short identifiers can lead to collisions if not handled carefully. To help avoid this, we introduce identifier *domains* that are used to isolate collections of identifiers for one component of MathJax from those for another component. For example, each input jax could have its own domain, as could each extension. This means you only have to worry about collisions within your own domain, and so can more easily manage the uniqueness id's in use.
|
|
|
|
|
|
To use a domain with your id, pass `_()` an array consisting of the domain and the id in place of the id. For example, the TeX input jax could use
|
|
To use a domain with your id, pass `_()` an array consisting of the domain and the id in place of the id. For example, the TeX input jax could use
|
... | @@ -63,5 +68,79 @@ in which case the message above could become |
... | @@ -63,5 +68,79 @@ in which case the message above could become |
|
|
|
|
|
This lets you avoid having to repeat the domain within every call to `_()` in the input jax. (It would also be possible for `TEX.Error()` to call `_()` for you, but see below for information about obtaining the translation data.)
|
|
This lets you avoid having to repeat the domain within every call to `_()` in the input jax. (It would also be possible for `TEX.Error()` to call `_()` for you, but see below for information about obtaining the translation data.)
|
|
|
|
|
|
...
|
|
|
|
|
|
### Substitutions ###
|
|
|
|
|
|
|
|
Many messages need to include words that are not available until run time (like file names, or a token that is causing an error, etc.). To include such values in a message, pass the values to `_()` following the main message string, and use `%1`, `%2`, etc., within the message to indicate where to put the additional strings. For example
|
|
|
|
|
|
|
|
MathJax.Message.Set(_("fnf","File %1 not found"));
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
TEX.Error(_("'%1' seen where '%2' was expected",token,delimiter));
|
|
|
|
|
|
|
|
Note that the extra arguments can be used in any order (in particular, a translation may put them in a different order), so
|
|
|
|
|
|
|
|
TEX.Error(_("'%2' was expected where '%1' was seen",token,delimiter));
|
|
|
|
|
|
|
|
would also be valid.
|
|
|
|
|
|
|
|
Although it would be rare to need more than 9 additional parameters, you can use `%10`, `%11`, etc., to get the 10-th, 11-th, and so on. If you need a parameter to be followed directly by a number, use `%{1}0` rather than `%10`.
|
|
|
|
|
|
|
|
A `%` followed by a non-number (and not matching `%\{\d+\}` as a regular expression) generates just the character following the percent, so `%%` is a literal `%`, and `%:` would generate just `:`.
|
|
|
|
|
|
|
|
|
|
|
|
### Plural Forms ###
|
|
|
|
|
|
|
|
If a message must be represented differently depending on a particular numeric value (say to distinguish between "1 file loaded" and "2 files loaded"), replace the message by an array consisting of the numeric value followed by the strings to use when that value is 1, 2, 3, etc., where the last string is used if the numeric value is outside the number of entries given. For example,
|
|
|
|
|
|
|
|
MathJax.Message.Set(_("fl",[n,"%1 file loaded","%1 files loaded"],n));
|
|
|
|
|
|
|
|
would select `"%1 file loaded"` when `n` is 1, and `"%1 files loaded"` for any other value of `n`. Then that string is used as the message, with the value of `n` inserted for `%1` (since `n` is passed as the third parameter to `_()`).
|
|
|
|
|
|
|
|
If you need a different value for 0, for example, you could use something like
|
|
|
|
|
|
|
|
MathJax.Message.Set(_("fl",[n+1,"No files loaded","%1 file loaded","%1 files loaded"],n));
|
|
|
|
|
|
|
|
to select the string based on `n+1` rather than `n`.
|
|
|
|
|
|
|
|
|
|
|
|
### HTML Snippets ###
|
|
|
|
|
|
|
|
A number of the dialogs used in MathJax are defined using [HTML snippets](http://docs.mathjax.org/en/latest/HTML-snippets.html), which allow you to encode an HTML DOM fragment using JavaScript objects. These can include things like bold and italic indicators, as well as other styling or layout. While it is possible to break these into pieces to pass to `_()` separately, it may be better to allow the translator to translate the complete snippet, so that styling and layout can be properly adjusted for the target language. Thus `_()` allows a complete HTML snippet in place of the message string (and will return an HTML snippet rather than a string literal). E.g.,
|
|
|
|
|
|
|
|
MathJax.HTML.Element("span",{},_("dtn",["Do this",["b",null,["now!"]]]));
|
|
|
|
|
|
|
|
would get the translation for the snippet (that is effectively `Do this <b>now!</b>`) and put it in a `<span>`.
|
|
|
|
|
|
|
|
If the snippet depends on a numeric value for its plural form, then you can use an array that consists of a number followed by the various HTML snippets; the snippet corresponding to the given numeric value will be selected (just as it was for strings above). E.g.,
|
|
|
|
|
|
|
|
MathJax.HTML.Element("span,null,_("fl",[n,
|
|
|
|
["%1 ",["b",null,"file"]," loaded"],
|
|
|
|
["%1 ",["b",null,"files"], loaded"]
|
|
|
|
],n));
|
|
|
|
|
|
|
|
would return a DOM element representing `<span>1 <b>file</b> loaded</span>` if `n` is 1, but `<span>3 <b>files</b> loaded</span>` if `n` is 3.
|
|
|
|
|
|
|
|
Note that parameter substitution is performed on the strings of the snippet that will become text in the DOM fragment that is generated from the snippet.
|
|
|
|
|
|
|
|
|
|
|
|
### Specifying a Form ###
|
|
|
|
|
|
|
|
Some words or phrases may be used in more than one way, and these may require different translations. For example, "Post" may be used as a verb as a button label, while "Post" as a noun could refer to a blog post. These may need to be translated into different words or phrases in another language. Since a translator will be presented with the same word ("Post") in both cases, you may need to give the translator more help in determining how the word will be used. You do this by providing an extra argument following the message string (or array) that indicates the extra data to be shown to the translator. For example
|
|
|
|
|
|
|
|
_("pn","Post",{form:"noun"})
|
|
|
|
|
|
|
|
or
|
|
|
|
|
|
|
|
_("pv","Post",{form:"verb"})
|
|
|
|
|
|
|
|
Note that the id is different for these two, so there will be two values for the translator; the `form` tells the translator how the word is used. The value for `form` can be anything that will help the translator figure out how best to translate the word, e.g.,
|
|
|
|
|
|
|
|
_("pcol","Post",{form:"column name"})
|
|
|
|
|
|
|
|
In fact, you can supply as much meta-data between the braces as you would like. [I'm not sure yet how this will be used, other than `form`, but it gives flexibility for the future.]
|
|
|
|
|
|
|
|
|
|
|
|
## The Localization Data ##
|
|
|
|
|