User:MadCowpoke/common.js

// == IMPORT REGEX MENU FRAMEWORK == // Regex menu framework // by m:user:Pathoschild  // Adds a sidebar menu of user-defined scripts. mw.loader.load('https://meta.wikimedia.org/w/index.php?title=User:Pathoschild/Scripts/Regex_menu_framework.js&action=raw&ctype=text/javascript'); //link "Download as EPUB" if (wgNamespaceNumber == 0) { $(document).ready( function {     mw.util.addPortletLink( 'p-coll-print_export', '//toolserver.org/~tpt/wsexport/book.php?lang=en&format=epub&page=' + mw.config.get('wgPageName'), 'Download as EPUB', 'n-epubExport', 'Download an EPUB version of this page', '',      '#t-print');    }); } // Scripts and notes by Hesperian // == 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]); } var pagenum=page; //convenience function - identifies namespace function get_namespace { var m = /index.php\?title=Page:/g.exec(location.href); if (m!=null) return "Page"; return "other"; } var namespace=get_namespace; //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; function getpagename { var m = /title=([^&]+)&/g.exec(location.href); if (m==null) return null; t = m[1].replace(/_/g, " "); t = t.replace(/%3F/g, "?"); t = t.replace(/%27/g, "'"); t = t.replace(/%22/g, '"');  return t; } var pagename = getpagename; // find out page quality status function getQuality {    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 = getQuality; var 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 roman = ''; var value; for (value in values) { while (number >= values[value] ) { roman = roman + value; number = number - values[value]; } }  return roman; } // 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 (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]; var headerbox = document.getElementsByName('wpHeaderTextbox')[0]; var footerbox = document.getElementsByName('wpFooterTextbox')[0]; // anything noincluded at the start or end of the edit box should be pushed into the header and footer respectively. if (/^\/.test(editbox.value)) { var e = editbox.value.indexOf(" ") // append to header a trimmed version of whatever is inside the leading noinclude headerbox.value = headerbox.value + "\n" + editbox.value.substr(11, e-11).replace(/^\s+|\s+$/g, ''); // remove leading noinclude from editbox editbox.value = editbox.value.substr(e+12); }       if (/\<\/noinclude\>$/.test(editbox.value)) { var s = editbox.value.lastIndexOf(" "); // prepend to footer a trimmed version of whatever is inside the trailing noinclude footerbox.value = editbox.value.substr(s+11, editbox.value.length-s-11-12).replace(/^\s+|\s+$/g, '') + "\n" + footerbox.value // remove trailing noinclude from editbox editbox.value = editbox.value.substr(0, s)       } // 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(/ +/g, ' '); // 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, ' '); // 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 tag: if (-1 == editbox.value.indexOf(" ")) { // 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(/\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(/–/g, '–') editbox.value = editbox.value.replace(/&quot;/g, '"');       // straighten quotes and apostrophes.        editbox.value = editbox.value.replace(/[“”]/g, '"'); editbox.value = editbox.value.replace(/[‘’`]/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(/ \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 { if (pagenum==null) return; var isEven = (0==pagenum%2); var headerbox = document.getElementsByName('wpHeaderTextbox')[0]; var generic = true; for (f in specialFormats) { var format = specialFormats[f]; if (-1 != location.href.indexOf(format[0])) { if (isEven) { headerbox.value = headerbox.value + '\n' + format[1]; } else { headerbox.value = headerbox.value + '\n' + format[2]; }           generic = false; break; }   }    // no special header matched, use a generic running header if (generic) { if (isEven) { // assume verso, with page number at left headerbox.value = headerbox.value + '\n'; } else { // assume recto, with page number at right headerbox.value = headerbox.value + '\n'; }   }    // 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 { var editbox = document.getElementsByName('wpTextbox1')[0]; var footerbox = document.getElementsByName('wpFooterTextbox')[0]; if ((-1 == editbox.value.indexOf(" ")) &&       (-1 == editbox.value.indexOf("{{#tag:ref"))) { // page contains no refs var generic = true; for (f in specialFormats) { var format = specialFormats[f]; if (-1 != location.href.indexOf(format[0])) { footerbox.value = footerbox.value.replace(' ',format[3]); generic = false; break; }       }        // no special footer matched, use just strip out the references tag if (generic) { footerbox.value = footerbox.value.replace(' ',''); }   } else { var generic = true; for (f in specialFormats) { var format = specialFormats[f]; if (-1 != location.href.indexOf(format[0])) { footerbox.value = footerbox.value.replace(' ',format[4]); generic = false; break; }       }        // no special footer matched, so use a generic ref tag if (generic) { footerbox.value = footerbox.value.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 { 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 = +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 = +name+; editbox.value = editbox.value.substring(0, selStart) + linked + editbox.value.substring(selEnd); editbox.focus; editbox.setSelectionRange(selStart+linked.length, selStart+linked.length); } function surnameFirst { 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) }       // 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 (i=0; i<nameArray.length-1; i++) name = name+" "+nameArray[i] var linked = +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 = ''; 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 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(' '); 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 = document.getElementsByName('wpTextbox1')[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 { var editbox = document.getElementsByName('wpTextbox1')[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 { 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 = ''; 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 = ''; editbox.value = editbox.value.substring(0, from) + post; } function putpagename { var editbox = document.getElementsByName('wpTextbox1')[0]; var selStart = editbox.selectionStart; var selEnd = editbox.selectionEnd; editbox.value = editbox.value.substring(0, selStart) + pagename + editbox.value.substring(selEnd); editbox.focus; editbox.setSelectionRange(selStart+pagename.length, selStart+pagename.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]; 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.focus; editbox.setSelectionRange(selStart, selStart+upperCaseText.length); } // == SHORTCUT SUPPORT == function deregisterShortcut(shortcut) { switch(shortcut) {               case "'": result = document.evaluate("//*[@accesskey=\"'\"]", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null); break; case '"':                       result = document.evaluate('//*[@accesskey=\'"\']', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null); break; default: result = document.evaluate("//*[@accesskey='"+shortcut+"']", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null); break; }       node = result.singleNodeValue; if (node) { node.setAttribute('accesskey',''); } } function regexToolWithShortcut(name,functionname,shortcut) { var newline = document.createElement('li'); var newlink = document.createElement('a'); newlink.setAttribute('href','javascript:'+functionname); newlink.setAttribute('title',name); newlink.setAttribute('class','sidebar-link'); deregisterShortcut(shortcut); newlink.setAttribute('accesskey', shortcut); newlink.appendChild(document.createTextNode(name)); newline.appendChild(newlink); toollist.appendChild(newline); } // == REGISTER TOOLS IN SIDEBAR == function rmflinks { // stuff I routinely do at the start if (namespace == "Page") { regexToolWithShortcut('header [z]','header','z'); regexToolWithShortcut('clean up [x]','cleanup', 'x'); regexTool('uc','uc'); regexTool('hwe','hwe'); }       // stuff I can do any time regexTool('Custom regex','custom'); // a default tool which performs regex input in a dynamic form regexToolWithShortcut('title [t]','title', 't'); regexToolWithShortcut('author [a]','author','a'); regexToolWithShortcut('author (surname first) [,]','surnameFirst',','); regexToolWithShortcut('small-caps [c]','smallcaps', 'c'); regexToolWithShortcut('upper [^]','upper', '6'); // stuff I do at the end if (namespace == "Page") { regexTool('hws','hws'); regexTool('makeref', 'makeref'); regexTool('makeoverflow1', 'makeoverflow1'); regexTool('makeoverflow2', 'makeoverflow2'); regexToolWithShortcut('footer [f]','footer', 'f'); }       // stuff I only do via shortcuts; if I could create these shortcuts without adding them to the sidebar, I would. regexToolWithShortcut('pagename','putpagename', 'n'); } self.proofreadpage_disable_wheelzoom = true; if (mwCustomEditButtons) { mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": "http://upload.wikimedia.org/wikipedia/commons/8/8b/Button_m-dash.png", "speedTip": "M-dash", "tagOpen": '—', "tagClose": '', "sampleText": ""}; }; if (mwCustomEditButtons) { mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": "http://upload.wikimedia.org/wikipedia/commons/8/8b/Button_n-dash.png", "speedTip": "N-dash", "tagOpen": '–', "tagClose": '', "sampleText": ""}; }; if (mwCustomEditButtons) { mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": "http://upload.wikimedia.org/wikipedia/commons/5/5e/Button API ɑ.png", "speedTip": "ae", "tagOpen": 'æ', "tagClose": '', "sampleText": ""}; }; if (mwCustomEditButtons) { mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": "http://upload.wikimedia.org/wikipedia/commons/5/5e/Button API ɑ.png", "speedTip": "AE", "tagOpen": 'Æ', "tagClose": '', "sampleText": ""}; }; if (mwCustomEditButtons) { mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": "http://upload.wikimedia.org/wikipedia/commons/1/1e/Button API œ.png", "speedTip": "oe", "tagOpen": 'œ', "tagClose": '', "sampleText": ""}; }; if (mwCustomEditButtons) { mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": "http://upload.wikimedia.org/wikipedia/commons/1/1e/Button API œ.png", "speedTip": "OE", "tagOpen": 'Œ', "tagClose": '', "sampleText": ""}; }; if (mwCustomEditButtons) { mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": "http://upload.wikimedia.org/wikipedia/commons/6/6f/Wikifier1-button-bg.png", "speedTip": "Pound", "tagOpen": '£', "tagClose": '', "sampleText": ""}; }; if (mwCustomEditButtons) { mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": "http://upload.wikimedia.org/wikipedia/commons/4/4e/Button_romain.png", "speedTip": "Small caps", "tagOpen": '', "sampleText": ""}; }; //