Fixing the Quote Tag <Q> in Internet Explorer

Much has been written about how the quote tag <Q> tag has no support in Internet Explorer. Many have complained that due to the age of the tag, they are greatly surprised that it has been ignored. To give Microsoft some credit, at least they created a facility to extend support within the browser through the addition of behaviors.

Here I will show a behavior to implement quotes for English users (but it will be easy to modify for any language). It will follow the rule of alternating double and single quotes as quotes are nested. I am borrowing this from the wikipedia page on the subject of quotes. Here is a demonstration with 3 levels of quotes (kind of excessive):

After seeing the movie, I quoted it, <q><q>HAL said, <q>Good morning, Dave,</q>?</q> recalled Frank.</q>

After seeing the movie, I quoted it, HAL said, Good morning, Dave,? recalled Frank.

Referencing the Behavior

To refence the behavior, just use some CSS like the following.

  1. <style type="text/css">
  2.   q { behavior:url(fixQuotes_en.htc); }
  3. </style>

This just tells Internet Explorer to use apply the bahavior at the url specified to the Q

The Quote Behavior

The following block is some code I've thrown together for a quote behavior.

  1. <public:attach event="oncontentready" onevent="init();" />
  2. <script>
  3. /*
  4. * This will make each level of nested quotes alternate between
  5. * single and double quotes.
  6. * Reference: http://en.wikipedia.org/wiki/Quotation_mark
  7. */
  8. var quotes = {
  9.   even : {open:0x201C, close:0x201D },
  10.   odd  : {open:0x2018, close:0x2019 }
  11. };
  12. /* Returns the level that a tag is nested within itself  */
  13. function getNestedLevel(tagName,node,cLevel){
  14.   var level = 0;
  15.   var parent = node.parentNode;
  16.   if(parent != null){
  17.     if(node.parentNode.tagName == tagName){
  18.       level++;
  19.     }
  20.     level += getNestedLevel(tagName,parent,level);
  21.   }
  22.   return level;
  23. }
  24. function init() {
  25.   var nestedLevel = getNestedLevel(this.tagName,this,0);
  26.   var type = (nestedLevel%2==0) ? "even":"odd";
  27.   var openQ  = document.createTextNode(
  28.     String.fromCharCode(quotes[type].open));
  29.   var closeQ = document.createTextNode(
  30.     String.fromCharCode(quotes[type].close));
  31.   this.insertBefore(openQ,this.firstChild);
  32.   this.appendChild(closeQ);
  33. }
  34. </script>

This behavior defines two sets of quotes, odd and even (lines 8-11). These are used to alternate between levels of nesting. The even (starting at zero) are character codes for facing double quotes. And, the odd are character codes for facing single quotes.

The getNestedLevel function (lines 13-23) is a recursive function that checks for the level of nesting. It works by determining how deeply a tag is nested within the same tag. This allows preventing other markup tags from affecting the result.

The init function (lines 24-33) checks the level of nesting to get the correct quotes. It then creates textNode objects for the quote characters (lines 27-30). Next, the text nodes are inserted at the beginning (line 31) and the end (line 32) of the quoted element.

Resources

Follow-up

If you are defining the title and cite attributes of the quote tag, then take a look at a technique to add hovering bubble tooltips to your quote elements.

I found a similar, alterative, implementation by Charles Conrad, from Conrad Consulting on his Web Development Odyssey page. See number 4 toward the bottom of his page. His behavior can be seen here: fixquotes behavior file.

Conrad takes a different approach to the same problem and uses a non-recursive algorithm. He still uses a behavior to make it work. The good thing about the behavior approach is it keeps the IE version separate from other browsers. very cool.

I've just discovered that Juicy Studio describes a non-behavior technique for fixing IE quotes. They give a much better description of the issue, as well (whereas I just talk about my own solution). Kudos to Gez Lemon.



Sponsors:

About willCode4Beer