text: var asciidoc = {  // Namespace.
  
  /////////////////////////////////////////////////////////////////////
  // Table Of Contents generator
  /////////////////////////////////////////////////////////////////////
  
  /* Author: Mihai Bazon, September 2002
   * http://students.infoiasi.ro/~mishoo
   *
   * Table Of Content generator
   * Version: 0.4
   *
   * Feel free to use this script under the terms of the GNU General Public
   * License, as long as you do not remove or alter this notice.
   */
  
   /* modified by Troy D. Hanson, September 2006. License: GPL */
   /* modified by Stuart Rackham, 2006, 2009. License: GPL */
  
  // toclevels = 1..4.
  toc: function (toclevels) {
  
    function getText(el) {
      var text = "";
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
          text += i.data;
        else if (i.firstChild != null)
          text += getText(i);
      }
      return text;
    }
  
    function TocEntry(el, text, toclevel) {
      this.element = el;
      this.text = text;
      this.toclevel = toclevel;
    }
  
    function tocEntries(el, toclevels) {
      var result = new Array;
      var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
      // Function that scans the DOM tree for header elements (the DOM2
      // nodeIterator API would be a better technique but not supported by all
      // browsers).
      var iterate = function (el) {
        for (var i = el.firstChild; i != null; i = i.nextSibling) {
          if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
            var mo = re.exec(i.tagName);
            if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
              result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
            }
            iterate(i);
          }
        }
      }
      iterate(el);
      return result;
    }
  
    var toc = document.getElementById("toc");
    if (!toc) {
      return;
    }
  
    // Delete existing TOC entries in case we're reloading the TOC.
    var tocEntriesToRemove = [];
    var i;
    for (i = 0; i < toc.childNodes.length; i++) {
      var entry = toc.childNodes[i];
      if (entry.nodeName.toLowerCase() == 'div'
       && entry.getAttribute("class")
       && entry.getAttribute("class").match(/^toclevel/))
        tocEntriesToRemove.push(entry);
    }
    for (i = 0; i < tocEntriesToRemove.length; i++) {
      toc.removeChild(tocEntriesToRemove[i]);
    }
    
    // Rebuild TOC entries.
    var entries = tocEntries(document.getElementById("content"), toclevels);
    for (var i = 0; i < entries.length; ++i) {
      var entry = entries[i];
      if (entry.element.id == "")
        entry.element.id = "_toc_" + i;
      var a = document.createElement("a");
      a.href = "#" + entry.element.id;
      a.appendChild(document.createTextNode(entry.text));
      var div = document.createElement("div");
      div.appendChild(a);
      div.className = "toclevel" + entry.toclevel;
      toc.appendChild(div);
    }
    if (entries.length == 0)
      toc.parentNode.removeChild(toc);
  },
  
  
  /////////////////////////////////////////////////////////////////////
  // Footnotes generator
  /////////////////////////////////////////////////////////////////////
  
  /* Based on footnote generation code from:
   * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
   */
  
  footnotes: function () {
    // Delete existing footnote entries in case we're reloading the footnodes.
    var i;
    var noteholder = document.getElementById("footnotes");
    if (!noteholder) {
      return;
    }
    var entriesToRemove = [];
    for (i = 0; i < noteholder.childNodes.length; i++) {
      var entry = noteholder.childNodes[i];
      if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
        entriesToRemove.push(entry);
    }
    for (i = 0; i < entriesToRemove.length; i++) {
      noteholder.removeChild(entriesToRemove[i]);
    }
  
    // Rebuild footnote entries.
    var cont = document.getElementById("content");
    var spans = cont.getElementsByTagName("span");
    var refs = {};
    var n = 0;
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnote") {
        n++;
        var note = spans[i].getAttribute("data-note");
        if (!note) {
          // Use [\s\S] in place of . so multi-line matches work.
          // Because JavaScript has no s (dotall) regex flag.
          note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
          spans[i].innerHTML =
            "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
            "' title='View footnote' class='footnote'>" + n + "</a>]";
          spans[i].setAttribute("data-note", note);
        }
        noteholder.innerHTML +=
          "<div class='footnote' id='_footnote_" + n + "'>" +
          "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
          n + "</a>. " + note + "</div>";
        var id =spans[i].getAttribute("id");
        if (id != null) refs["#"+id] = n;
      }
    }
    if (n == 0)
      noteholder.parentNode.removeChild(noteholder);
    else {
      // Process footnoterefs.
      for (i=0; i<spans.length; i++) {
        if (spans[i].className == "footnoteref") {
          var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
          href = href.match(/#.*/)[0];  // Because IE return full URL.
          n = refs[href];
          spans[i].innerHTML =
            "[<a href='#_footnote_" + n +
            "' title='View footnote' class='footnote'>" + n + "</a>]";
        }
      }
    }
  },
  
  install: function(toclevels) {
    var timerId;
  
    function reinstall() {
      //disable moving of footnotes to the bottom of the page
      //asciidoc.footnotes();
      if (toclevels) {
        asciidoc.toc(toclevels);
      }
      initStyle();
    }
  
    function reinstallAndRemoveTimer() {
      clearInterval(timerId);
      reinstall();
    }
  
    timerId = setInterval(reinstall, 500);
    if (document.addEventListener)
      document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
    else
      window.onload = reinstallAndRemoveTimer;
  }
  
  }
  
  