box.matto.nl

home/

Automatic Table of Contents in my awkiawki

Last edited

awkiawki is written in awk

awkiawki is a great, very light weight wiki running fine on a Raspberry Pi

I have become a great fan of Awkiawki.

It is very light weight, well written, easy and fun to hack.

My awkiakwi started as a personal wiki, as a replacement of my vimwiki. It has become my personal knowledge base and I use it every day.

Please see my other Awkiawki pages.

A nice automatic table of contents in javascript with jQuery

I wanted to have a automatic table of contents on the h3 titles and found this page: Automatic Table of Contents by Chris Coyier.

With some tweaking, this little piece javascript now automaticly creates a table of contents on the pages of my personal wiki ;)

Create uniq ID identifiers in h3 headers

This is how I create uniq identifiers in the h3 headers. In the file parser.awk a counter gets added:

/^==[^=]/ { $0 = "<h3 id=\"h3-" h3count++ "\">" substr($0, 3) "</h3>"; close_tags(); print; next; } 

(As you can see from this line, I use the vimwiki dialect of Markdown, which uses three equalsigns (===) to indicate an h3 header, instead of three poundsigns (###). More on this, why I use the vimwiki dialect, is in my other awkiawki-pages. See the link above.)

In the BEGIN part of file the parser.awk this counter is initialized:

h3count = 1

With these to small modifications, the wiki creates h3 headers that look like this:

<h3 id="h3-2"> Unplug</h3>

Every h3 gets an uniq ID, so the jQuery ToC script can create references to them.

Create the javascript that builds the ToC

I have added a few lines to the javascript from Chris Coyier (see above). First, I put the code inside a $(document).ready(function(){ }); block. Second, I only let the nav-part be put into the html when there is more then one h3 header on the page.

My awkiawki does not have a article-container in the html code, but it does use a id="content" div-container. So the script references this div-container instead of the article-container.

Here is the complete javascript code:

$(document).ready(function(){
var ToC =
  "<nav role='navigation' class='table-of-contents'>" +
    "<h2>On this page:</h2>" +
    "<ul>";

var newLine, el, title, link, count;

count = 0;

$("#content h3").each(function() {

  el = $(this);
  title = el.text();
  link = "#" + el.attr("id");

  newLine =
    "<li>" +
      "<a href='" + link + "'>" +
    title +
      "</a>" +
    "</li>";
  count++;
  ToC += newLine;

});

ToC +=
   "</ul>" +
  "</nav>";
if ( count > 1 ) {
    $("#content").prepend(ToC);
}
}); 

Add the javascript and jQuery to the html pages

The file index.cgi holds the code to create the outer part of the html files. The file parser.awk generates the inner part of these files.

So to get the javascript and the jQuery file loaded by the browser, we have to add these into the header of the html file, so we have to tweak index.cgi, by adding just two lines:

 print "<script src=\"/jquery.js\"></script>"
 print "<script src=\"/inserttoc.js\"></script>"

This will let the browser create a table of contents, based on the h3-headers in the output of the current awkiawki page. (see above).

Add some CSS code

I just copied the CSS code from Chris Coyier (see above).

This makes a nice grey block on the webpage, with the table of contents inside. The entries in the table of contents are clickable and refer to the corresponding h3 header.

For me, this works great.

Impact on the wiki

The javascript file is a separate file, so it will be cached by the browser. The only extra work the parser has to do, is to add the id="..." and incremement the counter. The result is that the automatic table of contents does not increase the load on the webserver, and the awkiawki is still very light weight.

However, on longer pages, it is great to have the table of contents in the upper right corner. The user sees what is more on the page ("below the fold") at a glance, without the need to scroll down.

The table of contents is build as links to the individual h3 headers, so the user can by just a single mouseclick jump to the according part of the webpage.

So it has great impact on the useability without any additional load on the server.