User:Mirabel75/vector.js

From Wikisource
Jump to navigation Jump to search
Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences

For details and instructions about other browsers, see Wikipedia:Bypass your cache.

//<nowiki> == IMPORT REGEX MENU FRAMEWORK ==
// Regex menu framework
// by [[m:user:Pathoschild]] <http://meta.wikimedia.org/wiki/User:Pathoschild/Scripts/Regex_menu_framework>
// Adds a sidebar menu of user-defined scripts.
mw.loader.load('//meta.wikimedia.org/w/index.php?title=User:Pathoschild/Scripts/Regex_menu_framework.js&action=raw&ctype=text/javascript');


// == IMPORT WORK-SPECIFIC INFORMATION ABOUT HEADERS, FOOTERS, REFS, ETC ==
//get specialFormats variable from work.js
mw.loader.load('//en.wikisource.org/w/index.php?title=User:Hesperian/works.js&action=raw&ctype=text/javascript');




// == CONVENIENCE FUNCTIONS ==
// === FOR EXTRACTING INFORMATION ABOUT PAGE ===

//convenience function - pulls djvu page number out of url
function page() {
	var m = /\.djvu\/([0-9]+)&action=edit/g.exec(location.href);
	if (m === null) return null;
	return parseInt(m[1], 10);
}

var pagenum = page();


//convenience function - pulls work title out of url.
// reversal of url encoding is a dirty hack
function work() {
	var m = /title=Page:([^\.]+\.djvu)/g.exec(location.href);
	if (m === null) return null;
	t = m[1].replace(/_/g, " ");
	return t;
}

var worktitle = work();


// find out page quality status
function quality() {
	var q = document.getElementById('pagequality');
	if (q === null) {
		return "Nonexistent";
	} else {
		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;
}

// These variables can be used to customize operations depending on whether you are working with unproofed OCR or already proofed text.
var quality;
var proofed;
$(function() {
	quality = quality();
	proofed = ((quality != "Nonexistent") && (quality != "Not proofread"));
});


// === FOR CONVERSIONS ===

// convenience function for converting to roman numerals
function roman(number) {
	var values = {
		m: 1000,
		cm: 900,
		d: 500,
		cd: 400,
		c: 100,
		xc: 90,
		l: 50,
		xl: 40,
		x: 10,
		ix: 9,
		v: 5,
		iv: 4,
		i: 1
	};
	var romanexpr = '';
	var value;

	for (value in values) {
		while (number >= values[value]) {
			romanexpr = romanexpr + value;
			number = number - values[value];
		}
	}
	return romanexpr;
}

function upperroman(number) {
	var values = {
		M: 1000,
		CM: 900,
		D: 500,
		CD: 400,
		C: 100,
		XC: 90,
		L: 50,
		XL: 40,
		X: 10,
		IX: 9,
		V: 5,
		IV: 4,
		I: 1
	};
	var romanexpr = '';
	var value;

	for (value in values) {
		while (number >= values[value]) {
			romanexpr = romanexpr + value;
			number = number - values[value];
		}
	}
	return romanexpr;
}

// 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() {
	var editbox = document.getElementsByName('wpTextbox1')[0];

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

	// remove trailing whitespace preceding a hard line break
	editbox.value = editbox.value.replace(/ +<br *\/?>/g, '<br />');

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

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

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

	// convert double-hyphen to mdash (avoiding breaking HTML comment syntax)
	editbox.value = editbox.value.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).
	editbox.value = editbox.value.replace(/ +— +/g, '—');

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

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

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

	}

	// dump spurious hard breaks at the end of paragraphs
	editbox.value = editbox.value.replace(/<br *\/?>\n\n/g, '\n\n');

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


	// unicodify
	editbox.value = editbox.value.replace(/&mdash;/g, '—');
	editbox.value = editbox.value.replace(/&ndash;/g, '–');


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

	// "the", "them", "their", etcetera
	editbox.value = editbox.value.replace(/tlie/g, 'the');

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



	// replace "float center" with "block center"; original template name was misleading enough be warrant routinely fixing
	editbox.value = editbox.value.replace(/\{\{float center/g, '{{block center');

	editbox.value = editbox.value.replace(/<center>\s*([.\n]*?)\s*<\/center>/g, '{{center|$1}}');


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




// automatically insert running header into header box
function header(doGeneric) {
	doGeneric = typeof doGeneric !== 'undefined' ? doGeneric : true; // if parameter not passed then it defaults to true

	if (pagenum === null) return;

	var isEven = (0 === pagenum % 2);

	var headerbox = document.getElementsByName('wpHeaderTextbox')[0];

	var generic = true;
	var headertext = "";

	for (var f in specialFormats) {
		var format = specialFormats[f];
		if (-1 != location.href.indexOf(encodeURI(format[0].replace(/ /g, "_")).replace(/\'/g, "%27"))) {
			if (isEven) {
				headertext = format[1];
			} else {
				headertext = format[2];
			}
			generic = false;
			break;
		}
	}

	// no special header matched, use a generic running header
	if (generic && doGeneric) {
		if (isEven) {
			// assume verso, with page number at left
			headertext = '{{running header|left=|center=}}';
		} else {
			headertext = '{{running header|center=|right=}}';
		}
	}

	if (headerbox.value === "") {
		headerbox.value = headertext;
	} else {
		headerbox.value = headerbox.value + '\n' + headertext;
	}


	// 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) {
		editbox.value = editbox.value.slice(editbox.value.indexOf('\n') + 1);
	}
}


// insert formatted references into footer box, if needed.
function footer(doGeneric) {
	doGeneric = typeof doGeneric !== 'undefined' ? doGeneric : true; // if parameter not passed then it defaults to true

	var editbox = document.getElementsByName('wpTextbox1')[0];
	var footerbox = document.getElementsByName('wpFooterTextbox')[0];

	var generic;

	var format;
	var f;
	if ((-1 == editbox.value.indexOf("<ref>")) &&
		(-1 == editbox.value.indexOf("{{#tag:ref"))) {
		// page contains no refs
		generic = true;
		for (f in specialFormats) {
			format = specialFormats[f];
			if (-1 != location.href.indexOf(encodeURI(format[0].replace(/ /g, "_")).replace(/\'/g, "%27"))) {
				footerbox.value = format[3];
				generic = false;
				break;
			}
		}

		// no special footer matched, use just strip out the references tag
		if (generic && doGeneric) {
			footerbox.value = '';
		}
	} else {
		generic = true;
		for (f in specialFormats) {
			format = specialFormats[f];
			if (-1 != location.href.indexOf(encodeURI(format[0].replace(/ /g, "_")).replace(/\'/g, "%27"))) {
				footerbox.value = format[4];
				generic = false;
				break;
			}
		}
		// no special footer matched, so use a generic ref tag
		if (generic && doGeneric) {
			footerbox.value = '{{block center|{{smallrefs}}}}';
		}
	}
}

// automatically insert block center wrapping into header box
function blockcenter() {
	var headerbox = document.getElementsByName('wpHeaderTextbox')[0];
	headerbox.value = headerbox.value + "\n{{block center/s}}";

	var footerbox = document.getElementsByName('wpFooterTextbox')[0];
	footerbox.value = "{{block center/e}}\n" + footerbox.value;
}



//Make selected text into appropriately capitalised title link
// e.g. "THE MAN FROM SNOWY RIVER" —> "[[The Man from Snowy River|THE MAN FROM SNOWY RIVER]]"
function title() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	var selStart = editbox.selectionStart;
	var selEnd = editbox.selectionEnd;
	var text = editbox.value.substring(selStart, selEnd);

	var target = titlecase(text);

	// construct link text
	var linked;
	if (target == text) {
		linked = '[[' + text + ']]';
	} else {
		linked = '[[' + target + '|' + text + ']]';
	}

	// replace text with link text
	editbox.value = editbox.value.substring(0, selStart) + linked + editbox.value.substring(selEnd);
	editbox.focus();
	editbox.setSelectionRange(selStart + linked.length, selStart + linked.length);
}

//Make selected text into author link
function author() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	var selStart = editbox.selectionStart;
	var selEnd = editbox.selectionEnd;
	var name = editbox.value.substring(selStart, selEnd);

	// If name is all in capitals, convert target to title case.
	var target = name;
	if (target == target.toUpperCase()) {
		target = titlecase(target);
	}

	var linked = '[[Author:' + target + '|' + name + ']]';
	editbox.value = editbox.value.substring(0, selStart) + linked + editbox.value.substring(selEnd);
	editbox.focus();
	editbox.setSelectionRange(selStart + linked.length, selStart + linked.length);
}

//Mark selected text up with small-caps
function smallcaps() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	var selStart = editbox.selectionStart;
	var selEnd = editbox.selectionEnd;
	var pre = editbox.value.substring(selStart, selEnd);

	// 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);
	}

	var post = '{{small-caps|' + pre + '}}';
	editbox.value = editbox.value.substring(0, selStart) + post + editbox.value.substring(selEnd);
	editbox.focus();
	editbox.setSelectionRange(selStart + post.length, selStart + post.length);
}

// As you work your way through the page, when you encounter a reference, just mark it with <ref></ref> 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() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	var refStart = editbox.selectionStart;
	var refEnd = editbox.selectionEnd;

	var firstref = editbox.value.indexOf('<ref></ref>');
	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 <ref></ref> 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 = document.getElementsByName('wpTextbox1')[0];
	var refStart = editbox.selectionStart;
	var refEnd = editbox.selectionEnd;

	var firstref = editbox.value.indexOf('<ref></ref>');
	if (-1 != firstref) {
		editbox.value = editbox.value.slice(0, firstref) + "{{#tag:ref|" + editbox.value.slice(refStart, refEnd) + " <includeonly>{{#section:Page:" + worktitle + "/" + (pagenum + 1) + "|overflow}}</includeonly>}}" + editbox.value.slice(firstref + 11, refStart) + editbox.value.slice(refEnd);
	}
}

function makeoverflow2() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	var refStart = editbox.selectionStart;
	var refEnd = editbox.selectionEnd;

	editbox.value = "<section begin=\"text\"/>" + editbox.value.slice(0, refStart) + "<section end=\"text\"/>\n\n<div style=\"font-size:smaller;\">\n<section begin=\"overflow\"/>" + editbox.value.slice(refStart, refEnd) + "<section end=\"overflow\"/>\n</div>";
}

//wrap first word in hwe template
function hwe() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	var to = editbox.value.search(/\W/);
	if (to == -1) to = editbox.value.length;

	var pre = editbox.value.substring(0, to);

	var post = '{{hyphenated word end|' + pre + '|…' + pre + '}}';
	editbox.value = post + editbox.value.substring(to);
}

//wrap last word in hws template
function hws() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	var from = editbox.value.lastIndexOf(" ");
	if (from == -1) from = 0;
	else from = from + 1;

	var pre = editbox.value.substring(from);

	if (pre.slice(-1) == "-") pre = pre.slice(0, -1);

	var post = '{{hyphenated word start|' + pre + '|' + pre + '…}}';
	editbox.value = editbox.value.substring(0, from) + post;
}


function diareses() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	var selStart = editbox.selectionStart;
	var selEnd = editbox.selectionEnd;
	var pre = editbox.value.substring(selStart, selEnd);

	switch (pre) {
		case 'a':
			post = 'ä';
			break;
		case 'A':
			post = 'Ä';
			break;
		case 'e':
			post = 'ë';
			break;
		case 'E':
			post = 'Ë';
			break;
		case 'i':
			post = 'ï';
			break;
		case 'I':
			post = 'Ï';
			break;
		case 'o':
			post = 'ö';
			break;
		case 'O':
			post = 'Ö';
			break;
		case 'u':
			post = 'ü';
			break;
		case 'U':
			post = 'Ü';
			break;
		case 'y':
			post = 'ÿ';
			break;
		default:
			post = pre;
			break;
	}

	editbox.value = editbox.value.substring(0, selStart) + post + editbox.value.substring(selEnd);
	editbox.focus();
	editbox.setSelectionRange(selStart + post.length, selStart + post.length);
}

function acute() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	var selStart = editbox.selectionStart;
	var selEnd = editbox.selectionEnd;
	var pre = editbox.value.substring(selStart, selEnd);

	switch (pre) {
		case 'a':
			post = 'á';
			break;
		case 'A':
			post = 'Á';
			break;
		case 'c':
			post = 'ć';
			break;
		case 'C':
			post = 'Ć';
			break;
		case 'e':
			post = 'é';
			break;
		case 'E':
			post = 'É';
			break;
		case 'g':
			post = 'ģ';
			break;
		case 'i':
			post = 'í';
			break;
		case 'I':
			post = 'Í';
			break;
		case 'o':
			post = 'ó';
			break;
		case 'O':
			post = 'Ó';
			break;
		case 'l':
			post = 'ĺ';
			break;
		case 'L':
			post = 'Ĺ';
			break;
		case 'n':
			post = 'ń';
			break;
		case 'N':
			post = 'Ń';
			break;
		case 'r':
			post = 'ŕ';
			break;
		case 'R':
			post = 'Ŕ';
			break;
		case 's':
			post = 'ś';
			break;
		case 'S':
			post = 'Ś';
			break;
		case 'u':
			post = 'ú';
			break;
		case 'U':
			post = 'Ú';
			break;
		case 'y':
			post = 'ý';
			break;
		case 'Y':
			post = 'Ý';
			break;
		case 'z':
			post = 'ź';
			break;
		case 'Z':
			post = 'Ź';
			break;
		default:
			post = pre;
			break;
	}

	editbox.value = editbox.value.substring(0, selStart) + post + editbox.value.substring(selEnd);
	editbox.focus();
	editbox.setSelectionRange(selStart + post.length, selStart + post.length);
}


function uc() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	matches = /\{\{[Uu]c\s*\|\s*([^\}]+)\}\}/g.exec(editbox.value);
	while (matches !== null) {
		editbox.value = editbox.value.replace(matches[0], matches[1].toUpperCase());
		matches = /\{\{[Uu]c\s*\|\s*([^\}]+)\}\}/g.exec(editbox.value);
	}
}



function upper() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	editbox.focus();
	var selStart = editbox.selectionStart;
	var selEnd = editbox.selectionEnd;
	var text = editbox.value.substring(selStart, selEnd);

	var upperCaseText = text.toUpperCase();

	editbox.value = editbox.value.substring(0, selStart) + upperCaseText + editbox.value.substring(selEnd);
	editbox.setSelectionRange(selStart, selStart + upperCaseText.length);
}


function link() {
	var editbox = document.getElementsByName('wpTextbox1')[0];
	editbox.value = editbox.value.replace(/\b([1-9][0-9]{0,2})\b/g, "{{subst:User:Zyephyrus/i|$1}}");
}

// == SHORTCUT SUPPORT ==

function deregisterShortcut(shortcut) {
	switch (shortcut) {
		case "'":
			result = document.querySelector("[accesskey=\"'\"]");
			break;
		case '"':
			result = document.querySelector('[accesskey=\'"\']');
			break;
		default:
			result = document.querySelector("[accesskey=\"" + shortcut + "\"]");
			break;
	}

	if (result) {
		result.removeAttribute("accesskey");
	}
}

function regexToolWithShortcut(name, functionname, shortcut) {
	var newline = document.createElement('li');
	newline.setAttribute('style', 'padding: 0px;');

	var newlink = document.createElement('button');
	newlink.setAttribute('style', 'background:none!important; border:none; padding:0!important; text-align: left; ');
	newlink.setAttribute('onclick', functionname);
	newlink.setAttribute('title', name);
	newlink.setAttribute('class', 'sidebar-link');

	if ((shortcut === null) || (shortcut === "")) {
		// do nothing
	} else {
		deregisterShortcut(shortcut);
		newlink.setAttribute('accesskey', shortcut);
	}

	newlink.appendChild(document.createTextNode(name));

	newline.appendChild(newlink);
	toollist.appendChild(newline);
}

function reload_page_image() {
	var thumbElement = document.getElementById("ProofReadImage");
	if (thumbElement === null) return;

	var match = thumbElement.src.match(/-([0-9]+)px/);
	if (match === null) return;

	thumbElement.src = thumbElement.src.replace(match[0], "-" + (match[1] * 9 / 10) + "px");
}

// == REGISTER TOOLS IN SIDEBAR ==
function rmflinks() {
	// stuff I routinely do at the start
	if (namespace == "Page") {
		regexToolWithShortcut('header', 'header()', null);
		regexToolWithShortcut('clean up', 'cleanup(false)', null);
		regexToolWithShortcut('uc', 'uc()', null);
		regexToolWithShortcut('hwe', 'hwe()', null);
	}

	// stuff I can do any time
	regexToolWithShortcut('Custom regex', 'custom()', null); // a default tool which performs regex input in a dynamic form
	regexToolWithShortcut('title [t]', 'maketitle()', 't');
	regexToolWithShortcut('author [a]', 'author()', 'a');
	regexToolWithShortcut('small-caps [c]', 'smallcaps()', 'c');
	regexToolWithShortcut('upper [u]', 'upper()', 'u');

	// stuff I do at the end
	if (namespace == "Page") {
		regexToolWithShortcut('hws', 'hws()', null);
		regexToolWithShortcut('makeref', 'makeref()', null);
		regexToolWithShortcut('footer', 'footer()', null);
	}

	// stuff I only do via shortcuts; if I could create these shortcuts without adding them to the sidebar, I would.
	regexToolWithShortcut('diaresis [:]', 'diareses()', ':');
	regexToolWithShortcut('acute [\']', 'acute()', '\'');
	regexToolWithShortcut('grave [`]', 'grave()', '`');
	regexToolWithShortcut('circumflex [^]', 'circumflex()', '6');
	regexToolWithShortcut('others [-]', 'catchall()', '-');
	regexToolWithShortcut('pagename [n]', 'putpagename()', 'n');

	regexToolWithShortcut('reload', 'reload_page_image()', null);
}
//</nowiki>