User:Crissov/cologneblue.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.
//<source lang="javascript">
// [[User:Werson/smartQuotes.js]]
// version 1.2, 2008-05-14 
// 

function quoteReplace(data) {
    // single quotation marks,
   //   problematic because apostrophes (same codepoint as closing quotes,
   //   unfortunately) can come at the beginning of words, so we need to
   //   list likely examples of that
   data = data.replace(/'([Nn])(\W)/g, '’$1$2');    // Guns 'n' Roses, or Guns 'n Roses, should use apostrophes
   data = data.replace(/'(\d)0s/g, '’$10s');  // '80s, '90s, etc.
   data = data.replace(/'([Tt]is)/g, '’$1');  // 'Tis the season, etc.
   data = data.replace(/'([Tt]was)/g, '’$1');  // 'Twas the season, etc.
   data = data.replace(/^'s(\W)/g, '’s$1');   // [[John]]'s (links are separate nodes, so this would otherwise be seen as 'S...')
    // the rest of these are homologous to double quotation marks
   data = data.replace(/\s'/g, ' ‘');
   data = data.replace(/^'([\d\w])/g, '‘$1');
   data = data.replace(/(\W)"([\d\w])/g, '$1“$2');
   data = data.replace(/'/g, '’');
    // double quotation marks
   data = data.replace(/\s"/g, ' “');              // a closing mark will never be preceded by a space
   data = data.replace(/"([\d\w])/g, '“$1');      // a closing mark will never be at the beginning of a line (and won't be after a link if it's followed by a letter)
   data = data.replace(/(\W)"([\d\w])/g, '$1“$2');          // a closing mark won't be after a punctuation mark but before a letter
   data = data.replace(/"/g, '”');            // anything else is probably a closer
   return data; 
}
// go through document and get all text nodes, then replace quotation marks 
function smartQuotes() {
   if (document.URL.indexOf('action=history') < 1 && document.URL.indexOf('action=edit') < 1) {
     // title is a special case, as replacing the node text doesn't do anything
     document.title = quoteReplace(document.title);
     // use an XPATH to find all text nodes, and run each one through quoteReplace()
     //   but do not alter PRE, CODE, or TT elements, or any of their descendents
     //   (I don't know how to do this elegantly in XPath)
     var xPathResult = document.evaluate('.//body//text()[not(ancestor::pre or ancestor::code or ancestor::input or ancestor::textarea) and (normalize-space(.) != "")]', document.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
     // .//*[name(.) != "PRE" and name(.) != "CODE" and name(.) != "TT"]/*[name(.) != "PRE" and name(.) != "CODE" and name(.) != "TT"]/*[name(.) != "PRE" and name(.) != "CODE" and name(.) != "TT"]/text()[normalize-space(.) != ""]
     for (var i = 0, l = xPathResult.snapshotLength; i < l; i++) {
       var textNode = xPathResult.snapshotItem(i);
       textNode.data = quoteReplace(textNode.data);
     }
     // crappy way to do this
     var html = document.body.innerHTML;
     document.body.innerHTML = html.replace('”<a ', '“<a ');
   } 
}
  // initiate smartQuotes script
$(smartQuotes);

//</source>