User:Cygnis insignis/common.js

// Scripts and notes by Hesperian

/** * TemplateScript adds configurable templates and scripts to the sidebar, and adds an example regex editor. * @see https://meta.wikimedia.org/wiki/TemplateScript * @update-token */ // $.ajax('//tools-static.wmflabs.org/meta/scripts/pathoschild.templatescript.js', { dataType:'script', cache:true }).then(function {	/*********	** Register scripts	*********/	// stuff I routinely do at the start	pathoschild.TemplateScript.add( [			{ name: 'header', script: header, accessKey: 'z' }, { name: 'clean up', script: cleanup, accessKey: 'x' }, { name: 'uc', script: uc }, { name: 'hwe', script: hwe } ],		{ forNamespaces: 'page' } // common fields );

// stuff I can do any time pathoschild.TemplateScript.add([		{ name: 'title', script: title, accessKey: 't' },		{ name: 'author', script: author, accessKey: 'a' },		{ name: 'author (surname first)', script: surnameFirst, accessKey: ',' },		{ name: 'small-caps', script: smallcaps, accessKey: 'c' },		{ name: 'upper', script: upper, accessKey: '6' }	]);

// stuff I do at the end pathoschild.TemplateScript.add(		[			{ name: 'hws', script: hws },			{ name: 'makeref', script: makeref },			{ name: 'makeoverflow1', script: makeoverflow1 },			{ name: 'makeoverflow2', script: makeoverflow2 },			{ name: 'footer', script: footer, accessKey: 'f' }		],		{ forNamespaces: 'page' } // common fields	);

// stuff I only do via shortcuts; if I could create these shortcuts without adding them to the sidebar, I would. pathoschild.TemplateScript.add([		{ name: 'pagename', script: putpagename, accessKey: 'n' }	]);

/*********	** Extract page info *********/	var pagenum = (function {		var m = /\.djvu\/([0-9]+)&action=edit/g.exec(location.href);		if (!m) return null;		return parseInt(m[1]);	}); var quality = (function getQuality {		var q = document.getElementById('pagequality');		if (!q)			return "Nonexistent";		else {			var c = q.getAttribute("class");			switch(c) {			case "quality0": return "Without text";			case "quality1": return "Not proofread";			case "quality2": return "Problematic";			case "quality3": return "Proofread";			case "quality4": return "Validated";			}		}		return null;	}); var proofed = quality !== 'Nonexistent' && quality !== 'Not proofread';

var specialFormats = [ // add as many as you like... 3}}		// format is ["url_to_match", "verso header", "recto header", "footer if no ref", "footer if ref"] [			"Journalproceedi421908roya", "",			"",			"",			""		],       [			"Emu", "",			"",			"",			""		],       [			"Tender_buttons", "",			"",			"",			""+(pagenum-6)+"" ],		[			"_Folk-Lore_Journal_", "",			"",			"",			""		],		[			"_A_Quarterly_Review", "",			"",			"",			""		],		[			"Magyars", "",			"",			"",			""		],		[			"The_fairy_tales_of_Hans_Christian_Andersen", "",			"",			"",			""		],		[			"_Tegner", "\n", "\n", "",			""		],		[			"_Craigie", "",			"",			"",			""		],		[			"Walker", "",			"",			"",			""		]	];

/*********	** Define scripts *********/	// === FOR CONVERSIONS === // Convenience function: converts some text into title case function titlecase(text) { // split text into individual words and examine them one by one var textArray = text.toLowerCase.split(" "); for (var i in textArray) { switch(textArray[i]) { case "a": case "an": case "and": case "as": case "at": case "but": case "by": case "etcetera": case "etc.": case "for": case "from": case "in": case "nor": case "of": case "o'": case "on": case "or": case "the": case "to": case "with": case "versus": case "vs.": case "v.": case "yet": break; // don't capitalise articles, "to" as part of an infinitive, prepositions or short conjunctions default: // capitalise everything else textArray[i] = textArray[i].substring(0,1).toUpperCase + textArray[i].substring(1,textArray[i].length); break; }		}

// capitalise first word regardless textArray[0] = textArray[0].substring(0,1).toUpperCase + textArray[0].substring(1,textArray[0].length);

// capitalise last word regardless var last = textArray.length-1; textArray[last] = textArray[last].substring(0,1).toUpperCase + textArray[last].substring(1,textArray[last].length);

// reconstruct title var titleCase=""; for (i in textArray) { titleCase += textArray[i]; if (i < last) titleCase += " "; }

return titleCase; }

// == SIDEBAR TOOLS == function cleanup(editor) { var headerbox = editor.forField('#wpHeaderTextbox'); var footerbox = editor.forField('#wpFooterTextbox');

// anything noincluded at the start or end of the edit box should be pushed into the header and footer respectively. if(editor.get.match(/^ /)) { var e = editor.get.indexOf(" ");

// append to header a trimmed version of whatever is inside the leading noinclude headerbox.append('\n' + editor.get.substr(11, e-11).replace(/^\s+|\s+$/g, ''));

// remove leading noinclude from editbox editor.set(editor.get.substr(e+12)); }

if (editor.get.match(/<\/noinclude>$/)) { var s = editor.get.lastIndexOf(" ");

// prepend to footer a trimmed version of whatever is inside the trailing noinclude footerbox.prepend(editor.get.substr(s+11, editor.get.length-s-11-12).replace(/^\s+|\s+$/g, '') + '\n');

// remove trailing noinclude from editbox editor.set(editor.get.substr(0, s)); }

editor // remove trailing spaces at the end of each line .replace(/ +\n/g, '\n')

// remove trailing whitespace preceding a hard line break .replace(/ +/g, ' ')

// remove trailing whitespace at the end of page text .replace(/\s+$/g, '')

// remove trailing spaces at the end of refs .replace(/ +<\/ref>/g, ' ')

// remove trailing spaces at the end of template calls .replace(/ +}}/g, '}}')

// convert double-hyphen to mdash (avoiding breaking HTML comment syntax) .replace(/([^\!])--([^>])/g, '$1—$2')

// remove spacing around mdash, but only if it has spaces on both sides // (we don't want to remove the trailing space from "...as follows:— ",			// bearing in mind that the space will already be gone if at end of line). .replace(/ +— +/g, '—')

// join words that are hyphenated across a line break // (but leave "|-" table syntax alone) .replace(/([^\|])-\n/g, '$1');

// stuff to do only if the page doesn't contain a tag: if (editor.get.indexOf(" ") === -1) { editor // remove single line breaks; preserve multiple. // but not if there's a tag, template or table syntax either side of the line break .replace(/([^>}\|\n])\n([^<{\|\n])/g, '$1 $2')

// collapse sequences of spaces into a single space .replace(/ +/g, ' '); }

editor // dump spurious hard breaks at the end of paragraphs .replace(/\n\n/g, '\n\n')

// remove unwanted spaces around punctuation marks .replace(/ ([;:\?!,])/g, '$1')

// unicodify .replace(/&mdash/g, '—') .replace(/&ndash/g, '–') .replace(/&quot;/g, '"')

// straighten quotes and apostrophes. .replace(/[“”]/g, '"')			.replace(/[‘’`]/g, '\'')

//OCR fixes // convert i9 to 19, etc.			.replace(/[il]([0-9])/g, '1$1')

// "the", "them", "their", etcetera .replace(/tlie/g, 'the')

// "U" -> "ll" when preceded by a lowercase letter. .replace(/([a-z])U/g, '$1ll')

// replace "float center" with "block center"; original template name was misleading enough be warrant routinely fixing .replace(/\{\{float center/g, '{{block center') .replace(/ \s*([.\n]*?)\s*<\/center>/g, '{{center|$1}}');

// temporary fix just for Portrait if (location.href.indexOf('A_Portrait_of_the_Artist_as_a_Young_Man') !== -1) editor.replace(/\n\n\n/g, '\n\n'); }

// automatically insert running header into header box function header(editor) { if (pagenum === null) return;

var isEven = pagenum % 2 === 0;

var headerbox = editor.forField('#wpHeaderTextbox');

var generic = true; for (var f in specialFormats) { var format = specialFormats[f]; if (location.href.indexOf(format[0]) !== -1) { if (isEven) headerbox.append('\n' + format[1]); else headerbox.append('\n' + format[2]);

generic = false; break; }		}

// no special header matched, use a generic running header if (generic) { if (isEven) headerbox.append('\n'); // assume verso, with page number at left else headerbox.append('\n'); // assume recto, with page number at right }

// if this is unproofed text, then delete the first line of the OCR text, which presumably is raw OCR of the header we've just inserted if (!proofed) editor.set(editor.get.slice(editor.get.indexOf('\n') + 1)); }

// insert formatted references into footer box, if needed. function footer(editor) { var footerbox = editor.forField('#wpFooterTextbox'); if (editor.get.indexOf(" ") === -1 && editor.get.indexOf("{{#tag:ref") === -1) { // page contains no refs var generic = true; for (var f in specialFormats) { var format = specialFormats[f]; if (location.href.indexOf(format[0]) !== -1) { footerbox.replace(' ', format[3]); generic = false; break; }			}

// no special footer matched, use just strip out the references tag if (generic) footerbox.replace(' ',''); }		else { var generic = true; for (var f in specialFormats) { var format = specialFormats[f]; if (location.href.indexOf(format[0]) !== -1) { footerbox.replace(' ', format[4]); generic = false; break; }			}

// no special footer matched, so use a generic ref tag if (generic) footerbox.replace(' ','{{block center|{{smallrefs}}}}\n'); }	}

//Make selected text into appropriately capitalised title link // e.g. "THE MAN FROM SNOWY RIVER" —> "THE MAN FROM SNOWY RIVER" function title(editor) { return editor.replaceSelection(function(text) {			var target = titlecase(text);			return target === text				? +text+				: +text+;		}); }

//Make selected text into author link function author(editor) { editor.replaceSelection(function(name) {			// if name is all in capitals, convert target to title case			var target = name === name.toUpperCase				? titlecase(name)				: name;			return +name+;		}); }

function surnameFirst(editor) { editor.replaceSelection(function(name) {			// If name is all in capitals, convert target to title case.			var target = name === name.toUpperCase				? titlecase(name)				: name;

// split text into individual words var nameArray = name.split(" ");

// put last first, followed by a comma, then all the rest preceded by spaces name = nameArray[nameArray.length - 1] + ","; for (var i = 0; i < nameArray.length - 1; i++) name = name+" "+nameArray[i];

return +name+; });	}

//Mark selected text up with small-caps function smallcaps(editor) { editor.replaceSelection(function(pre) {			// Applying small-caps to all-caps text is pointless...			// ... unless the all-caps is OCR of text that is actually small-caps.			// Check if text is all-caps, and if it is, convert it to title case before applying small-caps.			if (pre == pre.toUpperCase)				pre = titlecase(pre);			return '';		}); }

// As you work your way through the page, when you encounter a reference, just mark it with tags and continue. // Once you've got to the end of the page and proofed the references, simply highlight each reference in turn, // and use this function to move it to its proper position. function makeref(editor) { var editbox = $('#wpTextbox1').get(0); var refStart = editbox.selectionStart; var refEnd = editbox.selectionEnd;

var firstref = editbox.value.indexOf(' '); if (-1 != firstref) { editbox.value = editbox.value.slice(0,firstref+5) + editbox.value.slice(refStart, refEnd) + editbox.value.slice(firstref+5, refStart) + editbox.value.slice(refEnd); }	}

// As you work your way through the page, when you encounter a reference, just mark it with tags and continue. // Once you've got to the end of the page and proofed the references, simply highlight the overflow reference, and use this // function to move it to its proper position. function makeoverflow1 { var editbox = $('#wpTextbox1').get(0); var refStart = editbox.selectionStart; var refEnd = editbox.selectionEnd;

var firstref = editbox.value.indexOf(' '); if (-1 != firstref) { editbox.value = editbox.value.slice(0,firstref) + ""				+ editbox.value.slice(firstref+11, refStart) + editbox.value.slice(refEnd); }	}

function makeoverflow2(editor) { var editbox = $('#wpTextbox1').get(0); var refStart = editbox.selectionStart; var refEnd = editbox.selectionEnd;

editbox.value = "" + editbox.value.slice(0,refStart) + "\n\n\n" + editbox.value.slice(refStart, refEnd) + "\n "; }

//wrap first word in hwe template function hwe(editor) { var to = editor.get.search(/\W/); if (to == -1) to = editor.get.length;

var pre = editor.get.substring(0, to);

var post = ''; editor.set(post + editor.get.substring(to)); }

//wrap last word in hws template function hws(editor) { var from = editor.get.lastIndexOf(" "); if (from == -1) from = 0; else from = from + 1;

var pre = editor.get.substring(from); if (pre.slice(-1) == "-") pre = pre.slice(0, -1);

var post = ''; editor.set(editor.get.substring(0, from) + post); }

function putpagename(editor) { var pagename = mw.config.get('wgPageName').replace(/_/g, ' '); editor.replaceSelection(pagename); }

function uc(editor) { editor.replace(/(\{\{[Uu]c\s*\|\s*)([^\}]+)(\}\})/g, function(match, before, text, after) {			return before + text.toUpperCase + after;		}); }

function upper(editor) { editor.replaceSelection(function(text) {			return text.toUpperCase;		}); } }); //

if (mw.toolbar) { // 	$('#wpTextbox1').wikiEditor('addToToolbar', {		section: 'main',		group: 'format',		tools: {			'custom-Lgr': {				label: 'Lgr ',				type: 'button',				icon: ,				action: {					type: 'encapsulate',					options: {						pre: ,						post: ,						sampleText: 					}				}			},			'custom--Bl': {				label: '-Bl • ',				type: 'button',				icon: ,				action: {					type: 'encapsulate',					options: {						pre: ,						sampleText: 					}				}			},			'custom-Sm': {				label: 'Sm ',				type: 'button',				icon: ,				action: {					type: 'encapsulate',					options: {						pre: ,						post: ,						sampleText: 					}				}			},			'custom--Bs': {				label: '-Bl • ',				type: 'button',				icon: ,				action: {					type: 'encapsulate',					options: {						pre: ,						sampleText: 					}				}			},			'custom-C': {				label: 'C • ',				type: 'button',				icon: '',				action: {					type: 'encapsulate', options: { pre: '', post: '', sampleText: '' }				}			},			'custom-Bl-c': { label: 'Bl-c • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '', sampleText: '' }				}			},			'custom-Qt': { label: 'Qt • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '', sampleText: '' }				}			},			'custom-Rl': { label: 'Rl • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '', sampleText: '' }				}			},			'custom-Di': { label: 'Di • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '', sampleText: '' }				}			},			'custom-Rt': { label: 'Rt • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '', post: '', sampleText: '' }				}			},			'custom-Ref': { label: 'Ref • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: ' ', sampleText: '' }				}			},			'custom-Sct-b': { label: 'Sct-b • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '', sampleText: '' }				}			},			'custom-Sct-e': { label: 'Sct-e •', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '', sampleText: '' }				}			},			'custom-Ttl': { label: 'Ttl • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '', sampleText: '' }				}			},			'custom-Img-Flt': { label: 'Img-Flt • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '{| style="float:right; "\n|-\n|width=280px|\n\n|}\n', sampleText: '' }				}			},			'custom-Img-Ctr': { label: 'Img-Ctr • ', type: 'button', icon: '', action: { type: 'encapsulate', options: { pre: '\n\n', sampleText: '' }				}			}		}	});	// }