User:Waldyrious/formatcitations.js

function formatCitations(vertical) {

var txt = document.editform.wpTextbox1;

// Fill an array with one entry per each recognized citation template

// Note: the regex should be changed to allow parameter values that are themselves templates,

// e.g. {{cite book | author = John Doe | title = The Book | year = 1234 | ref = {{sfnRef|Doe (1234)}} | isbn = 0-12345-678-9 }}

// I got as far as this: /(\{\{[Cc]it(?:ation|(?:ar|e) [a-z ]+)\s*)(\|\s*[^=]+=\s*(?:\{\{)?.+(?:\}\})?\s*)+(\}\})/g

var originalTemplates = txt.value.match(/\{\{[Cc]it(ation|(ar|e) [a-z ]+) *\n? *\|[^{}]+\}\}/g);

// Duplicate the array, for editing. We need to keep the original strings for the replacement step

var tweakedTemplates = originalTemplates.slice();

for(var i = 0; i < originalTemplates.length; i++) {

if(vertical) {

// Fill an array with one entry per each parameter for this citation template

var originalParams = originalTemplates[i].match(/ *\n? *\| *\n? *[^ =]+ *= */g);

// Create array to be filled with the cleaned-up parameters.

// We need to keep the original strings for the replacement step.

var tweakedParams = [];

var maxWidth = 0;

for(var j = 0; j < originalParams.length; j++){

// Get rid of the delimiters and spaces, keep only the parameter string

tweakedParams[j] = originalParams[j].match(/[a-z1-9_-]+/)[0];

// Calculate the length of the longest parameter

maxWidth = (tweakedParams[j].length>maxWidth) ? tweakedParams[j].length : maxWidth;

}

maxWidth++; // We need an extra one because Array(n).join(' ') will produce a string with n-1 chars

// Generate the aligned versions of the parameters (with padding before the equal signs)

for(var k = 0; k < originalParams.length; k++) {

var numSpaces = maxWidth - tweakedParams[k].length;

var alignedParam = "\n | " + tweakedParams[k] + new Array(numSpaces).join(" ") + " = ";

// Replace the original parameters with the tweaked ones

tweakedTemplates[i] = tweakedTemplates[i].replace (originalParams[k], alignedParam);

}

// Also align the }}

tweakedTemplates[i] = tweakedTemplates[i].replace(/ *\n? *\}\}/g,"\n }}");

// Replace the original templates with the tweaked versions

txt.value = txt.value.replace(originalTemplates[i], tweakedTemplates[i]);

} else {

// Remove newlines

tweakedTemplates[i] = tweakedTemplates[i].replace(/\n/g, "");

// Normalize spaces around the pipes and equal signs

tweakedTemplates[i] = tweakedTemplates[i].replace(/ *\| *([a-z1-9_-]+) *= */g," |$1 = ");

// Remove potencial extra spaces before template ends

tweakedTemplates[i] = tweakedTemplates[i].replace(/ *\}\}$/," }}");

txt.value = txt.value.replace(originalTemplates[i], tweakedTemplates[i]);

}

}

// Update the edit summary

var sum = document.editform.wpSummary;

var summary = vertical ? "convert citation templates to vertical format, for readability" : "harmonize whitespace in citation templates" ;

summary += " (using Regex citation formatter)";

if (sum.value.indexOf(summary) == -1) {

if (sum.value.match(/[^\*\/\s][^\/\s]?\s*$/)) {

sum.value += "; ";

}

sum.value += summary;

}

if(!vertical) { document.editform.wpMinoredit.checked = true; }

}

$(function () {

if(document.forms.editform) {

mw.loader.using( ['mediawiki.util'], function() {

mw.util.addPortletLink('p-cactions', 'javascript:formatCitations(false)', '{{}}', 'ca-formatcitations', 'Format citations: add whitespace', '-', '');

mw.util.addPortletLink('p-cactions', 'javascript:formatCitations(true)', '{{}}+', 'ca-formatcitations-vertical', 'Formats citations vertically', '-', '');

});

}

});