Usuari:Vriullop/creation.js: diferència entre les revisions

Contingut suprimit Contingut afegit
Use of "wgPageName" [+"wgNamespaceNumber"] is deprecated. Use mw.config instead.
reorganització de funcions, sincronització amb versió 14:35, 7 set 2013‎
Línia 2:
Adaptat de en:User:Conrad.Irwin/creation.js
 
* Automatically create form-of entries based on meta-data within entries.
* See [[User:Conrad.Irwin/creation.js/documentation]] for information.
*/
*/
 
/**
* Language-specific formatting rules for form-of entries.
* Escape the values we are passing to AutoEdit
*
* These come in two different types. The first type is the "internal" type.
* These are entries whose content is generated directly from within the script.
* The second type is "extternal", where the content is generated by template-izing one
* of the subpages of the script, such as User:Conrad.Irwin/creation.js/basicNoun.
*
* The internal type is always attempted first. If no internal rule is available for the
* current to-be-created entry, the external type is used as a fallback.
*/
 
//AutoEdit irritatingly doesn't undo %XX encodings, so we can't send them.
 
//FIXME: Not a lot we can do about &s maybe patch AutoEdit.
/*
function get_escape (get) {
* "Internal" entry generation rules.
return get.replace (/&/g,"%26"); //This shouldn't do anything to variables.
*
* These are all called via the get_preload_text function, which returns a fully-formed entry with a language header.
*
* The functions are structured top-down, this allows innermost functions to just return text that is
* wrapped by outer functions, seems to result in shorter code, but should probably be refactored out :p.
*
* So each "declaration function" accepts a function (f) and returns an "edit function".
* and each "edit function" accepts some details (d) and returns the text to be wrapped (by calling f(d) where necessary)
*/
function get_preload_text(d)
{
try
{
return get_preload_text[d.lang](d);
}
catch (e)
{
return false;
}
}
 
function clean_regexp (re) {
/*
return re.replace (/([\\\*\+\[\]\{\}\(\)\.~])/g,"\\$1");
* First, define some helper functions that can be used to create parts of entries.
*/
function language_header(f)
{
return function (d)
{
return "=={"+"{-" + d.lang + "-}}==\n\n" + f(d);
};
}
 
function clean_variable (va) {
// Find the part of speech by looking at the current part of speech heading
return va.replace (/([\\~])/g,"\\$1").replace(/&/g,'{'+'{subst:⅋}}').replace(/#/,'{'+'{subst:♯}}'); //Yucky HACK
function default_pos(f)
{
return function (d)
{
return "===" + d.pos + "===\n" + f(d);
};
}
 
function variable (needle, replacement) {
// { {head|nl}}
return get_escape ('s~{'+'{'+'{' + clean_regexp (needle) + '}}}~' + clean_variable (replacement) + '~g;');
function posless_head(f)
{
return function (d)
{
return '{' + '{lema|' + d.lang + '}}\n\n' + f(d);
};
}
 
// { {head|fr|...}}
/**
function head_template(f)
* Variables in the templates.
{
return function (d)
{
return "{"+"{lema|" + d.lang + "|" + (
d.gender.indexOf('pl') > -1 ? 'plural' : d.pos.toLowerCase()
) + (
(d.gender ? "|g=" + d.gender.replace('pl','') : "") + (d.gender.indexOf('pl') > -1 ? '|g2=p' : '')
) + "}}\n\n" + f(d);
};
}
 
// { {head|nl}} or { {nl-noun-dim}}
function nl_head(f)
{
return function (d)
{
if (d.form == 'diminutive')
{
return '{' + '{nl-noun-dim}}\n\n' + f(d);
}
else if (d.pos == "Noun" && d.form == 'plural')
{
return '{' + '{lema|nl|substantiu en plural}}\n\n' + f(d)
}
else
{
return '{' + '{lema|nl}}\n\n' + f(d);
}
};
}
 
// { {tg-word}}
function tajik_head(f)
{
return function(d)
{
var head = '{'+'{tg-word' + (d.transliteration ? ('|tr=' + d.transliteration) : '') + '}}';
return head + "\n\n" + f(d);
}
}
 
// All definition lines start with #
function definition_line(f)
{
return function (d)
{
return "# " + f(d) + "\n";
};
}
 
// Common part of eo
function eo_form_of(f)
{
return function (d)
{
return '{'+'{eo-form of|' + f(d) + '}}';
};
}
 
// These ones always seem to happen toegether
function basic_entry(f)
{
return language_header(default_pos(f));
}
 
/** A sanely named wrapper around throw */
function preload_text_error()
{
throw true;
}
 
/*
* Generation rules for each language.
*/
 
// English
//get_preload_text.en =
 
// Esperanto
//get_preload_text.eo =
 
// French
//get_preload_text.fr =
 
 
/*
* "External" generation rule definitions.
*
* These are used when there is no "internal" rule for a given situation.
*/
 
/*
* Which template should be used for "external" rule definitions?
*
* Check if we know of a template that will do the job.
* Use an explicit list to make it harder to subvert.
*/
 
 
function get_preload_template (form, lang, link)
{
var prefix = 'User:Vriullop/creation/';
var pos = get_part_of_speech(link);
if (form == 'trad') {
if (lang == 'eo' && (pos == 'Nom' || pos == 'Adjectiu' || pos == 'Adverbi' || pos == 'Verb')) {
return prefix + 'eoTrad';
}
else if (lang == 'es' && (pos == 'Nom' || pos == 'Adjectiu' || pos == 'Adverbi' || pos == 'Verb')) {
return prefix + 'esTrad';
}
else if (lang == 'it' && (pos == 'Nom' || pos == 'Adjectiu' || pos == 'Adverbi')) {
return prefix + 'esTrad';
}
else if (pos == 'Nom' || pos == 'Adjectiu' || pos == 'Adverbi') {
return prefix + 'baseTrad';
}
else {
return false;
}
}
else if ((lang == 'ca' || lang == 'es' || lang == 'it') && pos == 'Adjectiu') {
return prefix + lang + 'Adj';
}
else if ((lang == 'ca' || lang == 'es' || lang == 'it') && pos == 'Nom') {
return prefix + lang + 'Nom';
}
else if (lang == 'eo') {
return prefix + 'eoBase';
}
else if (lang == 'en' && pos == 'Adverbi') {
return prefix + 'baseAdv';
}
else if (lang == 'en' && pos == 'Adjectiu') {
return prefix + 'baseAdj';
}
else if (lang == 'en' && pos == 'Nom') {
return prefix + 'baseNom';
}
else {
return false;
}
}
 
/*
* Rules to full in each of the values in the template subpage.
*
* The rules consist of a series of "set" functions. These set the parameters that
* are then used in one of the templated subpages of the script to make an entry.
* See the documentation page for a full list of subpages.
*
* Each function returns a "variable", which acts like a wrapper for a defined parameter.
* For example, returning variable('lang', 'en') will cause any instances of '{{{lang}}}'
* in the subpage template to be replaced with 'en'.
*/
 
// The page's language.
function set_lang (lang)
{
return variable ('lang', lang);
}
 
// The optional language parameter to give to a template
function set_template_lang (lang, form)
{
return variable ('template-lang', '|lang=' + lang);
}
function get_gender_template (gender, lang) {
 
}
//The gender template with a leading space (or an empty string if no gender)
function set_gender_template (gender, lang)
{
 
gender = gender.replace('pl','p').replace(/([mfnc])p/, '$1-p');
 
if (gender.length === 0) {
{
return variable ('gender-template', '');
}
else
{
return variable ('gender-template', '{'+'{'+ gender + '}}');
}
Linha 50 ⟶ 259:
 
//The optional |g= argument to { {head}}
function set_template_gender (gender, lang, form)
{
if (form == 'diminutive-plural')
return variable('template-gender','|plural=1');
Linha 65 ⟶ 275:
return variable('template-gender', '|g=' + gender);
}
 
//Form of templates for genders. These are the ones that exist, if we need others,
//either create them or use { {form-of}} manually.
function gender_form (gender)
{
if (gender == 'mpl')
 
{
if (gender == 'mpl') {
return 'masculina plural';
}
else if (gender == 'f') {
{
return 'femenina';
}
else if (gender == 'fpl') {
{
return 'femenina plural';
}
else if (gender == 'n') {
{
return 'neutra';
}
else if (gender == 'mfpl'){
{
return 'plural';
}
else
{
throw("Not simple gender?!");
}
 
}
 
// This pages name.
// The page name that the entry is a form of.
// Returns in PIPED format. Which, while kind of bad, works as either embedded in [[%s]] or { {template|%s}}
// and most templates take an optional display parameter as the first after the link.
function set_origin (given, lang)
{
 
//Remove links from given parameters, and unencode underscores to spaces
if (given) {
{
given = given.replace(/\[\[([^\|\]])*\|?([^\]]+)\]\]/g,"$2").replace(/_/g,' ');
if (lang == "ca" || lang == "es") {
return variable ('origin', given);
}
else {
return variable ('origin', wgTitle + '|' + given);
}
}
Linha 102 ⟶ 326:
return variable ('origin', wgTitle);
}
 
// The page we are about to create with links on individual words.
function set_pagename_linked_and_template_head (link, lang, form)
{
var pagename = (link.innerText || link.textContent);
Linha 112 ⟶ 338:
var templateHead = '';
if (op != pagename) {
{
pagename = '[['+pagename+']]';
return variable('pagename-linked', pagename) + variable('template-head','|head=' + pagename);
Linha 193 ⟶ 420:
}
 
// Script code
function set_template_sc (lang) {
function set_template_sc (lang)
{
var sc;

switch (lang) {
{
case 'he':
sc = 'Hebr';
Linha 202 ⟶ 433:
return variable('template-sc','');
}
return variable('template-sc','|sc='+sc);
}
 
//The form-of template we are to use - used for the basic verbs.
function set_form_template (form, lang, gender, link)
{
var formof = form.replace(/-/g,' ');
 
if (formof == 'plural') {
{
return variable('form-template', 'forma-p');
} else if (formof == 'femenina') {
return variable('form-template', 'forma-f');
}
return variable('form-template', 'forma-|' + formof);
}
 
function set_part_of_speech (link,lang,form)
//The part of speech, normally determined by other means.
{
function get_part_of_speech (link) {
return variable('part-of-speech', get_part_of_speech(link));
 
var node = link;
while(node) {
while (node.previousSibling) {
node = node.previousSibling;
if (node.nodeType == 1 && node.nodeName.match(/^[hH]3$/)) {
return $( node ).find( ".mw-headline" ).text().replace(/^[1-9.]* /,'');
}
}
node = node.parentNode;
}
throw("This entry seems to be formatted incorrectly.");
 
}
function set_part_of_speech (link,lang,form) {
 
/*
return variable('part-of-speech', get_part_of_speech(link));
* Create a "variable".
*
* This is a template-like replacement of text wrapped in {{{ }}} with something else.
*/
function variable (name, replacement)
{
return get_escape ('s~{'+'{'+'{' + clean_regexp (name) + '}}}~' + clean_variable (replacement) + '~g;')
}
/**
* Check if we know of a template that will do the job.
* Use an explicit list to make it harder to subvert.
*/
function get_preload_template (form, lang, link) {
 
//AutoEdit irritatingly doesn't undo %XX encodings, so we can't send them.
var prefix = 'User:Vriullop/creation/';
//FIXME: Not a lot we can do about &s maybe patch AutoEdit.
var pos = get_part_of_speech(link);
function get_escape (get)
{
if (form == 'trad') {
return get.replace (/&/g,"%26"); //This shouldn't do anything to variables.
if (lang == 'eo' && (pos == 'Nom' || pos == 'Adjectiu' || pos == 'Adverbi' || pos == 'Verb')) {
return prefix + 'eoTrad';
}
else if (lang == 'es' && (pos == 'Nom' || pos == 'Adjectiu' || pos == 'Adverbi' || pos == 'Verb')) {
return prefix + 'esTrad';
}
else if (lang == 'it' && (pos == 'Nom' || pos == 'Adjectiu' || pos == 'Adverbi')) {
return prefix + 'esTrad';
}
else if (pos == 'Nom' || pos == 'Adjectiu' || pos == 'Adverbi') {
return prefix + 'baseTrad';
}
else {
return false;
}
}
else if ((lang == 'ca' || lang == 'es' || lang == 'it') && pos == 'Adjectiu') {
return prefix + lang + 'Adj';
}
else if ((lang == 'ca' || lang == 'es' || lang == 'it') && pos == 'Nom') {
return prefix + lang + 'Nom';
}
else if (lang == 'eo') {
return prefix + 'eoBase';
}
else if (lang == 'en' && pos == 'Adverbi') {
return prefix + 'baseAdv';
}
else if (lang == 'en' && pos == 'Adjectiu') {
return prefix + 'baseAdj';
}
else if (lang == 'en' && pos == 'Nom') {
return prefix + 'baseNom';
}
else {
return false;
}
}
 
function unAnchorEncodeclean_regexp (xre) {
{
return decodeURI(x.replace(/\./g, '%'));
return re.replace (/([\\\*\+\[\]\{\}\(\)\.~])/g,"\\$1");
}
/**
* Convert a raw new link into a snazzy one.
*/
function add_create_button (details, link) {
 
function clean_variable (va)
var d = {
{
lang: 'ca',
return va.replace (/([\\~])/g,"\\$1").replace(/&/g,'{'+'{subst:⅋}}').replace(/#/,'{'+'{subst:♯}}'); //Yucky HACK
lang2: null,
gender: '',
form: '',
origin: wgTitle,
given_origin: false,
pos: get_part_of_speech(link),
target: (link.innerText || link.textContent)
}
 
for (var i = 0;i < details.length; i++) {
if (details[i].match(/(^| +)([^ ]+)-form-of( +|$)/)) {
d.form = RegExp.$2;
} else if (details[i].match(/(^| +)lang-([^ ]+)( +|$)/)) {
d.lang = RegExp.$2;
} else if (details[i].match(/(^| +)lang2-([^ ]+)( +|$)/)) {
d.lang2 = RegExp.$2;
} else if (details[i].match(/(^| +)gender-(([mfni]+|c)(pl)?)( +|$)/)) {
d.gender = RegExp.$2;
} else if (details[i].match(/(^| +)origin-(.+)( +|$)/)) {
d.given_origin = unAnchorEncode(RegExp.$2);
} else if (details[i].match(/(^| +)transliteration-(.+)( +|$)/)) {
d.transliteration = unAnchorEncode(RegExp.$2);
}
 
}
 
var workerHref = '';
 
try {
if (d.pos && (preload = get_preload_text(d))) {
 
workerHref = '&preloadtext=' + encodeURIComponent(preload);
 
} else if (d.pos && (preload = get_preload_template(d.form, d.lang, link)) ) {
workerHref = '&preload=' + encodeURIComponent(preload) + '&autoedit='
+ ((d.form == 'trad' || d.lang == 'eo') ? set_part_of_speech (link,d.lang,d.form) : '')
+ set_lang (d.lang) + set_template_lang (d.lang, d.form)
+ set_gender_template (d.gender, d.lang) + set_template_gender(d.gender, d.lang, d.form)
+ set_origin (d.given_origin, d.lang2 ? d.lang2 : d.lang) + set_pagename_linked_and_template_head (link, d.lang, d.form)
+ set_form_template (d.form, d.lang, d.gender, link)
+ set_template_sc (d.lang)
}
 
if (workerHref) {
 
link.href += '&editintro=User:Vriullop/creation/intro' + workerHref
+ '&autosummary=' + encodeURIComponent(
'Creant forma ' + d.form + ' de ' + d.lang + '.[[' + d.origin
+ ']] ([[VC:ACC|Accelerat]])' )
+ '&autominor=false';
 
link.style.color = '#22CC00';
}
}catch(e) {
}
}
 
/**
* The starting point of the whole script.
* For many languages the above is far too limiting - so let's define some more powerful functions.
*
* This adds a hook to the page load event so that the script runs
* The functions are structured top-down, this allows innermost functions to just return text that is
* and processes the accelerated links once the page is done loading.
* wrapped by outer functions, seems to result in shorter code, but should probably be refactored out :p.
*
* So each "declaration function" accepts a function (f) and returns an "edit function".
* and each "edit function" accepts some details (d) and returns the text to be wrapped (by calling f(d) where necessary)
*/
jQuery(document).ready(function get_preload_text(d) {
{
try{
// Don't do anything unless the current page is in the main namespace.
return get_preload_text[d.lang](d);
if (mw.config.get('wgNamespaceNumber') && mw.config.get('wgPageName') != 'Viccionari:Pàgina de proves')
} catch (e) {
return false;
}
// Find all the links that are marked as accelerated.
}
// Then go over each red link and see if we can "enhance" it into a green link.
poss = find_form_of_spans ();
for (var i = 0;i<poss.length; i++)
{
var link = find_red_link (poss[i]);
if (link)
{
// We can enhance this link, let's do it.
add_create_button (poss[i].className.replace(/(^| +)form-of( +|$)/,'').split(' '), link);
}
}
 
} );
/**
These templates are for constructing preloadtext manually.
*/
 
/*
function language_header(f) {
return function (d) { return "=={"+"{-" + d.lang + "-}}==\n\n" + f(d);};
}
 
// Find the part of speech by looking at the current part of speech heading
function default_pos(f) {
return function (d) {
return "===" + d.pos + "===\n" + f(d);
};
}
 
// { {head|fr|...}}
function head_template(f) {
return function (d) {
return "{"+"{head|" + d.lang + "|" + (
d.gender.indexOf('pl') > -1 ? 'plural' : d.pos.toLowerCase()
) + (
(d.gender ? "|g=" + d.gender.replace('pl','') : "") + (d.gender.indexOf('pl') > -1 ? '|g2=p' : '')
) + "}}\n\n" + f(d);
}
}
// { {head|nl}}
function posless_head(f) {
return function (d) {
return '{' + '{head|' + d.lang + '}}\n\n' + f(d);
}
}
 
// { {head|nl}} or { {nl-noun-dim}}
function nl_head(f) {
return function (d) {
if (d.form == 'diminutive') {
return '{' + '{nl-noun-dim}}\n\n' + f(d);
} else if (d.pos == "Noun" && d.form == 'plural') {
return '{' + '{lema|nl|substantiu en plural}}\n\n' + f(d)
} else {
return '{' + '{lema|nl}}\n\n' + f(d);
}
}
}
 
// { {tg-word}}
function tajik_head(f) {
return function(d) {
var head = '{'+'{tg-word' + (d.transliteration ? ('|tr=' + d.transliteration) : '') + '}}';
return head + "\n\n" + f(d);
}
}
 
// All definition lines start with #
function definition_line(f) {
return function (d) { return "# " + f(d) + "\n"; };
}
 
// Common part of eo
function eo_form_of(f) {
return function (d) { return '{'+'{eo-form of|' + f(d) + '}}'; };
}
 
// These ones always seem to happen toegether
function basic_entry(f) {
return language_header( default_pos( f ) );
}
 
// English
//get_preload_text.en =
 
// Esperanto
//get_preload_text.eo =
 
// French
//get_preload_text.fr =
 
/** A sanely named wrapper around throw */
function preload_text_error() { throw true; }
 
/**
* Recursively find first red link in "form-of" spans.
* FIXME: would be better to return an array as multiple params often occur
*/
function find_red_link (span)
{
 
var poss = span.firstChild;
 
while (poss) {
{
if(poss.nodeType == 1) {
{
if (poss.nodeName.toUpperCase () == 'A' && poss.className.indexOf('new') >= 0)
return poss;
Linha 466 ⟶ 529:
return recurse;
}
poss = poss.nextSibling;
}
Linha 471 ⟶ 535:
return null;
}
/**
* Recursively find anything tagged with "form-of"
*/
 
/*
function find_form_of_spans () {
* Recursively find anything tagged with the "form-of" class.
if (typeof(document.getElementsByClassName) == 'function') {
*/
function find_form_of_spans ()
{
if (typeof(document.getElementsByClassName) == 'function')
{
return document.getElementsByClassName('form-of');
}
else
{
var spans = document.getElementsByTagName ('span');
var form_ofs = new Array ();
 
for (var i=0; i<spans.length; i++) {
{
if (spans[i].className.match(/(^| +)form-of( +|$)/)) {
{
form_ofs.push (spans[i]);
}
Linha 492 ⟶ 562:
}
 
/**
* Convert a raw red link into a snazzy green one.
* Get the show on the road
*/
function add_create_button (details, link)
jQuery(document).ready(function () {
{
// First, gather all the information that was given in the span's class.
 
// Default values
// Mainspace only.
var d = {
if (mw.config.get('wgNamespaceNumber') && mw.config.get('wgPageName') != 'Wiktionary:Sandbox')
return;lang: 'ca',
lang2: null,
gender: '',
form: '',
origin: wgTitle,
given_origin: false,
pos: get_part_of_speech(link),
target: (link.innerText || link.textContent) }
 
// Go over each value and add it
poss = find_form_of_spans ();
for (var i = 0; i < details.length; i++)
{
if (details[i].match(/(^| +)([^ ]+)-form-of( +|$)/))
{
d.form = RegExp.$2;
}
else if (details[i].match(/(^| +)lang-([^ ]+)( +|$)/))
{
d.lang = RegExp.$2;
}
else if (details[i].match(/(^| +)lang2-([^ ]+)( +|$)/))
{
d.lang2 = RegExp.$2;
}
else if (details[i].match(/(^| +)gender-(([mfni]+|c)(pl)?)( +|$)/))
{
d.gender = RegExp.$2;
}
else if (details[i].match(/(^| +)origin-(.+)( +|$)/))
{
d.given_origin = unAnchorEncode(RegExp.$2);
}
else if (details[i].match(/(^| +)transliteration-(.+)( +|$)/))
{
d.transliteration = unAnchorEncode(RegExp.$2);
}
}
// Now build a new "green link" URL to replace the original red link with
var workerHref = '';
try
{
// First, try to create an entry "internally".
if (d.pos && (preload = get_preload_text(d)))
{
workerHref = '&preloadtext=' + encodeURIComponent(preload);
}
// If that doesn't work, then try generating an entry "externally" by using one of
// the script's subpages as a template.
else if (d.pos && (preload = get_preload_template(d.form, d.lang, link)) )
{
workerHref =
'&preload=' + encodeURIComponent(preload) + '&autoedit='
+ ((d.form == 'trad' || d.lang == 'eo') ? set_part_of_speech (link,d.lang,d.form) : '')
+ set_lang (d.lang) + set_template_lang (d.lang, d.form)
+ set_gender_template (d.gender, d.lang) + set_template_gender(d.gender, d.lang, d.form)
+ set_origin (d.given_origin, d.lang2 ? d.lang2 : d.lang) + set_pagename_linked_and_template_head (link, d.lang, d.form)
+ set_form_template (d.form, d.lang, d.gender, link)
+ set_template_sc (d.lang)
}
// Did we manage to generate a form-of entry?
// Then replace the red link with a green one and a new URL.
if (workerHref)
{
link.href +=
'&editintro=User:Vriullop/creation/intro' + workerHref
+ '&autosummary=' + encodeURIComponent('Creant forma ' + d.form + ' de ' + d.lang + '.[[' + d.origin + ']] ([[VC:ACC|Accelerat]])' )
+ '&autominor=false';
 
for (var i = 0;i<poss link.length;style.color i++)= {'#22CC00';
var link = find_red_link (poss[i]);
if (link) {
add_create_button (poss[i].className.replace(/(^| +)form-of( +|$)/,'').split(' '), link);
}
}
catch(e)
{
}
}
 
function unAnchorEncode(x)
} );
{
return decodeURI(x.replace(/\./g, '%'));
}
 
//The part of speech, normally determined by other means.
function get_part_of_speech (link)
{
var node = link;
while(node)
{
while (node.previousSibling)
{
node = node.previousSibling;
if (node.nodeType == 1 && node.nodeName.match(/^[hH][3]$/))
{
return $( node ).find( ".mw-headline" ).text().replace(/^[1-9.]* /,'');
}
}
node = node.parentNode;
}
throw("This entry seems to be formatted incorrectly.");
}