Jump to content

User:Erutuon/scripts/footnoteCleanup.js

From Wikipedia, the free encyclopedia
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>

	Moves refs and citation needed tags after punctuation.
*/

const namespaceNumber = mw.config.get("wgNamespaceNumber");

// Add a link just above the edit box, if you're in the main or Draft namespace.
if ( namespaceNumber === 0 || namespaceNumber === 118 )
{
	mw.loader.load("//en.wiktionary.org/w/index.php?title=User:Erutuon/styles/wikitext-cleanup.css&action=raw&ctype=text/css", "text/css");
		

	var cleanUpFootnotes = function ()
	{
		var textbox = $("#wpTextbox1");
		
		if ( !textbox )
			return;
		
		const oldContents = textbox.val();
		var contents = oldContents;
		
		var escaped = [];
		var i = 0;
		
		var replacements = [];
		var count = 0;
		
		var escape = function(text, regexString)
		{
			var regex = new RegExp(regexString, "g");
			text = text.replace(
				regex,
				function(match)
				{
					escaped[i] = match;
					var replacement = "%%" + i + "%%";
					i += 1;
					return replacement;
				}
			);
			return text;
		};
		
		var puncRegex = /((?:%%\d+%%)+)([\.\,\;\:\"]{1,3})/g;
		
		var reorder = function(match, capture1, capture2)
		{
			count += 1;
			var replacement = capture2 + capture1;
			replacements.push(replacement);
			return replacement;
		};
		
		var fixPunctuationPlacement = function(text)
		{
			while ( puncRegex.test(text) )
				text = text.replace(
					/((?:%%\d+%%)+)([\.\,\;\:\"]{1,3})/g,
					reorder
				);
			
			return text;
		};
		
		/*	Escape various things:
			ref tags				*/
		contents = escape(
			contents,
			"<ref[^>]*>[^<]+<\\/ref>"
		);
		contents = escape(
			contents,
			"<ref[^\\/]+\\/>"
		);
		
		// citation needed
		contents = escape(
			contents,
			"\\{\\{(?:[Cc]itation needed|[Cc]n|[Ff]act|[Cc]b|[Cc]tn|[Rr]ef\\?)\\|[^\}]+\\}\\}"
		);
		
		contents = fixPunctuationPlacement(contents);
		
		// footnote templates
		/*	Handles up to one level of nested templates.
			Any more, and there may be problems.			*/
		contents = escape(
			contents,
			"\\{\\{(?:sfn|efn|rfn)\\|(?:[^\\}]*?(?:\\{\\{[^\\}]+\\}\\})?)+\\}\\}"
		);
		
		if ( i > 0 )
		{
			mw.notify(i + " refs found.");
		}
		
		contents = fixPunctuationPlacement(contents);
		
		if ( count > 0 ) {
			mw.notify(count + " correction" + ( ( count > 1 && "s" ) || "" ) + " made: " + replacements.join());
		}
		
		/*	Unescape the various things escaped above.
			This has to be done twice, since escaping was done twice.	*/
		contents = contents.replace(
			/%%(\d+)%%/g,
			function(wholematch, number) {
				number = Number(number);
				return escaped[number];
			}
		);
		contents = contents.replace(
			/%%(\d+)%%/g,
			function(wholematch, number) {
				number = Number(number);
				return escaped[number];
			}
		);
		
		var isUnchanged = ( oldContents === contents );
		
		if ( isUnchanged )
		{
			mw.notify("No misplaced footnotes or tagging templates were found.");
		}
		
		textbox.val(contents);
		$("#wpSummary").val(function(index, summary)
			{
				var addition = "made sure refs are after punctuation with [[User:Erutuon/footnoteCleanup.js|JavaScript]]; see [[WP:REFPUNC]]";
				
				const afterSectionName = summary.match(/^(?:\/\*[^\*]+\*\/)?\s*(.+)/);
				
				if ( afterSectionName && afterSectionName[1].length > 1 )
				{
					addition = "; " + addition;
				}
				
				if ( !isUnchanged && ( !afterSectionName || !afterSectionName[1].includes(addition) ) )
					return summary + addition;
				else
					return summary;
			}
		);
	};
		
	if ( !$("#wikitext-cleanup-button-wrapper").length )
		$("#editform").prepend('<div id="wikitext-cleanup-button-wrapper"></div>');
	$("#wikitext-cleanup-button-wrapper")
		.append(`<div id="footnote-cleanup" class="wikitext-cleanup-button">clean up footnotes</div>`);
	$("#footnote-cleanup")
		.click(cleanUpFootnotes);
}

// </nowiki>