Jump to content

User:Est. 2021/Script/AutoCleanup.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.
/*
Fork of [[User:Qwerfjkl/scripts/autoCleanup.js]], based on [[User:Tol/AutoCleanup.js]]
*/

// <syntaxhighlight lang="js">

$(function() {
	
	function clean_wikitext(text) {
		const replacements = [

// SPACING
	[/(\u00A0|\u00AD|\u200A|\u200B|\u0009|\u0000-\u001F|\u0080-\u009F)/g, ' '], // Replace non-standard spacing with normal spacing #OWN // [[Help:CS1 errors#invisible char]]
	[/( )+/gm, '$1'], // Remove excess spacing #1 #OWN
	[/([^=\|\u3131-\uD79D]) (,|;|:[^:]|\.[^\.]|\![^\!]|\?)([^\w])/g, '$1$2$3'], // Remove excess spacing before punctuation #OWN // [[MOS:PUNCTSPACE]] (except: Korean)
	[/ː /g, ': '], // Replace misused IPA colons #OWN // [[MOS:COLON]]
	[/\[\[(.*)\|(\1)([\w']*)\]\]/gi, '[[$2]]$3'], // Fix piped links #OWN // [[MOS:PIPESTYLE]] & [[WP:NOPIPE]]
	[/(\n[^\|\}].+) +\n/g, '$1\n'], // Remove lines' trailing spaces (that don't start with "|" or "}"
	[/ \n/g, '\n'], // Remove excess spacing before line break #1 #OWN

// SPACING +
	// [/([^\n\{ ])\| ([^\]])/g, '$1|$2'], // Remove excess spacing after "|" #OWN
	[/(\w) \.(\s|\n)/g, '$1.$2'], // Remove spacing before dot #OWN
	[/(\n *\| *\w*) *\= */g, '$1 = '], // Fix spacing around equal signs, pt.1/2 #OWN
	[/(align|(col|row)span|scope|style) *\= */g, '$1='], // Fix spacing around equal signs, pt.2/2 #OWN

// TAGS (SPACING)
	[/ *\<[\/]*br *[\/]*\> */gi, '<br />'], // Remove excess spacing around line breaks #OWN // [[H:BR]]
	[/([^=\|]) (\<\!)/gi, '$1$2'], // Remove excess spacing before hidden tags #OWN
	[/([^=\|]) (\<ref|\{\{(sfn|r)\|)/gi, '$1$2'], // Remove excess spacing before refs #OWN
	[/(\!\!|\/ref\>)(\w)/g, '$1 $2'], // Add spacing after refs and "!!" #OWN

// TAGS & QUOTES
	[/(\n)*<(small)>([^\2\/]*)<\/?\2>/gis, '$1{{$2|$3}}'], // [[Template:Small]] #OWN
	[/(\n)*\:?<(block(quote))>([^\2\/]*)(\n)*<\/?\2>/gis, '$1{{$3|$4}}'], // [[Template:Quote]] #OWN
	[/\{\{block(quote)\|/gi, '{{$1|'], // #OWN
	[/\{\{i(ll)/gi, '{{i$1'], // #OWN
	[/\{\{l(ang)/gi, '{{l$1'], // #OWN
	[/\{\{n(otelist)/gi, '{{n$1'], // #OWN
	[/\{\{r(eflist)/gi, '{{r$1'], // #OWN
	[/\<references *\/\>/gi, '{{reflist}}'], // #OWN

// [[MOS:']] & [[MOS:"]] // [[MOS:CQ]]
	[/(‘|’|`|´|˹|˺)/g, '\''], // Replace curly single quotes with straight ones #CUSTOM
	[/(“|”)/g, '"'], // Replace curly double quotes with straight ones #CUSTOM

// [[MOS:NBSP]] & [[MOS:DASH]]
	[/(&ndash;)/g, '–'], // Replace "&ndash;" with "–" #OWN
	[/(&nbsp;|\{\{nbs\}\})(–|—)/gi, '{{snd}}'], // Replace "{{nbs}}–" with "{{dash}}" #OWN
	[/(–|—)(&nbsp;|\{\{nbs\}\})/gi, '{{snd}}'], // Replace "–{{nbs}}" with "{{dash}}" #OWN
	[/ *(\{\{(snd|dash)\}\}) */gi, '$1'], // Remove spacing around "{{dash}}" #OWN
	[/([^\=\!\"\'])\}\}(\w)/g, '$1}} $2'], // Add spacing after templates #OWN

// [[MOS:NUM]]
// Birthdates
	[/([^\w-–])b\. *(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/g, '$1born $2'], // replace "b. Jan" with "born Jan" #CUSTOM
	[/([^\w-–])b\. *([0-9]{1,2}) *(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/g, '$1born $2 $3'], // replace "b. 31 Jan" with "born 31 Jan" #CUSTOM
	[/([^\w-–])b\. *([0-9]{1,4})/g, '$1born $2'], // replace "b. 1987" with "born 1987" #OWN
	[/(born|b\.) \{\{ *birth ?date *\|/ig, 'born {{SUBST:User:Zyxw/bd|'], // fix duplicated birth date templates
	[/(\| *height *= *\{\{convert\| *[1-2]),([0-9]{1,2} *\| *m)/ig, '$1.$2'], // fix height with comma in {{convert}}
// Date formats
	[/(\| *)([0-9]{2})\/([0-9]{2})\/([0-9]{4})/g, '$1$4-$3-$2'], // replace "| 31/12/2015" with "| 2015-12-31"
	[/(\| *)([0-9]{4})[–—−\/]([0-9]{2})[–—−\/]([0-9]{2})/g, '$1$2-$3-$4'], // replace "| 2015–12–31" with "| 2015-12-31" (endash/emdash/minus/slash to hyphen)

// [[MOS:HEAD]]
	[/^(=+) *\<(big\>)(.*?)\<\/\2 *\1$/gm, '$1 $3 $1'], // Remove "<big>" tags from headers #OWN
	[/^(=+) *(.*?) *\1$/gm, '$1 $2 $1'], // Standardise spacing inside headers
	[/\n+^((=+) .*? \2)$/gm, '\n\n$1'], // Standardise spacing before headers
	[/^((=+) .*? \2)$\n+/gm, '$1\n'], // Standardise spacing after headers #CUSTOM
	[/\n{3,}/g, '\n\n'], // Replace three or more newlines with two newlines #1

// [[MOS:FOOTERS]]
	[/\n(== *)External (Links?)( *==)/i, '\n$1External links$3'], // #CUSTOM
	[/\n(== *)Further Reading( *==)/i, '\n$1Further reading$2'],
	[/\n(== *)Published Papers( *==)/i, '\n$1Published papers$2'],
	[/\n(== *)See Also( *==)/i, '\n$1See also$2'],
	[/\n(== *)Selected Works( *==)/i, '\n$1Selected works$2'],
// Add Ref section
	// [/\.\n\n== ?External links ?==/g, '.\n\n== References =='], // #OFF

// References
	[/((?:<ref[^>]*?>[^>]*?<\/ref>){1,})(\)?(,|;|:|\.)?)(\s|\n)/gm, '$2$1$4'], // Fix ref punctuation // Taken from [[User:Novem Linguae/Scripts/DraftCleaner.js]] #CUSTOM
	[/>\[(http)([^ ]*) "*([^\]"]*)"*\]</g, '>{{Citation |title=$3 |url=$1$2}}<'], // Format external links #OWN
	[/\| *(last|author)(\d*) *\= *(\w*), /g, '|last$2=$3 |first$2='], // Replace "last=Smith, John" with "last=Smith |first=John" #OWN

// Links
	[/(?<!\[)\[https?:\/\/en\.wikipedia\.org\/wiki\/([^ \]]*)(?: ([^\]]*))?\]/gs, function(match, p1, p2) {
		p1 = decodeURIComponent(p1);
		p1 = p1.replace(/_/g, ' ');
		if (p2 == undefined) {
		return `[[${p1}]]`;
		} else {
		return `[[${p1}|${p2}]]`; // format wikilinks
	} }],
	[/\[\[([^\]]*)\]\]/gs, function(match, p1) {
		p1 = decodeURIComponent(p1);
		p1 = p1.replace(/_/g, ' ');
		return `[[${p1}]]`;}], // remove "_" from wikilinks #OWN

// image cleanup
	[/((Image:|File:)([^\.\n])*(\.\w*))/g,  function(match, p1) {
		p1 = decodeURIComponent(p1);
		p1 = p1.replace(/_/g, ' ');
		return `${p1}`;}], // remove "_" from file names #OWN
	[/(\| *(image\d*|image_\w*|cover|flag|insignia|logo|photo|seal|shield) *= *)((Image|File):)?(([^\.\n])*(\.\w*))/g,  function(match, p1, p2, p3, p4, p5) {
		p5 = decodeURIComponent(p5);
		p5 = p5.replace(/_/g, ' ');
		return `${p1}${p5}`;}], // if "| image = File:name" is used, remove unneeded "File:" #OWN
	[/(\| *(image\d*|image_\w*|cover|flag|insignia|logo|photo|seal|shield) *= *)\[\[((Image|File):)?(([^\.\n])*(\.\w*))\]\]/g,  function(match, p1, p2, p3, p4, p5) {
		p5 = decodeURIComponent(p5);
		p5 = p5.replace(/_/g, ' ');
		return `${p1}${p5}`;}], // if "| image = [[File:name]]" is used, remove unneeded "[[File:]]" #OWN

// Taken from pywikibot safe-syntax replaces, from the fixes.py script
	[/\[\[(?<url>https?:\/\/[^\]]+?)\]\]/g, '[$1]'], // external link in double brackets
	[/\[\[(?<url>https?:\/\/.+?)\]/g, '[$1]'], // external link starting with double bracket
	[/\[(?<url>https?:\/\/[^\|\] \r\n]+?) +\| *(?<label>[^\|\]]+?)\]/, '[$1 $2]'], // external link and description separated by a dash, with whitespace in front of the dash, so that it is clear that the dash is not a legitimate part of the URL.
	[/\[(?<url>https?:\/\/[^\|\] ]+?(\.pdf|\.html|\.htm|\.php|\.asp|\.aspx|\.jsp)) *\| *(?<label>[^\|\]]+?)\]/, '[$1 $3]'], // dash in external link, where the correct end of the URL can be detected from the file extension. It is very unlikely that this will cause mistakes.
	[/\[\[([^\|\]]+)\|\1\]\]/, '[[$1]]'], // link equal to linktext

// Taken from [[User:Sam Sailor/Scripts/autoFormatterSettings.js]]
	// [/ =\n/g, ' = \n'], // add trailing space after = for empty infobox parameters #OFF
	[/\{\{ /g, '{{'], // remove space after {{
	[/\|tau\]\]/g, '|τ]]'], // fix unwanted change in category sorting
// spaces after bullets
	[/(\n[*#]+) *([^\s*#:;R])/g, '$1 $2'], // space after one or more * or # at start of line

// End cleaning
	[/( )+/gm, '$1'], // Remove excess spacing #2 #OWN
	[/ \n/g, '\n'], // Remove excess spacing before line break #2 #OWN
	[/\n{3,}/g, '\n\n'], // Replace three or more newlines with two newlines #2
	// [/\[\.\.\.\]/g, '[…]'], // Replace "[...]" with "[…]" #OWN #OFF // [[MOS:...]]
      ];
		for (const replacement of replacements) {
			text = text.replace(...replacement);
		}
		return text;
	}
	
	function process_summary(summary) {
		const ac_summary = 'cleanup via [[User:Est. 2021/Script/AutoCleanup.js|script]]';
		if (summary) {
			if (/^\/\*.*?\*\/ $/.test(summary)) { // auto summary
				return summary + ac_summary;
			} else {
				return summary + '; ' + ac_summary;
			}
		} else {
			return ac_summary;
		}
	}
	
	function main() {
		mw.notify(
			'Processing...',
			{
				tag: 'tol-autocleanup',
				title: 'AutoCleanup',
				type: 'info',
				autoHide: true,
				autoHideSeconds: 2
			}
		);
		let text_box = $('#wpTextbox1');
		let old_text = text_box.textSelection('getContents');
		let new_text = clean_wikitext(old_text);
		if (old_text != new_text) {
			text_box.textSelection('setContents', new_text);
			if (mw.util.getParamValue('section') != 'new') { // not section title instead of summary
			let summary_box = $('#wpSummary');
			summary_box.val(
				process_summary(summary_box.val())
			)}
			mw.notify(
				'Done',
				{
					tag: 'tol-autocleanup',
					title: 'AutoCleanup',
					type: 'success'
				}
			);
		} else {
			mw.notify(
				'No changes made',
				{
					tag: 'tol-autocleanup',
					title: 'AutoCleanup',
					type: 'info'
				}
			);
		}
	}
	
	function add_button() {
		try {
			if ($('editform').length) {
				mw.loader.using(['oojs-ui', 'oojs-ui-widgets'], function() {
					let button = new OO.ui.ButtonWidget({label: 'AutoCleanup'});
					button.on('click', main);
					$('.editButtons').append(button.$element);
				});
			}
		} catch(error) {
			alert(error);
		}
	}
	
	//$(add_button);
            
    if (mw.config.get('wgPageContentModel') === 'wikitext' && mw.config.get('wgAction') === 'edit' && mw.util.getParamValue( "ACdisable" ) != "1" ) {
	    mw.util.addPortletLink( "p-cactions", window.location.href + '&ACdisable=1', "Disable AutoCleanup", "pt-disableAC" );
		$(main);
	}
});

importScript('User:Est. 2021/Script/AutoCleanup/Tables.js'); // Backlink: [[User:Est. 2021/Script/AutoCleanup/Tables.js]]

importScript('User:Est. 2021/Script/AutoCleanup/Templates.js'); // Backlink: [[User:Est. 2021/Script/AutoCleanup/Templates.js]]

importScript('User:Est. 2021/Script/AutoCleanup/sandbox.js'); // Backlink: [[User:Est. 2021/Script/AutoCleanup/sandbox.js]]

// </syntaxhighlight>