I thought this tip may be useful for others, so I'm sharing it here.

Asciidoc normally does not insert a TOC (table of contents) into HTML 
output. While this can be achieved using docbook-generated HTML, there 
is an alternative, if you prefer Asciidoc's native HTML rendering.

To see it in action, first view this example document: 
http://tpl.sourceforge.net/userguide.html

Notice the TOC that sits on the right-hand side. (Your browser needs to 
have Javascript enabled, and its only been tested in Firefox and IE, so 
hopefully it looks right on your browser). Incidentally you may also 
notice the "top" navigational links that appear to the right of H3-level 
headers.

As you may have surmised, the TOC was dynamically generated by some 
Javascript. The styling of the TOC was done via CSS. To use this 
technique, I added this line into my Asciidoc text document where I 
wanted the TOC to appear:

include::toc.txt[]

I have pasted the content of toc.txt later in this email. (Thanks to 
Mihai Bazon, for the dynamic TOC code, which I have modified somewhat.)

To style the TOC and the "top" links, I appended some custom CSS, shown 
at this end of the email, to the default stylesheet in 
asciidoc/stylesheets/xhtml11.css. (Actually, I copied xhtml11.css and 
xhtml11-quirks.css to new files tdh.css and tdh-quirks.css, 
respectively, and then added the CSS to tdh.css.)

Then I ran Asciidoc using the command:

 asciidoc --unsafe --out-file=html/userguide.html -a linkcss=1 -a 
theme=tdh txt/userguide.txt

The resulting HTML document contains links to the external stylesheets, 
so I had to upload tdh.css and tdh-quirks.css to the webserver along 
with the HTML document.

A couple of notes: I chose to derive the TOC from only the H2 and H3 
headers. And the "top" link accompanies H3 headers. These are hardcoded 
into the Javascript (while not elegant code, it does the job). Also, my 
version of asciidoc is 7.x so I don't know if any changes are needed 
with newer versions. Lastly, I want to point out that I'm not an expert 
in the finer details of Asciidoc so, while my approach works, perhaps 
there is a simpler technique.

FILES
-------

First, below this line is the content of "toc.txt". It ends at the 
"endif" line:

ifdef::backend-xhtml11[]
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<div id="toc"></div>
<script>
window.onload=generate_TOC

/* 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 */

function H_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 += H_getText(i);
  }
  return text;
}

function TOC_EL(el, text, level) {
  this.element = el;
  this.text = text;
  this.level = level;
}

function getHeadlines(el) {
  var l = new Array;
  var rx = /[hH]([2-3])/;
  // internal recursive function that scans the DOM tree
  var rec = function (el) {
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
        if (rx.exec(i.tagName))
          l[l.length] = new TOC_EL(i, H_getText(i), parseInt(RegExp.$1));
        rec(i);
      }
    }
  }
  rec(el);
  return l;
}

function generate_TOC() {
  var parent = document.getElementById("toc");
  var toc_hdr = document.createElement("div");
  var toc_hdr_txt = document.createTextNode("CONTENTS");
  toc_hdr.appendChild(toc_hdr_txt);
  /* toc_hdr.setAttribute("id","hdr"); */
  toc_hdr.id = "hdr";
  parent.appendChild(toc_hdr);
  var hs = getHeadlines(document.getElementsByTagName("body")[0]);
  for (var i = 0; i < hs.length; ++i) {
    var hi = hs[i];
    var d = document.createElement("div");
    if (hi.element.id == "") hi.element.id = "gen" + i;
    var a = document.createElement("a");
    a.href = "#" + hi.element.id;
    a.appendChild(document.createTextNode(hi.text));
    d.appendChild(a);
    d.className = "level" + hi.level;
    parent.appendChild(d);
    if (hi.level == 3) {
        var dvtop = document.createElement("div");
        dvtop.className = "toplink";
        dvtop.appendChild(document.createTextNode("^top^"));
        dvtop.onclick=function(){scrollTo(0,0);};
        hi.element.appendChild(dvtop);
    }
  }
}
</script>
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
endif::backend-xhtml11[]


Lastly, here is the custom CSS styling that I added to "tdh.css":

#toc {
  float: right;
  font-family: sans-serif; 
  border: 1px solid #000;
  margin: 0px 0px 20px 20px;
  padding: 0px;
  background: #f0f0f0;
  font-size: 80%;
}

#toc #hdr {
  color:#ffffff;
  background:#98b1c4;
  text-align:center;
  margin-bottom:5px;
}

#toc a:visited, #toc a:link { color:#000; text-decoration: none }
#toc a:hover { color:#00f; text-decoration: underline; }

#toc .level2 { margin-left: 1em; margin-top: 2px; margin-bottom: 2px; 
text-decoration: underline; }
#toc .level3 { margin-left: 2em; font-size: 0.8em }

.toplink {
    float: right;
    font-size: 50%;
    cursor: pointer;
}





_______________________________________________
Asciidoc-discuss mailing list
Asciidoc-discuss@metaperl.com
http://metaperl.com/cgi-bin/mailman/listinfo/asciidoc-discuss

Reply via email to