User:Perhelion/simpleSVGcheck.js
Jump to navigation
Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
Documentation for this user script can be added at User:Perhelion/simpleSVGcheck. |
/**
* @Remarks
* Since Perhelion had quitted Wikipedia, this script is still much used; and maintenance is necessary. //ed_
* Because nobody else did it, I tried some reparations and enhancements; the problem is: I have no JS knowledge. //ed_
* It can be seen that I made a lot of helpless tries, marked all with //ed_ //ed_
* It can well be seen that I fight heavily with JS and made things much more complicated //ed_
* than an expert would have done it. Some things that I made function - more or less. Others don't. //ed_
*
*
* @Description:
* Adds several SVG-valid-check-links on file-pages. Get the real byte-size for SVG-images. Put the template Igen prefilled in the file-description page.
* 14.07.2016 added tool-name recognition from SVG-code
* For usage show [[c:Template:Image generation]]
* @Revision: 12:00, 08 September 2020 (UTC) by Perhelion
* @Last Revision: 18:00, 09 July 2021 💃💃💃💃💃💃💃💃💃💃💃💃💃💃💃💃 Sarang
* @Author: [[User:Perhelion]], together featured with [[User:Sarang]]
* @License: CC BY-SA 3.0
* @Required modules: jquery.badge, mediawiki.api, mediawiki.util, jquery.spinner
* @TODO:
**/
// [[Category:User scripts|simpleSVGcheck]] <nowiki>
/* eslint-env es6*/
/* global mediaWiki, OO, importScript */
(function ($, mw) {
'use strict';
let gbs = [],
c = mw.config.get([
'wgAction',
'wgPageName',
'wgTitle',
'wgUserLanguage',
'wgUserName' // For simplSVG
]),
isEdit = /^(edit|submit)$/.test(c.wgAction),
err,
// size, // For simplSVG
toolName,
$textarea,
expeUser = /^Sarang|Sarangbot|JoKalliauer|Perhelion$/.test(c.wgUserName),
summary = '[[User:Perhelion/simpleSVGcheck.js|Script]]+[[Template:Image generation|Template]]',
cSVG = {
// When maintaining this script always bump this number!
version: '0.5.7',
name: 'simpleSVGcheck',
failStr: 'FAIL automatic insert', // Igen, please insert manually
curSize: 0,
textPath: 0,
badSVG: 0,
PGF: 0,
switchTrans: 0,
init: function () {
// W3C-Validator check-link for every SVG (by [[User:Perhelion]] fixed also now for admins)
let $g = $('<a>', {
title: 'Get exact byte-size'
}).badge('B?', 'inline', 1),
$igen,
/* = $('<a>', {
title: 'Insert Template:Image_generation with W3-Validity',
href: '#',
text: '→SVG-Igen',
click: mw.libs.simpleSVGcheck.getW3Data
Uri <- Also
})*/
$SVGc = $('<a>', {
title: 'Commons-libRSVG-Validator',
href: '/wiki/Commons:Commons_SVG_Checker?withJS=MediaWiki:CommonsSvgChecker.js&checkSVG=' + encodeURIComponent(c.wgPageName),
text: '→SVG Checker',
target: '_blank'
}),
$rows = $('#mw-imagepage-section-filehistory').find('tr').slice(1),
$t1 = $rows.first();
$igen = $(mw.libs.commons.ui.addEditLink('', '→SVG Igen', 'e-igen', 'Insert Template:Image_generation with W3C-validity')).find('a')
.on('click', mw.libs.simpleSVGcheck.getW3Data);
$t1.children('td').slice(-3, -2).append(['<br>', $igen.clone(true)]);
$t1.find('td[style]').append(['<br>', $SVGc]);
$rows.each(function (i) {
let $t = $(this);
$t.find('td[style]>a:first').after(function () {
let linkTxt = '→Valid SVG',
file = $(this).attr('href'),
// var href = "http://validator.w3.org/check?uri=" + $(this).attr("href") + "&group=1"; // there is an discrepance in automatic check
href = 'https://validator.nu/?doc=' + file + '&group=1&schema=http%3A%2F%2Fs.validator.nu%2Fsvg-xhtml5-rdf-mathml.rnc+http%3A%2F%2Fs.validator.nu%2Fhtml5%2Fassertions.sch+http%3A%2F%2Fc.validator.nu%2Fall%2F&parser=xml',
a = $('<a>', {
title: 'W3C-Nu-Validator',
href: href,
target: '_blank'
});
return ['<br>', a.text(linkTxt),
a.clone().attr('href', href + '&showsource=1#result').text(' (+src)?')
// ,"<br>",a.clone().attr("href", "http://validator.w3.org/check?uri=" + file + "&group=1&ss=1").text( "(→old W3-check)" )
];
});
$t.children('td').slice(-3, -2).children('span').after(function () {
if (!/Byte/.test(this.textContent)) {
let $gb = $g.clone();
gbs.push($gb.attr('name', i).click(cSVG.getImgData));
return $gb;
}
gbs.push('');
});
});
},
getImgData: function () {
mw.loader.using(['mediawiki.api'], function () {
new mw.Api().get({
prop: 'imageinfo',
iiprop: 'user|size', // |archivename
iilimit: 9, // max requested images
titles: c.wgPageName
}).done(function (json) {
if (!json || !json.query || !json.query.pages)
return;
let data = json.query.pages;
for (let p in data)
p = data[p];
if (!p)
return;
data = [];
for (let i = 0; i < p.imageinfo.length; i++)
data.push(p.imageinfo[i].size);
c.wgUserName = p.imageinfo[0].user; // global var
cSVG.setImgSize(data);
});
});
},
warnMsg: function (w) {
mw.loader.using([], function () {
if (typeof w === 'number') {
return mw.notify('SVG file is with ' + w + ' error' + ((w === 1) ? '' : 's') + ' not valid! ', {
title: 'W3-Validity-check',
type: 'warn'
});
}
if (w instanceof Object)
return mw.notify(cSVG.failStr + '!', w);
mw.notify(w + ' Please check manually again with the web-service.', {
title: 'W3-Validity-check warning!',
type: 'error',
autoHideSeconds: 7
});
});
},
getW3Data: function (e) {
if (e && e.preventDefault)
e.preventDefault();
// FIXME: maybe use also Rillke Bot
if (isEdit) {
$('#editform').prepend($.createSpinner({
id: 'w3nu',
size: 'large',
type: 'block'
}));
if (cSVG.err)
return cSVG.addToFileDesc($textarea, cSVG.err, '', cSVG.toolName);
}
let file = '';
if (!(isEdit && e instanceof Object)) {
file = $('#file > a:first'); // fullImageLink
if (!file.length)
$(this).parent().prev().find('a'); // thumb preview, may superfluous
if (file.length)
file = file.attr('href');
}
if (!file || !/SVG$/i.test(file))
file = 'https:' + mw.config.get('wgServer') + '/wiki/Special:Filepath/' + c.wgTitle.replace(' ', '_');
// console.log(typeof e, e.nodeName , file );
/* https://validator.w3.org/docs/api.html */
// only once
if (cSVG.xhr)
return cSVG.addToFileDesc($textarea, -1);
cSVG.xhr = $.getJSON('https://validator.w3.org/nu/', {
'out': 'json',
'showsource': 1, // for check tool-name
// "charset" : "UTF-8",
'doctype': 'SVG 1.1 + URL + XHTML + MathML 3.0', // SVG+1.1+%2B+URL+%2B+XHTML+%2B+MathML+3.0
'parser': 'xml',
'user-agent': 'W3C_Validator/1.3 http://validator.w3.org/services', // W3C_Validator%2F1.3+http%3A%2F%2Fvalidator.w3.org%2Fservices
'schema': 'http://s.validator.nu/svg-xhtml5-rdf-mathml.rnc http://s.validator.nu/html5/assertions.sch http://c.validator.nu/all/',
'doc': file
}
// https://validator.w3.org/docs/users.html#Options
// $.getJSON("https://validator.w3.org/check?uri=" + file + "&ss=1&output=json" // CORS-Kopfzeile 'Access-Control-Allow-Origin' fehlt
).done(
function (json) {
let data = json.messages;
if (!data || !json.source || !json.source.code)
return cSVG.warnMsg('Fail to read file ' + json);
let code = json.source.code,
doctype = /<!DOCTYPE svg/i.test(code),
err = [],
warn = [],
warnRDF = 'This validator does not validate RDF.', // FIXME only discrepance if <!DOCTYPE present
para = {}; // Parameter 5
para.curSize = code.length;
para.badSVG = /[<:]image[\s>]/.test(code);
para.PGF = /<i:pgf[ \n]|[^#]adobe_illustrator_pgf/.test(code);
// para.PGF = /<i:pgf[ \n]|[^#]adobe_illustrator_pgf|\!\[CDATA/.test(code); // pgf cdata
let toolName = cSVG.toolName = cSVG.getToolName(code, para.PGF);
if (!(para.badSVG && para.PGF)) {
para.switchTrans = / systemLanguage/.test(code); // /[<:]switch[\s>]/;
para.textTrans = /[^>]\s?(<\/tspan>)?\s?<\/text>/.test(code);
if (para.switchTrans)
para.switchTrans = para.textTrans;
else
para.switchTrans = 0;
if (para.switchTrans && !expeUser)
para.textTrans = 0;
}
if (para.badSVG && !/[<:](path|text)[\s>]/.test(code))
para.badSVG = 2; // Fake SVG
if ((toolName === 'inkscape' || toolName === 'IA') && code.indexOf('aria-label=') > 20)
para.textPath = 1; // textPath
for (let i in data) {
// console.log(i, data[i], doctype); // data.messages is an array
json = data[i].type;
if (!json)
continue;
if (json === 'error')
err.push(data[i].message);
else if (json === 'info' && data[i].subType === 'warning')
warn.push(data[i].message);
}
err = err.length;
let w = warn.length;
if (w && doctype) {
while (w--) {
if (!warn[w].indexOf(warnRDF)) {
warn = warnRDF;
warnRDF = '';
break;
}
}
}
// console.log("Successfully checked for SVG errors ", err, w, warn.length, warnRDF); // error messages
if (isEdit) {
if (!(err || warnRDF))
cSVG.warnMsg(warn);
$.extend(cSVG, para);
return cSVG.addToFileDesc($textarea, err, warn, toolName);
} else if (!(err || warnRDF)) {
cSVG.warnMsg(warn);
setTimeout(function () {
cSVG.addIgenURL(err, '', toolName, para);
}, 4000);
} else {
cSVG.addIgenURL(err, '', toolName, para);
}
}).fail(function (e) {
mw.log.warn('Ajax error to ', e);
if (isEdit)
return cSVG.addToFileDesc($textarea, -1);
});
return false;
},
/**
* Gets the tool name from SVG code.
*
* @param {string} code
* @param {boolean} toolName
* @return {string} tool name
*/
getToolName: function (code, toolName) {
// TODO can be extended
let toolList = [
'geogebra',
'sodipodi',
'Sketch',
'ShareMap',
'openoffice',
'libreoffice',
'inkscape',
' potrace', // + whitespace
' graphviz', // + whitespace
' dot version 2.2.1', // ??
'QGIS',
'MetaPost',
'MATLAB',
'Illustrator',
'Gnuplot', 'GNUPLOT',
'fig2svg',
'EazyDraw', // Peter coxhead
'CorelDRAW',
'ElCompLib', // ed_wdh
'Method Draw', // Cookieman1.1.1
'Chemtool',
'ChemSketch', // ChristianBausW
'bkchem',
'Batik',
'ArcMap',
'Adobe',
// 'parliament diagram creator'],
'Generated with Qt', // <desc>Generated with Qt</desc>
'baseProfile="full"', // when nothing else can be used - only hint for GeoGebra
'parliament'],
i = toolList.length;
toolName = toolName ? 'Adobe' : '';
while (i-- && !toolName) {
if (code.indexOf(toolList[i]) + 1) {
toolName = toolList[i];
break;
}
}
if (!toolName) { // Guess tool, boilerplate in every Illustrator SVG export
i = /<svg [^>]+>/i.exec(code); // Root
if (i) {
if (i[0].indexOf('enable-background') + 1)
toolName = 'Adobe';
if (i[0].indexOf('id="svg2"') + 1)
toolName = toolName ? 'IA' : 'I';
}
} else if (toolName === 'inkscape' &&
/(inkscape:grid|sodipodi:(guide|cx))/.test(code)) {
toolName = 'Im';
} // IMPORTANT=yes
// Mixtures
if ((/^[Aa]dobe|Illustrator/.test(toolName) && /[Ii]nkscape/.test(code)) || (/^[Ii]nkscape/.test(toolName) && /[Aa]dobe|Illustrator/.test(code)))
toolName = 'IA';
return toolName;
},
setImgSize: function (data) { // get & set file size
$.each(gbs, function (i) {
$(this).prev().remove();
// no link for first
if (this && this[0].name !== '0') {
return $(this).text('→' + data[i])
.attr('title', 'Insert Template:Igen with actual simple size: ' + data[0])
.off('click')
.click(function (/* e*/) {
cSVG.addIgenURL('0', [data[i], data[0]]);
});
}
// first badge link only for display
return $(this).replaceWith(data[0] + ' Byte');
});
},
/* registerModules: function() { // Register custom modules
if ( !mw.loader.getState('mediawiki.commons.MwJSBot') ) mw.loader.implement('mediawiki.commons.MwJSBot', ["//commons.wikimedia.org/w/index.php?action=raw&ctype=text/javascript&title=User:Rillke/MwJSBot.js"], {
}, {
});
},
run: function() { // Create GUI
cSVG.registerModules();
mw.loader.using(['mediawiki.commons.MwJSBot'], function() {
});
}, */
setIgen: function (pre, post) {
$textarea.textSelection('encapsulateSelection', {
pre: pre,
// peri: '',
post: post
});
},
replaceTag: function (txt, err, toolname) {
if (!txt)
return;
let size = this.size,
txT = txt, // for test
imRE = /^\s*\| *[Oo]ther[_ ]fields *=\s*\{\{[Ii]mgen\|(\w+)\}\} *$/m,
coa = /\{\{COAInformation\s*\|\s*/.test(txT), // coat of arms template boolean
imgenRE = /\|\s*[Ii](?:m?gen|mage generation) *=\s*[^\s]+ *\n/,
imgen = ((coa && imgenRE.test(txT)) || imRE.test(txT)),
toolName = '', // default nothing, most possible is Inkscape
// sourcecode, // possible from which are generated for "Created with code"
g = '', // specify the Graphic lab
T = '', // additional trailing text for templates (extension)
p5 = '', // Parameter 5
r = '', // retouched
s = '', // suffix for subcat
s1 = '', // leading whitespaces as indent?
s2 = '', // whitespace on parameter?
ls = '', // last substring index
topp = '', // template igen on topposition
replaced = false,
LeyoChem = false,
ofRE = /( )*\|\s*[Oo]ther[_ ]fields( )*=\s*([^\n]*\n)/g,
inRE = [
/\{\{(COA)?[Ii]nformation\s*\|\s*/,
/( )*\|\s*[Pp]ermission( )*=\s*[^\n]*\n/,
/( )*\|\s*[Oo]ther[_ ]versions( )*=(\n?[^\n]*\n)/
],
IgenName = '{{Igen|',
IgenNameLong = '{{Image generation|',
tempPre = '}}\n',
user = '', // for u=
// Normalized toolnames different to code
toolNames = {
'Fig2svg': 'Fig2SVG',
'Illustrator': 'Adobe', 'Adobe Illustrator': 'Adobe',
'bkchem': 'BKchem', 'Bkchem': 'BKchem',
'Libreoffice': 'LibreOffice',
'geogebra': 'GeoGebra', 'BaseProfile="full"': 'GeoGebra',
'Openoffice': 'OpenOffice.org',
'Generated with Qt': 'Qt',
' potrace': 'Potrace',
' graphviz': 'Graphviz',
' dot version 2.2.1': 'Graphviz'
},
// Toolname abbreviations (experienced users only)
toolAbbr = {
'Adobe': 'A',
'Adobe-hand': 'AH',
'Inkscape': 'I',
'Inkscape-hand': 'H',
'BKchem': 'B', // ed_sf
'ChemDraw': 'C', // ed_sf
'CorelDraw': 'D',
'CorelDRAW': 'D',
'Fig2SVG': 'F',
'Gnuplot': 'G', 'GNUPLOT': 'G',
'LibreOffice': 'L',
'OpenOffice.org': 'OOo',
'Parliament': 'Wpdc'
},
// Full replace - use templates:W Expand this table when there are more (W)ikilink templates
Langtab = {
"en" : "W" ,
"ar" : "WA" ,
"bn" : "Wb" ,
"ca" : "WC" ,
"cs" : "Wc" ,
// "da" : "Wda" ,
"de" : "Wd" ,
// "el" : "Wel" ,
// "eo" : "Weo" ,
"es" : "We" ,
"fa" : "Wfa" ,
// "fi" : "Wfi" ,
"fr" : "Wf" ,
"gl" : "Wg" ,
"hu" : "Wh" ,
"he" : "Whe" ,
// "id" : "Wid" ,
"it" : "Wi" ,
"ja" : "W日" ,
"kn" : "ವಿ" ,
"ko" : "W말" ,
// "lt" : "Wlt" ,
// "lv" : "Wlv" ,
"mk" : "Wm" ,
"ml" : "വി" ,
"nl" : "Wn" ,
// "nn" : "Wnn" ,
// "no" : "Wno" ,
"pl" : "WP" ,
"pt" : "Wp" ,
"ru" : "Wr" ,
"si" : "වි" ,
"sl" : "Wsl" ,
"su" : "Wsu" ,
"sv" : "Wsv" ,
"th" : "Wth" ,
"tr" : "Wtr" ,
"uk" : "Wu" ,
"zh" : "Wz"
};
/*
* t instanceof RegExp
* return the end-index "topp" of info template before brackets
* ============================================================
*/
function encodeAlsoComponent(str) {
return encodeURIComponent(str).
replace(/[%'()]/g, escape); // i.e., %25 %27 %28 %29
}
function _findPosition(t) {
let p = 0; // end of info template
let arr;
let li = 0;
let str;
let RE = /[\s\S]+?\n\}\}\n/g;
// sometimes index = 0
t = t.lastIndex ? t.lastIndex - RegExp.lastMatch.length : txt.search(t);
str = txt.substr(t);
s1 = RegExp.$1 || s1;
s2 = RegExp.$2 || s2;
// Try to go at template end (fallback risky if another template ends in same way) ed_wd
// often wrong position when
while ((arr = RE.exec(str)) !== null) {
let m = arr[0];
li = arr.index;
p = m.lastIndexOf("{{");
if (m && (p === -1 || (p = m.indexOf("}}", p)) !== -1 && p < m.length - 3)) {
p = li + m.length - 3;
str = "";
break;
} else
p = 0;
}
if (!p) {
p = str.search(/\n?\}\}$\n/m); // \s is trimmed before
if (RegExp.lastMatch.length === 3) {
txt = txt.substr(0, t + p) + '\n' + txt.substr(t + p);
p++;
}
}
t = (p >= 0) ? t + p : 0;
return t;
}
// * ============================================================
function _ucfirst(s) { // Uppercase
return s.slice(0, 1).toUpperCase() + s.slice(1);
}
// * ============================================================
function generalCleanup(text) {
// TODO: namespace User could be extended with any language
// lowercase parameter name default, trim leading whitespace
if (inRE[0].test(text)) {
text = text.replace(/^( *)\|\s*([A-Z][^=\n{}|?!.]+ *=)/gm,
function (m, p1, p2) {
return p1 + '|' + p2.toLowerCase();
});
}
// For AutVec and Own based
let fileTruncate = function (m, p1) {
// Shorten parameter if names are the same (currently only 3 letter ext are supported)
let fExt = p1.slice(-4),
fName = p1.slice(0, -4);
fName = (fExt[0] === '.' && fName === c.wgTitle.slice(0, -4)) ? fExt : p1;
fName = fName === '.png' ? '.' : fName;
return m.replace(p1, fName);
};
/* ---------------- blocks
// For AutVec, Own based, F, File, Filelist, Other versions, Derived from, Derivative versions; Retouched
let fileTruncate = function (m, p1) {
// Shorten parameter if names are the same - currently only 3 (or 4) letter ext is supported
p1 = p1.trim();
let fExt = p1.slice(-4),
fEx4 = p1.slice(-5),
fName = p1.slice(0, -4);
fName = fName.substring(0, 5) === 'File:' ? fName.substring(5 ) : fName; //ed_wdh -
fName = fName.substring(0, 5) === 'file:' ? fName.substring(5 ) : fName; //ed_wdh -
fName = fName.substring(0, 6) === 'Image:' ? fName.substring(6 ) : fName; //ed_wdh -
fName = fName.substring(0, 6) === 'image:' ? fName.substring(6 ) : fName; //ed_wdh -
fwebp = (fEx4[0] === '.' && fName === c.wgTitle.slice(0, -5)) ? fExt : p1; //ed_wdh -
fName = (fExt[0] === '.' && fName === c.wgTitle.slice(0, -4)) ? fExt : p1;
fName = fName === '.png' ? '.' : fName;
fName = fName === '.gif' ? '.g' : fName; // ed_wdh:
fName = fName === '.jpg' ? '.j' : fName; // ed_wdh:
fName = fName === '.svg' ? '.s' : fName; // ed_wdh:
fName = fName === '.tif' ? '.t' : fName; // ed_wdh:
fName = fName === '.xcf' ? '.x' : fName; // ed_wdh:
fName = fwebp === '.webp' ? '.w' : fName; // ed_wdh:
return m.replace(p1, fName);
};
*/
return text
.replace(inRE[2], '$1|other versions$2=$3') // standardize
.replace (/( *\| *[Dd]ate *= *\d{4}-\d{2}-\d{2}) \d{2}:\d{2}(?::\d{2})?(?: \(UTC\))?/g, '$1') // ed_wdh: clock does not belong to date
// restore falsified parameter names:
.replace(/(\|\s*)svg(?= tool\s*=)/g, '$1 SVG') // ed_wdh: undo
.replace(/(\|\s*)tool(?=\s?name\s*=)/g, '$1 Tool') // ed_wdh: undo
.replace(/(\|\s*)other(?=\s?tool\s*=)/g, '$1 Other') // ed_wdh: undo
.replace(/(\|\s*)w3c(?= error count\s*=)/g, '$1 W3C') // ed_wdh: undo
.replace(/(\|\s*)topic(?=\s*=)/g, '$1 Topic') // ed_wdh: undo
.replace(/(\|\s*)text(?= embedded\s*=)/g, '$1 Text') // ed_wdh: undo
.replace(/(\|\s*)text(?= as path\s*=)/g, '$1 Text') // ed_wdh: undo
.replace(/(\|\s*)text(?=edit only\s*=)/g, '$1 Text') // ed_wdh: undo
.replace(/(\|\s*)draw(?= by hand\s*=)/g, '$1 Draw') // ed_wdh: undo
.replace(/(\|\s?)user(?=link\s*=)/g, '$1 User') // ed_wdh: undo
// shorten indentions:
.replace(/\|tincture = ?/, '|tincture =') // ed_wdh (ls)
.replace(/\|blazon of = ?/, '|blazon of =') // ed_wdh (ls)
.replace(/\|blazon = ?/, '|blazon =') // ed_wdh (ls)
.replace(/\|references = ?/, '|references =') // ed_wdh (ls)
.replace(/\|description = ?/, '|description =') // ed_wdh (ls)
.replace(/\|date = ?/, '|date =') // ed_wdh (ls)
.replace(/\|source = ?/, '|source =') // ed_wdh (ls)
.replace(/\|author = ?/, '|author =') // ed_wdh (ls)
.replace(/\|artist = ?/, '|artist =') // ed_wdh (ls)
.replace(/\|permission = ?/, '|permission =') // ed_wdh (ls)
.replace(/\|other fields *= ?/, '|other fields=') // ed_wdh (ls)
// remove the "1=" when text is without "="
// 1) plain text without equal sign ✓
// 2) plain text with equal sign ✓
// 3) text with templates - ignore "=" in template -no-
// 4) any series of text and templates - ignore "=" in template but not in text -no-
// .replace(/(\{\{\w\w\w? ?\|) ?1 ?=([^=\}]+\})/g, '$1$2') // remove when no '='
/* // clean text switch part of files treated with toolforge translator
// =================================================================
.replace(/<\/text><text>/g, '</text>\n<text>') // ed_wdh (insert newline)
// .replace(/<text id="trsvg[^"]+"><tspan id="trsvg[^"]+">([^<]+)<\/tspan><\/text>/g, '<text>$1</text>') // ed_wdh
.replace(/ id="trsvg[^"]+"><tspan id="trsvg[^"]+">([^<]+)<\/tspan><\/text>/g, '>$1</text>') // ed_wdh
.replace(/<\/tspan><tspan x="(\d+)" y="(\d+)" id="trsvg[^"]+">([^<]+)<\/tspan><\/text>/g, '</tspan><tspan x="$1" y="$2">$3</tspan></text>') // ed_wdh
.replace(/<text(?: id="trsvg[^"]+")? systemLanguage="(\w+)"(?: id="trsvg[^"]+")?><tspan id="trsvg[^"]+">([^<]+)<\/tspan><\/text>/g, '<text systemLanguage="$1">$2</text>') // ed_wdh
.replace(/<text(?: id="trsvg[^"]+")? systemLanguage="(\w+)"(?: id="trsvg[^"]+")?><tspan id="trsvg[^"]+">([^<]+)<\/tspan><tspan([^<]+)<\/tspan><\/text>/g, '<text systemLanguage="$1">$2</tspan><tspan>$3</tspan></text>') // ed_wdh
*/
// now simplify [[namespace: ...]] to the template transclusion {{N| ...}}
// =======================================================================
// namespaces: ns 0 = :W, ns 2 = U, ns 6 = :F, ns 10 = T, ns 14 = :C, ns 828 = M
/* replace: [[ns:link]] -> {{N|link}} one param
* [ns:link|name]] -> {{N|link|name}} two params
*
* [[ns:lx:link]] -> {{N|link||lx}} one param plus language (two pipes)
* [[ns:lx:link|name]] -> {{N|link|name|lx}} two params plus language
* [[ns:Link|Link]] -> {{N|Link}} two params, but 2nd is same
* [[ns:link|linkxyz]] -> {{N|link}}xyz two params, but 2nd is 1st with suffix
analog with language code
* [[ns:Link|link]] -> {{N|link}} two params, but 2nd is lcfirst
* [[ns:link|Link]] -> {{N|Link}} two params, but 2nd is ucfirst
analog with language code
* [[ns:lx:Link|linkxyz]] combination: same name lowercase,
* -> {{N|link||lx}}xyz plus language, plus suffix
*/
// first all other namespaces - then (as the last one) the namespace 0
// ===================================================================
.replace(/\[\[:?(?:[Ww](?:ikipedia)?):([Uu]ser|[Ff]ile|[Tt]emplate|[Cc]ategory|[Mm]odule):/g, '[[:en:$1:') // ed_wdh: W namespace
.replace(/\[\[:?(?:[Ww](?:ikipedia)?):([a-z]{2,3}):/g, '[[:$1:') // double interlink - remove useless :w
// 2 {{U Wikipedia user links:
.replace(/\|artist *= *\*?unknown\n\n\* *vectorized by \[\[(Chris die Seele)\]\]/m, '|artist = {{AutVec||$1}}') // ed_wdh:
.replace(/Thom.lanaud/g, 'Thom.Lanaud') //ed_wdh user writing
.replace(/User:Domdomegg/g, 'user:domdomegg') //ed_wdh user writing
.replace(/([Uu]ser|[Bb]enutzer|[Ff]ile|[Ii]mage|[Tt]emplate|[Cc]ategory|[Mm]odule): ?(_ucfirst([^\]\|]+?))(\|\2)([^\]]+?)?\]\]/g, '$1:$3|$3]]$4💖')
.replace(/\[\[(:?[Uu]ser|[Bb]enutzer|[Ff]ile|[Ii]mage|[Tt]emplate|[Cc]ategory|[Mm]odule): ?([^\]\|]+?)\|(_ucfirst(\2))([^\]]+?)?\]\]/g, '[[$1:$3|$3]]$4💗')
.replace(/\[\[:?(?:[Uu]ser|Benutzer): ?([^\]\|]+?)(?:\|\1)?\]\]/g, '{{U|$1}}') // ed_wdh: U [single or same]
.replace(/\[\[:?(?:[Uu]ser|Benutzer): ?([^\]\|]+?)\|(.+?)\]\]/g, '{{U|$1|$2}}') // ed_wdh: U [link & disp]
.replace(/\[\[:([a-z]{2,3}):(?:[Uu]ser|Benutzer): ?([^\]\|]+?)(?:\|\2)?\]\]/g, '{{U|$2||$1}}') // ed_wdh: U [single or same]:lg
.replace(/\[\[:([a-z]{2,3}):(?:[Uu]ser|Benutzer): ?([^\]\|]+?)\|(.+?)\]\]/g, '{{U|$2|$3|$1}}') // ed_wdh: U [link & disp]:lg
// 6 {{F l= for external
.replace(/\[\[:(?:[Ff]ile|[Ii]mage): ?([^\]\|]+?)(?:\|\1)?\]\]/g, '{{F|$1}}') // ed_wdh: F [single or same]
.replace(/\[\[:(?:[Ff]ile|[Ii]mage): ?([^\]\|]+?)\|(.+?)\]\]/g, '{{F|$1|$2}}') // ed_wdh: F [link & disp]
.replace(/\[\[:([a-z]{2,3}):(?:[Ff]ile|[Ii]mage): ?([^\]\|]+?)(?:\|\2)?\]\]/g, '{{F|$2||l=$1}}') // ed_wdh: F [single or same]:lg
.replace(/\[\[:([a-z]{2,3}):(?:[Ff]ile|[Ii]mage): ?([^\]\|]+?)\|(.+?)\]\]/g, '{{F|$2|$3|l=$1}}') // ed_wdh: F [link & disp]:lg
// test "by=":
.replace(/\{\{F\|([^\}]+?)\}\} *by *\{\{U\|([^\}]+?)\}\}/g, '{{F|$1|by={{U|$2}}}}') // ed_wdh: simplify by=U later
.replace(/\{\{U\|([^\|]+)\|(?:([^\|]*)?)?\|de\}\}/g, '{{Ud|$1|$2}}') // ed_wdh: Ud
// 10 {{T
.replace(/\[\[(?::?[Tt]emplate): ?([^\]\|]+?)(?:\|\1)?\]\]/g, '{{T|$1}}') // ed_wdh: T [single or same]
.replace(/\[\[(?::?[Tt]emplate): ?([^\]\|]+?)\|([^\]\|]+?)\]\]/g, '{{T|$1|$2}}') // ed_wdh: T
.replace(/\{\{[Tt]emplate:/g, '{{') //ed_wdh written by some users
.replace(/\[\[:([a-z]{2,3}):(?:[Tt]emplate): ?([^\]\|]+?)(\|[^\]]+?)?\]\]/g, '{{T|$2$3|$1}}') // ed_wdh: T [link & disp]:lg
// 14 {{C
.replace(/\[\[(?::[Cc]ategory): ?([^\]\|]+?)(?:\|\1)?\]\]/g, '{{C|$1}}') // ed_wdh: C [single or same]
.replace(/\[\[(?::[Cc]ategory): ?([^\]\|]+?)\|([^\]\|]+?)\]\]/g, '{{C|$1|$2}}') // ed_wdh: C
//828 {{M
.replace(/\[\[(?::?[Mm]odule): ?([^\]\|]+?)(?:\|\1)?\]\]/g, '{{M|$1}}') // ed_wdh: M [single or same]
.replace(/\[\[(?::?[Mm]odule): ?([^\]\|]+?)\|([^\]\|]+?)\]\]/g, '{{M|$1|$2}}') // ed_wdh: M
// 0 {{W Wikipedia interwikilinks: 🏮 (🔅🔆)
.replace(/\[\[:?(?:[Ww](?:ikipedia)?:)(?:([a-z]{2,3}):) ?([^\]\|]+?)(?:\|\2)?\]\]/g, '{{W|$2||$1}}') // ed_wdh: W [single/same]
.replace(/\[\[:?(?:[Ww](?:ikipedia)?:)(?:([a-z]{2,3}):) ?([^\]\|]+?)\|(.+?)\]\]/g, '{{W|$2|$3|$1}}') // ed_wdh: W [link & disp]
.replace(/\[\[:?(?:[Ww](?:ikipedia)?:) ?([^\]\|]+?)(?:\|\1)?\]\]/g, '{{W|$1||en}}') // ed_wdh: W:en [single/same]
.replace(/\[\[:?(?:[Ww](?:ikipedia)?:) ?([^\]\|]+?)\|(.+?)\]\]/g, '{{W|$1|$2|en}}') // ed_wdh: W:en [link & disp]
.replace(/\[\[:(?:([a-z]{2,3}):)?(?:[Ww](?:ikipedia)?:)? ?([^\]\|]+?)(?:\|\2)?\]\]/g, '{{W|$2||$1}}') // ed_wdh: W [single/same]
.replace(/\[\[:(?:([a-z]{2,3}):)?(?:[Ww](?:ikipedia)?:)? ?([^\]\|]+?)\|(.+?)\]\]/g, '{{W|$2|$3|$1}}') // ed_wdh: W [link & disp]
.replace(/\{\{(W|U|Ud|[FTCM])\|([^\|\}]*)\|([^\}\|]+)?\|?([a-z]{2,3})?\}\}/g, function (m, ns, link, disp, lang)// = '')
{ if (!disp || disp === '') disp = link; // same for default (later stripped)
if (!lang) lang = '';
if (lang !== '') lang = "|" + lang; // pipe only when present
let ssts = ""; // sub-string suffix
if (link.length <= disp.length) {
for (let i = 1; i < link.length; i++)
{ if ( link.substring(i, i+1) === "_")
link = link.substring(0, i) + " " + link.substring(i + 1); // replace
if ( disp.substring(i, i+1) === "_")
disp = disp.substring(0, i) + " " + disp.substring(i + 1); // replace, except {{U}}
}
ssts += disp.substring(0, link.length); // part of possible sameness
if (ssts === link
|| ssts === link.substring(0,1).toUpperCase() + link.substring(1)
|| ssts === link.substring(0,1).toLowerCase() + link.substring(1) )
{ link = ssts; // case_correct from disp
ssts = "" + disp.substring(link.length, disp.length); // suffix
disp = ""; // strip
}
else ssts = ""; // without suffix
}
if (disp !== "" || lang !== "") disp = "|" + disp;
return "{{" + ns + "|" + link + disp + lang + "}}" + ssts;
})
// Full replace (was not intentional by oalb) using Langtab
.replace(/\{\{[Ww]\|([^\|\}]*?)(?:\|\||(\|[^\|]*?)\|)([a-z]{2,3})\}\}/g, function (m, link, disp, lang)// = "")
{ if (!disp) disp = "";
if (!lang) lang = "";
let diss = "" + disp;
if (diss === "") diss = "|";
let ns = lang;
ns = Langtab[lang] ? Langtab[lang] : lang;
if (ns !== lang)
return "{{" + ns + "|" + link + disp + "}}"; // language replaced🔺
else
return "{{W|" + link + diss + "|" + lang + "}}"; // language not found
})
.replace(/\|by=\{\{U\|([^\|\}]+?)\}\}/g, '|by=$1') // ed_wdh: simplify by=U
.replace(/(XY \(siehe Dateiname\)|[Xx][Yy] ? \(see filename\))/g, '{{F|F}}') // ed_wdh: 'XY' TUBS
.replace(/von \{\{F\|F\}\}/g, 'von {{F|F}}') // ed_wdh: TUBS doublespace
.replace(/(XY \(див. назву файлу\))/g, '{{F|F}}') // ed_wdh: 'XY' TUBS
.replace (/\{\{AutVec\|o\=\{\{Creator/, '{{AutVec|{{Creator') // ed_wdh
.replace(/\(?\[\[[Uu]ser[ _]talk: ?([^\]|[]+)\|?[^\][]*\]\]\)?/g, '') // ed_wdh: User talk - only when not stand-alone
.replace(/\[\[Category:Location not applicable ?(\|[^\n\]]+)?\]\]\n*/, '')
.replace (/\{\{([Ll]ocation) (?:dms|dec)/g, '{{$1') // ed_wdh
.replace (/\{\{([Kk]oordynaty)/g, '{{Location') // ed_wdh
.replace(/\[\[Category:Created with ShareMap ?(\|[^\n\]]+)?\]\]\n*/, '') // ed_wdh
.replace(/Created with \[\[ShareMap:\|ShareMap\.org\]\]\n*/, '') // ed_wdh
.replace(/Created with \[http:\/\/sharemap\.org ShareMap\.org\]\n*/, '') // ed_wdh
.replace(/\[\[\Category:Created with Inkscape\]\]\s?/, '') // ed_wdh remove / uncat
.replace(/(?:<center>)?\{\{(?:[Cc]reated with |[Mm]ade with )?Inkscape(?:\|err=\d*)?\}\}(?:<\/center>)?\s?\n*/, '') // ed_wdh Orem remove
.replace(/<center>\s?\n*<\/center>\s?\n*/, '') // ed_wdh Orem remove
.replace(/\{\{Created with Inkscape\}\}\s?\n*/, '') // ed_wdh remove / uncat
.replace(/\[\[\Category:Inkscape\]\]\s?/, '') // ed_wdh remove even worse
.replace(/\[\[Category:SVG files ?(\|[^\n\]]+)?\]\]\n*/, '') // MetaCat
.replace(/ ?(?:[Vv]ector(?:ized|ization)|r?e?drawn|[Vv]ektorisiert) ?(?:by|von)? ?(\{\{U\|(?:[^}]+)\}\})/g, ' {{author|Vectorization|$1}}')
.replace(/\*\{\{F\|([^\]|[]+)\|\+\}\} licensed/g, '*{{F|$1|-}} licensed') // ed_wdh: Original upload log
.replace(/\[\[:[Cc]ategory: ?([^\]|[\n]+)(?:\| ?\1 ?)\]\]/g, '{{C|$1}}')
.replace(/=\s*\{?\{?(own)?\}?\}? ?(work|made|after|nach|from)?,? (?:based|basierend|from)? (after|nach|on|off):?/gi, '={{Own based}}')
.replace(/=\s*\{\{[Oo]wn\}\} ?from /g, '={{Own based}} ') // ed_wdh (previous did not work); include the file:
.replace(/=\s*\{\{[Oo]wn based\}\};*\s*(?:\[\[:(?:[Ff]ile|[Ii]mage):|\{\{[Ff]\|) ?([^\]|[\n]+)(?:\]\]\.?|\}\})/g, '={{Own based|$1}}')
.replace(/\| *[Oo]rig(?:off)? *=([^\]|[\n]+)(?:\}\}|\|)/g, fileTruncate) // ed_wdh
.replace(/\{\{ *[Oo]wn based *\|([^\]|[\n]+)(?:\}\}|\|)/g, fileTruncate) // ed_wdh
.replace(/\{\{ *[Vv][Vv][Aa] *=([^\]|[\n]+)(?:\}\}|\|)/g, fileTruncate) // ed_wdh + aliases
.replace(/\{\{ *[Dd]erived(?: +from)? *\|([^\]|[\n]+)(?:\}\}|\|)/g, fileTruncate) // ed_wdh
.replace(/\{\{ *[Ff]ile(?:list)? ?\|([^\]|[\n]+)(?:\}\}|\|)/g, fileTruncate) // ed_wdh
.replace(/=\s*(?:(?:[Nn]achgezeichnet )?nach|[Bb]ased on|(?:[Rr]edrawn )?after)? (?:Vorlage)?:?\s*\*?\[?(?:\{\{[Nn]gw2\|(?:1|url ?=)?)? ?(?:(?:heraldrywiki\/index\.php\?title=)([\w_ ()]*)|(?:(?:http:\/\/)?www\.ngw\.nl\/?(?:heraldrywiki\/index\.php\?title=([\w_ ()]*)|int\/dld\/\w+\/(?:images\/)?([\w_ ()]*)\.\w{3})?))\}?\}?(?: [\w .]+)?\]?/g, function (m, p1, p2, p3) {
m = '';
let l = [p1, p2, p3],
p = 3,
r = /\d$/,
w = '<!--PLEASE CHECK-->';
while (p--) {
m += (l[p] || '');
if (r.test(m)) {
m = m.replace(r, w);
w = '';
}
}
if (w && (m.length === 8 || c.wgTitle.toLowerCase().indexOf(m) === -1))
m += w;
// never use ngw2 on SVG
return '={{Ngw3|' + _ucfirst(m) + '}}';
})
//
// *** Iterative replacings for: Attrib; Legend; Gallery;
.replace(/\{\{\s?[Aa]ttrib(?:SVG)? ?\|(?: ?1 ?= ?)?(?:[Ff]ile:|[Ii]mage:)?/g, '{{Attrib|') // ed_wdh
// when there are more "Attrib"s, change to "Attribs": [[[without backreference ! ]]]
.replace(/(\s*\{\{Attrib\|(?:.*?)\}\})\{\{Attrib\|/gm, '$1@\n{{Attrib|') //ed_wdh
.replace(/(\s*\{\{Attrib\|(?:.*?)\}\})[\s ]*\{\{Attrib\|/gm, '$1@\n{{Attrib|') //ed_wdh
.replace(/(\s*\{\{Attrib\|(?:.*?)\}\})[\s ]*\{\{Attrib\|/gm, '$1@\n{{Attrib|') //ed_wdh
.replace(/(?:\}\}@[\s ]*\{\{Attrib\|)/gm, '\n |') //ed_wdh
.replace(/(\s*\{\{Attrib)/g, '$1s|t=\n ') //ed_wdh (all, also singles! - better: only first of queue)
// *** Assume "coat of arms" (c) - but be aware that it can be as well "map" (m/lm/wm) or another topic
.replace(/\{\{Attribs?\|t=\n \|Blason_Vide_3D\.svg\}\}/m, '{{Attrib|t=c|Blason Vide 3D.svg}}') //ed_wdh aroche
.replace(/\{\{Attribs?\|t=\n \|(.*?) map([^\|]*?)/g, '{{Attribs|t=m\n |$1 map$2') // it's a map
.replace(/\{\{Attribs?\|t=m\n \|(.*?)world([^\|]*?)/g, '{{Attribs|t=wm\n |$1 location $2') // wm/ggg map
.replace(/\{\{Attribs?\|t=m\n \|(.*?) location ([^\|]*?)/g, '{{Attribs|t=lm\n |$1 location $2') // locator map
.replace(/\{\{Attribs\|t=(c|lm|wm|m)?\n \|([^\n\}]*?)\}\} *\n/m, '{{Attrib|t=$1|$2}}\n') //ed_wdh re_singularize
.replace(/\{\{Attrib(s)?\|t= *([\n\|])/m, function (m, tm, lf) {
let topic = '';
if (!tm) tm = ''; // undefined ?
if (coa || /PD-Coa|coats? of arms|[Ee]scu|:CoA/i.test(txT))
topic = 'c';
else
if (/[Mm]aps/.test(txT) && /green and grey/i.test(txT))
topic = 'ggg';
else
if (/[Mm]aps/.test(txT) && /[Ww]orld/.test(txT))
topic = 'wm';
else
if (/[Mm]aps/.test(txT) && /[Ff]lag/.test(txT))
topic = 'fm';
else
if (/[: -_]icon/i.test(txT) && /[Ff]lag/.test(txT))
topic = 'fi';
else
if (/[Mm]aps/.test(txT))
topic = 'm';
// else
// if (/[Ff]ootball/.test(txT) && /line-up/.test(txT))
// topic = 'm';
else
if (/PD-Flag-|flag/.test(txT))
topic = 'f';
return '{{Attrib' + tm + '|t=' + topic + lf; //ed_wdh: topic
})
// *** template:Legend
.replace(/\{\{ *[Ll]egend(-small|-line| inline|2)? *\| *([^\|]*) *\| *([^\}]*)/g, function (m, typ, col, txt)
{ if (!typ) typ = "";
if (!col) col = ""; // otherwise (when col="") flagged
if (!txt) txt = "";
if (col.substring(0,2) === "1=") col = col.substring(2);
if (txt.substring(0,2) === "2=")
{ txt = txt.substring(2);
for (let i = 0; i < txt.length; i++)
{ if ( txt.substring(i, i+1) === "=")
txt = txt.substring(0, i) + "=" + txt.substring(i+1); // replace equal sign
if ( txt.substring(i, i+2) === ">=")
txt = txt.substring(0, i) + "≥" + txt.substring(i+2); // replace
if ( txt.substring(i, i+2) === "<=")
txt = txt.substring(0, i) + "≤" + txt.substring(i+2); // replace
}
}
return "{{Legend" + typ + "|" + col + "|" + txt; // txt without "="
})
.replace(/\s*\{\{[Ll]egend\|\|line=/g, '{{Legend-linew|') //ed_wdh
// dw .replace(/(\s*\{\{[Ll]egend(?:[^\|]*?)\|(?:[^\|]*?)\| *2 *= *[^=]*)=((?:.*?)\}\}(?:[\s ]*)\{\{[Ll]egend)/g, '$1🏮=🏮$2') //ed_wdh
// .replace(/(\s*\{\{[Ll]egend(?:[^\|]*?)\|)(?: *1 *= *)?([^\|]*\|?)(?: *2 *= *)?/g, '$1$2') //ed_wdh rem. pos. (??=both)
.replace(/(\s*\{\{[Ll]egend *\|(?:.*?)\}\}(?:[\s ]*))\{\{[Ll]egend([\s ]*)\|/gm, '$1✋{{Legend|$2') //ed_wdh
.replace(/(\s*\{\{[Ll]egend *\|(?:.*?)\}\}(?:[\s ]*))\{\{[Ll]egend([\s ]*)\|/gm, '$1✋{{Legend|$2') //ed_wdh
.replace(/(?:\}\}([\s ]*)✋\{\{[Ll]egend)/gm, '$1') //ed_wdh: remove all but 1st
.replace(/(\s*\{\{[Ll])(?:egend)( *\|)/g, '$1egtab$2') //ed_wdh (+ singles)
.replace(/(\s*\{\{[Ll])(?:egtab)\|([^\n\}]*?)\}\} *\n/m, '$1egend|$2}}\n') //ed_wdh re_singularize
.replace(/(\s*\{\{[Ll]egend-small *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend-small([\s ]*)\|/g, '$1☕$2{{Legend-small|$3') //ed_test
.replace(/(\s*\{\{[Ll]egend-small *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend-small([\s ]*)\|/g, '$1☕$2{{Legend-small|$3') //ed_ repeat
.replace(/(?:\}\}☕([\s ]*)\{\{Legend-small\|)/gm, '$1|') //ed_wdh
.replace(/(\s*\{\{[Ll])(?:egend-small *\|)/g, '$1egtab||M|') //ed_wdh (+ singles)
.replace(/(\s*\{\{[Ll]egend-line *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend-line([\s ]*)\|/g, '$1♓$2{{Legend-line|$3') //ed_test
.replace(/(\s*\{\{[Ll]egend-line *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend-line([\s ]*)\|/g, '$1♓$2{{Legend-line|$3') //ed_ repeat
.replace(/(?:\}\}♓([\s ]*)\{\{Legend-line\|)/gm, '$1|') //ed_wdh
.replace(/(\s*\{\{[Ll])(?:egend-line *\|)/g, '$1eglin|') //ed_wdh (+ singles)
.replace(/(\s*\{\{[Ll]egend-linew *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend-linew([\s ]*)\|/g, '$1♓$2{{Legend-linew|$3') //ed_test
.replace(/(\s*\{\{[Ll]egend-linew *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend-linew([\s ]*)\|/g, '$1♓$2{{Legend-linew|$3') //ed_ repeat
.replace(/(?:\}\}♓([\s ]*)\{\{Legend-linew\|)/gm, '$1|') //ed_wdh
.replace(/(\s*\{\{[Ll])(?:egend-linew *\|)/g, '$1eglin|w=33px|') //ed_wdh (+ singles)
.replace(/(\s*\{\{[Ll]egend inline *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend inline([\s ]*)\|/g, '$1⌛$2{{Legend inline|$3') //ed_test
.replace(/(\s*\{\{[Ll]egend inline *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend inline([\s ]*)\|/g, '$1⌛$2{{Legend inline|$3') //ed_test
.replace(/(?:\}\}⌛([\s ]*)\{\{Legend inline\|)/gm, '$1|') //ed_wdh
.replace(/(\s*\{\{[Ll])(?:egend inline *\|)/g, '$1eglin|t=Legend inline|') //ed_wdh (+ singles)
.replace(/(\s*\{\{[Ll]egend2 *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend2([\s ]*)\|/g, '$1⛺$2{{Legend2|$3') //ed_test
.replace(/(\s*\{\{[Ll]egend2 *\|(?:.*?)\}\})([\s ]*)\{\{[Ll]egend2([\s ]*)\|/g, '$1⛺$2{{Legend2|$3') //ed_test
.replace(/(?:\}\}⛺([\s ]*)\{\{Legend2\|)/gm, '$1|') //ed_wdh
.replace(/(\s*\{\{[Ll])(?:egend2 *\|)/g, '$1eglin|t=Legend2|') //ed_wdh (+ singles)
// *** Set 6-byte-Colorcode to uppercase; when possible, shorten 'rrggbb' to 'rgb'
.replace(/(#[\dA-Fa-f]{6})/g, function (m, c)
{ let rgb = c.toUpperCase(); // if (expeUser &&
if (rgb.substring(1,2) === rgb.substring(2,3) // rr
&& rgb.substring(3,4) === rgb.substring(4,5) // gg
&& rgb.substring(5,6) === rgb.substring(6,7) ) // bb
return rgb.substring(0,2) + rgb.substring(3,4) + rgb.substring(5,6);
else
return rgb; // uppercase only
})
.replace(/([^{])[Dd]erivative[ _]versions?[ _]?(?!of):?([^s}])/, '$1{{Derivative versions}}$2') // TODO: parameter as filenames
.replace(/([^{])[Dd]erivative[ _]work(?![ _]of)(:?)([^s}])/, '$1{{Derivative}}$2$3') // TEST
.replace(/[Ss]ource( +)?=( +)?\{\{\w\w\|(?:1=)?([^|\]]+)([| ])(?:Vorlage|Template)(\]\]?)?\s*\}\}/, 'source$1=$2$3$4{{Template-ns}}$5')
// *** gallery treating
.replace (/(?:\n?)<[Gg]allery>([\w\s]+?)<\/[Gg]allery>/gm, '{{G|$1}}☕') // ed_wdh
// .replace (/<[Gg]allery>([\n\s\w]+?)<\/[Gg]allery>/gm, '{{H|$1}}') // ed_wdh dmy template
// .replace (/<[Gg]allery>(?:[^\n]+?)(\n.+)<\/[Gg]allery>/gm, '{{J|$1}}') // ed_wdh
// .replace (/<[Gg]allery>(.*?)<\/[Gg]allery>/gm, '{{X|$1}}') // ed_wdh
// .replace (/<[Gg]allery>([\n.]+?)<\/[Gg]allery>/gm, '{{Y|$1}}⌛') // ed_wdh
.replace(/(?:\n?)<[Gg]allery>\s*(?:[Ff]ile\:|[Ii]mage\:)?([^\n|]+)(\|?[^\n]+)?\s*<\/[Gg]allery>(?:\n?)/g, '{{G|\n$1$2}}\n') // ed_wdh test
.replace(/\{\{G\|\n([^\n\}]+?)\}\}/gm, '{{G|$1}}') // ed_wdh: single item gallery only one line
.replace (/<[Gg]allery>([^<]*?)\n?<\/[Gg]allery>/gm, '{{G|$1}}') // ed_wdh: multiple lines
// *** General very specific cleanup (old usernames) */
.replace( /[Mm]axxl2/g, 'MaxxL' )
// .replace ( /\[\[[Uu]ser:(.*?)(\|[^\]|[]+)?\]\]/g, '{{U|$1}}') // ed_wdh test ????
// *** Try to sort the parameters: date - source - author
// dsa✓ das sda sad ads asd
// as dsa✓ sad
// ad sda das sda
// as dsa✓
// sd dsa✓ dsa✓ dsa✓
.replace (/( *\| *[Aa]uthor(?:.*))\n( *\| *[Ss]ource(?:.*))\n/, '$2\n$1\n' ) // ed_wdh sort: as
.replace (/( *\| *[Aa]uthor(?:.*))\n( *\| *[Dd]ate(?:.*))\n/, '$2\n$1\n' ) // ed_wdh sort: ad
.replace (/( *\| *[Ss]ource(?:.*))\n( *\| *[Dd]ate(?:.*))\n/, '$2\n$1\n' ) // ed_wdh sort: sd
.replace (/\{\{self-photographed\}\}/, '{{Own}}') // Aliman
.replace (/\(\[\[Switzerland\]\]\)/, '({{W|Switzerland}})') // Aliman
.replace(/\|s\=-COAInformation/, '|s=c') // ed_wdh ???
.replace(/https:\/\/armorialdefrance\.fr\/page_blason\.php\?ville=(\d+)/, '{{Page blason|$1}}') // ed_wdh
.replace(/https?:\/\/www\.newgaso\.fr\/lecture[ _]fiche[ _]commune\.php3\?page=(f\d+)/, '{{Fiche commune|$1}}') // ed_wdh
.replace(/^ *\|\s*[Pp]ermission\s*= *(?:\[\])? *\n( *[\|\}])/m, '$1') // ed_wdh remove empty permission param up
.replace(/^ *\|\s*[Pp]ermission\s*= *[Pp]ublic domain *\n( *[\|\}])/m, '$1') // ed_wdh remove obsolete permission
.replace(/^ *\|\s*[Pp]ermission\s*= *(?:[Oo]wn work,?)? *(?:all rights released)? *(?:\(?Public domain\)?)? *\n( *[\|\}])/, '$1') // ed_wdh rem
// *** AutVec([[Switzerland]])
.replace(/Original:? ([^\n|<]+)(?:<br ?\/?>)?\s*(?:SVG:? )(\[\[[\w:]*User:[^\n|[\]]+(?:\|[^\n|[\]]+)?\]\])/i, '{{AutVec|o=$1|v=$2}}')
.replace(/=\s*{{AutVec ?\|\s*(?:o=)?(?:(?:{{Uc?\|[^}]+)(?:\}\})|[^}|]*)?\|(?:v=)?(?:(?:{{Uc?\|[^}]+)(?:\}\})|[^}|]*)?\|([^\]|[\n]+)(?:\}\}|\|)/g, fileTruncate);
}
// COAInformation has special parameter ¿imgen/image? so warn if present
if (/=\s*\{\{[Ii](m?gen|mage[ _]generation)/.test(txT) || imgen) {
cSVG.warnMsg({
title: 'Already present, ' + (err ? 'There are ' + err + ' error' : 'but file is valid') + '!',
type: 'warn'
});
if (/s\=sf|s\=eq/.test(txT)) {
LeyoChem = 1; // use FGD 773
}
}
/* SVG Template and cosmetic replace (continued line 950 ff) */
txt = txt /* Other SVG related templates (for T), currently only working for sure if they are on a single line */
.replace(/\s?(\{\{\s?(\w+werkstatt[^\|\n\}]*|[Gg]raphic[ _][Ll]ab[^\|\n\}]*|[Ww]PGW[ _]vector[ _]im[^\|\n\}]+|[Tt]HV[^\|\n\}]*|[Aa]telier[ _]graphique[^\|\n\}]*|[Ll]aboratorio[ _]grafico\|?[^\|\n\}]*|[Pp]rojet[ _]Blasons)\}\})\s?/g, function (m, p) {
T += p;
return '';
})
.replace(/(\{\{(TracedSVG|Autotraced|Bad[ _]trace|PoorSVG)\}\})\s?/i, function (m, p) {
p5 = '|§';
return '';
}) // PoorSVG
.replace(/\{\{\s?Bad[ _]?SVG\s?\}\}\s?/i, function (/* m, p*/) {
p5 = '|!';
return '';
}) // BadSVG
.replace(/\{\{\s?[Ee]asy[ _-]border(?:\s?\|\s?([^\n]+))?\s?\}\}\s?/, function (m, p) {
p5 += '|°';
s = p || s;
return '';
}) // Easy-border
.replace(/(\{\{([Tt]ranslat(?:e|able|ion possible)|[Ee]asy translation)[^\\n}]*}})\s?/, function () {
p5 += '|%';
return '';
})
.replace(/\{\{\s?([Ss]uper[cs]eded(?:-Image)|(?:[Rr]aster|PNG|Bitmap)(?:[ _]version)?(?:[ _]available)|[Oo]bsolete)(?:\s?\|\s?([^\n]+))?\s?\}\}\s?/, function (m, p, p2) {
p5 += '|\\' + (p2 ? '=' + p2 : '');
return '';
}) // Superseded
// .replace(/\{\{\s?([Ss]uper[cs]edes)(?:\s?\|\s?([^\n]+))?\s?\}\}\s?/, function (m, p, p2) {
.replace(/\{\{\s?([Ss]uper[cs]edes)(?:\s?\|\s?(?:1=)?([^\n]+))?\s?\}\}\s?/, function (m, p, p2) {
p5 += '|\\+=' + p2;
return '';
}) // Supersedes
.replace(/\{\{\s?([Cc]ommonist)(?: no icon)?(?:\s?\|\s?([^\n]+))?\s?\}\}\s?/, function () {
p5 += '|$';
return '';
}) // Commonist (works not properly}
.replace(/(?:\{\{(?:[Rr]etouched[ _]?(?:[Pp]icture|[Ii]mage)?|[Rr]estored|[Mm]odified)([^}\n]+\}\}))/, function (m, p) {
T += '{{retouched' + p; // 1st create "T= ", later make it with "|r="; variable 'p' contains all the parameters
return '';
})
.replace(/\{\{\s?(in)?valid[ _]?(SVG)?[^}]*\}\}\s?/ig, '') // remove SVG validity templates
.replace(/\[\[\Category:ChemSketch\]\]\s?/ig, '') // ed_wdh
.replace(/\[\[\Category:Created with Inkscape\]\]\s?/ig, '') // ed_wdh 2nd
.replace(/^ *\|\s*[Pp]ermission\s*= *\n( *[\|\}])/m, '$1') // ed_wdh remove empty permission param
.replace(/^ *\|\s*[Oo]ther[ _]versions\s*= *\n*( *[\|\}])/m, '$1') // ed_wdh remove empty other_versions param
.replace(/^\s*\}\}\s*$/gm, '}}\n'); // trim on every separate temp end
/* Search SVG templates for tool-name and remove them */
if (size) {
txt = txt.replace(/\{\{\s?[Ss]implSVG\|([^{}|]+)\|[^}]+\}\}\s*/ig, function (m, p) {
toolName = p;
return '\n';
});
}
txt = txt.replace(/\{\{(Inkscape(-hand)?|Adobe([ _]Illustrator|-hand)?|Illustrator|Gnuplot|CorelDraw)\|?[^{}]*\}\}\s?/i,
function (m, p, p2) {
if (p2)
toolName = /[Aa]dobe-hand$/m.test(p2) ? 'AH' : 'H';
else
toolName = p;
replaced = 1;
if (/code ?=/.test(m))
T += m;
else if (p === 'Inkscape' && /IMPORTANT=yes/.test(m))
toolName = 'Im';
return '\n';
} // replace success
);
if (!replaced) { // search Created with ... templates
txt = txt.replace(/\{\{[Cc]reated with ([^{}|]+)\|?([^{}]*)\}\}\s?/, function (m, p, p2) {
toolName = p;
replaced = 1;
if (/code/.test(p2))
T += m;
return '\n';
} // replace success
);
if (!replaced) { // TODO: search redirects to Created with ... templates
txt = txt.replace(/\{\{(QGIS|[Ll]ibreOffice|[Oo]penOffice(?:\.org)?|MATLAB|[Gg]numeric|[Mm]athematica)\|?[^{}]*\}\}\s*/,
function (m, p) {
toolName = p || toolName;
replaced = 1;
return '\n';
});
if (!replaced) { // replace previous igen
if (/s\=sf|s\=eq/.test(txT)) {
LeyoChem = 1; // use FGD
}
// FIXME: don't replace fully
txt = txt.replace(/(\s)?\{\{[Ii](gen|mage[ _]generation)\|([\w ]*)?\|?[^{}]*\}\}\1?/,
function (m, s, i, p) {
if (i.length > 4)
IgenName = IgenNameLong;
toolName = p || toolName;
replaced = 1;
return /code ?=/.test(m) ? m : '\n';
} // replace success
);
if (!replaced) { // replace completely previous FGD (834) ed_wdh
if (/structural formula|chemical equation/.test(txT)) {
LeyoChem = 1; // use FGD
}
txt = txt.replace(/\{\{File generation description((?:[^\}]{2})+\}\}\n)/m, '');
}
}
}
}
toolName = toolname || toolName; // "toolname" from SVG code has priority over "toolName" from file desc
// (this inhibits tool specification if is later e.g. inkscaped)
/* Exclude nowiki text with split */
let nowiki = txt.split('<nowiki>'), // TODO: Works only on non nested (may be sufficient)
wikiTxt = [nowiki.shift()];
if (nowiki.length) {
for (let n = 0; n < nowiki.length; n++) {
let nClose = nowiki[n].split('<\/nowiki>');
if (nClose.length > 1) {
nowiki[n] = '<nowiki>' + nClose.shift() + '<\/nowiki>';
wikiTxt.push(nClose.join());
} else {
wikiTxt[n - 1] += nowiki.splice(n, 1);
}
// console.log(n, nowiki[n])
}
}
txt = ''; // clear
for (let wt in wikiTxt)
txt += generalCleanup(wikiTxt[wt]) + (nowiki[wt] || '');
txT += c.wgTitle;
/* Search for sub suffix parameter */
if (/text[: -_]?logo/i.test(txT)) {
this.textTrans = 0; // Logos don't get translated
s = 'tl'; // :textlogo
} else if (/Logos? of |:Logos?/i.test(txT)) {
s = 'l'; // :Logos
} else if (/[Mm]aps/.test(txT) && /green and grey/i.test(txT)) {
s = 'ggg'; // :green and gray world maps
} else if (/[Mm]aps/.test(txT) && /[Ww]orld/.test(txT)) {
s = 'wm'; // :World maps
} else if (/[Mm]aps/.test(txT) && /[Ff]lag/.test(txT)) {
s = 'fm'; // :flag maps
} else if (/[Mm]aps/.test(txT)) {
s = 'm'; // :Maps
} else if (/[: -_]icon/i.test(txT) && /[Ff]lag/.test(txT)) {
s = 'fi'; // :flag icons
} else if (/[: -_]icon/i.test(txT)) {
s = 'i'; // :Icons
} else if (coa) {
s = 'c'; // :CoA
} else if (/PD-Coa|coats? of arms|escu|:CoA|heraldic/i.test(txT)) {
s = 'c'; // :CoA / ecclesiastical heraldry
} else if (/[Ii]nsignia|[Ii]dentification badge|[Ee]mblem/.test(txT)) {
s = 'em'; // :Emblems
} else if (/[Pp][Dd]-chem|ChemDraw|BKchem|Chemtool|ChemSketch|GChemPaint|N2S|[Cc]hemical structure/.test(txT)) {
LeyoChem = 1; // use FGD
s = 'sf'; // :Structural formulas
// IgenName = IgenNameLong; // for Leyo
} else if (/[Rr]ibbon bar|Order /.test(txT)) {
s = 'o'; // :Orders
} else if (/ signs\]/.test(txT)) {
s = 'v'; // :Signs {when category}
} else if (/PD-Unicode|[Uu]nicode|alphabet|letter/.test(txT)) {
s = 'u'; // :Unicode
} else if (/[Ss]ymbol/.test(txT)) {
s = 'y'; // :Symbols
} else if (/[Ss]eal/.test(txT)) {
s = 's'; // :seal
} else if (/[Mm]athematic|[Aa]lgoritmo|[Tt]rigonometry|[Gg]eometry|[Ii]sometric/.test(txT)) {
s = 't'; // :Trigonometry
} else if (/Diagram/i.test(txT) && toolName !== 'Wpdc') { // ed_wdh
s = 'd'; // :Diagrams
} else if (/PD-Flag-|flag/.test(txT)) {
s = 'f'; // :Flags
} else if (/[Ff]ootball/.test(txT) && /line-up/.test(txT)) {
s = 'm|sd=/line-up'; // :line ups
} else if (/[Ff]ootball/.test(txT)) {
s = 'fk'; // :Football kits
} else if (LeyoChem) {
s = 'sf'; // :Structural formulas
} else if (/[Aa]utograph/.test(txT)) {
s = 'sig'; // :Signatures
} else if (/[Ss]ignature/.test(txT) && !/[Ss]ignature-talk/.test(txT)) {
s = 'sig'; // :Signatures // 'sig' comes too often
}
// topic with UserID (only special users) // ed_wdh if
if (s === 'm' && /globe/.test(txT) && /Hagar66/.test(txT) && toolName === 'Adobe')
s = 'wm|U=Hagar66'; // Hagars world maps (precedence over TUBS)
if (s === 'm' && /globe/.test(txT) && /NordNordWest/.test(txT))
s = 'wm|u=NordNordWest'; // NordNordWest world maps (precedence over TUBS, but not over Hagar)
if (s === 'm' && /globe/.test(txT) && /TUBS/.test(txT))
s = 'wm|u=TUBS'; // TUBS world maps
// if (s === 'm' && /globe/.test(txT))
// s = 'wm'; // world maps
if (/Hagar66/.test(txT) && /[Ll]ocator|[Ll]ocation /.test(txT) && s === 'm' && toolName === 'Adobe')
s = 'lm|U=Hagar66'; // Hagars location maps (precedence over TUBS)
if (/NordNordWest/.test(txT) && /[Ll]ocator|[Ll]ocation /.test(txT) && s === 'm')
s = 'lm|u=NordNordWest'; // NordNordWest location maps (precedence over TUBS, but not over Hagar)
if (/TUBS/.test(txT) && /[Ll]ocator|[Ll]ocation /.test(txT) && s === 'm')
s = 'lm|u=TUBS'; // TUBS location maps
if (/Hagar66/.test(txT) && s === 'm' && toolName === 'Adobe')
s = 'm|U=Hagar66'; // Hagars maps (precedence over TUBS)
if (/NordNordWest/.test(txT) && s === 'm') // (/NordNordWest/.test(txT) && s === 'm')
s = 'm|u=NordNordWest'; // NordNordWest maps (precedence over TUBS)
if (/TUBS/.test(txT) && s === 'm') // (/TUBS/.test(txT) && s === 'm' && toolName === 'Adobe')
s = 'm|u=TUBS'; // TUBS maps
// if (/Hagar66/.test(txT) && (s === 'm' || s === 'm|u=TUBS'))
// s = 'm|U=Hagar66'; // Hagars maps (replacing TUBS)
if (/Locator|Location maps/i.test(txT) && s === 'm')
s = 'lm'; // location maps
if (/Petrus3743/.test(txT) && s === 't') // && toolName === 'GeoGebra'
s = 't|u=Petrus3743|<v'; // Petrus_trigonometry ✔
if (/\[\[User\:Cdang\|Cdang\]\]/i.test(txT) || /\{\{U\|Cdang\}\}/i.test(txT)) // Cdang ?
s += '|u=cdang'; // cdang ✔
// default: "Unknown tool" (but can also be Text Editor)
toolName = _ucfirst(toolName) || ((this.curSize && this.curSize > 50 && this.curSize < 2000) ? 'T' : 'U');
toolName = toolNames[toolName] ? toolNames[toolName] : toolName;
if (expeUser)
toolName = toolAbbr[toolName] ? toolAbbr[toolName] : toolName;
// Graphic Lab replace: Map Lab 🐞🐞🐞🐞🐞🐞 this buggy procedure is disabled 🐞🐞🐞🐞🐞🐞
if (T) {
T = T.replace(/\{\{Grafikwerkstatt🐜\}\}/, function (/* m*/) {
// ed_ g = 'de';
gd;
return '';
});
if (T && !g) {
T = T.replace(/\{\{[Aa]telier🐜[ _]graphique([ _]carte)?\}\}/, function (m, p) {
// ed_ g = 'fr';
gf;
s = (p && !s) ? 'm' : s;
return '';
});
}
if (T && !g) {
T = T.replace(/\{\{[Ll]aboratorio🐜[ _]grafico([ _]mappa)?\}\}/, function (m, p) {
// ed_ g = 'it';
gi;
s = (p && !s) ? 'm' : s;
return '';
});
}
if (T && !g) {
T = T.replace(/\{\{\s*[Gg]raphic[ _][Ll]ab\s*\|\s*([\w-]+)\|?(map|[^{}]*)?\}\}/, function (m, p1, p) {
// ed_ g = p1;
gP;
s = (p && !s) ? 'm' : s;
return '';
});
}
if (T && !g) {
T = T.replace(/\{\{WPGW🐜 vector image\}\}/, function (m, p1, p) {
gP;
s = (p && !s) ? 'm' : s;
return '';
});
}
g = g ? '|g=' + g : '';
// put $1 (modifications) into '|r', $2 contains all the other parameters
if (/\{\{retouched\|([^|}\n]*)\|?([^}\n]+)\}\}/.test(T)) { // TODO: filename can't contain "}"
r = '|r=' + (RegExp.$1 || '-') + '|' + (RegExp.$2 || '');
T = T.replace(RegExp.lastMatch, ''); // FIXME: non standard
}
T = (T.length > 4) ? '|T=' + T : '';
}
// Cleanup remnants
txt = txt.replace(/\{\{\s?[Ii]n(formation[ _]field|Fi)\|[^{}\n|]+\|\s?value\s?=(\s*\}\})?\s*/g, ''); // empty field
if (s === 'm')
txt = txt.replace('<!--PLEASE CHECK, not generally for all SVG maps-->', '');
/** *
* Get lastIndex, from now, NO text manipulation anymore, or var topp must be fixed
***/
if (!ofRE.test(txt)) {
let i = inRE.length;
while (i--) { // iter over possible positions
if ((topp = new RegExp(inRE[i], 'g')).test(txt)) {
topp = _findPosition(topp);
// console.log(" topp '%i', i '%i'", topp, i); //---test
i = 0;
break;
} else
topp = 0;
}
} else {
topp = ofRE.lastIndex;
txt = txt.replace(ofRE, '');
topp -= RegExp.lastMatch.length;
ls = RegExp.$3;
}
s1 = s1 || RegExp.$1;
s2 = s2 || RegExp.$2;
if (!coa && /[Ii]mgen\|/.test(ls)) { // CoA but without COAInformation
IgenName = '|image' + s2 + '=' + s2;
tempPre = '';
} else if (!topp && /\}\}/g.test(txt)) {
topp = txt.lastIndexOf(tempPre) + 3; // put on last postion of a template
} else {
IgenName = '|other fields' + s2 + '=' + s2 + IgenName;
}
// console.log(" ofRE s1 '%s', s2 '%s', ls '%s'", s1, s2, ls, topp); //---test
if (typeof err === 'number') {
if (!topp) {
this.setIgen(IgenName += (toolName || '×?×') + (err ? '|' + err.toString() : '') + '|+|s=' + s, tempPre);
return '';
}
} else if (typeof err === 'undefined') {
return txt; // don't insert igen
}
// Parameter 5
if (this.badSVG) {
if (!/^\|!/.test(p5))
p5 += '|!';
if (this.badSVG > 1)
p5 += '=f'; // Fake SVG
else if (!expeUser && s !== 'm')
p5 += '<!--PLEASE CHECK, not generally for all graphic types-->'; // Maybe
}
if (this.curSize > 3407872) // 3407872 = 3.4M; 4194304 = 4M
p5 += '|>'; // Large SVG 4 MB? 3.4 MB?
if (this.textPath)
p5 += '|<'; // "less" sign to insert the {Path text SVG} tag.
if (this.PGF)
p5 += '|~'; // "squiggle" sign for PGF CDATA
else if (this.switchTrans)
p5 = p5.replace(/\|%/, '') + '|%s';
else if (this.textTrans && !/\|%/.test(p5) && toolName !== 'Wpdc') // ed_wdh
p5 += '|%';
T = p5 + r + T;
if (topp) {
err = Number(err);
if (size) {
IgenName += toolName + '|' + size + '|9=+|10=S|user=' + c.wgUserName + ((s === '-COAInformation') ? '|sub=' : '|4=') + s + T;
} else {
if (s === '-COAInformation' && $.inArray(toolName, ['I', 'Inkscape', '']) !== -1) {
let coaUsers;
// ls = ls.replace( /\{\{[Ii]mgen\|([\w\d ]+)\}\} *\n/, function(m, p){ user = p; return "";} );
if (!user) {
coaUsers = [// [[Template: Igen/coa]]
['{{Projet Blasons}}', 'f'], // must be first // ed_wdh
['Aroche', 'Ar'], // ed_wdh
['Chatsam', 'Ch'], // ed_wdh
['Chris die Seele', 'CS'], ['Gliwi', 'Gl'],
['Dan Koehl', 'DK'], // ed_wdh
['Erlenmeyer', 'Er'], // ed_wdh
['Doc Taxon', 'DTx'], // ed_wdh
['Ipankonin', 'Ip'], // ed_wdh
['Jimmy44', 'JN'],
['Jpgibert', 'JPG'], // ed_wdh
['Jürgen Krause', 'JK'],
// ['Kaboldy', 'Ka'] // ed_wdh
['Lanaud', 'Tl'], // ed_wdh
// ['Macucal', 'Ma'] // ed_wdh
['Madboy74', 'Mb'],
['MaxxL', 'ML'],
['Milenioscuro', 'Mi'], // ed_wdh
['Odejea', 'Od'], // ed_wdh
['Ruthven', 'Ru'], // ed_wdh
['SajoR', 'Sa'], // ed_wdh (Alejandro Rojas)
['Simon.eller', 'SE'], // ed_wdh
['Spax89', 'S0'],
['Spedona', 'Sp'], // ed_wdh
['SteveK', 'SK'],
['Syriatsu', 'Sy'], // ed_wdh
['Thom.Lanaud', 'TL'], // ed_wdh
['The Eloquent Peasant', 'PE'], //ed_wdh
['Zardoz91', 'Za'] // ed_wdh
];
let l = coaUsers.length;
while (l--) {
if (txt.indexOf(coaUsers[l][0]) !== -1) {
user = coaUsers[l][1];
coaUsers = coaUsers[l][0];
break;
}
}
}
if (user) {
if (err) {
IgenName += 'I|' + err + '|s=:CoA by ' + coaUsers + T;
} else {
IgenName = '|image' + s2 + '=' + s2 + user; // ed_wdh
tempPre = '\n';
}
if (user !== 'f') { // ed_wdh
// Remove redundant cats (when Igen/coa writes them)
coaUsers = {
Ch: 'Blason chatsam', // ed_wdh
DK: 'Coats of arms by Dan Koehl', // ed_wdh
Er: 'Contribuciones de Erlenmeyer', // ed_wdh
Ip: 'Images by Ipankonin', // ed_wdh
Gl: 'Files by User:Gliwi',
JN: 'Files by User:Jimmy from fr.wikipedia',
Mi: 'Coats of arms by User:Milenioscuro', // ed_wdh
ML: 'COAs by User:MaxxL',
Mb: 'Pictures by Madboy74 - 0',
Za: 'SVG coats of arms of France', // ed_wdh
Od: 'Files by Odejea/SVG coat of arms', // ed_wdh
// Ka: 'Files by User:Kaboldy',
Sy: 'Blason par Syryatsu', // ed_wdh
S0: '{{Projet Blasons}}' // "Blason spax89" don't want
// "SK": "COA by SteveK" don't want
}
[user];
if (coaUsers && ['S0', 'SK'].indexOf(user) === -1) { // Spax, Steve do not want
coaUsers = '[[Category:' + coaUsers + ']]\n';
}
}
if (coaUsers) {
if (txt.lastIndexOf(coaUsers) < topp)
topp -= coaUsers.length;
txt = txt.replace(coaUsers, '');
}
// replace only TODO: may skip this complete or check the replacing para
if (imgen) {
// topp -= txt.length;
// TODO: exclude unsure users (with multiple shorthands)
if (['ML', 'JN', 'S0', 'SK'].indexOf(user) === -1)
txt = txt.replace(imgenRE, template + '\n');
// topp += txt.length;
IgenName = '';
tempPre = '';
s1 = '';
}
// ls = ""; // delete other fields?
} else if (!imgen) { // Default
IgenName = '|image' + s2 + '=' + s2 + err; // ed_wdh
tempPre = '\n';
}
} else {
IgenName += toolName + (err ? '|' + err : '') + '|+' + g + T + '|s=' + s;
}
}
txt = txt.substr(0, topp) + s1 + IgenName + tempPre + ls + txt.substr(topp);
return txt;
}
mw.log.warn('Igen not inserted ');
return {
type: 'warn'
};
},
addToFileDesc: function ($textarea, e, warn, toolName) {
// WikiEditor
$textarea = $textarea.$textarea || $textarea;
return mw.loader.using('oojs-ui-core', function () {
let txt = $textarea.val();
if (typeof e === 'string') {
e = Number(e);
if (e)
cSVG.warnMsg(e);
if (warn)
cSVG.warnMsg(warn);
}
$.removeSpinner('w3nu');
txt = cSVG.replaceTag(txt, e, toolName);
if (txt) {
if (txt instanceof Object)
return cSVG.warnMsg(txt);
else
$textarea.val(txt);
}
// mw.notify("Igen inserted ", { title: "Done!" });
$('#wpSummary').val(function (i, v) {
return (v.replace(summary, '') + ' ' + summary).trim();
});
$('#wpMinoredit').prop('checked', 1);
// if (typeof e === 'string')
mw.hook('gadget.cleanup.done').add(function () {
mw.loader.using(['mediawiki.action.edit.preview', 'mediawiki.diff.styles']).always(
function () {
$('#wpDiff').trigger('click');
});
});
// TODO: may only manual or cleanup same time?
mw.hook('gadget.cleanup.run').fire({ text: 0 });
return false;
});
},
addIgenURL: function (err, size, toolName, para) {
let param = '';
if (typeof err === 'number')
console.log('Successfully checked for SVG errors: ', err);
// else err = 0;
size = ($.isArray(size)) ? '&SVGsize=' + size[0] + '|' + size[1] + '&username=' + encodeURIComponent(c.wgUserName) : '';
toolName = toolName ? '&toolname=' + encodeURI(toolName) : '';
if (para instanceof Object) {
$.each(para, function (i, o) {
param += '&' + i + '=' + Number(o);
});
}
location.href = mw.config.get('wgScript') + '?title=' + encodeURIComponent(c.wgPageName) + '&action=edit&' + cSVG.name + '=' + err + size + toolName + param;
},
/**
* Get the text of a template
* @param {string} fullStr
* @param {number} start
* @return {string} endPart
*/
getTempBlock: function (fullStr, start) {
start = start || 0;
let pos = 0,
endPos = 0,
RE = /\}\}/g,
endPart = fullStr.slice(start + 2);
while (RE.test(endPart)) {
endPos = RE.lastIndex;
// console.log(endPos, endPart.slice(pos, endPos - 2));
if (!/\{\{/.test(endPart.slice(pos, endPos - 2)))
break;
pos = endPos;
}
endPart = endPos ? fullStr.slice(start, start + endPos) : '';
return endPart;
},
insertIgenSub: function () {
let txt = $textarea.val(),
$this = $(this),
sub = $this.data('key'),
igenRE = /\s*\{\{[Ii](m?gen|mage[ _]generation)/g, // =?
t1 = 0, // first
t2 = 0; // last
if (igenRE.test(txt)) {
t1 = igenRE.lastIndex;
} else {
cSVG.warnMsg({
title: 'Igen not found!',
type: 'warn'
});
return;
}
igenRE = /\|\s*[Ss](ub|[c: -m])?= ?([^\n|}]*)/g;
t2 = txt.substr(t1);
if (igenRE.test(t2)) {
t2 = t1 += igenRE.lastIndex;
t1 -= RegExp.lastMatch.length;
} else {
t2 = cSVG.getTempBlock(t2);
// console.log('getTempBlock', t2);
igenRE = /([^\n|}]+)/g;
if (igenRE.test(t2)) {
let lastIndex = igenRE.lastIndex;
igenRE.lastIndex = 0;
while (igenRE.test(t2))
lastIndex = igenRE.lastIndex;
// console.log('para', RegExp.lastMatch);
t2 = t1 += lastIndex;
} else {
t1 = 0;
}
}
cSVG.XHR.abort(); // current ajax
$this.off('mouseover');
if (t1) {
txt = txt.substr(0, t1) + '|s=' + sub + txt.substr(t2);
$textarea.val(txt);
} else { // Should never happen?
cSVG.warnMsg({
title: 'Igen not valid!?',
type: 'error'
});
}
},
// Template:AutVec
insertAutVec: function ($textarea) {
let autRE = /^( *\|\s*[Aa](?:uthor|rtist)\s*=\s*)\*? ?(?:{{[Uu]nknown\|?(?:artist|author)?}}\s*)?(?:\*? ?vectorized by \s*)?({{[Uu]\|([^|\n]+)}}|[^\n]+) *$/m,
txt,
lm,
pr,
p1,
p2,
pre = '{{AutVec|',
post = '}}';
$textarea = $textarea.$textarea;
txt = $textarea.val();
if (autRE.test(txt)) {
lm = RegExp.lastMatch;
pr = RegExp.$1;
p1 = RegExp.$2;
p2 = RegExp.$3;
if (!p2 && /(?:\[\[(?:[Uu]ser:)?)([^|\n]+)(\|\1)?(?:\]\])/.test(p1))
p2 = RegExp.$1;
p2 = p2 ? '|' + p2 : 'o=|2=' + p1;
txt = txt.replace(lm, pr + pre + p2 + post);
$textarea.val(txt);
} else {
$textarea.textSelection('encapsulateSelection', {
pre: pre + 'o=|2=',
post: post
});
}
},
addButtons: function ($textarea) {
cSVG.done = 1;
$textarea.on('wikiEditor-toolbar-buildSection-IgenSub', function (/* event, section*/) {
$.removeCookie('wikiEditor-0-toolbar-section', {
path: '/'
});
// $('.wikiEditor-ui-toolbar .sections').hide(); not working
$('#wikiEditor-section-IgenSub')
.attr('aria-expanded', 'false')
.removeClass('section-visible')
.addClass('section-hidden')
.parent().hide();
});
$textarea.wikiEditor('addToToolbar', {
section: 'main',
groups: {
SVG: {
tools: {
Igen: {
label: 'SVG Image Generation (+W3Ccheck)',
type: 'button',
icon: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/SVG_Simple_Icon.svg/24px-SVG_Simple_Icon.svg.png',
action: {
type: 'callback',
execute: mw.libs.simpleSVGcheck.getW3Data
}
},
AutVec: {
label: 'Author-Vector',
type: 'button',
icon: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Gnome-vector-author.svg/24px-Gnome-vector-author.svg.png',
action: {
type: 'callback',
execute: mw.libs.simpleSVGcheck.insertAutVec
}
},
descCleanup: {
label: 'Description cleanup (without Igen)',
type: 'button',
icon: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Gnome-vector-cleanup.svg/24px-Gnome-vector-cleanup.svg.png',
action: {
type: 'callback',
execute: mw.libs.simpleSVGcheck.addToFileDesc
// execute: function (el) { cSVG.addToFileDesc(el.$textarea); }
}
}
}
}
},
sections: {
IgenSub: {
type: 'booklet',
// label: 'SubCats',
pages: {
subtree: {
// label: 'SubCats1',
layout: 'characters'
}
}
}
}
});
this.$button = $('#wikiEditor-section-main .group.group-insert a[rel="Igen"]').css('float', 'left');
// Made section button (HACK)
$('#wikiEditor-ui-toolbar .tabs .tab-IgenSub')
.before(this.$button)
.find('a').css('padding', '0 8px').append($('<img>', {
'src': 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/32/SVG_category_subtree.svg/24px-SVG_category_subtree.svg.png',
'width': 22,
'height': 22,
'title': 'Igen subtree parameter',
'rel': 'IgenSub',
'role': 'button',
'class': 'tool tool-button'
})).one('click', cSVG.addToolbar);
// Add another toollink to the edit-dropdown
mw.loader.using('ext.gadget.editDropdown', function () {
mw.libs.commons.ui.addEditLink('', 'SVG Igen +', 'e-igen', 'Insert Template:Image_generation with W3-validity')
.addEventListener('click', mw.libs.simpleSVGcheck.getW3Data);
});
},
getIgenTop: function () {
let $this = $(this),
toolTip,
// mouseOut = function(){ if ($this.tipsy) $this.tipsy('hide'); },
mouseOut = function (tooltip) {
if (tooltip && tooltip.visible)
tooltip.toggle(false);
},
json = cSVG.jsonIgenTop,
r,
lang = c.wgUserLanguage,
sub = $this.data('key');
if (!sub)
return false;
// $this.tipsy(); // install tooltip
// Auto-close
setTimeout(function () {
if (!toolTip || !toolTip.visible)
return;
setTimeout(function () {
mouseOut(toolTip);
}, 2000);
}, 1000);
function addTooltip(r) {
// $this.attr('title', r).tipsy('show');
let tooltip = new OO.ui.PopupWidget({
padded: true,
width: 'auto',
align: 'forwards',
// label: $this.attr('title'),
// classes: [ 'mw-revslider-tooltip', 'mw-revslider-revision-tooltip' ],
$content: r
});
$this.append(tooltip.$element)
// .removeAttr('title')
.on('mouseout', function () {
mouseOut(tooltip);
})
.on('mouseover', function () {
tooltip.toggle(true);
});
// setTimeout(function () { if (tooltip) tooltip.toggle(false); }, 2000);
tooltip.toggle(true);
toolTip = tooltip;
}
function getParse(text) {
// console.log('getParse', text);
// $.getJSON('/w/api.php?action=expandtemplates&format=json&text=%7B%7BIgen%2Ftop%7C' + sub + '%7D%7D&prop=wikitext',
cSVG.XHR = $.getJSON('/w/api.php?action=parse&format=json&text=' + text + '&prop=text&pst=1&disablelimitreport=1&disableeditsection=1&disabletidy=1&contentmodel=wikitext&noimages=1', function (r) {
// if (!(r = r.expandtemplates) || !(r = r.wikitext))
if (!(r = r.parse) || !(r = r.text) || !(r = r['*']))
r = $('<p>').text(sub);
else
r = $(r).unwrap(); // div
if (!(text = r.html()))
return;
addTooltip(r);
// Save parsed to json for possible later usage
cSVG.jsonIgenTop[sub][lang] = text;
});
}
// TODO: could be outsourced as lib
// r = json[sub]
function langSwitch(r) {
let i;
if (!(lang in r)) {
lang = 'en';
// Allow input in format: {{LangSwitch|de=Grün|es/it/pt=Verde|fr=Vert|en=Green |lang=en}}
// with multiple languages mapping to a single value
for (let name in r) {
var val,
args;
if (typeof name === 'string' && (val = r[name])) {
args = name.split('/');
if (args.length === 2)
for (i = 1; i >= 0; i--)
r[args[i]] = val.replace('{{{lang|{{int:lang|}}}}}', args[i]);
// TODO: {{#switch:{{{1}}} pre parse?
}
}
cSVG.jsonIgenTop[sub] = r; // put back
// get the list of accepetable language (lang + those in lang's fallback chain) and check their content
for (i = cSVG.langChain.length - 1; i >= 0; i--)
if (cSVG.langChain[i]in r)
lang = cSVG.langChain[i]; // no break as lower i is better
}
r = r[lang];
// if (r)?
if (/{/.test(r))
getParse(encodeURIComponent(r));
else
addTooltip($('<p>').html(r));
}
// JSON source!
if (json instanceof Object && (r = json[sub])) {
if (r instanceof Object) {
langSwitch(r);
} else if (typeof(sub = r) === 'string' && (r = json[r]) && r instanceof Object) {
// link
langSwitch(r);
} else {
r = 0;
}
}
if (!r) { // Fallback API parse!?
getParse('%7B%7BIgen%2Ftop%7C' + sub + '%7D%7D');
}
},
addToolbar: function () {
$.getJSON('/w/index.php?title=Template:Igen/sub.json&action=raw', function (r) { // &ctype=text/javascript
// mw.util.addCSS( '#wikiEditor-section-IgenSub .index{display:none}\n#wikiEditor-section-IgenSub .page div span {line-height:.8em;font-size:.8em;}' );
if (c.wgUserLanguage === 'en') {
cSVG.getIgenTop = null;
} else {
$.getJSON('/w/index.php?title=Template:Igen/top.json&action=raw', function (json) {
cSVG.langChain = mw.language.getFallbackLanguages();
cSVG.jsonIgenTop = json;
});
}
mw.loader.load('oojs-ui'); // 'jquery.tipsy'
let section = [],
itemChk = {},
$section = $('#wikiEditor-section-IgenSub');
$section.find('.index').remove();
// TODO: could be improved
$.each(r, function (key, value) {
let title = key,
mouseover = cSVG.getIgenTop;
if (!value) {
value = '-';
title = 'inhibit subcategorizing';
mouseover = null;
} else {
value = value.replace(':', '');
}
// Exclude double values
if (itemChk[value]) {
// console.log(value, 'is double', key, itemChk[value]);
return;
}
itemChk[value] = key;
section.push($('<span>', {
title: title,
data: {
key: key
},
text: value,
style: 'font-size:.8em',
click: cSVG.insertIgenSub
})
// .tipsy({title: mouseover, fallback: title })
.one('mouseover', mouseover));
});
$section.find('.page div').append(section);
$section.parent().animate({
opacity: 1
}, 200);
// });
});
}
};
mw.libs.simpleSVGcheck = cSVG; // Expose globally
if (mw.config.get('wgNamespaceNumber') === 6 && /SVG$/i.test(c.wgTitle)) {
if (isEdit) {
// Allways collapsed
if ($.fn.cookie && $.cookie('wikiEditor-0-toolbar-section') === 'IgenSub')
$.removeCookie('wikiEditor-0-toolbar-section', {
path: '/'
}); // 0 is original $( this ).data( 'context' ).instance
// Late try?
// (window.RLQ = window.RLQ || []).push(function () {
window.addEventListener('load', function () {
if ($.fn.wikiEditor && mw.loader.getState('ext.wikiEditor') === 'ready') {
if (!cSVG.done)
cSVG.addButtons($textarea);
} else if (expeUser) {
mw.log.error('WikiEditor not ready!?', mw.loader.getState('ext.wikiEditor'), $textarea, $.fn.wikiEditor);
}
});
$textarea = $('#wpTextbox1');
// Early try, direct load (as we don't know if the ready load event triggered)
if ($textarea[0]) {
$textarea.on('wikiEditor-toolbar-doneInitialSections', function () {
if (!cSVG.done)
cSVG.addButtons($textarea);
});
} else if (expeUser) {
throw Error('$textarea is not ready!?!');
}
/* if (mw.loader.getState('ext.wikiEditor') === 'registered') {
mw.loader.using('user.options', function () {
if (!mw.user.options.get('usebetatoolbar')) mw.log.warn('You must enable the Wikieditor to use the SVG-Igen buttons.');
});
}*/
// Force Wikieditor on!?
$.when(mw.loader.using(['mediawiki.util', 'mediawiki.user', 'jquery.spinner', 'ext.wikiEditor']), $.ready).always(function () {
// if (mw.config.get('wgPageContentModel') === 'wikitext' && /^(edit|submit)$/.test(c.wgAction)) {
// deprecated [[phab:T30856]]
/* mw.loader.using( 'mediawiki.toolbar', function () {
mw.toolbar.addButtons( {
speedTip: 'SVG Igen',
imageFile: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/SVG_Simple_Icon.svg/24px-SVG_Simple_Icon.svg.png',
onClick: mw.libs.simpleSVGcheck.getW3Data
} );
});
*/ // $textarea = $( '#wpTextbox1' );
if (!cSVG.done)
cSVG.addButtons($textarea);
// cleanup?
if (!mw.libs.fastCleanup)
importScript('User:Sarang/cleanup.js'); // ed_wdh
// Get parameter
let URL = window.location.search,
param = {},
nameReg = new RegExp(cSVG.name + '=(\\d+)', 'g');
err = nameReg.test(URL);
if (c.wgAction === 'edit' && err) {
cSVG.err = err = mw.util.getParamValue(cSVG.name); // TODO only one err needed
cSVG.size = mw.util.getParamValue('SVGsize');
c.wgUserName = mw.util.getParamValue('username');
toolName = mw.util.getParamValue('toolname');
let URn = URL.substr(nameReg.lastIndex + 1); // RL is readonly ?
for (let aItKey, nKeyId = 0, aCouples = URn.split('&'); nKeyId < aCouples.length; nKeyId++) {
aItKey = aCouples[nKeyId].split('=');
param[aItKey[0]] = aItKey.length > 1 ? Number(aItKey[1]) : 0;
}
$.extend(cSVG, param);
cSVG.addToFileDesc($textarea, err, '', toolName);
}
});
} else {
mw.loader.using(['ext.gadget.jquery.badge', 'ext.gadget.editDropdown'], cSVG.init);
}
// mw.libs.simpleSVGcheck.addButtons($('#wpTextbox1')); // DEBUG
}
}
(jQuery, mediaWiki));
// EOF </nowiki>