// smartQuotes.js
// by Werson
// version 1.2, 2008-05-14
// works correctly in:
// · Firefox 2.0
// works somewhat in:
// · Safari 3.1 (doesn't skip PRE/TT/CODE sections)
//
// I, Werson, the copyright holder of this work, hereby release it into the public domain. This applies worldwide.
// In case this is not legally possible, I grant any entity the right to use this work for any purpose,
// without any conditions, unless such conditions are required by law.
// take a string and replace all straight marks with curly marks,
// applying some basic rules (it's almost always a closing mark,
// so figure out the few cases where it's an opening mark)
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('.//*[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(.) != ""]', document.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
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);