Benutzer:Umherirrender/monobook-tidy-up.js

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Internet Explorer/Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
  • Opera: Strg+F5
/*
 * @author Umherirrender - [[:de:User:Umherirrender]]
 * develop with and for Internet Explorer 11
 *
 * gegen Übernahmen spricht nichts, nur bitte nicht diese JavaScript-Seite direkt einbinden
 * ohne Gewähr und ohne Support
 *
 * Wiki-Quelltexte aufräumen, sogenannte „kosmetische Änderungen“
 *
 * Änderungen sollten immer mit "Änderungen zeigen" kontrolliert werden
 */

if ( mw.loader.getState( 'umherirrender.wikitexthelper' ) === null ) {
 //Import the mw.libs.WikiTextHelper module - for reference: [[Benutzer:Umherirrender/WikiTextHelper.js]]
 mw.loader.implement( 'umherirrender.wikitexthelper', [ '//de.wikipedia.org/w/index.php?title=Benutzer:Umherirrender/WikiTextHelper.js&action=raw&ctype=text/javascript'
 ] );
}

//<nowiki>

/*
 * räumt den Quelltext etwas auf
 */
function tidyup() {
 var textarea = document.getElementById( 'wpTextbox1' );
 //falls man nicht darf
 if( !textarea || textarea.getAttribute( 'readonly' ) ) {
  return;
 }
 //selbstschutz
 if ( mw.config.get( 'wgUserName' ) !== "Umherirrender" || mw.config.get( 'skin' ) !== "monobook" ) {
  return;
 }
 //zur Prüfung, ob nur einmal vorhanden
 var defaultsort = null;
 var displaytitle = null;

 //Array aller im Quelltext gesetzten Kategorien
 var cats = {};

 //original Inhalt
 var content = textarea.value;
 //index
 var indexstart = content.indexOf("\n");
 var indexend = content.indexOf("\n",indexstart+1);
 //erste Zeile
 var newcontent = mw.libs.WikiTextHelper.trimAtEnd(content.substring(0,indexstart))+"\n";
 //solange Zeilen vorhanden sind
 while (indexend !== -1) {
  //neuen Ausschneiden
  var line = content.substring(indexstart+1,indexend);
  //trimmen
  var trimbeginline = mw.libs.WikiTextHelper.trimAtBegin(line);
  var trimendline = mw.libs.WikiTextHelper.trimAtEnd(line);
  var trimline = mw.libs.WikiTextHelper.trim(line);
  //verarbeitung
  //veränderungen übernehmen
  trimline = mw.libs.WikiTextHelper.trimAtEnd( line );
  //bei parameterlisten keinen trim, überschriften wohl
  //bei tabellensyntax auch nicht
  if ((trimline.substring(trimline.length-1,trimline.length) === "=" &&
   line.substring(0,1) !== "=") ||
   (trimline.substring(trimline.length-2,trimline.length) === "||") ||
   ((trimline.substring(0,1) === "!" || trimline.substring(0,1) === "|") &&
    trimline.substring(trimline.length-1,trimline.length) === "|")
   )
  {
   newcontent = newcontent+line+"\n";
  }
  else
  {
   newcontent = newcontent+trimline+"\n";
  }
  //neue Zeile
  indexstart = content.indexOf("\n",indexend);
  indexend = content.indexOf("\n",indexstart+1);
 }
 //letzte Zeile
 newcontent = newcontent + mw.libs.WikiTextHelper.trimAtEnd(content.substring(indexstart+1));
 
 // </nowiki>
 // Alternativen:
 // * [[Benutzer:Codeispoetry/Kosmetika]]
 // * [[Benutzer:TMg/autoFormatter.js]]
 // * [[Benutzer:BLueFiSH.as/JS/markup.js]]
 // * [[Benutzer:PerfektesChaos/js/WikisyntaxTextMod/flow]]
 // MediaWiki interner Aufräumer:
 // * http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/Sanitizer.php?view=markup
 // <nowiki>
 newcontent = newcontent
 //Anfangsleerzeichen ersetzen, ein pre-Block am Anfang wäre ungewöhnlich
 .replace( /^\s+/, '' )
 //viele leerzeilen ersetzen
 .replace( /\n{3,}/g, '\n\n' )
 //Unnötige Angabe bei Einbindungen
 .replace( /\{\{[\s_]*:?[\s_]*(?:template|vorlage)[\s_]*:[\s_]*/gi, '{{' )
 //Aufzählungen, aber nicht Einrückungen
 .replace( /^([\*#][\*#:]*)\s*/mg, '$1 ' )
 //Überschriften
 .replace( /^(=+)[ \f\t\v]*([^\n]*[^ \f\t\v\n])[ \f\t\v]*\1/mg, '$1 $2 $1')
 //Weiterleitungen einheitlich /Leerzeichen nach # nicht erlaubt, korrigiert so aber Verschönerung Aufzählungszeichen
 .replace( /^\s*#\s*(?:redirect|weiterleitung)[\s=:]*\[\[/i, '#WEITERLEITUNG [[' )
 //Linktrenner
 .replace( /<\s*(?:nowiki|span|b|i|em)\s*\/\s*>/gi, '<nowiki />' )
 .replace( /\]\]([äöüßa-z]*)<\s*nowiki\s*>([^\s<]*\s*)<\s*\/\s*nowiki\s*>/gi, ']]$1<nowiki />$2' )
 //Prozent /nbsp bereits durch MediaWiki
 // nicht style="…%", style="…%; …", hexwerte, 100%ige
 .replace( /([^=\d:]\d+)(?:\s|&nbsp;|&thinsp;)*(%[^;"0-9A-Za-z])/g, '$1 $2' )
 //prettytable -> wikitable bei tabellen
 .replace( /^((?:\s*<!--[^>]*-->|:)*\s*\{\|.*)\bprettytable\b(.*)$/mg, '$1wikitable$2' )
 //extrahiert defaultsort
 .replace(
  /\s*\{\{\s*(?:SORTIERUNG|DEFAULTSORT|DEFAULTSORTKEY|DEFAULTCATEGORYSORT)\s*:([^\}]*)\}\}\s*(<!--[^>]*-->\s*)?/gi,
  function( textstelle, sortkey, trail ) {
   //normalize
   sortkey = mw.libs.WikiTextHelper.trim( normalizeSortkey( sortkey ) );
   if ( sortkey === '' || sortkey === mw.config.get( 'wgTitle' ) ) {
    //leeren sortkey und sortkey wie Seitennamen (Namensraum egal) entfernen
    return '';
   } else if ( defaultsort === null ) {
    //globalen sortkey setzen
    defaultsort = sortkey;
    //zusammenbauen
    var newDefaultsort = '\n\n{{SORTIERUNG:' + sortkey + '}}';
    if( trail ) {
     newDefaultsort += ' ' + mw.libs.WikiTextHelper.trim( trail );
    }
    newDefaultsort += '\n';
    return newDefaultsort;
   } else {
    //doppelten, aber ungleichen anzeigen
    if( sortkey !== defaultsort ) {
     showMessage( 'defaultsort-double', [ defaultsort, sortkey ] );
    }
    //entfernen
    return '';
   }
  }
 )
 //extrahiert displaytitle
 //TODO Checker einbauen, der die Validität des Parameters prüft
 .replace(
  /[ \f\t\v]*\{\{\s*(?:SEITENTITEL|DISPLAYTITLE)\s*:([^\}]*)\}\}/gi,
  function(textstelle, title) {
   //normalize
   title = mw.libs.WikiTextHelper.trim(title);
   if( title === '' || title === mw.config.get( 'wgPageName' ) ) {
    //leeren Seitentitel und unveränderten Seitentitel (Namensraum beachten) entfernen
    return '';
   } else if( displaytitle === null ) {
    //displaytitle global setzen
    displaytitle = title;
    //zusammenbauen
    return '{{SEITENTITEL:' + title + '}}';
   } else {
    //doppelten, aber ungleichen anzeigen
    if( title !== displaytitle ) {
     showMessage( 'displaytitle-double', [ displaytitle, title ] );
    }
    //entfernen
    return '';
   }
  }
 )
 //extrahiert Wikilinks und verarbeitet jeden
 // FIXME: anchor kann eckige Klammern enthalten
 .replace(
  /\[\[([^\[\|\]#]*)#?([^\[\|\]]*)\|?([^\[\]]*)\]\]([äöüßa-z]*)/g,
  function(textstelle, link, anchor, linktext, linktrail) {
   //Dateien und Kategorien hier ausschließen, extrabehandlung
   if (link.match(/^[\s_]*(?:datei|file|bild|image|kategorie|category)[\s_]*\:/i)) {
    return textstelle;
   }
   //Link
   link = normalizeLink(link);
   //Anker
   anchor = normalizeAnchor(anchor);
   //linktext: ersetze mehrere Leerzeichen durch ein Leerzeichen
   linktext = mw.libs.WikiTextHelper.trim( mw.libs.WikiTextHelper.fixTags( linktext.replace(/\s+/g,' ') ) );
   //gleichen Linktext entfernen, sofern kein Anker gegeben ist
   if (anchor === '' && mw.libs.WikiTextHelper.ucfirst(link) === mw.libs.WikiTextHelper.ucfirst(linktext)) {
    //damit die Groß- und Kleinschreibung erhalten bleibt
    link = linktext;
    linktext = '';
   }
   //erzeuge neuen Linktrail, wenn link am Anfang des linktextes vorhanden ist
   if ( linktext !== '' && anchor === ''
    && link === linktext.substring( 0, link.length )
    && linktext.substring( link.length ).match( /^[äöüßa-z]*$/ )
   ) {
    linktrail = linktext.substring( link.length ) + linktrail;
    linktext = '';
   }
   //zusammenbauen
   var newLink = '[[' + link;
   if (anchor !== '') {
    newLink += '#' + anchor;
   }
   if (linktext !== '') {
    newLink += '|' + linktext + linktrail;
   }
   newLink += ']]';
   if (linktext === '') {
    newLink += linktrail;
   }
   return newLink;
  }
 )
 //extrahiere kategorielinks und verarbeite jeden, wird bei den Wikilinks ausgeschlossen
 .replace(
  /\n?[ \f\t\v]*\[\[[\s_]*(?:kategorie|category)[\s_]*:([^\|\]]*)\|?([^\]]*)\]\]/gi,
  function(textstelle, cat, sortkey) {
   //normalize cat
   cat = normalizeLink(cat);
   //Anfang groß
   cat = mw.libs.WikiTextHelper.ucfirst(cat);
   //Doppelte Kategorie-Einträge erkennen
   if( cats[cat] ) {
    return ''; //doppelt
   }
   //Das Leerzeichen als einziges Sortierkriterium kommt bei Hauptartikeln vor
   if ( sortkey.match( /^\s+$/ ) ) {
    //damit auch nur eins vorhanden ist
    sortkey = ' ';
   } else {
    //normalize sortkey
    sortkey = normalizeSortkey( sortkey );
    //nur trimend, da Leerzeichen als Sortierkriterium gelten kann
    sortkey = mw.libs.WikiTextHelper.trimAtEnd(sortkey);
   }
   //falls cat dem sortkey entspricht, passiert beim vergessen der Pipe ([[Kategorie:cat|]])
   //falls sortkey dem globalem sortkey entspricht, kann dieser entfernt werden
   if (sortkey === cat || sortkey === defaultsort ) {
    sortkey = '';
   }
   //zusammenbauen
   var newCat = '\n[[Kategorie:' + cat;
   if (sortkey !== '' ) {
    newCat += '|' + sortkey;
   }
   newCat += ']]';
   cats[cat] = newCat; //speichere normalizierten Namen und normalisierten Wikitext
   return newCat;
  }
 )
 //extrahiere dateieinbindungen und verarbeite jeden, wird bei den Wikilinks ausgeschlossen
 // FIXME: eckige Klammern in Dateibeschreibung möglich (keine Wikilinks, sondern Weblinks etc)
 // TODO: Lokalisierungen einsetzen
 // TODO: Beschreibung ans Ende setzen
 // TODO: doppeltes rausschmeißen (right|thumb)
 .replace(
  //auch enthaltende Wikilinks beachten
  /\[\[[\s_]*(datei|file|bild|image)[\s_]*:([^\|\]]*)\|?((?:[^\[\]]|\[\[[^\[\]]*\]\])*)\]\]/gi,
  function(textstelle, ns, file, options) {
   //normalize
   file = normalizeLink(file);
   //Anfang groß
   file = mw.libs.WikiTextHelper.ucfirst( file );
   //zerlegen
   var optionsArray = mw.libs.WikiTextHelper.explodeParams( options );
   //Hinweis: keine weitere Verarbeitung - Nammensraum auch erstmal unverändert lassen
   //zusammenbauen
   var newFile = '[[' + mw.libs.WikiTextHelper.trim( mw.libs.WikiTextHelper.ucfirst( mw.libs.WikiTextHelper.lc( ns ) ) ) + ':' + file;
   for( var i = 0; i < optionsArray.length; i++ ) {
    //keine leeren anfügen
    optionsArray[i] = mw.libs.WikiTextHelper.trim( optionsArray[i]
     .replace( /[ \f\t\v]+/, ' ' )
     //entferne nur Zeilenumbrüche, die nicht nach <br/> folgen oder die nicht vor Aufzählungen oder Vorlagen stehen
     .replace( /([^(?:<\s*\/?\s*br\s*\/?\s*>)])\n+([^\s\{\#\*])/gi, '$1 $2' )
    );
    if ( optionsArray[i] !== '' ) {
     newFile += '|' + mw.libs.WikiTextHelper.fixTags( optionsArray[i] );
    }
   }
   return newFile + ']]';
  }
 )
 //extrahiert Personendaten
 .replace(
  //Personendaten und enthaltende Vorlagen (einfache Verschachtelung)
  /\s*\{\{[\s_]*:?[\s_]*(?:(?:Template|Vorlage)[\s_]*:[\s_]*)?Personendaten[\s_]*\|((?:[^\{\}]|\{\{[^\{\}]*\}\})*)\}\}\s*/gi,
  //nehme erst die komplette Einbindung und dann extrahiere die Parameter,
  //dadurch ist die Reihenfolge egal, die parameter können auch fehlen,
  //doppelte Parameter werden ignoriert, die reihenfolge wird angepasst
  function( textstelle, pd ) {
   //Parameter extrahieren
   var templateParams = mw.libs.WikiTextHelper.extractTemplateParams( pd );
   var name = templateParams.NAME;
   var alternativnamen = templateParams.ALTERNATIVNAMEN;
   var kurzbeschreibung = templateParams.KURZBESCHREIBUNG;
   var geburtsdatum = templateParams.GEBURTSDATUM;
   var geburtsort = templateParams.GEBURTSORT;
   var sterbedatum = templateParams.STERBEDATUM;
   var sterbeort = templateParams.STERBEORT;
   //entlinken
   if( geburtsdatum ) {
    geburtsdatum = geburtsdatum.replace( /\[\[([^\|\]]*)\|?[^\]]*\]\]/g, '$1' );
    //remove empty wikilink
    geburtsdatum = geburtsdatum.replace( /\[\[[\s_]*\]\]/, '' );
   }
   if( geburtsort ) {
    //remove empty wikilink
    geburtsort = geburtsort.replace( /\[\[[\s_]*\]\]/, '' );
   }
   if( sterbedatum ) {
    sterbedatum = sterbedatum.replace( /\[\[([^\|\]]*)\|?[^\]]*\]\]/g, '$1' );
    //remove empty wikilink
    sterbedatum = sterbedatum.replace( /\[\[[\s_]*\]\]/, '' );
   }
   if( sterbeort ) {
    //remove empty wikilink
    sterbeort = sterbeort.replace( /\[\[[\s_]*\]\]/, '' );
   }
   //zusammenbauen, dabei unnötige Leerzeichen entfernen
   var newPd = '\n\n{{Personendaten';
   newPd += '\n|NAME=' + ( name ? name.replace( /\s+/g, ' ' ) : '' );
   newPd += '\n|ALTERNATIVNAMEN=' + ( alternativnamen ? alternativnamen.replace( /\s+/g, ' ' ) : '' );
   newPd += '\n|KURZBESCHREIBUNG=' + ( kurzbeschreibung ? kurzbeschreibung.replace( /\s+/g, ' ' ) : '' );
   newPd += '\n|GEBURTSDATUM=' + ( geburtsdatum ? geburtsdatum.replace( /\s+/g, ' ' ) : '' );
   newPd += '\n|GEBURTSORT=' + ( geburtsort ? geburtsort.replace( /\s+/g, ' ' ) : '' );
   newPd += '\n|STERBEDATUM=' + ( sterbedatum ? sterbedatum.replace( /\s+/g, ' '  ) : '' );
   newPd += '\n|STERBEORT=' + ( sterbeort ? sterbeort.replace( /\s+/g, ' ' ) : '' );
   newPd += '\n}}\n\n';
   return newPd;
  }
 )
 //extrahiert Vorlage:NaviBlock
 .replace(
  //NaviBlock und enthaltende Vorlagen (einfache Verschachtelung)
  /\s*\{\{[\s_]*:?[\s_]*(?:(?:Template|Vorlage)[\s_]*:[\s_]*)?NaviBlock[\s_]*\|((?:[^\{\}]|\{\{[^\{\}]*\}\})*)\}\}\s*/gi,
  function( textstelle, pd ) {
   //Parameter extrahieren
   var templateParams = mw.libs.WikiTextHelper.extractTemplateParams( pd );
   //zusammenbauen, dabei unnötige Leerzeichen entfernen
   var newNaviBlock = '\n\n{{NaviBlock';
   for( var param in templateParams ) {
    var innerNavi = mw.libs.WikiTextHelper.normalizeWhitespaces( templateParams[param] );
    if( innerNavi !== '' ) {
     //entferne Namensraum
     innerNavi = innerNavi.replace( /^[\s_]*(?:template|vorlage)[\s_]*:[\s_]*/i, '' );
     //Anfang groß
     innerNavi = mw.libs.WikiTextHelper.ucfirst( innerNavi );
     newNaviBlock += '\n|' + innerNavi;
    }
   }
   newNaviBlock += '\n}}\n\n';
   return newNaviBlock;
  }
 )
 //extrahiert ref-tags
 .replace(
  /<ref\b\s*([^<>\/]*)\s*>((?:[^<>]|<[^<>(?:ref)]*>)*)<\/ref\s*>/gi,
  function( textstelle, zusatz, inhalt ) {
   inhalt = mw.libs.WikiTextHelper.trim( inhalt );
   zusatz = mw.libs.WikiTextHelper.fixTagAttributes( zusatz, 'ref' );
   //ohne Inhalt
   if( inhalt === '' ) {
    //leere entfernen
    if( zusatz === '' ) {
     return '';
    } else {
     //leere wiederholte refs umwandeln
     return '<ref' + zusatz + ' />';
    }
   }
   return '<ref' + zusatz + '>' + inhalt + '</ref>';
  }
 )
 //extrahiert wiederholte ref-tags
 .replace(
  /<ref\b(?:\/|([^<>\/]*(?:<[^<>\/]*>[^<>\/]*)*)\/)\s*>/gi,
  function( textstelle, _zusatz ) {
   //ein <ref/> matched nicht richtig
   var zusatz = mw.libs.WikiTextHelper.trim( _zusatz ? _zusatz : '' );
   //leere entfernen
   if( zusatz === '' ) {
    return '';
   }
   //zusammenbauen
   return '<ref' + mw.libs.WikiTextHelper.fixTagAttributes( zusatz, 'ref' ) + ' />';
  }
 )
 //extrahiert references-tags
 .replace(
  /\n?[ \f\t\v]*<references\b([^\/]*)\/\s*>/gi,
  function( textstelle, zusatz ) {
   zusatz = mw.libs.WikiTextHelper.fixTagAttributes( zusatz, 'references' );
   return '\n<references' + zusatz + ' />';
  }
 )
 .replace(
  /\n?[ \f\t\v]*<references\b\s*([^<>\/]*)\s*>((?:[^<>]|<[^<>]*>)*)<\/?references\s*\/?\s*>/gi,
  function( textstelle, zusatz, inhalt ) {
   zusatz = mw.libs.WikiTextHelper.fixTagAttributes( zusatz, 'references' );
   inhalt = mw.libs.WikiTextHelper.trim( inhalt );
   //zusammenbauen
   var newReferences = '\n<references' + zusatz;
   //Ein leeres references vereinfachen
   if( inhalt === '' ) {
    newReferences += ' />';
    return newReferences;
   }
   newReferences += '>\n';
   newReferences += inhalt;
   newReferences += '\n</references>';
   return newReferences;
  }
 )
 //handle gallery-tags
 .replace(
  /<\s*gallery([^>]*)>([\s\S]*?)<\s*\/\s*gallery\s*>/gi,
  function( textstelle, attributes, content ) {
   attributes = mw.libs.WikiTextHelper.fixTagAttributes( attributes, 'gallery' );
   content = mw.libs.WikiTextHelper.trim( content );
   var newText = '';
   var lines = mw.libs.WikiTextHelper.explodeLines( content );
   for( var i = 0; i < lines.length; i++ ) {
    var line = lines[i];
    line = mw.libs.WikiTextHelper.trim( line );
    if( line === '' ) {
     //leave emtpy lines, for readablity
     newText += '\n';
     continue;
    }
    var param = mw.libs.WikiTextHelper.explodeParams( line );
    if( !param ) {
     continue; //skip invalid line, should not happen
    }
    var match = param[0].match( /^[\s_]*(?:(datei|file|bild|image)[\s_]*:)?(.+)$/i );
    var ns = match[1];
    if( !ns ) {
     ns = '';
    }
    var file = match[2];
    //normalize
    file = normalizeLink( file );
    //Anfang groß
    file = mw.libs.WikiTextHelper.ucfirst( file );
    var label = '';
    for( var j = 1; j < param.length; j++ ) { //skip the first param (already used before)
     if( label !== '' ) {
      label += '|';
     }
     label += param[j];
    }
    label = mw.libs.WikiTextHelper.trim( label );
    label = mw.libs.WikiTextHelper.fixTags( label );
    //zusammenbauen der Zeile
    newText += '\n';
    if( ns !== '' ) {
     newText += mw.libs.WikiTextHelper.ucfirst( mw.libs.WikiTextHelper.lc( ns ) ) + ':';
    }
    newText += file;
    if( label !== '' ) {
     newText += '|' + label;
    }
   }
   if( newText === '' ) {
    return ''; //remove empty gallery
   }
   return '<gallery' + attributes + '>' + newText + '\n</gallery>';
  }
 )
 //Endleerzeichen ersetzen
 .replace( /\s*$/, '\n' );

 //Tabellen formatieren
 newcontent = mw.libs.WikiTextHelper.fixTables( newcontent );

 //HTML-Entitäten ersetzen
 newcontent = mw.libs.WikiTextHelper.decodeCharReferences( newcontent );

 //Reihenfolge der Kategorien bei Personenartikel
 if( cats && cats.length !== 0 ) {
  // holder
  var born = null;
  var death = null;
  var gender = null;
  var lastCat = null;
  // zuordnen
  for( var cat in cats ) {
   var matches = cat.match( /^(Mann|Frau|Intersexueller|Geschlecht[\s_]+unbekannt|(?:Geboren|Gestorben)[\s_]+[^\]]*)$/i );
   if( matches ) {
    if( matches[1].match( /^Geboren/i ) ) {
     born = cats[cat];
    } else if( matches[1].match( /^Gestorben/i ) ) {
     death = cats[cat];
    } else {
     gender = cats[cat];
    }
   } else {
    // die letzte Kat, danach wird alles eingefügt
    lastCat = cats[cat];
   }
  }
  var lastCatIndexEnd = -1;
  if( lastCat === null || newcontent.indexOf( lastCat ) === -1 ) {
   //Es gibt nur born, death und gender cats oder die letzte Kategorie konnte nicht gefunden werden
   // die erste Kategorie holen
   for( var cat in cats ) {
    lastCat = cats[cat];
    break;
   }
   //Position dieser Kategorie merken, dient als Einfügepunkt
   lastCatIndexEnd = newcontent.indexOf( lastCat );
  }
  var addText = ''; //der einzufügende Text
  if( born ) {
   addText += born;
   var bornIndex = newcontent.indexOf( born );
   //entfernen
   newcontent = newcontent.substring( 0, bornIndex ) + newcontent.substring( bornIndex + born.length );
  }
  if( death ) {
   addText += death;
   var deathIndex = newcontent.indexOf( death );
   //entfernen
   newcontent = newcontent.substring( 0, deathIndex ) + newcontent.substring( deathIndex + death.length );
  }
  if( gender ) {
   addText += gender;
   var genderIndex = newcontent.indexOf( gender );
   //entfernen
   newcontent = newcontent.substring( 0, genderIndex ) + newcontent.substring( genderIndex + gender.length );
  }
  if( addText !== '' ) {
   if( lastCatIndexEnd === -1 ) {
    //Einfügeposition ermitteln, erst hier, weil vorher noch Text weggeschnitten werden könnte
    lastCatIndexEnd = newcontent.indexOf( lastCat ) + lastCat.length;
   }
   //dazwischen setzen
   newcontent = newcontent.substring( 0, lastCatIndexEnd ) + addText + newcontent.substring( lastCatIndexEnd );
  }
 }
 newcontent = mw.libs.WikiTextHelper.fixTags( newcontent );

 //falls etwas geändert wurde
 if ( mw.libs.WikiTextHelper.trimAtEnd( content ) !== mw.libs.WikiTextHelper.trimAtEnd( newcontent ) ) {
  //waren wir schonmal hier?
  var hinweis = $( '#cosmetic-changes' );
  //falls nicht einen Hinweis anzeigen
  if ( !hinweis.length ) {
   showMessage( 'cosmetic-changes' );
  } else {
  //für jedes weitere Mal ein Plus anhängen
   hinweis.text( hinweis.text() + '+' );
  }
  //Zusammenfassungszeile bestücken
  var summary = $( '#wpSummary' );
  if ( summary.length && !hinweis.length ) {
   var summaryVal = summary.val();
   var index = summaryVal.indexOf( ' |' );
   if ( index === -1 ) {
    summary.val( summaryVal + ' | kosmetische Änderungen' );
   }
  }
  //text zurückschreiben
  textarea.value = newcontent;
 }
}

/* normaliziert Links: UTF-8-decode, doppelte Leerzeichen und Unterstriche entfernen
 */
function normalizeLink(link) {
 //UTF-8-decode
 try {
  link = decodeURIComponent( link.replace( /%([0-9A-Fa-f]{2})/g, function(textstelle, dollar1) {
   var hex = parseInt(dollar1, 16);
   return validateCharCode( hex ) ? escape( String.fromCharCode( hex ) ) : textstelle;
  } ) );
 } catch (e) { /*ignore*/ }
 //Anfangsbuchstaben hier nicht groß, da es nicht in allen Situationen erwünscht ist
 return mw.libs.WikiTextHelper.normalizeWhitespaces( link );
}

/* normaliziert Anker: UTF-8-decode, doppelte Leerzeichen und Unterstriche entfernen
 * MediaWiki decodiert Anker mit Punkten anstatt Prozentzeichen
 */
function normalizeAnchor(anchor) {
 //UTF-8-decode
 try {
  anchor = decodeURIComponent( anchor.replace( /[.%]([0-9A-Fa-f]{2})/g, function(textstelle, dollar1) {
   var hex = parseInt(dollar1, 16);
   return validateCharCode( hex ) ? escape( String.fromCharCode( hex ) ) : textstelle;
  } ) );
 } catch (e) { /*ignore*/ }
 //Anfangsbuchstaben hier nicht groß, da es nicht in allen Situationen erwünscht ist
 return mw.libs.WikiTextHelper.normalizeWhitespaces( anchor );
}

/* normaliziert den Sortkey: aktuell noch nichts
 */
function normalizeSortkey( sortkey ) {
 //hier wäre auch Platz um die Zeichen alle umzuwandeln … [[Hilfe:Sortierung]]
 // hier kein trim, da Leerzeichen auch Sortierkriterium sein kann
 return sortkey.replace(/\s+/g,' ' );
}

/* löst den key auf und setzt den Text in den Header
 */
function showMessage( key, param ) {
 var firstHeading = document.getElementById( 'firstHeading' );
 if ( firstHeading ) {
  var message = messages[key];
  // es gibt eine Nachricht
  if( message ) {
   //ein Parameter wird benötigt
   if( !(param instanceof Array) ) {
    param = new Array( param );
   }
   //Parameter ersetzen
   for( var i = 0; i < param.length; i++ ) {
    message = message.replace(new RegExp( '\\{' + i + '\\}' ), param[i] );
   }
   var span = document.createElement( 'span' );
   span.style.fontSize = '75%';
   span.style.color = 'red';
   span.style.fontFamily = 'Courier New';
   span.id = key;
   span.appendChild( document.createTextNode( ' ' + message ) );
   firstHeading.appendChild( span );
  }
 }
}

/* definiert Standardtexte
 * {0} definiert einen Parameter
 */
var messages = {
 'defaultsort-double': '(doppelter defaultsort >{0}|{1}<)',
 'displaytitle-double': '(doppelter displaytitle >{0}|{1}<)',
 'cosmetic-changes': '(kosmetische Änderungen durchgeführt)'
};

/* prüft, welche CharCodes ersetzt werden sollen
 */
function validateCharCode(charCode) {
 return charCode         /* definiert */
     && (charCode > 127
     || charCode === 40   /* ( */
     || charCode === 41   /* ) */
     || charCode === 47   /* / */
     || charCode === 58   /* : */
     || charCode === 44   /* , */
     ) &&
     !( charCode === 160  /* nsbp; */
     || charCode === 8194 /* emsp */
     || charCode === 8195 /* ensp */
     || charCode === 8201 /* thinsp */
     );
}

/*
 * erfragt ein Regex und zu ersetzen Text vom Benutzer und führt ein replace durch
 */
function tidyupReplace() {
 var textarea = document.getElementById( 'wpTextbox1' );
 //falls man nicht darf
 if( !textarea || textarea.getAttribute( 'readonly' ) ) {
  return;
 }
 //selbstschutz
 if ( mw.config.get( 'wgUserName' ) !== "Umherirrender" || mw.config.get( 'skin' ) !== "monobook" ) {
  return;
 }
 //Regex eingeben
 var regex = prompt( 'Regex:', '' );
 if( regex && regex !== '' ) {
  //Regex prüfen
  var regexObj;
  try {
   regexObj = new RegExp( regex, 'g' );
  } catch(e) {
   alert('Fehler mit Regex: ' + e.message );
   return; //nicht weiter machen
  }
  //Text eingeben
  var text = prompt( regexObj + ' ersetzen mit ','' );
  if ( text ) {
   var old = textarea.value.match( regexObj );
   if( old ) {
    textarea.value = textarea.value.replace( regexObj, text );
    alert( 'Der Regex ' + regex + ' konnte ' + old.length + ' mal durch ' + text + ' ersetzt werden.');
   } else {
    alert( 'Der Regex ' + regex + ' ergab keine Treffer.' );
   }
  }
 }
}

mw.loader.using( [ 'umherirrender.wikitexthelper' ], function() {
 if ( $.isFunction( window[window.callbackMonobookTidyUpJs] ) ) {
  $( window[window.callbackMonobookTidyUpJs] );
 }
} );

/** Ablage **
 *
 * Regex zur Wikilink-Entfernung
 .replace( /\[\[(?:[^\|\]]*\|([^\]]*)|([^\|\]]*))\]\]/g, '$1$2' )
 *
 ** Ablage **

* siehe FIXME innerhalb dieses js
* TODOs im js enthalten
 */
//</nowiki> __NOINDEX__