Jump to content

User:RossPatterson/Reorganize References.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.
/* <nowiki> */

/* Add an editting tab called "ReorgRef" to convert reorganize references */

/*
Simply add ''importScript("User:RossPatterson/Reorganize References.js");'' to your own monobook.js and clear the cache before it will work.
*/

/* Version 1.0 */
var RossPatterson_Reorganize_References = function () {
	var _private = {
		generatedNameIndex: 0
		,
		debugLevel: 0
		,

		debug: function(text) {
			if (_private.debugLevel > 0) {
				alert(text);
			}
		}
		,
		reorgRefs: function (articleText, refs) {
			_private.debug("reorgRefs: start");
			// Match "<ref>...</ref>", "<ref name=x>...</ref>", etc., but not "<ref name=x/>"
			var refPat = new RegExp("(<ref[^/>]*>[^<]*</ref\\s*>)", "gi");
			var refElements = (articleText.match(refPat));
			_private.debug("reorgRefs: Found " + refElements.length + " references");
			for (var i=0; i < refElements.length; i++) {
				_private.debug("reorgRefs: i=" + i);
				_private.debug("reorgRefs: refElements[" + i + "]=" + refElements[i]);
				var name = '';
				var originalRef=refElements[i];
				var refParms=refElements[i].substr(4, refElements[i].indexOf('>') - 4);	// "<ref xxxx>yyy" -> " xxxx"
				if (refParms != "" && refParms.search(new RegExp("\\s+name\\s*=", "i")) != -1) {
					// Extract the existing "name=x"
					name = refParms.replace(new RegExp("\\s+name\\s*=\\s*([^\\s]*)", "i"), '$1');
					_private.debug("reorgRefs: found name=" + name);
				} else {
					_private.debug("reorgRefs: no name=");
					// No "name=x", add one
					name = _private.chooseUniqueName(refElements[i], articleText);
					refElements[i] = "<ref name=" + name + refElements[i].substr(4);  // "<ref xxxx>yyy" -> " <ref name=zzz xxxx>yyy"
					_private.debug("reorgRefs: modified refElements[" + i + "]=" + refElements[i]);
				}
				refs.push(refElements[i]);		
				articleText = articleText.replace(originalRef, "<ref name=" + name + "/>");
			}
			_private.debug("reorgRefs: end");
			return articleText;
		}
		,

		chooseUniqueName: function (refText, articleText) {
			_private.debug("chooseUniqueName: start");
			var name='';
			// Try to use the parameters of {{cite whatever}} to set the reference name
			if (refText.search(new RegExp("\\{\\{[Cc]ite")) != -1) {
				_private.debug("chooseUniqueName: found {{cite");
				// Build an array of parameters by name
				var temp = refText.substr(refText.indexOf("|"));	// "{{cite whatever |aa=bb |cc=dd}}eee" -> "|aa=bb |cc=dd}}eee"
				temp = temp.substr(0, temp.indexOf("}}"));		// "|aa=bb |cc=dd}}eee" -> "|aa=bb |cc=dd"
				var temp2 = temp.split("|");				// "|aa=bb |cc=dd" -> ["aa=bb", "cc=dd"]
				var citeParms = new Array();
				for (var i=0; i < temp2.length; i++) {
					var temp3 = temp2[i].split("=");		// "aa=bb" -> ["aa",bb"]
					if ((temp2[i] == "") || (temp3[0] == "")) {
						continue;
					}
					citeParms[_private.trim(temp3[0])] = _private.trim(temp3[1]);	// citeParams["aa"] = "bb"
				}
				// Build the reference name from some of the parameters
				if ((citeParms["last1"] != null) && (citeParms["last1"] !=  "")) {
					name = citeParms["last1"];	// Add the last1= value
				} else if ((citeParms["last"] != null) && (citeParms["last"] !=  "")) {
					name = citeParms["last"];	// Add the last= value
				} else if ((citeParms["author1"] != null) && (citeParms["author1"] !=  "")) {
					name = citeParms["author1"];	// Add the author1= value
				} else if ((citeParms["author"] != null) && (citeParms["author"] !=  "")) {
					name = citeParms["author"];	// Add the author= value
				} else if ((citeParms["editor1"] != null) && (citeParms["editor1"] !=  "")) {
					name = citeParms["editor1"];	// Add the editor1= value
				} else if ((citeParms["editor"] != null) && (citeParms["editor"] !=  "")) {
					name = citeParms["editor"];	// Add the editor= value
				} else if ((citeParms["publisher"] != null) && (citeParms["publisher"] !=  "")) {
					name = citeParms["publisher"];	// Add the publisher= value
				} else if ((citeParms["title"] != null) && (citeParms["title"] !=  "")) {
					name = citeParms["title"];	// Add the title= value
				}
				name = name + " ";
				if ((citeParms["date"] != null) && (citeParms["date"] !=  "")) {
					name = name + citeParms["date"];	// Add the date= value
				} else if ((citeParms["year"] != null) && (citeParms["year"] !=  "")) {
					name = name + citeParms["year"];	// Add the year= value
				}
				name = name.replace(new RegExp("[\\W]+", "g"), " ");	// Replace whitespace, specials, ...
				name = (_private.trim(name)).replace(new RegExp("[\\s]+", "g"), "_");	// ... with "_"
				_private.debug("chooseUniqueName: name=" + name);
				if (articleText.indexOf(name) == -1) {
					return '"' + name + '"';
				}
				_private.debug("chooseUniqueName: name already in use");
			}
			// Try to use the URL components to set the reference name
			if (refText.search(new RegExp("^<ref[^/>]*>\\s*\\[\\s*https?:")) != -1) {
				_private.debug("chooseUniqueName: found http:");
				var URL = (refText.match(new RegExp("https?:[^\\s]*[^?;<\\]]*")))[0];	// "<ref xx>[http://aaa/bbb ccc]</ref>" -> "http://aaa/bbb ccc"
				_private.debug("chooseUniqueName: URL=" + URL);
				var host = URL.replace(new RegExp("^https?:\\/\\/([^\\/]*)\\/.*$"), '$1');	// Isolate the hostname/IP addr
				_private.debug("chooseUniqueName: host=" + host);
				var path = URL.replace(new RegExp("^https?:\\/\\/[^\\/]*\\/([^\\s]*).*$"), '$1');	// Isolate the pathname
				_private.debug("chooseUniqueName: path=" + path);
				var title = URL.replace(new RegExp("^https?:\\/\\/[^\\/]*\\/[^\\s]*\\s+(.*)$"), '$1');	// Isolate the title
				_private.debug("chooseUniqueName: title=" + title);
				var file= path.replace(new RegExp("^.*([^\\/]*)$"), '$1');		// Isolate the file name from the pathname
				_private.debug("chooseUniqueName: file=" + file);
				if (host != "") {
					name = host;
				}
				name = name + " ";
				if (title != "") {
					name = name + title;
				} else if (file != "") {
					name = name + file;
				} else if (path != "") {
					name = name + path;
				}
				name = name.replace(new RegExp("[\\W]+", "g"), " ");	// Replace whitespace, specials, ...
				name = (_private.trim(name)).replace(new RegExp("[\\s]+", "g"), "_");	// ... with "_"
				_private.debug("chooseUniqueName: name=" + name);
				if (articleText.indexOf(name) == -1) {
					return '"' + name + '"';
				}
				_private.debug("chooseUniqueName: name already in use");
			}
			// Make up a name of our own when all else fails
			for (var i=0; i < 20; i++) {
				name = '"RRGEN_' + _private.generatedNameIndex++ + '_"';
				_private.debug("chooseUniqueName: name=" + name);
				if (articleText.indexOf(name) == -1) {
					return name;
				}
				_private.debug("chooseUniqueName: name already in use");
			}
			alert("chooseUniqueName: Unable to generate a unique name for reference: " + refText);
			exit(1);
		}
		,

		addRefs: function (articleText, refs) {
			_private.debug("addRefs: start");
			var referencesEndTag = new RegExp("(</references[^>]*>)", "i");
			var referencesMinTag = new RegExp("<(references)([^\\/>]*)\\/>", "i");
			var reflistWithRefs  = new RegExp("(\\{\\{[Rr]eflist[^\\}]*\\s*\\|\\s*refs=)");
			var reflistNoRefs    = new RegExp("(\\{\\{[Rr]eflist[^}]*)\\}\\}");
			if (articleText.search(referencesEndTag) != -1) {
				// Add our collected refs to the existing <references>...</references>
				articleText = articleText.replace(referencesEndTag, refs.join("\n") + "\n$1");
			} else if (articleText.search(reflistWithRefs) != -1) {
				// Add our collected refs to the existing {{reflist refs=...}}
				articleText = articleText.replace(reflistWithRefs, "$1\n" + refs.join("\n") + "\n");
			} else 	if (articleText.search(referencesMinTag) != -1) {
				// Expand the references tag and insert our collected refs
				articleText = articleText.replace(referencesMinTag, "<$1$2>\n" + refs.join("\n") + "\n</$1>");
			} else if (articleText.search(reflistNoRefs) != -1) {
				// Expand the {{reflist}} and include our collected refs
				articleText = articleText.replace(reflistNoRefs, "$1 |refs=\n" + refs.join("\n") + "\n}}");
			} else {
				alert("addRefs: Can't find reference list, adding my own!!!!");
				articleText += "<references>\n" + refs.join("\n") + "\n</references>";
			}
			_private.debug("addRefs: end");
			return articleText;
		}
		,
		trim: function (input) {
			if (input == null) {
				return "";
			}
			var start;
			var end;
			for (start = 0; start < input.length; start++) {
				if (input[start] != " ") {
					break;
				}
			}
			for (end = input.length; end >= 0; end--) {
				if (input[end] != " ") {
					break;
				}
			}
			return input.substr(start, end);
		}
	}

	var _public = {
		run: function () {
			_private.debug("run: start");
			var articleTextField = document.editform.wpTextbox1;
			var articleText = articleTextField.value;
			var refs = new Array();
			articleText = _private.reorgRefs(articleText, refs);
			articleTextField.value = _private.addRefs(articleText, refs);
			// Add a tag to the summary box
			var summaryField = document.editform.wpSummary;
			var summary = "Reorganize references";
			if (summaryField.value.indexOf(summary) == -1) {
				// If the summary contains anything other than a section comment, add a separator
				if (summaryField.value.match(/[^\*\/\s][^\/\s]?\s*$/)) {
					summaryField.value += "; ";
				}
				summaryField.value += summary;
			} 
			// Press the "Show changes" button to let the user see the diffs.
			document.editform.wpDiff.click()
				_private.debug("run: end");
		}
		,

		initialize: function () {
			if (document.forms.editform) {
				mw.util.addPortletLink('p-cactions', 'javascript:RossPatterson_Reorganize_References.run()',
						'RefReorg', 'ca-ref-reorg', 'Reorganize references', '', '');
			}
		}

	}

	return _public;
}();
addOnloadHook(RossPatterson_Reorganize_References.initialize);

/* </nowiki> */