User:Frietjes/indent.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:Frietjes/indent. |
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;
}
}
}
}
// -------------------------------------------------------------------------------- //
});