User:Qwerfjkl/translatedautoformatter.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Qwerfjkl/translatedautoformatter. |
/** Translated via google translate at 16:52, 14 October 2021 (UTC)
* Shows an "Auto-Format" function in the toolbar, which eliminates many typical wikification errors
* corrected automatically. A detailed description can be found on the discussion page.
* (<nowiki> to bypass [[bugzilla: 8761]].)
*/
( function( $, mw ) {
if ( !document.forms['editform']
|| ( mw.config.get( 'wgAction' ) !== 'edit' && mw.config.get( 'wgAction' ) !== 'submit' )
) {
return;
}
function escapeRE( s ) {
return s.replace( /([$()*+\-.?[\\\]^{|}])/g, '\\$1' );
}
mw.libs = mw.libs || {};
mw.libs.autoFormatter = {
/**
* @param {HTMLAnchorElement} [clickedElement]
* @return {boolean}
*/
click: function( clickedElement ) {
var e = document.forms['editform'].elements,
textbox = e['wpTextbox1'],
summaryElement = e['wpSummary'];
if ( !textbox ) {
return false;
}
/* Reset the button as fast as possible, even before triggering WikEd */
this.updateButton( clickedElement );
if ( window.wikEd && window.wikEd.useWikEd ) {
wikEd.UpdateTextarea();
}
this.clickedElement = clickedElement;
this.isAll = false;
this.isDisambiguation = /\{\{\s*[Bb]egriffsklärung\s*[|}]/.test( textbox.value );
this.lang = mw.config.get( 'wgContentLanguage' );
this.localisation = typeof window.autoFormatLocalisation === 'undefined' ||
window.autoFormatLocalisation === true ? this.lang : window.autoFormatLocalisation;
var hasChanges = this.cleanElement( textbox );
summaryElement.value = this.cleanSummary( summaryElement.value );
if ( window.wikEd && window.wikEd.useWikEd ) {
wikEd.UpdateFrame();
}
if ( hasChanges ) {
mw.hook( 'AutoFormatterDoneWithChange' ).fire();
}
/* Do not follow the links href if the clicked element was a link */
return false;
},
isChanged: function( oldValue, newValue ) {
/ * Removed spaces at the end of the text never count as a change * /
oldValue = oldValue.replace( /\s+$/, '' );
newValue = newValue.replace( /\s+$/, '' );
/ * Do not show removed spaces at the end of a line as a change, but replace it anyway * /
var changed = oldValue.replace( /[\r ]+\n/g, '\n' ) !== newValue.replace( /[\r ]+\n/g, '\n' );
this.updateButton( this.clickedElement, changed );
/ * Never consider normalized line breaks as a change, this avoids flickering * /
return changed || oldValue.replace( /\r+$/gm, '' ) !== newValue;
},
/**
* @param {HTMLAnchorElement} [a]
* @param {boolean} [changed]
*/
updateButton: function( a, changed ) {
if ( !a || !a.nodeType || a.rel === 'autoFormatter' ) {
$( a && a.nodeType ? a : '[rel=autoFormatter]' ).css( {
backgroundColor: changed ? '#DEF740' : '',
borderRadius: changed ? '3px' : '',
opacity: changed === false ? '.4' : ''
} );
} else if ( a && a.style ) {
a.style.color = changed === false ? 'silver' : ( changed ? 'green' : '' );
}
},
cleanElement: function( e ) {
var t ;
e.focus();
if ( typeof e.selectionStart === 'number' ) {
var scroll = e.scrollTop,
s1 = e.selectionStart,
s2 = e.selectionEnd;
if ( s2 > s1 && ( s1 > 0 || s2 < e.value.length ) ) {
t = this.cleanText( e.value.substring( s1, s2 ) );
if ( t === false ) {
return false;
}
var newValue = e.value.substr( 0, s1 ) + t + e.value.substr( s2 );
e.value = newValue;
/* Fix for Opera */
s2 = s1 + t.length + ( e.value.length - newValue.length );
} else if ( !this.cleanAll( e ) ) {
return false;
}
e.selectionStart = s1;
e.selectionEnd = s2;
e.scrollTop = scroll;
return true;
} else if ( typeof document.selection === 'object' ) {
var range = document.selection.createRange();
if ( range.text.length ) {
t = this.cleanText( range.text );
if ( t !== false ) {
range.text = t;
}
return t !== false;
} else {
return this.cleanAll( e );
}
} else {
return this.cleanAll( e );
}
},
cleanAll: function( e ) {
this.isAll = true;
var t = this.cleanText( $( e ).val() );
if ( t !== false ) {
$( e ).val( t.replace( /^\s*\n/, '' ) );
}
return t !== false;
},
/**
* @param {string} summary
* @return {string}
*/
cleanSummary: function( summary ) {
summary = this.cleanWikimediaLinks( summary );
summary = this.cleanInternalLinks( summary );
return this.cleanTypography( summary );
},
/**
* @param {string} t
* @return {string|boolean}
*/
cleanText: function( t ) {
var oldValue = t;
/* Remove control characters, undefined code points, LINE/PARAGRAPH SEPARATOR, BOM */
t = t.replace( /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\u2028\u2029\uFEFF]+/g, '' );
t = t.replace(
/[\t ]*[\t\xA0\xAD\u1680\u180E\u2000-\u200D\u202F\u205F\u2060\u3000]+[\t\r ]*\n/g,
'\n'
);
t = t.replace( /(^|==|[^=\\]) +\n/g, '$1\n' );
/ * Make invisible soft separator visible, no matter where * /
t = t.replace( /(?:\xAD|&#*(?:shy|x0*AD\b|0*173\b);?)+/gi, '­' );
/ * Remove ZERO WIDTH SPACE only in Latin * /
t = t.replace( /([\x00-\u024F])\u200B+(?=[\x00-\u024F])/g, '$1' );
/ * LRM has no effect if it is next to an LR symbol * /
t = t . replace ( / \ u200E + (? = [AZ \] ªµºÀ-ÖØ-öø- \ u02B8]) / gi , '' );
t = t . replace ( / ([A-ZªµºÀ-ÖØ-öø- \ u02B8]) \ u200E + / gi , '$ 1' );
t = t.replace( /\u200E+/g, '‎' );
t = this.backupNowikis( t );
t = this.cleanCharacterEntities( t );
t = this.cleanGalleries( t );
t = this.backupFilenames( t );
t = this.cleanHeadlines( t );
/ * Uniform notation for keywords including space adjustment * /
t = t.replace(
/ \ {\ {\ s * (PAGE TITLE | DISPLAYTITLE): \ s * / gi ,
this . location === 'of' ? '{\ {SEITENTITEL:' : this . location
? '{\{DISPLAYTITLE:'
: '{\{$1:'
);
t = t.replace(
/ # (FORWARD | REDIRECT) [\ s: =] * \ [+ \ s * ([^ [\] |] * [^ \ s [\] |]) (?: \ S * \ | [^ [ \]] *)? \] + / gi ,
this.localisation === 'de' ? '#WEITERLEITUNG [[$2]]' : this.localisation
? '#REDIRECT [[$2]]'
: '#$1 [[$2]]'
);
t = t.replace(
/\[\[ *(Category|Kategorie)\s*:\s*([^[\]|]*[^\s[\]|])\s*(?=[\]|])/gi,
this . location === 'of' ? '[[Category: $ 2' : this . location
? '[[Category:$2'
: '[[$1:$2'
);
t = this.cleanThumbnails( t );
t = this.cleanReferences( t );
t = this.cleanTags( t );
t = this.cleanExternalLinks( t );
t = this.cleanWikimediaLinks( t );
t = this.cleanInternalLinks( t );
t = this.cleanTemplates( t );
t = this.cleanISSNs( t );
t = t.replace(
/\bclass\s*=\s*(?:(") *([ \w-]*? ?))?(?: *\bprettytable\b)+/g,
'class=$1$2wikitable'
);
/ * Unnecessary spaces in HTML attributes, important before the quotation marks * /
t = t.replace( /[!<|][ \w"-;=?[\]]*\b *= +"/g, function( $0 ) {
return $0.replace( /(\b[a-z]+\b) *= *"/g, '$1="' );
} );
/ * Find the first interlanguage link; 9 because of [[zh-classical:…]] * /
var i = t.search( /^\[\[ *[a-z]{2,3}(?:-[a-z-]{2,9})? *:/m ),
slice;
if ( i > 0 ) {
i = Math.max( i, t.indexOf( '<references', i ) );
slice = t.slice( i );
t = t.slice( 0, i );
}
t = this.cleanTypography( t );
t = this.cleanDates( t );
if ( slice ) {
t += slice;
}
t = this.cleanDuplicateLinks( t );
t = this.cleanUnits( t );
t = this.cleanNonBreakingSpaces( t );
t = this.cleanISBNs( t );
t = this.cleanPMIDs( t );
t = this.cleanCategories( t );
t = this.cleanNewlines( t );
t = this.cleanRedundantTemplateParameters( t );
t = this.cleanTemplatesByRules( t );
t = this.executeUserReplacements( t );
t = this.restoreFilenames( t );
t = this.restoreNowikis( t );
var changed = this.isChanged( oldValue, t );
return changed ? t : false;
},
cleanCharacterEntities: function( t ) {
var entities = {
/ * Unicode block basic Latin (U + 0000 to U + 007F) * /
'grave': '`',
/ * Unicode block Latin-1, supplement (U + 0080 to U + 00FF) * /
'cent' : '¢' , 'pound' : '£' , 'yen' : '¥' , 'sect' : '§' , 'laquo' : '«' , 'deg' : '°' ,
'plusmn': '±', 'pm': '±', 'sup2': '²', 'sup3': '³', 'acute': '´', 'centerdot': '·',
'middot': '·', 'raquo': '»', 'frac14': '¼', 'frac12': '½', 'half': '½',
'frac34' : '¾' , 'Auml' : 'Ä' , 'Ouml' : 'Ö' , 'times' : '×' , 'Uuml' : 'Ü' , 'szlig' : 'ß' ,
'auml' : 'ä' , 'ouml' : 'ö' , 'div' : '÷' , 'divide' : '÷' , 'uuml' : 'ü' ,
/ * Unicode block general punctuation (U + 2000 to U + 206F) * /
'ndash': '–', 'mdash': '—', 'lsquo': '‘', 'rsquo': '’', 'rsquor': '’',
'lsquor': '‚', 'sbquo': '‚', 'ldquo': '“', 'rdquo': '”', 'rdquor': '”',
'bdquo': '„', 'ldquor': '„', 'dagger': '†', 'Dagger': '‡', 'ddagger': '‡',
'bull': '•', 'bullet': '•', 'hellip': '…', 'mldr': '…', 'permil': '‰', 'prime': '′',
'Prime': '″', 'lsaquo': '‹', 'rsaquo': '›',
/ * Unicode block currency symbols (U + 20A0 to U + 20CF) * /
'euro': '€',
/ * Unicode block arrows (U + 2190 to U + 21FF) * /
'rarr' : '→' , 'harr' : '↔' ,
/ * Unicode block mathematical operators (U + 2200 to U + 22FF) * /
'minus': '−', 'infin': '∞', 'ap': '≈', 'approx': '≈', 'asymp': '≈', 'ne': '≠',
'le' : '≤' , 'leq' : '≤' , 'ge' : '≥' , 'geq' : '≥'
};
/* Limit to U+FFFF because of compatibility reasons, keep 𐀏 intact */
t = t.replace(
/&#*(x([\dA-F]{2,})|(\d{3,})|[a-z]{2,9}\d{0,2}\b)(?![\dA-F=]);?/gi,
function( $0, $1, $2, $3 ) {
if ( $2 ) {
$3 = parseInt( $2, 16 );
}
/* Don't decode spaces and control characters */
if ( $3 > 160 && $3 < 8191
|| $3 > 8207 && $3 < 8232
|| $3 > 8239 && $3 < 8287
|| $3 > 8303 && $3 < 55296
) {
return String.fromCharCode( $3 );
}
return entities[$1] || entities[$1.toLowerCase()] || $0;
}
);
t = t.replace( /&#*(?:amp|x0*26|0*38)\b;?/gi, '&' );
t = t.replace( /&(?![#\w])/gi, '&' );
/ * Non-breaking spaces uniformly as "& nbsp;", simplifies many of the following search patterns * /
return t.replace( /&#*(?:nbsp|x0*A0\b|0*160\b);?/gi, ' ' );
},
cleanTags: function( t ) {
t = t.replace( /(<\/?s)trike\b/gi, '$1' );
t = t.replace(
/<sub\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
'<sub$1/sub>'
);
t = t.replace(
/<sup\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
'<sup$1/sup>'
);
/* Drop default font attributes */
t = t.replace(
/(<font\b[^<>]*?)\s+fa\w+(?:[\s"',=]*(?:Arial|Helvetica(?:\W?N\w*)?|sans\W?serif)\b)+[\s"';]*(?=\s\w+\s*=|>)/gi,
'$1'
);
t = t.replace(
/(<font\b[^<>]*?)\s+size[\s"',=]*(?:-1\b|2\b|100\b[ ,.]*\d*%|1(?:\.0*)?em\b)["';]*/gi,
'$1'
);
/* Remove tags with no content and no attributes */
t = t.replace(
/<(\w+)\s*(\s\w[^<\/>]*)?>\s*<\/\1\b[^<>]*>/gi,
function( $0, $1, $2 ) {
if ( ( $2 && /^ref/i.test( $1 ) ) || /^[bh]r$/i.test( $1 ) ) {
return '<' + $1.toLowerCase() + ( $2 || '' ) + ' />';
}
return $2 && /\bclear:/i.test( $2 ) ? $0 : '';
}
);
/* Remove inline elements with no attributes */
while ( /<(font|span)\s*>\s*(?:<(?!\1)|[^<])*?\s*<\/\1[^<>]*>/i.test( t ) ) {
t = t.replace( /<(font|span)\s*>\s*((?:<(?!\1)|[^<])*?)\s*<\/\1[^<>]*>/gi, '$2' );
}
t = t.replace(
/<font\s+color[\s"',=]*(#[\dA-F]{3,6}|[a-z]{3,20})[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
'<span style="color:$1;">$2<\/span>'
);
t = t.replace(
/<font\s+size[\s"',=]*(?:-[2-9]|[01])[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
'<small>$1<\/small>'
);
t = t.replace(
/<font\s+size[\s"',=]*(?:[+-]0|3)[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
'<span style="font-size:larger;">$1<\/span>'
);
/* Merge nested inline tags */
t = t.replace(
/<(abbr|cite|mark|q|s|small|u)\s*><(font|span)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/\2\s*>\s*(?=<\/\1\s*>)/gi,
'<$1 style="$3;">$4'
);
t = t.replace(
/(<span\b[^<>]*?)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*><span\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/span\s*>\s*(?=<\/span\s*>)/gi,
'$1 style="$2; $3;">$4'
);
/ * Replace various forms of HTML line breaks with uniform ones * /
t = t.replace( /<(?:[\s\/\\]*br\b)+\s*(\s\w[^<>]*?)?[\s.\/\\]*>/gi, '<br$1 />' );
/ * Remove unnecessary HTML line breaks if a paragraph follows anyway * /
t = t.replace( / *<br \/>(?=\n[\n#*:;])/gi, '' );
t = t.replace(
/<(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*><small\s*>([^<>]*)<\/small\s*><\/\1\s*>/gi,
'<$1$2>$3<\/$1>'
);
t = t.replace(
/<small\s*><(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*?( ?\/|>[^<>]*<\/\1)\s*><\/small\s*>/gi,
'<$1$2$3>'
);
/* Drop old navigation bar wrapper, see [[Template:NaviBlock]] */
return t.replace(
/<div\s+class[^<>\w]*BoxenVerschmelzen[^<>\w]*>\s*(\{\{[^#:<>{}]*\}\})\s*<\/div>/gi,
'$1'
);
},
cleanGalleries: function( t ) {
return t.replace(
/<gallery\b([^<>]*)>([^<>]+)<\/gallery\b[^<>]*>/gi,
function( $0, $1, $2 ) {
return '<gallery' + $1 + '>' + $2
.replace( /^(\s*)\[+([^[\]]*)\]\]?\s*$/gm, '$1$2' )
.replace( /^(\s*)\[+/gm, '$1' ) + '<\/gallery>';
}
);
},
cleanHeadlines: function( t ) {
/* Fettung zumindest kompletter Überschriften ist unerwünscht */
t = t.replace( /^(=+) *'''([^\n']+)''' *(?==+$)/gm, '$1 $2 ' );
/ * Repairs broken headings, removes colons, adds spaces * /
t = t.replace( /^(=+) *(.*[^\s=:]) *:? *\1$/gm, '$1 $2 $1' );
/* Normalize "External links" headlines, use "Weblinks" in German */
return t.replace(
/ ^ == * (?: Externer? | External)? (?: & Nbsp; | \ s) * (?: Weblinks? | Links? | Websites? | Websites?) * = + / Gim ,
this.lang === 'de' ? '== Weblinks ==' : '== External links =='
);
},
cleanThumbnails: function( t ) {
if ( this.localisation === 'de' ) {
/ * Shorten unnecessary "right" * /
t = t.replace(
/(\[\[Datei:[^\n[\]]*[^\s[\]|])\s*\|+\s*(?:(?:mini|miniatur|thumb)\s*\|+\s*r(?:echts|ight)|r(?:echts|ight)\s*\|+\s*(?:mini|miniatur|thumb))\s*\|+\s*/gi,
'$1|thumb|'
);
/* Set the order to "thumb|upright" if one isn't localized */
t = t.replace(
/(\[\[Datei:[^\n[\]]*[^\s[\]|])\s*\|+\s*(?:upright([\s=_\d.]*)\|+\s*(?:mini|miniatur|thumb)|(?:hochkan|uprigh)t([\s=_\d.]*)\|+\s*thumb)\s*\|+\s*/gi,
'$ 1 | mini | upright $ 2 $ 3 |'
);
t = t.replace(
/ (\ [\ [Datei: [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * (?: mini | thumb) \ s * \ | + \ s * / gi ,
'$1|mini|'
);
t = t.replace(
/(\[\[Datei:[^\n[\]]*[^\s[\]|])\s*\|+\s*r(?:echts|ight)\s*\|+\s*/gi,
'$ 1 | right |'
);
/ * Change from "miniature" to "mini" only together with other changes * /
t = t.replace(
/(\[\[Datei:[^\n[\]]*[^\s[\]|])\s*\|+\s*(?:((?:left|none|cent[er]+|[en]*framed?|frameless|upright)\s*\|+)\s*miniatur|miniatur\s*(\|+\s*(?:left|none|cent[er]+|[en]*framed?|frameless|upright)))\s*\|+\s*/gi,
'$1|$2mini$3|'
);
t = t.replace(
/(\[\[Datei:[^\n[\]]*[^\s[\]|])\s*\|+\s*l(?:inks|eft)\s*\|+\s*/gi,
'$1|links|'
);
t = t.replace(
/ (\ [\ [Date: [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * (?: oh | no) ne \ s * \ | + \ s * / gi ,
'$ 1 | without |'
);
t = t.replace(
/ (\ [\ [File: [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * (?: centered | cent [er] +) \ s * \ | + \ s * / gi ,
'$ 1 | centered |'
);
t = t.replace(
/ (\ [\ [File: [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * (?: framed | [en] * framed?) \ S * \ | + \ s * / gi ,
'$ 1 | framed |'
);
t = t.replace(
/ (\ [\ [File: [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * (?: rahmenlo | frameles) s \ s * \ | + \ s * / gi ,
'$ 1 | frameless |'
);
t = t.replace(
/(\[\[Datei:[^\n[\]]*[^\s[\]|])\s*\|+\s*(?:hochkan|uprigh)t[\s=_]*([\d.]*)\s*\|+\s*/gi,
function( $0, $1, $2 ) { return $1 + '|hochkant' + ( $2 ? '=' + $2 : '' ) + '|'; }
);
}
/* vertical-align values from the CSS standard */
t = t.replace(
/ (\ [\ [(?: File | File): [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * (?: baseline | baseline) \ s * \ | + \ s * / gi ,
'$1|baseline|'
);
t = t.replace(
/ (\ [\ [(?: File | File): [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * (?: low (?: Placed )? | sub) \ s * \ | + \ s * / gi ,
'$1|sub|'
);
t = t.replace(
/ (\ [\ [(?: File | File): [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * (?: superscript (?: Set )? | sup | super) \ s * \ | + \ s * / gi ,
'$1|super|'
);
t = t.replace(
/ (\ [\ [(?: File | File): [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * (?: top | top) \ s * \ | + \ s * / gi ,
'$1|top|'
);
t = t.replace(
/ (\ [\ [(?: File | File): [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * text - (?: top | top ) \ s * \ | + \ s * / gi ,
'$1|text-top|'
);
t = t.replace(
/ (\ [\ [(?: Datei | File): [^ \ n [\]] * [^ \ s [\] |]) \ s * \ | + \ s * mi (?: Tt | ddl) e \ s * \ | + \ s * / gi ,
'$1|middle|'
);
t = t.replace(
/(\[\[(?:Datei|File):[^\n[\]]*[^\s[\]|])\s*\|+\s*(?:unten|bottom)\s*\|+\s*/gi,
'$1|bottom|'
);
return t.replace(
/(\[\[(?:Datei|File):[^\n[\]]*[^\s[\]|])\s*\|+\s*text-(?:unten|bottom)\s*\|+\s*/gi,
'$1|text-bottom|'
);
},
cleanExternalLinks: function( t ) {
t = t.replace( /\b(?:http(s?)(?::+\/*|\/\/+:*)\b)+/gi, 'http$1://' );
/ * Simplify double square brackets around web links * /
t = t.replace( /\[+ *(https?:\/\/[^\n[\]]*?) *\]+/gi, '[$1]' );
/ * Repair web links with a vertical line * /
t = t.replace( /(\[https?:\/\/[^\s[\]|]*?) *\| *(?=[^\s=[\]|]+\])/gi, '$1 ' );
/ * Add slashes at the end of simple domains * /
t = t.replace( /(\[https?:\/\/\w[\w.-]*\w\.\w+) +/gi, '$1/ ' );
/ * Write domains in lower case, regardless of whether they are labeled or not * /
return t.replace( /\bhttps?:\/\/\b[0-9a-z.-]*[A-Z][\w.-]*/g, function( $0 ) {
return $0.toLowerCase();
} );
},
cleanWikimediaLinks: function( t ) {
if ( typeof window.autoFormatWikimediaLinks !== 'undefined'
&& !window.autoFormatWikimediaLinks
) {
return t;
}
var wiki = mw.config.get( 'wgDBname' ).replace( /wiki$/i, '' ),
ns = mw.config.get( 'wgFormattedNamespaces' )[-1];
/ * Convert permanent web links into special page syntax * /
var permaLinkReplace = function( $0, $1, $2, $3, $4 ) {
var m = /^(\d*([^#]*))(.*)$/.exec( $3 );
/* Must use {{fullurl:…}} when there are more parameters than title and oldid */
if ( m && m[2] ) {
/* {{fullurl::|oldid=…}} with no page name is not possible any more */
if ( !$2 ) {
return $0;
}
return '[{\{fullurl:' + ( $1 === wiki ? '' : $1 + ':' )
+ $2.replace( /_/g, ' ' ) + '|oldid=' + m[1] + '}}' + m[3]
+ ( typeof $4 === 'string' ? ' ' + $4 : '' ) + ']';
} else {
return '[[:' + $1 + ':' + ( $1 === wiki ? ns : 'Special' )
+ ': Permanent' + ( $ 1 === 'de' ? 'Er' : '' ) + 'Link /' + $ 3
+ ( typeof $4 === 'string' ? '|' + $4 : '' ) + ']]';
}
};
/ * Convert web links in language versions (including your own) into wikilinks * /
var interWikiReplace = function( $0, $1, $2, $3 ) {
/ * Use an alternative if parameters are included wind * /
var m = /^([^?]*)\?([^#]*)(.*)$/.exec( $2 );
try {
return m ? '[{\{fullurl:' +
( $1 === wiki ? '' : $1 + ':' ) +
decodeURIComponent( m[1] ).replace( /_/g, ' ' ) + '|' + m[2] + '}}' + m[3] +
( typeof $3 === 'string' ? ' ' + $3 : '' ) + ']' :
'[[:' + $1 + ':' + $2.replace( /_/g, ' ' ) +
( typeof $3 === 'string' ? '|' + $3 : '' ) + ']]';
} catch ( ex ) {
return $0;
}
};
/* Alle projektinternen Weblinks protokollrelativ machen */
t = t.replace( /\[ *https?:\/+(?=[a-z-]+\.wikipedia\.org\b)/gi, '[//' );
/* Schreibweise [[Weblink#Anker mit Leerzeichen|Beschriftung]] reparieren */
t = t.replace(
/\[+\/\/([a-z-]+)\.wikipedia\.org\/w\/[\w.]*\?(?:title=([^\s&[\]|]*)&)?oldid=([^\n?[\]|]+?) *\|+ *([^\n[\]|]*?) *\]+/gi,
permaLinkReplace
);
t = t.replace(
/\[+\/\/([a-z-]+)\.wikipedia\.org\/wiki\/([^\n[\]|]*?) *\|+ *([^\n[\]|]*?) *\]+/gi,
interWikiReplace
);
/* Schreibweise [Weblink#Anker Beschriftung] umwandeln */
t = t.replace(
/\[+\/\/([a-z-]+)\.wikipedia\.org\/w\/[\w.]*\?(?:title=([^\s&[\]|]*)&)?oldid=([^\s?[\]|]+) +([^\n[\]|]+?) *\]+/gi,
permaLinkReplace
);
t = t.replace(
/\[+\/\/([a-z-]+)\.wikipedia\.org\/wiki\/([^\s[\]|]*) +([^\n[\]|]+?) *\]+/gi,
interWikiReplace
);
/* Schreibweise [Weblink#Anker] umwandeln */
t = t.replace(
/\[+\/\/([a-z-]+)\.wikipedia\.org\/w\/[\w.]*\?(?:title=([^\s&[\]|]*)&)?oldid=([^\s?[\]|]+) *\]+/gi,
permaLinkReplace
);
t = t.replace(
/\[+\/\/([a-z-]+)\.wikipedia\.org\/wiki\/([^\s[\]|]*) *\]+/gi,
interWikiReplace
);
/* Verbliebene projektinterne Weblinks ohne eckige Klammern ebenfalls umwandeln */
t = t.replace(
/\bhttps?:\/\/([a-z-]+)\.wikipedia\.org\/w\/[\w.]*\?(?:title=([^\s&[\]|]*)&)?oldid=([^\s?<>[\]{|}]*[^\s!"),.:;<>?[\\\]{|}])(?=[\s!),.:;<]|$)/gim,
permaLinkReplace
);
return t.replace(
/\bhttps?:\/\/([a-z-]+)\.wikipedia\.org\/wiki\/([^\s<>\[\]{|}]*[^\s!",.:;<>?\[\\\]{|}])(?=[\s!,.;<]|$)/gim,
interWikiReplace
);
},
cleanInternalLinks: function( t ) {
var wiki = mw.config.get( 'wgDBname' ).replace( /wiki$/i, '' ),
ns = mw.config.get( 'wgFormattedNamespaces' )[-1];
/* Unnötig gewordene Vorlage in Spezialseiten-Syntax umwandeln */
t = t.replace(
/\{\{\s*Permalink\s*\|[^{|}]*\|\s*(\d+(?: ?#[^{|}]*?)?)\s*(?:(\|)\s*([^{|}]*?))?\s*\}\}/gi,
'[[' + ns + ':Permanent' + ( wiki === 'de' ? 'er ' : '' ) + 'Link/$1$2$3]]'
);
/* Make selected "fullurl" parser function calls more compact */
t = t.replace(
/\{\{\s*fullurl:\s*([^\n{|}]+)\|\s*(?:diff=prev&oldid=(\d+)|oldid=(\d+)&diff=prev)\s*\}\}/gi,
'{\{fullurl:$1|diff=$2$3}}'
);
/* https://www.mediawiki.org/wiki/Help:Lint_errors/multi-colon-escape */
t = t.replace( /\[\[::+/gi, '[[:' );
/* Wikilinks mit unnötigem Präfix ":w:de:", "w:de:" oder ":de:" vereinfachen */
t = t.replace(
new RegExp(
'\\[\\[ *(?::? *w *)?: *' + wiki
+ ' *: *(((?:Bild|Datei|File|Image|[CK]ategor[iy]e?) *:)?[^\\n[\\]]*\\S) *\\]\\]',
'gi'
),
function( $0, $1, $2 ) {
return '[[' + ( $2 ? ':' : '' ) + $1 + ']]';
}
);
/* Anker in internen Links dekodieren */
t = t.replace(
/(\[\[[^\n#[\]{|]*#)([^\n#[\]|]+)(?=\|?[^\n#[\]|}]*\]\])/g,
function( $0, $1, $2 ) {
try {
/ * Keep coding of some characters (% 25,% 5B,% 5D,% 7B-% 7D) * /
return $1 + decodeURIComponent( $2.replace( /\.(?=[289A-E][\dA-F]|[357][B-F]|40|60)/g, '%' ) ).
replace( /[%[\]{|}]/g, function( $0 ) {
return '%' + $0.charCodeAt( 0 ).toString( 16 ).toUpperCase();
} );
} catch ( ex ) {
return $0;
}
}
);
/ * Decode other coded link targets * /
t = t.replace(
/\[\[([^\n#%[\]{|}]*%[2-9A-E][^\n#[\]{|}]*)(?=#?[^\ n[\]{|}]*\|?[^\n[\]{|}]*\]\])/gi ,
function( $0, $1 ) {
try {
/ * Keep coding of some characters (% 25,% 3C,% 3E,% 5B,% 5D,% 7B-% 7D) * /
return '[[' + decodeURIComponent( $1 ).replace( /[%<>[\]{|}]/g, function( $0 ) {
return '%' + $0.charCodeAt( 0 ).toString( 16 ).toUpperCase();
} );
} catch ( ex ) {
return $0;
}
}
);
/ * Remove remaining underscores from links * /
t = t.replace(
/\[\[[^\n[\]_{|}]+_[^\n[\]{|}]+(?=\|?[^\n[\]{|}]*\]\])/g,
function( $0 ) {
return $0.replace( /_/g, ' ' );
}
);
/* Save relevant spaces at the beginning of links */
t = t.replace( /(?: +|(\S))(\[\[[^\n[\]|]\|) +/g, '$1 $2' );
/* Save relevant spaces at the end of links */
t = t.replace( /(\[\[[^\n[\]|]\|[^\n[\]|]*[^\s[\]|]) +]](?: +|(?=\S))/g, '$1]] ' );
/ * [[Link | Dash-]] becomes [[Link | Dash]] - and [[Link | Die]] s becomes [[Link | Dies]] because it is easier to read;
MediaWiki really only accepts lowercase letters, ä, ö, ü and ß * /
t = t.replace(
/\[\[ *([^\n[\]|]+?) *(\|[^\n[\]|]+?)(?:(-+)]](?![^\w"'(<[«\xC0-\u024F‚„‹])|]]([a-zßäöü]*))/g,
'[[$1$2$4]]$3'
);
t = t.replace( /(^|[^'])\[\[([^\n:[\]|]+)\|('{2,5}) *\2 *\3]](?!')/g, '$1$3[[$2]]$3' );
var unmaskLinks = typeof window.autoFormatMaskedLinks === 'undefined'
|| window.autoFormatMaskedLinks,
capitalLinks = /^\w+wiki$/.test( mw.config.get( 'wgDBname' ) );
/ * [[Link | Link]] s become [[Link]] s because they are shorter and easier to read * /
return t.replace(
new RegExp(
'\\[\\[([^\\n:[\\]|])([^\\n:[\\]|]*)\\| *([^\\n:[\\]|]\\2)('
+ ( unmaskLinks ? '[^\\n[\\]|]' : '[a-zßäöü]' )
+ '*?) *]]',
'g'
),
function( $0, $1, $2, $3, $4 ) {
return ( capitalLinks
? $1.toLowerCase() !== $3.charAt().toLowerCase()
: $1 !== $3.charAt() )
? $0
: '[[' + $3 + ']]' + $4;
}
);
},
cleanDuplicateLinks: function( t ) {
/* Remove links from dates that start with a year (e.g. ISO) */
t = t.replace(
/\[+([12]\d{3}\W+(?:3[01]|[12]\d|0?[1-9])\W+(?:3[01]|[12]\d|0?[1-9]))\]+/g,
'$1'
);
/* Never link dates and years in Persondata templates */
var re = /\{\{\s*P(erson(?:endaten|data)\b[^{}]*\|\s*(?:GEBURTSD|STERBED|DATE)[\s\w]*=[^\n=[\]{|}]*)\[+([^\n=[\]{|}]+)\]+/i;
while ( re.test( t ) ) {
t = t.replace( re, '{\{P$1$2' );
}
/* Exclude articles with titles like "1. März" or "March 1" */
if ( /^(3[01]|[12]\d|[1-9])\.? \S+$/.test( mw.config.get( 'wgTitle' ) )
|| /^\w+ (3[01]|[12]\d|[1-9])$/.test( mw.config.get( 'wgTitle' ) )
|| /\[\[[CK]ategor[iy]e?:(Tag|Days of the year)[|\]]|\{\{(Artikel Jahr|Year nav)\s*[|}]/i.test( t )
) {
return t;
}
/* Exclude files and infoboxes from the start of the article */
var m = /^(?:\s*\[\[\w+:(?:\[\[[^\n\]]*\]\]|[^\n\]])*\]\])*(?:\s*\{\{(?:\{\{[^}]*\}\}|[^}])*\}\})+/.exec( t ),
start = m ? m[0].length : 0,
found = [],
a = [];
/* Unlink years that are linked more than one time */
re = /\[\[ *([12]\d{3}) *\]\]/g;
/* Jeweils ersten Fund eines Jahres merken, danach entlinken */
while ( m = re.exec( t ) ) {
if ( m.index >= start ) {
found[m[1]] ? a.push( m ) : found[m[1]] = true;
}
}
var r = '',
p = 0;
for ( var i = 0; i < a.length; i++ ) {
r += t.slice( p, a[i].index ) + a[i][1];
p = a[i].index + a[i][0].length;
}
return p ? r + t.slice( p ) : t;
},
cleanDates: function( t ) {
var months = mw.config.get( 'wgMonthNames' ) || ['', 'Januar', 'Februar', 'März', 'April',
'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];
if ( this.lang === 'de' && /österreichbezogen\b/i.test( t ) ) {
months[1] = 'Jänner';
}
/* Add missing space between day and month */
t = t.replace( new RegExp( '([\\s!\'(>|„](?:3[01]|[12]\\d|0?[1-9])\\.?)(?=(?:' +
months.slice( 1 ).join( '|' ) + ')\\b)', 'g' ), '$1 ' );
/* No non-breaking space between month and year */
t = t.replace( new RegExp( '(\\b(?:3[01]|[12]\\d|0?[1-9])\\.?(?:[\\s\\xA0]| )+(?:' +
months.slice( 1 ).join( '|' ) + '))(?:\xA0| )(?=[12]\\d{3}\\b)', 'g' ), '$1 ' );
if ( this.lang !== 'fi' ) {
/* Missverständliches deutsches Datumsformat durch Langform ersetzen */
var separator = this.lang === 'en' ? ' ' : '. ';
t = t.replace(
/([\s'(>„])(3[01]|[12]\d|0?[1-9])\. *(1[012]|0?[1-9])\. *(?=[12]\d{3}[!,.:;?]?[\s')<\]“](?!\w*\d))/g,
function( $0, $1, $2, $3 ) {
return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
}
);
}
/* Unspaced dashes in "1850–14 January" are bad style in German and English */
var dash = this.lang === 'ru' ? '—' : '–';
separator = this.lang === 'de' ? ' bis ' : ' – ';
t = t.replace(
/(\b +[12]\d{3}'*) *[–—−-] *('*(?:3[01]|[12]\d|0?[1-9])\.?) *([A-S][a-zä]{2,}\b)/g,
function( $0, $1, $2, $3 ) {
for ( var i = months.length; --i; ) {
if ( $3 === months[i] ) {
return $1 + separator + $2 + ' ' + $3;
}
}
return $0;
}
);
/* Bis-Striche in 4-stellige Jahreszahlenbereiche einsetzen */
t = t.replace(
/([\s!'(>|„])(?:\[\[ *([12]\d{3}) *\]\]|([12]\d{3})) *[–—-] *(?:\[\[ *([12]\d{3}) *\]\]|([12]\d{3}))(?=[!,.:;?]?[\s!')\/<\]|}“])/g,
function( $0, $1, $2, $3, $4, $5 ) {
return ( $2 || $3 ) < ( $4 || $5 ) ? $1 + ( $2 || $3 ) + dash + ( $4 || $5 ) : $0;
}
);
/* Bis-Striche in 2-stellige Jahreszahlenbereiche einsetzen */
t = t.replace(
/([\s!'(>|„][12]\d(\d\d)) *[—-] *(?=(1[3-9]|[2-9]\d)[!,.:;?]?(?:[\s!')\/<\]|“]|$)|\?)/g,
function( $0, $1, $2, $3 ) {
return !$3 || $2 < $3 ? $1 + dash : $0;
}
);
/* "1980 – 90" becomes "1980–1990" in the German Wikipedia, "1980–90" otherwise */
var full = typeof window.autoFormatShortYearRanges !== 'undefined'
? window.autoFormatShortYearRanges : this.lang === 'de';
t = t.replace(
/([\s!'(>|„]([12]\d)(\d\d)) *– *(?!(?:3[01]|[12]\d|0[1-9])\.? [A-S][a-zä]{2,}\b)(?=(\d\d)[!,.:;?]?(?:[\s!')\/<|“]|$))/g,
function( $0, $1, $2, $3, $4 ) {
return $3 < $4 ? $1 + '–' + ( full ? $2 : '' ) : $0;
}
);
/* ISSNs aber ohne Bis-Striche, wichtig nach den Jahreszahlen */
return t.replace( /(IS\wN\W*\d{4})–(?=\d)/g, '$1-' );
},
/**
* @param {string} t
* @return {string}
*/
cleanTypography: function( t ) {
var de = this.lang === 'de',
ru = this.lang === 'ru';
/* Double quotes */
if ( de || ru ) {
t = t.replace(
/(^|[\s!#'(*+\/:;>[|-])(?:"|,,)(?![\s>])([^\n"“”„]*[^\s"(;=“”„])"(?=[\s!'),.\/:;<?\]}-]|$)/g,
ru || /\bschweizbezogen\b/i.test( t )
&& ( t.indexOf( '«' ) !== -1 || t.indexOf( '„' ) === -1 )
? '$1«$2»'
: '$1„$2“'
);
}
t = t.replace(
/\{\{\s*((?:Zitat|")\s*\|\s*(?:(?:1|Text)\s*=)?[^={|}]*)/gi,
function( $0, $1 ) {
return '{\{' + $1.replace( /„([^\n‘‚“”„]+)“/g, '‚$1‘' );
}
);
if ( this.lang !== 'en' ) {
/* Replace exactly three dots with ellipsis */
t = t.replace( /(^|[ '(>[|„])\.\.\.(?=[ '),<?\]}“]|$)/gm, '$1…' );
}
t = t.replace( /[,;](?:[ \xA0]| )*†(?: | )*(?=[\w[])/gi, '; † ' );
t = t.replace(
/\( *([\d,.]*\d(?: | )*[KMk]i?B)(?:ytes?)?([,;]) *([A-Z]{3,4}(?:\W+Datei)?) *\)/g,
'($3$2 $1)'
);
t = t.replace(
/\( *([A-Z]{3,4}(?:\W+Datei)?)([,;]) *([\d,.]*\d)(?: | )*([KMk]i?B)(?:ytes?)? *\)/g,
function( $0, $1, $2, $3, $4 ) {
$3 = $3.replace( de ? /\b\.(?=\d{3}\b)/g : /\b,(?=\d{3}\b)/g, '' );
$3 = $3.replace( /^(\d*),(?=\d*$)/, '$1.' );
$3 = ( $4.charAt() === 'M' ? Math.round( $3 * 10 ) / 10 : Math.round( $3 ) ) || $3;
return '(' + $1 + ( de ? ( '; ' + $3 ).replace( /\./, ',' ) : $2 + ' ' + $3 )
+ ' ' + $4 + ')';
}
);
/ * Bis dashes for page numbers * /
t = t.replace(
/\b(Sp?\.|Seiten?|Spalten?) *(\d+) *[–—−-] *(?=\d+(?:[\s!),.\/:;<?\]|}“]|$))/g,
'$1 $2–'
);
if ( this.lang !== 'it' ) {
t = t.replace(
/([\w"')>\]\xC0-\u024F“]) +-(,?) +(?=[\w"'(\[\xC0-\u024F„])/g,
'$1 –$2 '
);
}
return t;
},
cleanUnits: function( t ) {
/ * Percentage values have automatically been given a protected space since mid-2007 * /
t = t.replace( /(\S)(?:\xA0| )(?=%)/gi, '$1 ' );
if ( this.lang === 'de' || this.lang === 'ru' ) {
t = t.replace(
/([\s'(*+;«„][\u2212-]?\d+(?:[,–]\d+)?)(?=%[\s!'),.:<?\]|»“](?! *[\d"#);]))/gi,
'$1 '
);
t = t.replace(
/((?:\d|\b)[cmk]?m) *<[Ss][Uu][Pp]\s*>\s*([23²³])\s*<\/[Ss][Uu]\w\s*>(?=[\s!"'),\-.:;<?\]{|}–“])/g,
function( $0, $1, $2 ) {
return $1 + ( { '2': '²', '3': '³' }[$2] || $2 );
}
);
}
/ * Units of measurement always with spaces * /
return t.replace(
/([ '(*+:;„][\u2212-]?\d+(?:[,–]\d+)?) ?(k[Bgm]|Ki?B|k?Hz|[MGT](?:i?B|Hz)|cm|ha|m[lm]|[gm€¥])(?=[²³]?[ !'),.\/:;<?“])/g,
'$1 $2'
);
},
cleanNonBreakingSpaces: function( t ) {
/ * Paragraph, paragraph and sentence with protected spaces * /
t = t.replace(
/§(?: *| )(\d\w* +Ab?s?\.)(?: *| )(\d+ +S\.) *(?=\d)/gi,
'§ $1 $2 '
);
t = t.replace( /§(?: *| )(\d\w* +Ab?s?\.) *(?=\d)/gi, '§ $1 ' );
t = t.replace( /§ *(?=\d)/gi, '§ ' );
/* No non-breaking spaces in headlines */
return t.replace( /^=.* .*=$/gim, function( $0 ) {
return $0.replace( /(?: |\s)+/gi, ' ' );
} );
},
cleanISBNs: function( t ) {
t = t.replace( /\bISBN\W*(?:\d+­(?=\d))+/gi, function ( $0 ) {
return $0.replace( /­/g, '' );
} );
/ * Structure ISBNs with hyphens * /
return t.replace(
/(^|[\s#'(*>|])(?:(ISBN\d?\s*=\s*)|ISBN(?:-?1[03]\b| *1[03]:)?:?\s*)(9-?7-?[89]-?)?([013][\d\u2010-\u2012\u2212-]{8,}[\dX]\b)/gim,
function( $0, $1, $2, $3, $4 ) {
return $1 + ( $2 || 'ISBN ' ) + ( $3 || '' ).replace( /^9\D*7\D*(\d)\D*/, '97$1-' ) + $4.
/* Remove all dashes */
replace( /[^\dX]+/gi, '' ).
/* Group 0 for English books */
replace( /^0([01]\d)(\d{6})\B/, '0$1-$2-' ).
replace( /^0([2-6]\d\d)(\d{5})\B/, '0$1-$2-' ).
replace( /^0(7\d{3}|8[0-4]\d\d)(\d{4})\B/, '0$1-$2-' ).
replace( /^0(8[5-9]\d{3})(\d{3})\B/, '0$1-$2-' ).
replace( /^0(9[0-4]\d{4})(\d\d)\B/, '0$1-$2-' ).
replace( /^0(9[5-9]\d{5})(\d)\B/, '0$1-$2-' ).
/* Group 1 for English books */
replace( /^1(0\d)(\d{6})\B/, '1$1-$2-' ).
replace( /^1([1-3]\d\d)(\d{5})\B/, '1$1-$2-' ).
replace( /^1(4\d{3}|5[0-4]\d\d)(\d{4})\B/, '1$1-$2-' ).
replace( /^1(5[5-9]\d{3}|[67]\d{4}|8[0-5]\d{3}|86[0-8]\d\d|869[0-7]\d)(\d{3})\B/, '1$1-$2-' ).
replace( /^1(869[89]\d\d|8[7-9]\d{4}|9[0-8]\d{4}|99[0-8]\d{3})(\d\d)\B/, '1$1-$2-' ).
replace( /^1(999\d{4})(\d)\B/, '1$1-$2-' ).
/* Group 3 for German books */
replace( /^3(0[0-24-9]|1\d)(\d{6})\B/, '3$1-$2-' ).
replace( /^3(03[0-3]|[2-6]\d\d)(\d{5})\B/, '3$1-$2-' ).
replace( /^3(03[4-6]\d|7\d{3}|8[0-4]\d\d)(\d{4})\B/, '3$1-$2-' ).
replace( /^3(03[7-9]\d\d|8[5-9]\d{3}|95[4-9]\d\d|9[69]\d{3})(\d{3})\B/, '3$1-$2-' ).
replace( /^3(9[0-4]\d{4})(\d\d)\B/, '3$1-$2-' ).
replace( /^3(95[0-3]\d{4}|9[78]\d{5})(\d)\B/, '3$1-$2-' ).
/* Add missing dash after group */
replace( /^([0-57]|6\d\d|8\d|9[0-4]|9[5-8]\d|99[0-8]\d|999\d\d)\B/, '$1-' );
}
);
},
cleanISSNs: function( t ) {
return t.replace(
/(^|[\s#'(*>{|])ISSN *(\|?)[ #:\u2010-\u2014\u2212-]*((?:\d[ \u2010-\u2014\u2212-]*){7}[\dX]\b)/gi,
function( $0, $1, $2, $3 ) {
return $1 + 'ISSN' + ( $2 || ' ' ) + $3.replace( /[^\dX]+/gi, '' )
.replace( /^(.{4})/, '$1-' );
}
);
},
cleanPMIDs: function( t ) {
return t.replace(
/(^|[\s#'(*=>|])PMID[ #:\u2010-\u2014\u2212-]*(?=\d+\b)/gi,
'$1PMID '
);
},
cleanReferences: function( t ) {
t = t.replace(
/<\s*references\s*(\s\b[^<>]*?)?\s*(?:\/|>\s*<\s*\/\s*references)\s*>/gi,
'<references$1 />'
);
t = t.replace( /<\s*references\s*(\s\b[^<\/>]*?)?\s*>/gi, '<references$1>' );
t = t.replace( /<\s*\/\s*references\s*>/gi, '<\/references>' );
if ( this.isAll ) {
var re = /(<references[^<\/>]*)>/g,
m;
while ( m = re.exec( t ) ) {
if ( t.indexOf( '<\/references>', m.index ) < 0 ) {
t = t.slice( 0, m.index ) + m[1] + ' />' + t.slice( m.index + m[0].length );
}
}
}
t = t.replace( /< *ref\s*(\s\b[^<>]*?)\s*(?:\/+|>\s*<\s*\/+\s*ref) *>/gi, '<ref$1 />' );
/* Zeilenumbrüche in Einzelnachweisen nur oben im Artikel entfernen */
var i = t.indexOf( '<references' ),
slice;
if ( i > 0 ) {
slice = t.slice( i );
slice = slice.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>[\t ]*/gi, '<ref$1>' );
slice = slice.replace( /(?:(\n[\t ]*)|[\t ]*)<\s*\/+\s*ref\s*>/gi, '$1<\/ref>' );
t = t.slice( 0, i );
}
t = t.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>\s*/gi, '<ref$1>' );
t = t.replace( /\s*<\s*\/+\s*ref\s*>/gi, '<\/ref>' );
if ( slice ) {
t += slice;
}
/* Leerzeichen zwischen Satzende und <ref> oder zwei <ref> entfernen */
t = t.replace( /([!,.;?]|<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>) +(?=<ref[ >])/gi, '$1' );
/ * Shorten two identical punctuation marks before and after a <ref> to one * /
return t.replace( /([!,.:;?])(<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>)\1/gi, '$1$2' );
},
cleanCategories: function( t ) {
if ( this.lang !== 'de' && this.lang !== 'en' ) {
return t;
}
t = t.replace(
/ \ {\ {\ s * (SORTING | DEFAULT? \ w * SORT \ w *) \ s * [: |] [\ s \ xA0] * / gi ,
this.localisation === 'de' ? '{\{SORTIERUNG:' : this.localisation ? '{\{DEFAULTSORT:' : '{\{$1:'
);
/* Match every character thats in one of the two replacement maps or should be deleted */
var re = / ["& '\ - \ /?` ¡- ¥ © -´ · -ſǍ- \ u01ED \ u01F8- \ u021B \ u02B0- \ u036FΆ-ώ \ u0400-Ј \ u040D-ј \ u045DўҐ-ғҚқңңҮ -үҺһ \ u04D0- \ u04D7 \ u1E00-ỹ \ u2010- • ′ ″ ‹› - ff-st] / g ;
/ * Unicode block Latin-1, supplement (U + 0080 to U + 00FF) * /
var trSet1 = '"/?¡¢£¤¥©ª«¬®°±²³·¹º»¿ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝàáâãäåçèéêëìíîïðñòóôõö÷øùúûüýÿ';
var trSet2 = 'cL YCa R 23 1o AAAAAACEEEEIIIIDNOOOOOxOUUUUYaaaaaaceeeeiiiidnooooo ouuuuyy' ;
/ * Unicode block Latin, extended-A (U + 0100 to U + 017F) * /
trSet1 + = '' .
trSet2 + = 'AaAaAaCcCcCcCcDdDdEeEeEeEeEeGgGgGgGgHhHhIiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnnnnOoOoOoRrRrRr' ;
trSet1 + = 'ŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ' ;
trSet2 += 'SsSsSsSsTtTtTtUuUuUuUuUuUuWwYyYZzZzZzs';
/ * Unicode block Latin, extended-B (U + 0180 to U + 024F) * /
trSet1 + = 'ǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǤǥǦǧǨǩǪǫǬǭǸǹǺǻǾǿȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚț' ;
trSet2 += 'AaIiOoUuUuUuUueAaAaGgGgKkOoOoNnAaOoAaAaEeIiIiOoOoRrRrUuUuSsTt' ;
/ * Unicode block Cyrillic (U + 0400 to U + 04FF) * /
trSet1 + = '' .
trSet2 += 'EIJIUABWGDESIJKLMNOPRSTUFZAYEabwgdesijklmnoprstufzayeeijiuGgQqUuUuHhAaAaEe';
/ * Unicode block Latin, further addition (U + 1E00 to U + 1EFF) * /
trSet1 + = 'ḀḁḂḃḄḅḆḇḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿṀṁṂṃṄṅṆṇṈṉṊṋṌṍṎṏṐṑṒṓṔṕṖṗ' ;
trSet2 += 'AaBbBbBbCcDdDdDdDdDdEeEeEeEeEeFfGgHhHhHhHhHhIiIiKkKkKkLlLlLlLlMmMmMmNnNnNnNnOoOoOoOoPpPp';
trSet1 += 'ṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿẀẁẂẃẄẅẆẇẈẉẊẋẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛ\u1E9C\u1E9D\u1E9F' ;
trSet2 += 'RrRrRrRrSsSsSsSsSsTtTtTtTtUuUuUuUuUuVvVvWwWwWwWwWwXxXxYyZzZzZzhtwyasssd';
trSet1 += 'Wonderful God's Father's Death' to be able to call the number of people living in the house with the consent of the Government ;
trSet2 + = 'AaAaAaAaAaAaAaAaAaAaAaAaEeEeEeEeEeEeEeEeIiIiOoOoOoOoOoOoOoOoOoOoOoOoUuUuUuUuUuUuUuYyYyYyYy' ;
/ * Unicode block general punctuation (U + 2000 to U + 206F) * /
trSet1 += '\u2012—―\u2016‗‘‚\u201B“”„\u201F†‡•′″‹›−';
trSet2 += ' ';
var trMap = {
'&' : 'and' , '¼' : '14' , '½' : '12' , '¾' : '34' ,
'Æ': 'Ae', 'Þ': 'Th', '\u1E9E': 'SS', 'ß': 'ss', 'æ': 'ae', 'þ': 'th', 'IJ': 'Ij',
'ij' : 'ij' , 'Œ' : 'Oe' , 'œ' : 'oe' , 'Ǣ' : 'Ae' , 'ǣ' : 'ae' , 'Ǽ' : 'Ae' , 'ǽ ' : ' ae ' ,
/ * Unicode block Greek and Coptic (U + 0370 to U + 03FF) * /
'Ά' : 'Alpha' , 'Έ' : 'Epsilon' , 'Ή' : 'Eta' , 'Ί' : 'Iota' , 'Ό' : 'Omikron' ,
'Ύ' : 'Ypsilon' , 'Ώ' : 'Omega' , 'ΐ' : 'iota' , 'Α' : 'Alpha' , 'Β' : 'Beta' , 'Γ' : 'Gamma' ,
'Δ' : 'Delta' , 'Ε' : 'Epsilon' , 'Ζ' : 'Zeta' , 'Η' : 'Eta' , 'Θ' : 'Theta' , 'Ι' : 'Iota' ,
'Κ' : 'Kappa' , 'Λ' : 'Lambda' , 'Μ' : 'My' , 'Ν' : 'Ny' , 'Ξ' : 'Xi' , 'Ο' : 'Omikron' ,
'Π' : 'Pi' , 'Ρ' : 'Rho' , 'Σ' : 'Sigma' , 'Τ' : 'Tau' , 'Υ' : 'Ypsilon' , 'Φ' : 'Phi' ,
'Χ' : 'Chi' , 'Ψ' : 'Psi' , 'Ω' : 'Omega' , 'Ϊ' : 'Iota' , 'Ϋ' : 'Ypsilon' , 'ά' : 'alpha' ,
"E" : 'epsilon' , 'or' : 'eta' , 't' : 'IOTA' , 'à' : 'Ypsilon' , 'a' : 'alpha' , 'b' : 'beta' ,
'c' : 'gamma' , 'S' : 'delta' , 'e' : 'epsilon' , 'z' : 'zeta' , 'the' : 'eta' , 'i' : 'theta' ,
'ι' : 'iota' , 'κ' : 'kappa' , 'λ' : 'lambda' , 'μ' : 'my' , 'ν' : 'ny' , 'ξ' : 'xi' ,
'ο' : 'omikron' , 'π' : 'pi' , 'ρ' : 'rho' , 'ς' : 'sigma' , 'σ' : 'sigma' , 'τ' : 'tau' ,
'υ' : 'ypsilon' , 'φ' : 'phi' , 'χ' : 'chi' , 'ψ' : 'psi' , 'ω' : 'omega' , 'ϊ' : 'iota' ,
'D' : 'Ypsilon' , 'v' : 'Omikron' , 'J' : 'Ypsilon' , 'h' : 'omega' ,
/ * Unicode block Cyrillic (U + 0400 to U + 04FF) * /
'Ё': 'Jo', 'Ђ': 'Dje', 'Ѓ': 'Gje', 'Є': 'Je', 'Ѕ': 'Dze', 'Ї': 'Ji', 'Џ': 'Dsche',
'Ж': 'Sch', 'Х': 'Ch', 'Ч': 'Tsch', 'Ш': 'Sch', 'Щ': 'Schtsch', 'Ю': 'Ju',
'Я': 'Ja', 'ж': 'sch', 'х': 'ch', 'ч': 'tsch', 'ш': 'sch', 'щ': 'schtsch',
'ю': 'ju', 'я': 'ja', 'ё': 'jo', 'ђ': 'dje', 'ѓ': 'gje', 'є': 'je', 'ѕ': 'dze',
'ї': 'ji', 'Ғ': 'Gh', 'ғ': 'gh', 'Ң': 'Ng', 'ң': 'ng', 'Ӕ': 'Ae', 'ӕ': 'ae',
/* Unicodeblock Alphabetische Präsentationsformen (U+FB00 bis U+FB4F) */
'ff': 'ff', 'fi': 'fi', 'fl': 'fl', 'ffi': 'ffi', 'ffl': 'ffl', 'ſt': 'st', 'st': 'st'
};
trSet1 += this.lang === 'de' ? "–" : "'-–";
trSet2 += this.lang === 'de' ? " " : "'--";
var trReplace = function( $0, $1, $2 ) {
return $1 + $2.replace( /&#?\w+;/g, ' ' ).replace( re,function( $0 ) {
/* Some characters are replaced with the empty charAt(-1) on purpose */
return trMap[$0] || trSet2.charAt( trSet1.indexOf( $0 ) );
} ).replace( /(\S) +(?= |$)/g, '$1' ).replace( /(\S)# */g, '$1 #' );
};
t = t.replace( /(\{\{(?:SORTIERUNG|DEFAULT\w*SORT\w*):)([^\n{}]+)(?=\}\})/g, trReplace );
t = t.replace( /(\[\[[CK]ategor[iy]e?:[^\n[\]|]+\|)([^\n[\]|]+)(?=\]\])/g, trReplace );
/* Groß-/Kleinschreibung wird seit dem 8. März 2011 ignoriert */
var title = escapeRE( mw.config.get( 'wgTitle' ) );
t = t.replace(
new RegExp( '\\{\\{(?:SORTIERUNG|DEFAULT\\w*SORT\\w*):\\s*' + title + '\\}\\}\\s*', 'gi' ),
''
);
var m = /\{\{(?:SORTIERUNG|DEFAULT\w*SORT\w*):([^\n{}]*)/.exec( t );
t = t.replace( new RegExp( '(\\[\\[[CK]ategor[iy]e?:[^[\\]|]*)\\|'
+ ( m && escapeRE( m[1] ) || title ) + '\\s*(?=\\]\\])', 'gi' ), '$1' );
return t.replace(
/(\[\[[CK]ategor[iy]e?:)([a-z])/g,
function( $0, $1, $2 ) {
return $1 + $2.toUpperCase();
}
);
},
cleanNewlines: function( t ) {
/* Mehrfache Leerzeilen auf einzelne reduzieren */
t = t.replace( this.isDisambiguation ? /\n{3,}(?=\n)/g : /\n{3,}/g, '\n\n' );
/* Keine Leerzeile vor einzeiligen <references /> */
t = t.replace( /(==\n)\n+(?=<references[^\n<>]*\/>\n\n)/gi, '$1' );
/* Leerzeile nach Einzelnachweisen */
t = t.replace(
/(<\/?references[^\n<>]*>)\s*(?=\{\{Navi(?:gationsleiste |Block)|\{\{SORTIERUNG:|\{\{DEFAULT\w*SORT\w*:|\[\[[CK]ategor[iy]e?:)/gi,
'$1\n\n'
);
/* Leerzeile zwischen Listen/bestimten Vorlagen und Kategorienblock */
t = t.replace(
/(\{\{(?:Begriffsklärung|Coordinate|Navi(?:gationsleiste |Block)|Normdaten)[^{}]*\}\}|^\* *[h[{][^\n]*)\s*(?=\{\{SORTIERUNG:|\{\{DEFAULT\w*SORT\w*:|\[\[[CK]ategor[iy]e?:)/gim,
'$1\n\n'
);
/* Split categories into separate lines (don't make this a look-ahead, it's slow!) */
t = t.replace( /([^\s>-]) *(\[\[[CK]ategor[iy]e?:[^\n[\]]*\]\])/gi, '$1\n$2' );
t = t.replace( /(\[\[[CK]ategor[iy]e?:[^\n[\]]*\]\]) *(?![\s<-]|$)/gi, '$1\n' );
t = t.replace(
/(\[\[[CK]ategor[iy]e?:[^\n[\]]*\]\]\n) *(?!\[\[[CK]ategor[iy]e?:|[\s<-]|$)/gi,
'$1\n'
);
/* Keine Leerzeile zwischen SORTIERUNG und Kategorie */
t = t.replace(
/(\{\{(?:SORTIERUNG|DEFAULT\w*SORT\w*):[^\n{}]*\}\})\s*(?=\[\[[CK]ategor[iy]e?:)/gi,
'$1\n'
);
/* Two empty lines in front of English stub templates */
return t.replace(
/(\[\[[CK]ategor[iy]e?:[^\n[\]]*\]\])\s*(?=\{\{[\w-]+-stub\b)/gi,
'$1\n\n\n'
);
},
cleanTemplates: function( t ) {
var de = this.lang === 'de';
t = t.replace( /\{\{\s*:?\s*(?:Vorlage|Template)\s*:\s*/gi, '{\{' );
/* Unterstriche aus allen Vorlagennamen entfernen */
t = t.replace(
/(?:^|[^{])\{\{([ \da-z\xC0-\u024F-]*_[ \w\xC0-\u024F-]*[|}])/gi,
function( $0, $1 ) {
return /^[A-Z_]+\}$/.test( $1 )
? $0
: $0.replace( /_+(?=[|}])/, '' ).replace( /[ _]+/g, ' ' ).replace( /\{ +/, '{' );
}
);
/* Drop empty templates */
t = t.replace(
/\{\{(?:Datum|e?dtsx?|Format(?:Date\d*|Num\w*|Zahl\w*)|Literatur|nts|Sort(?:Date\d*|Key\w*))[\s|]*\}\}(?!\})/gi,
''
);
/* Wirkungslose Leerzeilen aus Vorlagen entfernen */
while ( /^\{\{(?:<(?:br|file>)[^>]*>|[^<>{}])*\n\n+ *[|}]/m.test( t ) ) {
t = t.replace( /^(\{\{(?:<(?:br|file>)[^>]*>|[^<>{}])*\n)\n+(?= *[|}])/gm, '$1' );
}
/* Use the "Commons category" template instead of "Commons" with a category */
t = t.replace( /\{\{\s*Commons *(?:cat|category)?\s*\|\s*[CK]ategor[iy]e?\s*:\s*/gi,
de ? '{\{Commonscat|' : '{\{Commons category|' );
/ * Project-wide uniform notation for frequently used templates * /
t = t.replace(
/\{\{\s*(-|Br|Breakafterimages|Clr)[\s|]*(?=\}\})/gi,
de ? '{\ {Paragraph' : '{\ {$ 1'
);
t = t.replace(
/\{\{\s*(?:Absatz|(Clear)(?:[ |]*(?:all|both))?)[\s|]*(?=\}\})/gi,
de ? '{\{Absatz' : function( $0, $1 ) { return '{\{' + ( $1 || 'Clear' ); }
);
t = t.replace(
/ \ {\ {\ s * (?: Article about living Pe \ w * | BLP) [\ s |] * (? = \} \}) / gi ,
de ? '{\ {Article about living person' : '{\ {BLP'
);
t = t.replace(
/ \ {\ {\ s * (?: Receipts | Sources?) (?: * missing)? (?: [\ s |] * (? = \} \}) | * (? = \ s * \ | )) / gi ,
'{\ {Receipts are missing'
);
t = t.replace( /\{\{\s*(?:Benutzer(?:in)?|IP|User|Vandale)\s*\|\s*/gi,
de ? '{\ {User |' : '{\ {User |' );
t = t.replace( /\{\{\s*Commons(?:[\s|]*(?=\}\})|\s*(\|)\s*)/gi, '{\{Commons$1' );
t = t.replace( /\{\{\s*Commons *cat(?:egory)?(?:[\s|]*(?=\}\})|\s*(\|)\s*)/gi,
the ? '{\{Commonscat$1' : '{\{Commons category$1' );
t = t . replace ( / \ {\ {\ s * This * article \ s * \ | \ s * / gi , '{\ {This article |' );
t = t.replace( /\{\{\s*DOI\s*\|\s*/gi, '{\{DOI|' );
t = t.replace( /\{\{\s*dts(x?)\s*\|\s*/gi, '{\{dts$1|' );
t = t . replace ( / \ {\ {\ s * Done [\ s | ~] * \} \} / gi , '{\ {Done | ~~ \ ~~}}' );
t = t.replace(
/ \ {\ {\ s * (?: Fallen | Fall | Loss | Worsened | Decrease | Down | Loss) [\ s |] * (? = \} \}) / gi ,
de ? '{\ {Liked' : '{\ {decrease'
);
t = t.replace(
/ \ {\ {\ s * (?: Increased | Increase | Profit | Profit | Improved | Increase | Gain) [\ s |] * (? = \} \}) / gi ,
de ? '{\ {Increased' : '{\ {increase'
);
t = t.replace(
/ \ {\ {\ s * (?: Hauptartikel | Main | Main | Main * articles? | See * main) \ s * \ | \ s * / gi ,
de ? '{\ {Main article |' : '{\ {Main |'
);
t = t.replace( /\{\{\s*IMDb\s*\|\s*(\w+)\s*/gi, '{\{IMDb|$1' );
t = t.replace( /\{\{\s*(?:Internetquelle|Weblink)(?=\s*\|)/gi, '{\{Internetquelle' );
t = t.replace(
/ \ {\ {\ s * (?: Convert to * TeX * | TeX) (?: [\ s |] * (? = \} \}) | \ s * (\ |) \ s *) / gi ,
'{\ {Convert to TeX $ 1'
);
t = t.replace( /\{\{\s*lang\s*\|\s*/gi, '{\{lang|' );
t = t.replace( /\{\{\s*Link *([FG]A)\s*\|\s*/gi, '{\{Link $1|' );
t = t.replace( /\{\{\s*nts\s*\|\s*/gi, '{\{nts|' );
t = t . replace ( / \ {\ {\ s * (?: Nur * List | List) (?: [\ s |] * (? = \} \}) | * (? = \ s * \ |)) / gi , '{\ {Nur List' );
t = t.replace( /\{\{\s*Okina[\s|]*\}\}/gi, '\u02BB' );
t = t.replace( /\{\{\s*Rotten *Tomatoes\s*\|\s*/gi, '{\{Rotten Tomatoes|' );
t = t.replace(
/ \ {\ {\ s * S (?: iehe * also | ee [-] * also) \ s * \ | \ s * / gi ,
de ? '{\ {See also |' : '{\ {See also |'
);
t = t.replace(
/\{\{\s*(?:SortDate|Datesort)\d*\s*\|\s*/gi,
of ? '{\ {SortDate |' : '{\ {dts |'
);
t = t.replace(
/\{\{\s*SortKey(Name)?\s*\|\s*/gi,
de ? '{\{SortKey$1|' : function( $0, $1 ) { return $1 ? '{\{sortname|' : '{\{sort|'; }
);
t = t.replace(
/\{\{\s*(?:(?:Toter|Bad|Broken|Dead)[ -]*Link|404|Dead|DL)[\s|]*(?=[|}])/gi,
de ? '{\ {Dead link' : '{\ {dead link'
);
t = t.replace(
/ \ {\ {\ s * (u) nsign? (?: iert | ed)? \ s * \ | \ s * / gi ,
de ? '{\{$1nsigniert|' : '{\{$1nsigned|'
);
t = t.replace(
/\{\{\s*(?:Unverändert|Stabil|Steady|Nochange|Unchanged)[\s|]*(?=\}\})/gi,
de ? '{\{Unverändert' : '{\{steady'
);
t = t.replace(
/\{\{\s*(?:Vorlage|Tl?1?|Temp|Template(?: *link)?)\s*\|\s*/gi,
de ? '{\{Vorlage|' : '{\{tl|'
);
t = t.replace(
/\{\{\s*Wik(ibooks|inews|iquote|isource|ivoyage|tionary)[\s|]*(?=[|}])/gi,
'{\{Wik$1'
);
/* Lower case German language template names "enS" and so on */
t = t.replace(
/\{\{\s*([A-Za-z])([a-z]+S)(?:[\s|]*(?=\}\})|\s*(\|)\s*)/g,
function( $0, $1, $2, $3 ) {
return '{\{' + $1.toLowerCase() + $2 + ( $3 || '' );
}
);
t = t.replace(
/\{\{\s*IMDb *([a-z])(\w+)\s*\|\s*/gi,
function( $0, $1, $2 ) {
return '{\{IMDb ' + ( de ? $1.toUpperCase() : $1.toLowerCase() ) + $2 + '|';
}
);
t = t.replace( /\(\{\{\s*B\s*((?:\|[^\n{|}]*){2,4})\}\}\)/gi, '{\{Bibel$1}}' );
/* Remove navigation bar wrapper if it contains a single navigation bar only */
t = t.replace( /\{\{\s*NaviBlock\s*\|[\s|]*([^\n<>{|}]+)[\s|]*(?=\}\})/gi, '{\{$1' );
t = t.replace(
/\{\{\s*(NaviBlock[^<>{}]*?)(?:[\s|]-*)*(?=\}\})/gi,
function( $0, $1 ) {
return '{\{' + $1.replace( /\s*\|(?:-*[\s|])*/g, '\n|' ) + '\n';
}
);
t = t.replace( /\{\{\s*Normdaten\s*\|\s*PND\s*=\s*/g, '{\{Normdaten|TYP=p|GND=' );
t = t.replace( /\{\{\s*WBA\s*\|\s*/gi, '{\{Waybackarchiv|' );
t = t.replace(
/\[ *\{\{\s*Wayback\w*\s*\|\s*url\s*=\s*[^\s\d{|}]*(\d{1,14})\/(\w+:[^\s{|}]*)[^{}]*\}\}\s+([^[\]|]*)\]/gi,
'{\{Webarchiv | url=$2 | wayback=$1 | text=$3}}'
);
return t.replace( /(\|\s*(?:Breit|Läng)engrad\s*=\s*[\d.\/]*?)\/[\/0]*(?=[\n|}])/g, '$1' );
},
cleanRedundantTemplateParameters: function( t ) {
var parameters = window.redundantTemplateParameters || [
'(?:IMDb(?: Name| Titel)?|OFDb|Rotten Tomatoes)|2',
'Infobox (?:Arcade|Computer- und Videospiel|Musikalbum)|Titel',
'Infobox (?:Bahnhof|Band|Burg|Chemikalie|County \\(Vereinigte Staaten\\)|Eishockeyspieler|Flug(?:gesellschaft|hafen|zeug)|Fußballsaison|Gemeinde in '
+ '(?:Deutschland|Österreich)|Gemeindeverband in Deutschland|Hochschule|Landkreis|Medaillen|Militärische Einheit|Ort in '
+ '(?:den Niederlanden|den Vereinigten Staaten|der Türkei|Portugal)|Schiff|Schutzgebiet|Software|Stadion|Tennis(?:spieler|turnierjahrgang)|Unternehmen)|Name',
'Infobox (?:Berg|Burg|Fluss|Gebirgsgruppe|Insel|Ort|See|Stadt in Lateinamerika|Stausee|Verwaltungseinheit)|NAME',
'Infobox Brücke|BEZEICHNUNG',
'Infobox Fußballspieler|kurzname',
'Infobox Galaxie|Caption',
'Infobox Gemeinde in Italien|nomeComune',
'Infobox Gemeinde in Spanien|Gemeinde',
'Infobox Gemeinde in Spanien|nombre',
'Infobox Militärischer Konflikt|KONFLIKT',
'Infobox Nationalpark|title',
'Infobox Ort in der Schweiz|NAME_ORT',
'Infobox Ort in (?:Polen|Tschechien)|Ort',
'Infobox Ortsteil einer Gemeinde(?: in Deutschland)?|Ortsteil',
'Infobox PKW-Modell|Modell',
'Infobox (?:Publikation|Nationalpark)|titel',
'Infobox Schule|Schulname'
];
var title = '\\s*(?:' +
escapeRE( mw.config.get( 'wgTitle' ) ).replace( /\s+/g, '\\s+' ) +
'|\\{+\\w*\\}+)?\\s*';
for ( var i = parameters.length; i--; ) {
var m = /^(.+)\|(\d+)$/.exec( parameters[i] );
var re = m ? m[1] + '\\s*(?:\\|[^{|}]*){' + ( m[2] - 1 ) + '})\\|' + title + '(?=\\}\\})' :
parameters[i].replace( /[\s_]+/g, '[\\s_]+' ).replace( /\|(?=[^|]*$)/, '\\s*(?:\\|[^{}]*)?)\\|\\s*' ) +
'\\s*=' + title + '(?=\\||\\}\\})';
t = t.replace( new RegExp( '(\\{\\{\\s*' + re, 'g' ), '$1' );
}
return t;
},
cleanTemplatesByRules: function( t ) {
var rules = window.autoFormatTemplates || [{ name: 'Personendaten', format: '|_=_\n' }];
for ( var rule in rules ) {
if ( !rules[rule] || !rules[rule].name ) {
continue;
}
rule = rules[rule];
/* Format muss minimalst |_=_ lauten */
if ( !rule.format ) {
rule.format = '';
}
if ( rule.format.indexOf( '|' ) < 0 ) {
rule.format = '|' + rule.format;
}
if ( rule.format.indexOf( '_' ) < 0 ) {
rule.format = rule.format.replace( '|', '|_' );
}
if ( rule.format.indexOf( '=' ) < 0 ) {
rule.format += '=';
}
if ( rule.format.match( /_+/g ).length < 2 ) {
rule.format += '_';
}
var re = new RegExp( '\\{\\{[\\s\\xA0]*' + rule.name.replace( /[\s_]+/g, '[\\s_]+' )
+ '(\\s*<![^>|}]*>)?[\\s\\xA0]*\\|', 'gi' ),
m,
a = [];
while ( m = re.exec( t ) ) {
a.push( m );
}
for ( var i = a.length; i--; ) {
t = this.cleanTemplateByRule( t, rule, a[i].index + 2, a[i][1] );
}
}
return t;
},
cleanTemplateByRule: function( t, rule, start, comment ) {
var parameters ,
p = '',
pos = start - 1,
nesting = { '[': 0, '{': 0 };
while ( ++pos < t.length ) {
var c = t.charAt( pos );
if ( c === '[' || c === '{' ) {
nesting[c]++;
} else if ( c === ']' && nesting['[']-- <= 0 ) {
return t;
} else if ( c === '}' && nesting['{']-- <= 0 ) {
/* Parsing started after opening brackets, so stop before closing */
if ( t.charAt( pos + 1 ) !== '}' ) {
return t;
}
if ( parameters ) {
parameters.push( p );
}
break;
} else if ( c === '|' && nesting['['] <= 0 && nesting['{'] <= 0 ) {
if ( parameters ) {
parameters.push( p );
} else {
parameters = [];
}
p = '';
}
p += c;
}
if ( pos >= t.length || nesting['['] > 0 ) {
return t;
}
var m = /((_+)#*)( *)[^_]*((_+)#*)( *)/.exec( rule.format );
var kMax = m ? m[1].length : 0,
kMin = m ? m [ 2 ]. length : 0 ,
kFix = m ? m[3].length : 0,
vMax = m ? m[4].length : 0,
vMin = m && m[5].length > 1 ? m[5].length : 0,
vFix = m ? m[6].length : 0;
var result = rule.name + ( comment || '' ) + ( /\n$/.test( rule.format ) ? '\n' : '' );
for ( var f, i = 0; parameters && i < parameters.length; i++ ) {
p = parameters[i];
if ( !( m = /^\s*\|[\s\xA0]*(([^=|]*?) *)[\s\xA0]*=[\t \xA0]*([\s\S]*? *)\s*$/.exec( p ) ) ) {
/ * Discard empty unnamed parameters if followed by a named one * /
if ( !/^\s*\|-*\s*$/.test( p ) || ( parameters[i + 1] && parameters[i + 1].indexOf( '=' ) < 1 ) ) {
result += p;
}
continue;
}
p = rule.parameters && typeof rule.parameters[m[2]] !== 'undefined' ? rule.parameters[m[2]] : m[1];
/* Parameter verwerfen, die in den Regeln mit false oder ähnlich markiert sind */
if ( !p ) {
continue;
}
for ( f = 0; ( f < kFix || kMax && p.length > kMax ) && /\s$/.test( p ); f++ ) {
p = p.slice( 0, -1 );
}
for ( f = 0; ( f < vFix || vMax && m[3].length > vMax ) && /\s$/.test( m[3] ); f++ ) {
m[3] = m[3].slice( 0, -1 );
}
while ( p.length < kMin ) {
p += ' ';
}
while ( m[3].length < vMin ) {
m[3] += ' ';
}
result += rule.format.replace( /_+#*([^_]*)_+#*/, p.replace( /\$/g, '$$$$' ) + '$1' +
m[3].replace( /\$/g, '$$$$' ) );
}
if ( rule.format.indexOf( '\n' ) >= 0 ) {
if ( typeof rule.trim === 'undefined' || rule.trim ) {
result = result.replace( /[\t\r ]+$/gm, '' );
}
/ * Closing}} always on a separate line if there is any break in the game * /
result = result.replace( /\n+\s*$/, '' ) + '\n';
}
return t.slice( 0, start ) + result + t.slice( pos );
},
executeUserReplacements: function( t ) {
var from ,
replacements = window.autoFormatReplacements || {};
for ( from in replacements ) {
var to = replacements[from];
/ * If the replacements are not an associative object but a 2-dimensional array * /
if ( typeof to === 'object' && to.length > 1 ) {
from = to[0];
to = to [ 1 ];
}
/* If the search pattern is a regular expression already, 'function' is for older Chrome */
if ( typeof from === 'object' || typeof from === 'function' ) {
t = t.replace( from, to );
continue;
}
/ * To be on the safe side, do not allow empty search patterns * /
if ( /^\s*$/.test( from ) || typeof to !== 'string' ) {
continue;
}
/ * Mask most regex characters except character classes * /
from = from.replace( /([$()*+.?^{|}])/g, '\\$1' );
to = to.replace( /\$/g, '$$$$' );
/ * Note word boundaries * /
from = from.replace( /^(?=\w|\\d)/, '\\b' ).replace( /(\w)$/, '$1\\b' );
var a = [];
for ( var re = /\\[dw]/g, m, i = 1; m = re.exec( from ); a.push( m ) ) {
to = to.replace( m[0], '$' + i++ );
}
for ( i = a.length; i--; ) {
from = from.slice( 0, a[i].index ) + ( a[i][0] === '\\d' ? '(\\d+)' :
'([A-Za-z\xB5\xC0-\xD6\xD8-\xF6\xF8-\u024F]+)' ) +
from.slice( a[i].index + 2 );
}
/ * Use look-ahead if there is a placeholder in the search pattern and a replacement at the end * /
if ( /\+\)\\b$/.test( from ) && new RegExp( '\\$' + a.length + '$' ).test( to ) ) {
from = from.replace( /([^()]+)\)\\b$/, '?=$1\\b)' );
to = to.replace( /\$\d+$/, '' );
}
/* Allow optional spaces after dots in the search pattern */
from = from.replace( /\\\.(?=[(\w\xC0-\u024F])/g, '\\.(?:[ \xA0]| )*' );
t = t.replace( new RegExp( from, 'g' ), to );
}
return t;
},
backupNowikis: function( t ) {
this.nowikis = [];
var re = /<(nowiki|includeonly|syntaxhighlight|source|html|pre|code|graph|mapframe|score|templatedata|templatestyles|timeline|hiero|math)\b(?!\s*\/>)[\s\S]*?<\/\1\s*>/gi;
var m;
while ( m = re.exec( t ) ) {
delete m.input;
this.nowikis.push( m );
}
for ( var i = this.nowikis.length; i--; ) {
var placeholder = '<nowiki>' + i + '<\/nowiki>';
t = t.slice( 0, this.nowikis[i].index ) + placeholder +
t.slice( this.nowikis[i].index + this.nowikis[i][0].length );
if ( /^<\w+\s*>\s*<\/\w+\s*>$/.test( this.nowikis[i][0] ) ) {
this.nowikis[i][0] = /^no/i.test( this.nowikis[i][1] ) ? '<nowiki />' : '';
} else if ( /^s[oy]/i.test( this.nowikis[i][1] ) ) {
this.nowikis[i][0] = this.nowikis[i][0].replace( /^(<)\w+|\w+\s*(?=>$)/g, '$1syntaxhighlight' );
}
this.nowikis[i][1] = placeholder;
delete this.nowikis[i].index;
}
return t;
},
restoreNowikis: function( t ) {
for ( var i = 0, len = this.nowikis.length, index = 0; i < len; i++ ) {
index = t.indexOf( this.nowikis[i][1], index );
if ( index >= 0 ) {
t = t.slice( 0, index ) + this.nowikis[i][0] +
t.slice( index + this.nowikis[i][1].length );
}
}
delete this.nowikis;
return t;
},
backupFilenames: function( t ) {
/* Dateinamen retten incl. Vereinheitlichung als "Datei:" */
this.files = [];
var ns = mw.config.get( 'wgFormattedNamespaces' )[6],
ext = mw.config.get( 'wgFileExtensions' ) || ['png', 'gif', 'jpg', 'jpeg', 'tiff',
'tif', 'xcf', 'pdf', 'mid', 'ogg', 'ogv', 'svg', 'djvu', 'oga', 'flac', 'wav', 'webm'];
/* Match <gallery> lines, [[File:Thumbnails]] and template parameters with file names */
var m,
re = new RegExp(
'(^ *|\\[\\[:*(?:\\w+:)?)\\s*(' + ns + '|Bild|File|Image) *: *([^\\n[\\]|]*?) *(?=[\\n\\]|])|'
+ '(^ *|\\|\\n?(?:[^=[\\]{|}]*=)? *)\\s*([^\\n/[\\]{|}]*\\.(?:'
+ ext.join( '|' ) + '))(?= *[\\n|}])|'
+ '(\\|\\s*Commons(?:cat)? *= *)([^\\n/[\\]{|}]*)(?=[\\n|}])',
'gim'
);
while ( m = re.exec( t ) ) {
var o = ( m[6] || ( m[5] ? m[4] : m[1] ) ).length;
m.index += o;
m.l = m[0].length - o;
/* Multiple underscores and spaces never have a meaning in filenames */
m[3] = ( m[6] ? m[7] : m[5] || m[3] ).replace( /(?:[ _\xA0]|%20|%5F|%C2%A0| )+/gi, ' ' );
this.files.push( m );
}
var r = '',
p = 0;
for ( var i = 0; i < this.files.length; i++ ) {
this.files[i][0] = '<file>' + i + '<\/file>';
r += t.slice( p, this.files[i].index );
if ( this.files[i][2] ) {
/* Einheitliche Schreibweise und Leerzeichenausgleich */
r += ( this.localisation && !/\w:$/.test( this.files[i][1] ) ? ns : this.files[i][2] ) + ':';
}
r += this.files[i][0];
p = this.files[i].index + this.files[i].l;
}
return p ? r + t.slice( p ) : t;
},
restoreFilenames: function( t ) {
/* Gerettete Dateinamen wieder einsetzen */
var r = '',
p = 0;
for ( var index, i = 0; i < this.files.length; i++ ) {
if ( ( index = t.indexOf( this.files[i][0], p ) ) < 0 ) {
continue;
}
r += t.slice( p, index ) + this.files[i][3];
p = index + this.files[i][0].length;
delete this.files[i];
}
if ( p ) {
t = r + t.slice( p );
}
/* Fehlschläge nochmal versuchen, passiert bspw. bei umsortierten Galeriezeilen */
for ( i = this.files.length; i--; ) {
if ( this.files[i] ) {
t = t.replace( this.files[i][0], this.files[i][3] );
}
}
delete this.files;
return t;
}
};
var label = window.autoFormatterButtonLabel || 'Auto-Format';
mw.loader.using( 'user.options', function() {
if ( mw.user.options.get( 'usebetatoolbar' ) ) {
mw.loader.using( 'ext.wikiEditor', function() {
$( function() {
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', {
'section': 'main',
'group': 'format',
'tools': {
'autoFormatter': {
'label': label,
'type': 'button',
'icon': '//upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Broom_icon.svg/22px-Broom_icon.svg.png',
'action': {
'type': 'callback',
'execute': function() { return mw.libs.autoFormatter.click( this ); }
}
}
}
} );
} );
} );
} else if ( mw.user.options.get( 'showtoolbar' ) ) {
mw.loader.using( 'mediawiki.action.edit', function() {
mw.toolbar.addButton(
'//upload.wikimedia.org/wikipedia/commons/2/2e/Button_broom.png',
label,
'', '', '',
'mw-customeditbutton-autoFormatter'
);
$( function() {
$( '#mw-customeditbutton-autoFormatter' ).click( function() {
return mw.libs.autoFormatter.click( this );
} );
} );
} );
} else {
$( function() {
/ * If necessary as a link under the editing window * /
var b = $( '.editButtons' ),
c = b.children().last(),
a = $( '<a href="#">' + label + '<\/a>' );
( c.is( 'span' ) ? c : b ).append( $( '.mw-editButtons-pipe-separator', b ).first().clone() );
a.click( function() { return mw.libs.autoFormatter.click( this ); } );
b.append( a );
} );
}
} );
} )( jQuery, mediaWiki );
// </nowiki>