Jump to content

User:Frietjes/indent.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
jQuery(document).ready(function($) {

var myContent = document.getElementsByName('wpTextbox1')[0];
// -------------------------------------------------------------------------------- //
//var mysummary = "Indent templates using [[:en:User:Frietjes/indent.js|indent]]";
var mysummary = "";
//var mysmallsummary = "Indent templates and remove small tags per [[MOS:SMALL]] using [[:en:User:Frietjes/indent.js|indent]]";
var mysmallsummary = "Remove small tags per [[MOS:SMALL]]";

if(typeof indenteditsummary == 'string') {mysummary = indenteditsummary;}
var linktext = "Indent";
// -------------------------------------------------------------------------------- //

if(mw.config.get('wgNamespaceNumber') != -1 && myContent && (mw.config.get('wgUserName') == 'MB' || mw.config.get('wgUserName') == 'Hhkohh' || mw.config.get('wgUserName') == 'Frietjes')) {
	mw.loader.using(['mediawiki.util']).done( function() {
	  var portletlink = mw.util.addPortletLink('p-tb', '#', linktext, 't-fdup');
	  $(portletlink).click(function(e) {
	    e.preventDefault();
	    wpIndentTemplates(0);
	  });
	});
}
// -------------------------------------------------------------------------------- //
function wpIndent(s)
{
	var alignflag = 0;
	// Mangle file/image link
	while(s.search(/(\[\[[\t _]*(?:image|file)[\t _]*:[^\[\]=]*)=/gi) >=0 ) {
		s = s.replace(/(\[\[[\t _]*(?:image|file)[\t _]*:[^\[\]=]*)=/gi, '$1<!-- FIX EQ MARKER -->');
	}
	// Mangle html tags
	while(s.search(/(<[\t \r\n]*[a-z]+[^<>]*)=/gi) >=0 ) {
		s = s.replace(/(<[\t \r\n]*[a-z]+[^<>]*)=/gi, '$1<!-- FIX EQ MARKER -->');
	}
	// Election box
	s = s.replace(/(\{\{[_ ]*[Ee]lection[_ ]*box[^{}\|\r\n]*[a-z])[\t ]*\|[\t ]*([\r\n][\t ]*\|)/g, '$1$2');
	// Mark some spacing
	s = s.replace(/(= ) (\|)/g, '$1<!-- SPACE MARKER -->$2');
	// Space before end of line
	while(s.search(/([^=])[\t ]+[\r\n]/g) >= 0) {
		s = s.replace(/([^=])[\t ]+([\r\n])/g, '$1$2');
	}
	// Unroll infobox
	if(s.search(/\{\{[_\t\r\n ]*(?:[Ii]nfobox|[Ss]peciesbox|[Ff]ootball[_ ]*box)/g) >=0 ) {
		s = s.replace(/([^\t \r\n])([\t ]*\|[\t ]*[^=\|\[\]\{\]\t ][^=\|\[\]\{\]]*=)/g, '$1\n$2');
		s = s.replace(/(=)([\t ]*\|[\t ]*[^=\|\[\]\{\]\t ][^=\|\[\]\{\]]*=)/g, '$1\n$2');
	}

	// Add some markers
	s = s.replace(/(\|[ ]*(?:[a-z_ ]+)[\t ]*=[^\r\n]*(?:[\r\n][\t ]*♦§[0-9][0-9]*§♦[\t ]*|)*)[\r\n]([\t ]*\|[\t ]*(?:pattern|left|right|body|shorts|socks))/g, '$1<!-- UNGAP MARKER -->\n\n$2');
	s = s.replace(/(\|[ ]*(?:league|cup[0-9]+)(?:[ ]*result|)[\t ]*=[^\r\n]*(?:[\r\n][\t ]*♦§[0-9]+§♦[\t ]*|))[\r\n]([\t ]*\|[ ]*(?:[a-z]+ attendance|[a-z]+ topscorer|league scorer))/g, '$1<!-- UNGAP MARKER -->\n\n$2');
	s = s.replace(/[\r\n]([\t ]*\|[ ]*prevseason[ ]*=)/g, '<!-- UNGAP MARKER -->\n\n$1');
	s = s.replace(/[\t ]*[\r\n][\t ]*([\r\n][\t ]*\|[\t ]*[A-Za-z0-9_\-\t ]*=)/g, '\n<!--\n GAP MARKER\n -->$1');
	s = s.replace(/([0-9])([\t ]*qualifiers?)([\t ]*=)/g, '$1$3<!-- FIX THIS $2 -->');
	// s = s.replace(/([A-Za-z])(_rank|_year)([\t ]*=)/g, '$1$3<!-- FIX THIS $2 -->');
	s = s.replace(/(resting[_ ]*place)([\t _]*coordinates)([\t ]*=)/g, '$1$3<!-- FIX THIS $2 -->');
	s = s.replace(/(conventional)([\t _]*long_name)([\t ]*=)/g, '$1$3<!-- FIX THIS $2 -->');
	s = s.replace(/(population_density)([\t _]*[a-z]+[0-9]*_[a-z0-9]+)([\t ]*=)/g, '$1$3<!-- FIX THIS $2 -->');
	s = s.replace(/[\r\n][\t ]*[\r\n]/g, '\n<!-- GAP MARKER -->\n');

	// uniform pre-pipe indentation
	var c0 = s.split(/[\r\n]\|/g).length;
	var c1 = s.split(/[\r\n][\t ]\|/g).length;
	var c2 = s.split(/[\r\n][\t ][\t ][\t ]*\|/g).length;
	if (c0 >= c1 && c0 >= c2) {
		s = s.replace(/([\r\n])[\s]*(\|)/g, '$1$2');
	} else if (c1 >= c0 && c1 >= c2 ) {
		s = s.replace(/([\r\n])[\s]*(\|)/g, '$1 $2');
	} else {
		s = s.replace(/([\r\n])[\s]*(\|)/g, '$1  $2');
	}
	// uniform post-pipe indentation
	c0 = s.split(/[\r\n][\t ]*\|[^=\|\[\]\{\]\t ]/g).length;
	c1 = s.split(/[\r\n][\t ]*\|[\t ][\t ]*[^=\|\[\]\{\]\t ]/g).length;
	if (c1 >= c0) {
		s = s.replace(/([\r\n][\t ]*\|)[\t ]*([^=\|\[\]\{\]\t ])/g, '$1 $2');
	} else {
		s = s.replace(/([\r\n][\t ]*\|)[\t ]*([^=\|\[\]\{\]\t ])/g, '$1$2');
	}
	// flip space and =
	s = s.replace(/([^=\|\[\]\{\]\t ][\t ]*)(=)([\t ][\t ][\t ]*)/g, '$1$3$2');
	if (s.split(/[^=\|\[\]\{\}][\s][\s][\s]*=/g).length > 2) {
		// Unalign
		s = s.replace(/[\s]*\|[\s]*[\r\n]([\s]*[^=\|\[\]\{\]]*?=)[\t ]*/g, '\n|$1 ');
		s = s.replace(/(\|[\s ]*[^=\|\[\]\{\]]*?)[\s]*=[\t ]*/g, '$1 = ');
		s = s.replace(/[\r\n]([\s]*[^\s\|])/g, '<!-- ♦§NEWLINE§♦ -->$1');
		s = s.replace(/<!--[\s]*<!-- ♦§NEWLINE§♦ -->[\s]*GAP MARKER[\s]*<!-- ♦§NEWLINE§♦ -->[\s]*-->/g, '<!--\n GAP MARKER\n -->');

		// Realign
		for(var i=40; i>1; i--) {
			var r1 = new RegExp('([\\r\\n][\\s]*\\|[^=\\|\\[\\]\\{\\}]{'+(i)+'}=[^\\r\\n]*[\\r\\n][\\s]*\\|[^=\\|\\[\\]\\{\\}]{0,'+(i-1)+'})(=)','g');
			while( s.search(r1) > -1) {
				s = s.replace(r1, '$1 $2');
			}
			var r2 = new RegExp('([\\r\\n][\\s]*\\|[^=\\|\\[\\]\\{\\}]{0,'+(i-1)+'})(=[^\\r\\n]*[\\r\\n][\\s]*\\|[^=\\|\\[\\]\\{\\}]{'+(i)+'}=)','g');
			while( s.search(r2) > -1) {
				s = s.replace(r2, '$1 $2');
			}
		}
	}
	s = s.replace(/<!-- ♦§NEWLINE§♦ -->/g, '\n');
	s = s.replace(/<!-- FIX EQ MARKER -->/g, '=');
	s = s.replace(/<!-- SPACE MARKER -->/g, ' ');
	s = s.replace(/<!--[\s]*GAP MARKER[\s]*-->/g, '');
	s = s.replace(/<!--[\s]*UNGAP MARKER[\s]*-->[\t ]*[\r\n][\t ]*[\r\n]*([\s]*)/g, '\n$1');
	s = s.replace(/([0-9A-Za-z]|resting[_ ]*place|conventional|density)[\t ]*(=)[\t ]*<!-- FIX THIS ([^<>]*) -->[\t ]*/g, '$1$3 $2 ');
	s = s.replace(/([^\|\{\t ])[\t ]*(\|)[\t ]*([\r\n])([^\*:;\{\|])/g, '$1$3$2$4');
	s = s.replace(/(\{\{cite[^{}\r\n]*)[\t ][\t ]+([^{}\r\n]*\}\})/g, '$1 $2');

	return s;
}
// -------------------------------------------------------------------------------- //
function wpUnsmall(s)
{
	var strlist = s.split(/(\{\{[\t \r\n]*(?:[Ii]nfobox|[Ff]ootball[_ ]*box)(?:[^{}]|\{\{(?:(?:[^{}]|\{\{(?:[^{}]|\{\{(?:[^{}]|\{\{[^{}]*\}\})*\}\})*\}\})*|\{\{[^{}]*\}\})*\}\})*\}\})/);
	for (i = 0; i < strlist.length; i++) {
		s = strlist[i];
		if(s.search(/\{\{[_\t\r\n ]*(?:[Ii]nfobox|[Ff]ootball[_ ]*box)/g) >=0 ) {
			var stmp = '';
			while( stmp != s ) {
				stmp = s;
				s = s.replace(/(\|[ ]*name[ ]*=[^\[\]\|\{\}]*sm)(all)/gi, '$1<!--MARKER DO NOT FIX MARKER-->$2');
			}
			s = s.replace(/<[\t ]*\/?[\t ]*small[^<>]*>/gi, '');
			s = s.replace(/\{\{small(?:er|)[\t ]*\|[\t ]*1[\t ]*=[\t ]*((?:[^{}]|\{\{(?:(?:[^{}]|\{\{(?:[^{}]|\{\{(?:[^{}]|\{\{[^{}]*\}\})*\}\})*\}\})*|\{\{[^{}]*\}\})*\}\})*?)[\t ]*\}\}/gi, '$1');
			s = s.replace(/\{\{small(?:er|)[\t ]*\|((?:[^{}]|\{\{(?:(?:[^{}]|\{\{(?:[^{}]|\{\{[^{}]*\}\})*\}\})*|\{\{[^{}]*\}\})*\}\})*)\}\}/gi, '$1');
			s = s.replace(/<!--[ ]*MARKER DO NOT FIX MARKER[ ]*-->/g, '');
			strlist[i] = s;
		}
	}
	return strlist.join('');
}
// -------------------------------------------------------------------------------- //
function wpIndentTemplates(debugflag)
{
	// Regular expression which matchs a template arg
	var argexp = new RegExp("(\\|[\\s]*[^=\\|\\[\\]\\{\\}]*=[\\s]*)", "gm");
	// 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 = []; 
	// Copy the contents of the text window so we can modify it without problems
	var mytxt = myContent.value;
	// Mark dollar signs which are problematic for regexp
	mytxt = mytxt.replace(/\$/g, '♦§DOLLAR§♦');

	// Remove comments
	loopcount = 0;
	while( (mytxt.search(/<!--.*?-->/g) >= 0) && (loopcount < 20) ) {
		// Split into chunks, isolating the comments
		var strlist = mytxt.split(/(<!--.*?-->)/);
		// Loop through the chunks, removing the comments templates
		for (i = 0; i < strlist.length; i++) {
			if( strlist[i].search(/^<!--.*?-->$/) >= 0 ) {
				tlist.push(strlist[i]);
				strlist[i] = '♦§' + (tlist.length - 1) + '§♦';
			}
		}
		// Join the chunks back together for the next iteration
		mytxt = strlist.join('');
		loopcount++;
	}

	var istart = tlist.length;
	// Now start unnesting the templates
	loopcount = 0;
	while( (mytxt.search(/(?:\{\{|\}\})/g) >= 0) && (loopcount < 20) ) {
		// Split into chunks, isolating the unnested templates
		var strlist = mytxt.split(/(\{\{[^\{\}]*\}\})/);
		// Loop through the chunks, removing the unnested templates
		for (i = 0; i < strlist.length; i++) {
			if( strlist[i].search(/^\{\{[^\{\}]*\}\}$/) >= 0 ) {
				tlist.push(strlist[i]);
				strlist[i] = '♦§' + (tlist.length - 1) + '§♦';
			}
		}
		// Join the chunks back together for the next iteration
		mytxt = strlist.join('');
		loopcount++;
	}

	// Now start indenting the list of unnested templates
	for(i=istart; i < tlist.length; ++i) {
		tlist[i] = wpIndent(tlist[i]);
	}
	// Reassemble the article
	while(mytxt.search(/♦§[0-9][0-9]*§♦/g) >= 0) {
		var n = mytxt.match(/♦§[0-9][0-9]*§♦/)[0].replace(/♦§([0-9]*)§♦/, '$1');
		mytxt = mytxt.replace(new RegExp('♦§' + n + '§♦', 'g'), tlist[Number(n)]);
	}

	mytxt = mytxt.replace(/[\t ]*[\r\n]*[\t ]*[\r\n][\t ]*(\{\{)[\t ]*((?:[Ii]nfobox|[Ss]peciesbox))/g, '\n$1$2');
    mytxt = mytxt.replace(/(\{\{[^{}=\|\r\n]*)([\r\n])(\|)[\t ]*(\{\{)/g, '$1$3$2$4');
	// Unmark dollar signs which are problematic for regexp
	mytxt = mytxt.replace(/♦§DOLLAR§♦/g, '\$');

    // Remove small tags (if opt-in)
	if(typeof removesmalltags == 'string' && removesmalltags == 'yes') {
		var oldtxt = mytxt;
		mytxt = wpUnsmall(mytxt);
		if (oldtxt != mytxt) {
			mysummary = mysmallsummary;
		}
	}
	
	myContent.value = mytxt;
	
	var editsummary = document.getElementsByName('wpSummary')[0];
    if(typeof editsummary == 'object') {
      if (editsummary.value.indexOf(mysummary) == -1) {
        if (editsummary.value.match(/[^\*\/\s][^\/\s]?\s*$/)) {
          editsummary.value += '; ' + mysummary;
        } else {
          editsummary.value += mysummary;
        }
      }
    }
}
// -------------------------------------------------------------------------------- //

});