User:WOSlinker/findparameterdups.js

var myContent = document.getElementsByName('wpTextbox1')[0];

if(mw.config.get('wgNamespaceNumber') != -1 && myContent) addOnloadHook(myscriptButton) function myscriptButton { mw.util.addPortletLink('p-tb','javascript:wpFindDuplicateArgs(0)', 'Find dups', 't-fdup'); }

// // function wpFindDuplicateArgs(debugflag) { // Flag used to determine if we have issued an alert popup var alertissued=0; // Internal for and while loop variables var i=0; var j=0; var loopcount=0; // Array used to hold the list of unnested templates var tlist = []; // Regular expression which matchs a template arg var argexp = new RegExp("\\|[\\s]*([^\\s=\\|\\[\\]\\{\\}][^=\\|\\[\\]\\{\\}]*[^\\s=\\|\\[\\]\\{\\}]|[^\\s=\\|\\[\\]\\{\\}])[\\s]*=", "gm"); // Copy the contents of the text window so we can modify it without problems var mytxt = myContent.value; // Remove some includeonly, noinclude, and onlyinclude tags mytxt = mytxt.replace(/<\/?[ ]*(?:includeonly|noinclude|onlyinclude)[ ]*>/gi, ''); // Remove PAGENAME, BASEPAGENAME, ... nested inside of triple braces mytxt = mytxt.replace(/\{\{\{[^\{\}]*\|[ ]*\{\{[A-Z]+\}\}\}\}\}/g, ''); // Remove some triple braces loopcount = 0; while((mytxt.search(/\{\{\{[^\{\}]*\}\}\}/g) >= 0) && (loopcount < 5) ) { mytxt = mytxt.replace(/\{\{\{[^\{\}]*\}\}\}/g, ''); loopcount++; } // Replace some bare braces with HTML equivalent mytxt = mytxt.replace(/([^\{])\{([^\{])/g, '$1&#123;$2'); mytxt = mytxt.replace(/([^\}])\}([^\}])/g, '$1&#125;$2'); // Remove newlines and tabs which confuse the regexp search mytxt = mytxt.replace(/[\s]/gm, ' '); // Compress whitespace mytxt = mytxt.replace(/[\s][\s]+/gm, ' '); // Remove some HTML comments mytxt = mytxt.replace(//gm, ''); // Modify some = inside of file/image/wikilinks which cause false positives loopcount = 0; while((mytxt.search(/\[\\}\})/); // Now start unnesting the templates  loopcount = 0;  while( (strlist.length > 0) && (loopcount < 10) ) {    for (i = strlist.length - 1; i >= 0; i--) {      if((i+2) < strlist.length && strlist[i] == ) {        tlist.push(strlist[i] + strlist[i+1] + strlist[i+2]);        strlist.splice(i,3);      } else if((i+3) < strlist.length && strlist[i] == ) {        if( strlist[i+1].search(/[\{\}]/g) < 0 && strlist[i+2].search(/[\{\}]/g) < 0 ) {           tlist.push(strlist[i] + strlist[i+1] + strlist[i+2] + strlist[i+3]);           strlist.splice(i,4);        }      } else if( strlist[i].search(/^[\s]*$/g) >= 0 ) {        strlist.splice(i,1);      } else if((i+1) < strlist.length && strlist[i].search(/[\{\}]/g) < 0 && strlist[i+1].search(/[\{\}]/g) < 0) {        strlist[i] = strlist[i] + strlist[i+1];        strlist.splice(i+1,1);      }    }    loopcount++;  }  // Now find duplicates in the list of unnested templates  for(i=0; i < tlist.length; ++i) {    // Add numbers for unnamed parameters    var unp=0;    while((tlist[i].search(/(\{\{(?:[^{}\[\|\[\^\[\*\]\])*?\|)((?:[^{}\[\]=\|]|\[\^\[\*\]\])*(?:\||\}\}))/) >= 0)          && (unp < 25)) {      unp++;      tlist[i] = tlist[i].replace(/(\{\{(?:[^{}\[\]]|\[\^\[\*\]\])*?\|)((?:[^{}\[\]=\|]|\[\^\[\*\]\])*(?:\||\}\}))/, '$1' + unp + '=$2'); }   // Split the template into an array of | arg = ... strings var p = tlist[i].match(argexp); if( p ) { for(j=0; j < p.length; ++j) { p[j] = p[j].replace(argexp, '$1'); }     p = p.sort; for(j=0; j < p.length - 1; ++j) { if( p[j] == p[j+1]) { alertissued = 1; alert(p[j] + ' in ' + tlist[i]); }     }    }  }  var editsummary = document.getElementsByName('wpSummary')[0]; if (alertissued && editsummary) { editsummary.value = 'Clean up duplicate template arguments'; } }