MediaWiki:Gadget-CreerTrad.js
Apparence
Remarque: après avoir sauvegardé, vous devez vider le cache de votre navigateur pour que les changements prennent effet. Mozilla, cliquez sur Actualiser (ou ctrl-r). Internet Explorer / Opera: ctrl-f5. Safari: cmd-r. Konqueror ctrl-r.
/*******************************************************************************************
* (en)
* Lets the users create the page for a translation just by clicking its (red) link in the
* French entry.
*******************************************************************************************
* (fr)
* Permet aux utilisateurs de créer la page d’une traduction en cliquant juste sur son lien
* (rouge) dans l’entrée en français.
*******************************************************************************************
* v1.0 2013-06-13
* v2.0 2020-11-01 Full rewrite.
* v2.1 2021-05-08 Smarter wikicode analysis;
* page reloads instead of having its content replaced
* v2.2 2021-05-18 Now requires gadget wikt.preload-edit-text.
*******************************************************************************************
* [[Catégorie:JavaScript du Wiktionnaire|CreerTrad]]
* <nowiki>
*******************************************************************************************/
$(function () {
if (wikt.page.hasNamespaceIn(["", "Reconstruction"])
&& ["view", "edit", "submit"].includes(mw.config.get("wgAction"))) {
console.log("Chargement de Gadget-CreerTrad.js…");
window.gadget_createTranslation = {
NAME: "Créer traduction",
VERSION: "2.2",
/** @type {string} */
_word: "",
/** @type {string} */
_translation: "",
/** @type {string} */
_langCode: "",
/**
* Map that associates a language code to a
* function that generates the code for it.
* @type {Object<string, Function>}
*/
_generators: {},
/**
* Initializes this gadget by hooking a callback to
* every red links in the infoboxes with the "translations" class.
*/
init: function () {
var self = this;
$(".translations .new").each(function () {
var $link = $(this);
var translation = $link.text();
if (translation) {
var langCode = $link.parent().attr("lang");
$link.css("background-color", "#77b5fe");
$link.attr("title", "Cliquez pour créer «\u00a0{0}\u00a0» avec le gadget".format(translation));
$link.click(function (event) {
event.preventDefault();
self.createTrans(translation, langCode);
});
}
});
},
/**
* Register a generator for the given language.
* @param langCode {string} Language’s code.
* @param generator {Function} The generator function.
*/
registerGeneratorForLanguage: function (langCode, generator) {
this._generators[langCode] = generator;
},
/**
* Makes a GET request to get the wikicode for the current page.
* Stores the word, translation and language code for use further down the line.
* @param translation {string} The word to create.
* @param lang {string} The word’s language code.
*/
createTrans: function (translation, lang) {
this._word = mw.config.get("wgTitle");
this._translation = translation;
switch (lang) {
case "zh-Hans":
case "zh-Hant":
this._langCode = "zh";
break;
case "ko-Hani":
this._langCode = "ko";
break;
case "vi-Hani":
case "vi-Hans":
case "vi-Hant":
this._langCode = "vi";
break;
case "nan-Hani":
case "nan-Hans":
case "nan-Hant":
this._langCode = "nan";
break;
default:
this._langCode = lang;
}
// Get current article’s wikicode
$.get(
mw.config.get("wgServer") + mw.config.get("wgScript"),
{
"title": this._word,
"action": "raw",
},
this._generateWikicode.bind(this)
);
},
/**
* Extracts relevent data to generate translation’s wikicode from the given wikicode.
* @param wikicode {string} Current article’s wikicode.
* @private
*/
_generateWikicode: function (wikicode) {
var wikicodeLines = wikicode.split("\n");
var translationLineIndex = 0;
var translationLine = "";
// Fetch line where the translation is.
for (var i = 0; i < wikicodeLines.length && !translationLine; i++) {
var line = wikicodeLines[i];
var translationMatch = new RegExp(
"{{trad[+-]?\\|" + this._langCode + "\\|(?:[^}]*?tradi=)?" + this._translation
).exec(line);
if (translationMatch) {
translationLineIndex = i;
translationLine = line;
}
}
if (!translationLine) {
console.log("{0} could not find trad template for {1}".format(this.NAME, this._translation));
return;
}
var self = this;
var tradTemplateArgs = $.grep(translationLine.match(/{{trad[+-]?\|[^}]+?}}/g), function (m) {
return m.includes(self._translation);
})[0];
var templateArgsArray = $.map(
tradTemplateArgs.substr(2, tradTemplateArgs.length - 4).split("|"),
function (s) {
return s.trim();
}
);
var transcription = "";
var dif = "";
var gender = "";
for (var i2 = 0; i2 < templateArgsArray.length; i2++) {
var arg = templateArgsArray[i2];
var m;
// Get transcription if there is one.
if (m = /^(?:tr|R)\s*=\s*(.+)$/.exec(arg)) {
transcription = m[1];
// Get dif parameter if it is defined.
// Example : * {{T|he}} : {{trad+|he|מכלב|R=makhlev|dif=מַכְלֵב}}
} else if (m = /^dif\s*=\s*(.+)$/.exec(arg)) {
dif = m[1];
// Get gender if there is one.
} else if (/^(m|f|n|c|s|p|d|mf|mp|fp|mfp|np|ma|mi|fa|fi|na|ni)$/.test(arg)) {
gender = arg;
}
}
var sectionLineIndex = 0;
var nature = "";
var definitionNumber = [1];
var definitionNumberFound = false;
var definitionsLines = [];
/*
* We go through each line upwards from the translation until we encounter a level-2 (===) section.
* This section is the nature of the word.
* We also gather all encountered definitions and the definition number the translation refers to.
*/
for (var i3 = translationLineIndex; i3 >= 0 && !nature; i3--) {
var line2 = wikicodeLines[i3];
// Fetch enclosing trad-début template to get definition number
var tradStartTemplateMatch;
if (!definitionNumberFound && (tradStartTemplateMatch = /{{trad-début\|[^|]*\|([^|}]+)/.exec(line2))) {
definitionNumber = $.map(
tradStartTemplateMatch[1].toLowerCase().split("."),
function (s, i) {
s = s.trim();
var n = parseInt(s);
if (isNaN(n)) {
switch (i) {
case 0:
return NaN;
case 1:
return /^[a-z]$/.test(s) ? s.charCodeAt(0) - "a".charCodeAt(0) + 1 : NaN;
default:
return wikt.text.romanNumeralToInt(s);
}
} else {
return n;
}
}
);
definitionNumberFound = true;
}
// Fetch word type
var natureMatch;
if (natureMatch = /^===\s*{{S\|([^|}]+)/.exec(line2)) {
nature = natureMatch[1];
sectionLineIndex = i3;
}
}
// Fetch all definitions starting from the line after
// the word type section line until the next encountered section
for (var i4 = sectionLineIndex + 1; i4 < translationLineIndex && !/^(=+).+\1$/.test(wikicodeLines[i4]); i4++) {
var line3 = wikicodeLines[i4];
var defMatch;
if ((defMatch = /^(#+)/.exec(line3)) && !/^#+\*/.test(line3)) {
definitionsLines.push([defMatch[1].length, i4])
}
}
// Recursively fetches the line for definitionNumber
var getDefinitionLine = function (level, i) {
var levelCounter = 0;
for (var i5 = i; i5 < definitionsLines.length; i5++) {
var item = definitionsLines[i5];
if (item[0] === level + 1) {
levelCounter++;
if (levelCounter === definitionNumber[level]) {
if (level === definitionNumber.length - 1) {
// We reached the end of definitionNumber array, return line number
return item[1];
} else {
// Recursively handle the rest of the definitionNumber array
return getDefinitionLine(level + 1, i5 + 1);
}
}
}
}
return NaN;
};
var definitionLineIndex = getDefinitionLine(0, 0) || definitionsLines[0][1];
var domains = "";
// We look for a template of the form {{lexique|boulangerie|fr}}.
var domainMatch;
if (domainMatch = /{{lexique\|([^}]+?)\|[^|}]+?}}/.exec(wikicodeLines[definitionLineIndex])) {
domains = domainMatch[1];
}
// Wikicode generation.
var newWikicode = "== {{langue|{0}}} ==\n".format(this._langCode);
newWikicode += "=== {{S|étymologie}} ===\n";
newWikicode += ": {{ébauche-étym|{0}}}\n\n".format(this._langCode);
newWikicode += "=== {{S|{0}|{1}}} ===\n".format(nature, this._langCode);
var generator;
if (generator = this._generators[this._langCode]) {
newWikicode += generator(this._translation, nature, gender, transcription, dif).trim();
} else {
newWikicode += this._genericGenerator(nature, gender, transcription, dif).trim();
}
newWikicode += "\n# ";
if (domains) {
newWikicode += "{{lexique|{0}|{1}}} ".format(domains, this._langCode);
}
newWikicode += "[[{0}#fr|{1}]].\n".format(this._word, this._word.charAt(0).toUpperCase() + this._word.substring(1));
newWikicode += "#* {{exemple|lang={0}}}\n\n".format(this._langCode);
// Get HTML code of translation’s page.
location.href = mw.config.get("wgServer") + mw.config.get("wgScript")
+ "?title={0}&action=edit&preload-edit-text={1}&preload-edit-summary={2}".format(
encodeURIComponent(this._translation),
encodeURIComponent(newWikicode),
encodeURIComponent("Création avec [[Aide:Gadget-CreerTrad|{0} v{1}]].".format(this.NAME, this.VERSION))
);
},
/**
* Appends the appropriate gender templates to the wikicode, and return the wikicode.
*
* @param wikicode {string} Current article’s wikicode.
* @param nature {string} Part of speech in French ('nom', 'adjectif', etc.).
* @param gender {string} Gender parameter extracted from {{trad}}.
* @private
*/
_addGender: function (wikicode, nature, gender) {
var gender_to_wikicode = {
"m": "{{m}}",
"f": "{{f}}",
"n": "{{n}}",
"c": "{{c}}",
"s": "{{s}}",
"p": "{{p}}",
"d": "{{d}}",
"mf": "{{mf}}",
"mp": "{{m}} {{p}}",
"fp": "{{f}} {{p}}",
"np": "{{n}} {{p}}",
"mfp": "{{mf}} {{p}}",
"ma": "{{m|a}}",
"mi": "{{m|i}}",
"fa": "{{f|a}}",
"fi": "{{f|i}}",
"na": "{{n|a}}",
"ni": "{{n|i}}",
};
if (nature === "nom" && gender in gender_to_wikicode) {
wikicode += " {0}".format(gender_to_wikicode[gender]);
}
return wikicode;
},
/**
* Fallback wikicode generator for languages not explicitly supported by the gadget.
* @param nature {string} Word’s grammatical nature.
* @param gender {string?} Word’s gender if any.
* @param transcription {string?} Word’s latin transcription if any.
* @param dif {string?} Text to show on the in place of the translation.
* @return {string} The content of the main section.
* @private
*/
_genericGenerator: function (nature, gender, transcription, dif) {
var wikicode = "";
if (dif) {
wikicode += "'''{0}'''".format(dif);
} else {
wikicode += "'''{0}'''".format(this._translation);
}
if (transcription) {
wikicode += ", ''{0}''".format(transcription);
}
wikicode += " {{pron||{0}}}".format(this._langCode);
wikicode = this._addGender(wikicode, nature, gender);
return wikicode;
}
};
/*
* Generators registration
*/
// Catalan/Catalan
gadget_createTranslation.registerGeneratorForLanguage(
"ca",
function (translation, nature, gender) {
var wikicode = "";
if (nature === "nom") {
wikicode += "{{ca-rég|<!-- Compléter -->}}\n";
}
wikicode += "'''{0}''' {{pron||ca}}".format(translation);
wikicode = gadget_createTranslation._addGender(wikicode, nature, gender);
return wikicode;
}
);
// Esperanto/Espéranto
gadget_createTranslation.registerGeneratorForLanguage(
"eo",
function (translation, nature) {
var wikicode = "";
if (nature === "adjectif" || nature === "nom") {
wikicode += "{{eo-flexions|<!-- Compléter -->}}\n";
} else if (nature === "verbe") {
wikicode += "{{eo-verbe}}\n";
}
wikicode += "'''{0}''' {{pron||eo}}".format(translation);
if (nature === "verbe") {
wikicode += " {{valence ?|eo}} {{conjugaison|eo}}";
}
return wikicode;
}
);
// Spanish/Espagnol
gadget_createTranslation.registerGeneratorForLanguage(
"es",
function (translation, nature, gender) {
var wikicode = "";
if (nature === "nom") {
wikicode += "{{es-rég|<!-- Compléter -->}}\n";
}
wikicode += "'''{0}''' {{pron||es}}".format(translation);
wikicode = gadget_createTranslation._addGender(wikicode, nature, gender);
return wikicode;
}
);
// Italian/Italien
gadget_createTranslation.registerGeneratorForLanguage(
"it",
function (translation, nature, gender) {
var wikicode = "";
if (nature === "nom") {
wikicode += "{{it-flexion|<!-- Compléter -->}}\n";
}
wikicode += "'''{0}''' {{pron||it}}".format(translation);
if (nature === "nom" && gender) {
wikicode = gadget_createTranslation._addGender(wikicode, nature, gender);
} else {
wikicode += " {{genre ?|it}}";
}
return wikicode;
}
);
// Occitan/Occitan
gadget_createTranslation.registerGeneratorForLanguage(
"oc",
function (translation, nature, gender) {
var wikicode = "";
if (nature === "adjectif") {
wikicode += "{{oc-accord-mixte|<!-- Compléter -->}}\n";
} else if (nature === "nom") {
wikicode += "{{oc-rég|<!-- Compléter -->}}\n";
}
wikicode += "'''{0}''' {{pron||oc}}".format(translation);
wikicode = gadget_createTranslation._addGender(wikicode, nature, gender);
return wikicode;
}
);
// Russian/Russe
gadget_createTranslation.registerGeneratorForLanguage(
"ru",
function (translation, nature, gender) {
var wikicode = "";
if (nature === "nom" && gender) {
wikicode += "{{ru-décl{0}|<!-- Compléter -->}}\n".format(gender);
}
wikicode += "'''{0}''', ''{{transliterator|ru|{0}}}'' {{pron||ru}}".format(translation);
wikicode = gadget_createTranslation._addGender(wikicode, nature, gender);
return wikicode;
}
);
// Swedish/Suédois
gadget_createTranslation.registerGeneratorForLanguage(
"sv",
function (translation, nature, gender) {
var wikicode = "";
if (nature === "adjectif") {
wikicode += "{{sv-adj}}\n";
} else if (nature === "nom") {
if (translation.endsWith("a")) {
wikicode += "{{sv-nom-c-or}}\n";
} else if (translation.endsWith("ing")) {
wikicode += "{{sv-nom-c-ar}}\n";
} else if (translation.endsWith("are")) {
wikicode += "{{sv-nom-c-ar|are=}}\n";
} else if (translation.endsWith("ande")) {
wikicode += "{{sv-nom-n-n}}\n";
} else if (translation.endsWith("ende")) {
wikicode += "{{sv-nom-n-n}}\n";
} else if (translation.endsWith("um")) {
wikicode += "{{sv-nom-n-er|um=}}\n";
} else if (translation.endsWith("tion")) {
wikicode += "{{sv-nom-c-er}}\n";
} else if (translation.endsWith("tör")) {
wikicode += "{{sv-nom-c-er}}\n";
} else if (translation.endsWith("ier")) {
wikicode += "{{sv-nom-c-er|r=}}\n";
} else if (translation.endsWith("iker")) {
wikicode += "{{sv-nom-c-er|r=}}\n";
} else if (translation.endsWith("else")) {
wikicode += "{{sv-nom-c-er|e=}}\n";
} else if (gender === "neutre") {
wikicode += "{{sv-nom-n-0}}\n";
} else {
wikicode += "{{sv-nom-c-er}}\n";
}
} else if (nature === "verbe") {
wikicode += "{{sv-conj-ar}}\n";
}
wikicode += "'''{0}''' {{pron||sv}}".format(translation);
if (nature === "nom") {
if (gender) {
wikicode = gadget_createTranslation._addGender(wikicode, nature, gender);
} else if (translation.endsWith("ande") || translation.endsWith("ende") || translation.endsWith("um")) {
wikicode += " {{n}}";
} else {
wikicode += " {{c}}";
}
}
return wikicode;
}
);
gadget_createTranslation.init();
}
});
// </nowiki>