I'm using jQuery, and a very simple script to replace quotes, apostrophes and double-dashes with their "smart" counterparts:
function smarten(a) {
a = a.replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018"); // opening singles
a = a.replace(/'/g, "\u2019"); // closing singles & apostrophes
a = a.replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201c"); // opening doubles
a = a.replace(/"/g, "\u201d"); // closing doubles
a = a.replace(/--/g, "\u2014"); // em-dashes
return a
};
I'm using this as a callback to TwitterJS, which parses links and produces a block like so:
<ul> <li>Here's a link! <a href="http://www.foobar.com">http://www.foobar.com</a></li> </ul>
The problem is that if I do this:
$('#tweet li').html(smarten($('#tweet li').html()))
it wrecks the links, and if I do this:
$('#tweet li').html(smarten($('#tweet li').text()))
it discards them altogether.
Is there a smart, robust way to grab only the text (out of the <a>
tag as well, if necessary), "smarten", and then put it back, without interfering with TwitterJS's link-parsing?
Let's make a jQuery plugin:
jQuery.fn.smarten = (function(){
function smartenNode(node) {
if (node.nodeType === 3) {
node.data = node.data
.replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018")
.replace(/'/g, "\u2019")
.replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201c")
.replace(/"/g, "\u201d")
.replace(/--/g, "\u2014");
} else if (node.nodeType === 1) {
if (node = node.firstChild) do {
smartenNode(node);
} while (node = node.nextSibling);
}
}
return function() {
return this.each(function(){
smartenNode(this);
});
};
}());
Usage:
$('#tweet li').smarten();