After years of fear and procrastination I decided to learn regular expressions. This is the result:CoffeScript:str = <h2><a name=\#{chapter._id}\>#{chapter.title}</a></h2>\n\n#{chapter.content}\n\nstr.replace(/>([^>]+)</g, (r) ->  r.replace(/(>|\s)/g, $1)   .replace(//g, )   .replace(/(|\s)'/g, $1)   .replace(/'/g, ))JavaScript:var str = <h2><a name=\ + chapter._id + \> + chapter.title + </a></h2>\n\n + chapter.content + \n\n;str.replace(/>([^>]+)</g, function(r) {  return r.replace(/(>|\s)/g, $1)          .replace(//g, )          .replace(/(|\s)'/g, $1)          .replace(/'/g, );});As you can see, the code turns all straight quotation characters (plus apostrophe) to curly ones. It was a bit hard because the input had stuff like this:<p class=>Yes, he said, I met her. She's very 'friendly.'</p>So I had to make sure the quotes inside the HTML tags were not being included. And make the code know that quotations wouldn't always be preceded by a space (sometimes by an >).I welcome any suggestion to make the code shorter, more efficient/readable.
Regex for curly quotes and apostrophes
javascript;regex;coffeescript
Since you know that the double quotes will always be matched, you might try this instead of your first two replaces:r.replace(/([^]*)/g, $1)I think that's a little stronger.  The unmatched single quotes are harder, and I think what you have is reasonable.  I might try this tack though if JavaScript has the \w for word letters.  (If not, use [a-zA-Z].).replace(/(\w)'(\w)/g, $1$2).replace(/'([^']*)'/g, $1)