Initial implementation of MathJax.Localization. Some experiments with French localization.

This commit is contained in:
Frédéric Wang 2013-02-19 19:40:52 +01:00
parent fc7aa04a44
commit 4ced117e05
2 changed files with 362 additions and 26 deletions

View File

@ -1,3 +1,5 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax.js
@ -2476,3 +2478,313 @@ MathJax.Hub.Startup = {
}}
/**********************************************************/
MathJax.Localization = {
locale: "fr",
directory: "[MathJax]/localization",
strings: {
fr: {
isLoaded: true,
domains: {
"_": {
strings: {
}
},
// FontWarnings: {
// isLoaded: true,
// strings: {
// fonts:
// [
// ["p"],
// "MathJax peut utiliser soit les ",
// ["a",{href:"http://www.stixfonts.org/",target:"_blank"},"polices STIX"],
// " soit les ",
// ["a",{href:"http://www.mathjax.org/help-v2/fonts/",target:"_blank"},["polices TeX de MathJax"]],
// ". Téléchargez et installez une de ces familles pour rendre plus confortable votre utilisation de MathJax."
// ]
// }
// },
Menu: {
isLoaded: true,
strings: {
WebkitNativeMMLWarning:
"Votre navigateur ne semble pas comporter de support MathML, " +
"changer le mode de rendu pourrait rendre illisibles " +
"les expressions mathématiques.",
MSIENativeMMLWarning:
"Internet Explorer a besoin de module complémentaire MathPlayer " +
"pour afficher le MathML.",
OperaNativeMMLWarning:
"Le support MathML d'Opera est limité, changer le mode de rendu " +
"pourrait entrainer un affichage médiocre de certaines expressions.",
SafariNativeMMLWarning:
"Le support MathML natif de votre navigateur ne comporte pas " +
"toutes les fonctionnalités requises par MathJax, certaines " +
"expressions pourront donc ne pas s'afficher correctement.",
FirefoxNativeMMLWarning:
"Le support MathML natif de votre navigateur ne comporte pas " +
"toutes les fonctionnalités requises par MathJax, certaines " +
"expressions pourront donc ne pas s'afficher correctement.",
SwitchAnyway:
"Êtes vous certain de vouloir changer le mode de rendu ?\n\n" +
"Appuyez sur OK pour valider ou Annuler pour continuer avec le " +
"mode de rendu actuellement sélectionné.",
ScaleMath:
"Mise à l'échelle des expressions mathématiques (par rapport au " +
"text environnant) de %1%%",
NonZeroScale:
"L'échelle ne peut être nulle",
PercentScale:
"L'échelle doit être un pourcentage (e.g. 120%%)",
IE8warning:
"Ceci désactivera le menu de MathJax et les fonctionalités de " +
"zoom mais vous pourrez toujours obtenir le menu de MathJax " +
"en utilisant la commande Alt+Clic sur une expression.\n\n" +
"Êtes vous certain de vouloir choisir les options de MathPlayer?",
IE9warning:
"Le menu contextuel de MathJax sera désactivé, " +
"mais vous pourrez toujours obtenir le menu de MathJax " +
"en utilisant la commande Alt-Clic sur une expression.",
NoOriginalForm:
"Aucune forme originelle",
Close:
"Fermer",
EqSource:
"Source de l'équation MathJax"
}
}
}
}
},
_: function (messageId, englishPhrase) {
// These variables are used in string parsing
var plural = this.plural;
var args = arguments;
var i, s, result;
function parseNextUnicodePoint(appendToResult)
{
var n = s.charCodeAt(i);
if (n <= 0xD7FF || 0xE000 <= n) {
// Code points U+0000 to U+D7FF and U+E000 to U+FFFF.
// Append the character.
if (appendToResult) result += s[i]
i++;
return;
} else if (i+1 < m) {
// Code points U+10000 to U+10FFFF
// Append the surrogate pairs.
if (appendToResult) { result += s[i]; result += s[i+1]; }
i+=2
return;
}
// Ignore lead surrogate at the end of the string.
// This should not happen with valid unicode string.
i++;
}
function parseArgument(appendToResult)
{
if (!(/\d/.test(s[0]))) return false;
// %INTEGER argument substitution
var argIndex = s.match(/^\d+/)[0];
i += argIndex.length;
var key = +argIndex+1;
if (key in args) {
if (appendToResult) { result += args[key]; }
return true;
}
// invalid index: just %INTEGER and continue
if (appendToResult) { result += "%" + argIndex; }
i++;
return true;
}
function parseInteger(appendToResult)
{
var number = s.match(/^\{(\d+)\}/);
if (!number) return false;
// %{INTEGER} escaped integer
if (appendToResult) { result += number[1]; }
i += number[0].length;
return true;
}
function parseChoiceBlock(blockName, choiceFunction)
{
var pattern = "^\\{"+blockName+":%(\\d)+\\|";
var blockStart = s.match(pattern);
if (!blockStart) return false;
var key = +blockStart[1]+1;
if (!(key in args)) return false;
// %\{blockName:%INTEGER|form1|form2 ... \}
i = blockStart[0].length;
var choiceIndex = choiceFunction(args[key]), j = 1;
var isChosenBlock = (j === choiceIndex);
var blockFound = false;
while (i < m) {
if (s[i] == "|") {
// new choice block
i++; j++;
isChosenBlock = (j === choiceIndex);
if (isChosenBlock) blockFound = true;
continue;
}
if (s[i] == "}") {
// closing brace
i++;
break;
}
if (s[i] != "%" || i+1 == m) {
// normal char or % at the end of the string
parseNextUnicodePoint(isChosenBlock);
continue;
}
// keep only the substring after the %
i++; s = s.substr(i); m -= i; i = 0;
// %INTEGER argument substitution
if (parseArgument(isChosenBlock)) continue;
// %{INTEGER} escaped integer
if (parseInteger(isChosenBlock)) continue;
// %CHAR: escaped character
parseNextUnicodePoint(isChosenBlock);
continue;
}
if (!blockFound) {
i = 0;
return false;
}
return true;
}
function transformString(string)
{
s = string;
i = 0;
m = s.length;
result = "";
while (i < m) {
if (s[i] != "%" || i+1 == m) {
// normal char or % at the end of the string
parseNextUnicodePoint(true);
continue;
}
// keep only the substring after the %
i++; s = s.substr(i); m -= i; i = 0;
// %INTEGER argument substitution
if (parseArgument(true)) continue;
// %{INTEGER} escaped integer
if (parseInteger(true)) continue;
// %\{plural:%INTEGER|form1|form2 ... \} plural forms
if (parseChoiceBlock("plural", plural)) continue;
// %CHAR: escaped character
parseNextUnicodePoint(true);
continue;
}
return result;
}
function transformHTMLSnippet(snippet)
{
for (key in snippet) {
var e = snippet[key];
if (typeof e === "string") {
snippet[key] = transformString(e);
continue;
}
var lastIndex = e.length-1;
if (Array.isArray(e[lastIndex])) {
e[lastIndex] = transformHTMLSnippet(e[lastIndex]);
}
}
return snippet;
}
// try to get the translated phrase or use the englishPhrase fallback
var phrase = englishPhrase;
var translationData = this.strings[this.locale];
if (translationData) {
if (translationData.isLoaded) {
var domain = "_";
if (Array.isArray(messageId) && messageId.length == 2) {
domain = messageId[0];
messageId = messageId[1];
}
if (domain in translationData.domains) {
domain = translationData.domains[domain]
if (domain.isLoaded && messageId in domain.strings) {
phrase = domain.strings[messageId];
}
}
}
}
if (typeof phrase === "string") {
// handle the phrase as a simple string
return transformString(phrase);
}
// handle the phrase as a HTML snippet
return transformHTMLSnippet(phrase);
},
setLocale: function(locale) {
this.locale = locale;
// TODO
},
addTranslation: function (locale, domain, definition) {
// TODO
},
fontFamily: function () {
return null;
},
plural: function(n) {
if (n == 1) return 1;
return 2;
}
};

View File

@ -1,3 +1,5 @@
/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*************************************************************
*
* MathJax/extensions/MathMenu.js
@ -33,6 +35,13 @@
signal: SIGNAL
};
var _ = function (id) {
return MathJax.Localization._.apply(
MathJax.Localization,
[ ["Menu", id] ].concat([].slice.call(arguments,1))
);
};
var isPC = HUB.Browser.isPC, isMSIE = HUB.Browser.isMSIE, isIE9 = ((document.documentMode||0) > 8);
var ROUND = (isPC ? null : "5px");
@ -690,7 +699,10 @@
return;
}
} else {
if (MENU.jax.originalText == null) {alert("No original form available"); return}
if (MENU.jax.originalText == null) {
alert(_("NoOriginalForm", "No original form available"));
return;
}
MENU.ShowSource.Text(MENU.jax.originalText,event);
}
};
@ -706,16 +718,17 @@
var w = MENU.ShowSource.Window(event); delete MENU.ShowSource.w;
text = text.replace(/^\s*/,"").replace(/\s*$/,"");
text = text.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
var title = _("EqSource", "MathJax Equation Source");
if (MENU.isMobile) {
w.document.open();
w.document.write("<html><head><meta name='viewport' content='width=device-width, initial-scale=1.0' /><title>MathJax Equation Source</title></head><body style='font-size:85%'>");
w.document.write("<html><head><meta name='viewport' content='width=device-width, initial-scale=1.0' /><title>"+title+"</title></head><body style='font-size:85%'>");
w.document.write("<pre>"+text+"</pre>");
w.document.write("<hr><input type='button' value='Close' onclick='window.close()' />");
w.document.write("<hr><input type='button' value='"+_("Close", "Close")+"' onclick='window.close()' />");
w.document.write("</body></html>");
w.document.close();
} else {
w.document.open();
w.document.write("<html><head><title>MathJax Equation Source</title></head><body style='font-size:85%'>");
w.document.write("<html><head><title>"+title+"</title></head><body style='font-size:85%'>");
w.document.write("<table><tr><td><pre>"+text+"</pre></td></tr></table>");
w.document.write("</body></html>");
w.document.close();
@ -740,7 +753,7 @@
MENU.Scale = function () {
var HTMLCSS = OUTPUT["HTML-CSS"], nMML = OUTPUT.NativeMML, SVG = OUTPUT.SVG;
var SCALE = (HTMLCSS||nMML||SVG||{config:{scale:100}}).config.scale;
var scale = prompt("Scale all mathematics (compared to surrounding text) by",SCALE+"%");
var scale = prompt(_("ScaleMath", "Scale all mathematics (compared to surrounding text) by %1%%",SCALE));
if (scale) {
if (scale.match(/^\s*\d+(\.\d*)?\s*%?\s*$/)) {
scale = parseFloat(scale);
@ -752,8 +765,9 @@
MENU.cookie.scale = scale;
MENU.saveCookie(); HUB.Reprocess();
}
} else {alert("The scale should not be zero")}
} else {alert("The scale should be a percentage (e.g., 120%)")}
} else {alert(_("NonZeroScale", "The scale should not be zero"))}
} else {alert(_("PercentScale",
"The scale should be a percentage (e.g., 120%%)"))}
}
};
@ -791,8 +805,10 @@
break;
}
if (message) {
message += "\n\nSwitch the renderer anyway?\n\n" +
"(Press OK to switch, CANCEL to continue with the current renderer)";
message += "\n\n";
message += _("SwitchAnyway",
"Switch the renderer anyway?\n\n" +
"(Press OK to switch, CANCEL to continue with the current renderer)");
MENU.cookie.renderer = jax[0].id; MENU.saveCookie(); if (!confirm(message)) {return}
if (warned) {MENU.cookie[warned] = CONFIG.settings[warned] = true}
MENU.cookie.renderer = CONFIG.settings.renderer; MENU.saveCookie();
@ -805,28 +821,34 @@
};
MENU.Renderer.Messages = {
MML: {
WebKit: "Your browser doesn't seem to support MathML natively, " +
"so switching to MathML output may cause the mathematics " +
"on the page to become unreadable.",
WebKit: _("WebkitNativeMMLWarning",
"Your browser doesn't seem to support MathML natively, " +
"so switching to MathML output may cause the mathematics " +
"on the page to become unreadable."),
MSIE: "Internet Explorer requires the MathPlayer plugin " +
"in order to process MathML output.",
MSIE: _("MSIENativeMMLWarning",
"Internet Explorer requires the MathPlayer plugin " +
"in order to process MathML output."),
Opera: "Opera's support for MathML is limited, so switching to " +
"MathML output may cause some expressions to render poorly.",
Opera: _("OperaNativeMMLWarning",
"Opera's support for MathML is limited, so switching to " +
"MathML output may cause some expressions to render poorly."),
Safari: "Your browser's native MathML does not implement all the features " +
"used by MathJax, so some expressions may not render properly.",
Safari: _("SafariNativeMMLWarning",
"Your browser's native MathML does not implement all the features " +
"used by MathJax, so some expressions may not render properly."),
Firefox: "Your browser's native MathML does not implement all the features " +
"used by MathJax, so some expressions may not render properly."
Firefox: _("FirefoxNativeMMLWarning",
"Your browser's native MathML does not implement all the features " +
"used by MathJax, so some expressions may not render properly.")
},
SVG: {
MSIE: "SVG is not implemented in Internet Explorer prior to " +
"IE9, or when the browser is emulating IE8 or below. " +
"Switching to SVG output will cause the mathemtics to " +
"not display properly."
MSIE: _("MSIESVGWarning",
"SVG is not implemented in Internet Explorer prior to " +
"IE9, or when the browser is emulating IE8 or below. " +
"Switching to SVG output will cause the mathemtics to " +
"not display properly.")
}
};
@ -861,13 +883,15 @@
};
MENU.MPEvents.Messages = {
IE8warning:
_("IE8warning",
"This will disable the MathJax menu and zoom features, " +
"but you can Alt-Click on an expression to obtain the MathJax " +
"menu instead.\n\nReally change the MathPlayer settings?",
"menu instead.\n\nReally change the MathPlayer settings?"),
IE9warning:
_("IE9warning",
"The MathJax contextual menu will be disabled, but you can " +
"Alt-Click on an expression to obtain the MathJax menu instead."
"Alt-Click on an expression to obtain the MathJax menu instead.")
};
/*************************************************************/