User:SD0001/parseAllTemplates.js

/** * Returns an array of objects representing all templates used in the given * wikitext. The object key-value pairs are the template |parameter=value pairs. * * Piped links, nested templates, nowiki tags and even HTML comments in parameter * values are adequately accounted for. * * Usage: Can be executed from the browser console or within another script. * * @param {string} wikitext Wikitext in which to search for the templates * * @returns {Object[]} The 0 key holds the name of the template. The remaining * key-value pairs are the template |parameter=value pairs. * * ISSUES: * 1. Very rare situations where, within a parameter value, there are nowiki tags *   inside a comment, or vice-versa, will cause problems. * * Found any other bug? Report at User talk:SD0001 or via email. * */

var parseAllTemplates = function (wikitext) {

var strReplaceAt = function(string, index, char) { return string.slice(0,index) + char + string.slice(index + 1); };

var result = []; var processTemplateText = function (startIdx, endIdx) { var text = wikitext.slice(startIdx, endIdx);

// swap out pipe in links with \1 control character text = text.replace(/(\[\^\*?)\|(.*?\]\])/g, '$1\1$2') // can have multiple pipes, let's do this a couple of times more .replace(/(\\])/g, '$1\1$2') .replace(/(\\])/g, '$1\1$2');

var chunks = text.split('|'); var res = {};

// name of the template as used in the wikitext is saved as 0th index of the object res[0] = chunks[0].trim;

var unnamedIdx = 1; for (var i=1; i < chunks.length; i++) { var indexOfEqualTo = chunks[i].indexOf('='); if (indexOfEqualTo === -1) { res[unnamedIdx++] = chunks[i].replace(/\1/g,'|').trim; } else { var key = chunks[i].slice(0, indexOfEqualTo).trim; if (key.indexOf('{{') !== -1) { res[unnamedIdx++] = chunks[i].replace(/\1/g,'|').trim; continue; }				var val = chunks[i].slice(indexOfEqualTo + 1).replace(/\1/g,'|').trim; // changed back '\1' in value to pipes res[key] = val; }		}		result.push(res); };

var n = wikitext.length; // number of unclosed braces var numUnclosed = 0;

// are we inside a comment or between nowiki tags? var inCommentOrNowiki = false;

var startIdx, endIdx; for (var i=0; i 2) { // swap out pipes in nested templates with \1 character wikitext = strReplaceAt(wikitext, i,'\1'); } else if (/^(|<\/nowiki ?>)/.test(wikitext.slice(i, i + 10))) { inCommentOrNowiki = false; i += 2; }		}

}

return result;

};

window.parseAllTemplates = parseAllTemplates;