» JeaseCMS » Блог

Non-english quotation marks with jQuery

Quotation marks are simple as cake for people producing english content on the web: just use "..." on your keyboard and you're done...

But for non-english people the story is a lot more complicated. They can still press "..." and will get "..." on the screen, but in regard to correct typography this is simply wrong, because quotation marks in non-english languages have different forms in print... e.g. they should look like „…“ in German... so why not on the web, too?

If you try to create content with correct quotation marks in a non-english language, this may work if you are very focused and use weird keyboard shortcuts noone can remember... sooner or later you (or your co-worker) start using "..." again and the quotation mark chaos breaks free.

So if people are not capable of doing things correctly, because they are frustrating without a good reason, let the machine do the crackbrained work. And with the power of jQuery it is very easy to exchange the english-quotation marks with the correct foreign ones on the fly.

Here's an example which provides the translation of quotation marks for the German language which is built on top of jQuery. It should be easily adaptable to other languages or use cases.

The first part selects and filters all text nodes (besides script,pre,code or kbd tags, here we want to keep the good old english quotes in code listings) in the body of the document and performs a text transformation on each node, where a set of more or less complicated regular expressions will do the replacemant of all single and double quotes with their correct counterparts.

[example?print View an example]

$(document).ready(function() {  
  $("*", "body").not("script,pre,code,kbd").contents().filter(function(){
    return this.nodeType == 3;    
        this.nodeValue = transform(this.nodeValue);
  function transform(str) {
    if (/^\s+$/.test(str)) {
      return str;
    var doubleOpen = "\u201E", doubleClosed = "\u201C", singleOpen = "\u201A", singleClose = "\u2018";
    str = str.replace(/(^|\s|[\("\-])'([^']*)'($|[\.,;:!?\/"\)\-]|\s)/g, "$1" + singleOpen + "$2" + singleClose + "$3");
    str = str.replace(/(^|\s|\(|\-)'$/g, "$1" + singleOpen);
    str = str.replace(/^'([\.,;:!?\/\)\-]|\s)/g, singleClose + "$1");
    str = str.replace(/(^|\s|\(|\-)"([^"]*)"($|[\.,;:!?\/\)\-]|\s)/g, "$1" + doubleOpen + "$2" + doubleClosed+ "$3");
    str = str.replace(/(^|\s|\(|\-)"(\s*)$/g, "$1" + doubleOpen + "$2");
    str = str.replace(/^(\s*)"([\.,;:!?\/\)\-]|\s)/g, "$1" + doubleClosed + "$2");
    return str;

Last modified on 2012-04-23 by Maik Jablonski