<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>stylesheets/xhtml11.sass</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -28,6 +28,7 @@ file JTR_XML =&gt; [JTR_TXT, *CHAPTER_FILES] do
 end
 
 namespace :build do
+  # the formats going over docbook format
   formats.each do |format|
     jtr_dir = &quot;#{format}/&quot;
     jtr_base = &quot;journey_to_ramaze.#{format}&quot;
@@ -56,16 +57,24 @@ namespace :build do
     file(jtr_dir){ mkdir(jtr_dir) }
   end
 
+  # the asciidoc-xhtml
+
+  jtr_scripts = File.expand_path('javascripts')
+  jtr_styles  = File.expand_path('stylesheets')
+  jtr_css = 'stylesheets/xhtml11.css'
   jtr_dir = 'asciidoc-xhtml/'
   jtr_base = 'journey_to_ramaze.html'
   jtr_path = File.join(jtr_dir, jtr_base)
-  CLOBBER.include(jtr_dir)
+
+  jtr_depends = [jtr_dir, JTR_TXT, jtr_css] + CHAPTER_FILES + XMP_FILES
+
+  CLOBBER.include(jtr_dir, File.join(jtr_styles, '**/*.css'))
 
   file(jtr_dir){ mkdir(jtr_dir) }
-  file jtr_path =&gt; [jtr_dir, JTR_TXT, *(CHAPTER_FILES + XMP_FILES)] do
-    scripts_dir = File.expand_path('javascripts')
+  file jtr_path =&gt; jtr_depends do
     sh('asciidoc',
-       '--attribute', &quot;scriptsdir=#{scripts_dir}&quot;,
+       '--attribute', &quot;scriptsdir=#{jtr_scripts}&quot;,
+       '--attribute', &quot;stylesdir=#{jtr_styles}&quot;,
        '--attribute', 'toc',
        '--backend', 'xhtml11',
        '--doctype', 'book',
@@ -89,21 +98,20 @@ namespace :xmp do
     '--interpreter', RUBY
   ]
 
-  SOURCE_FILES.each do |source_file|
-    xmp_file = source_file.sub(/\.rb$/, '.xmp')
+  rule('.xmp' =&gt; ['.rb']) do |t|
+    source_file = t.source
+    xmp_file = t.name
 
-    file xmp_file =&gt; [source_file] do
-      invocation = (xmp_invocation + [source_file]).join(' ')
+    invocation = (xmp_invocation + [source_file]).join(' ')
 
-      puts &quot;Converting #{source_file} to xmp =&gt; #{xmp_file}&quot;
-      puts invocation
-      original_source = File.read(source_file).strip
-      xmp_source = `#{invocation}`.strip
+    puts &quot;Converting #{source_file} to xmp =&gt; #{xmp_file}&quot;
+    puts invocation
+    original_source = File.read(source_file).strip
+    xmp_source = `#{invocation}`.strip
 
-      fail(&quot;XMP failed for #{source_file}&quot;) if xmp_source == original_source
+    fail(&quot;XMP failed for #{source_file}&quot;) if xmp_source == original_source
 
-      File.open(xmp_file, 'w+'){|xmp| xmp.write(xmp_source) }
-    end
+    File.open(xmp_file, 'w+'){|xmp| xmp.write(xmp_source) }
   end
 
   CHAPTER_FILES.each do |chapter_file|
@@ -114,3 +122,10 @@ namespace :xmp do
     end
   end
 end
+
+rule('.css' =&gt; ['.sass']) do |t|
+  sh('sass',
+     '--style', 'compressed', # nested, compact, compressed, expaned
+     t.source,
+     t.name)
+end</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,70 +1,145 @@
-/* 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, October 2006. License: GPL */
- /* modified by Michael Fellinger, April 2009. License: GPL */
-
-function getText(el) {
-  var text = &quot;&quot;;
-  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;
-}
+TOCCreator = {
+  Header: function(level, text, visible, id){
+    var obj = {
+      level: level,
+      text: text,
+      id: id,
+      visible: visible,
+      childs: [],
+      mother: null,
 
-function TocEntry(el, text, toclevel) {
-  this.element = el;
-  this.text = text;
-  this.toclevel = toclevel;
-}
+      add_child: function(child){
+        this.childs.push(child);
+        child.mother = this;
+      },
+
+      to_html: function(out){
+        var ol, li, a;
+
+        if(this.visible){
+            li = document.createElement('li');
+            a = document.createElement('a');
+            a.innerHTML = this.text;
+            a.href = '#' + this.id;
+            li.appendChild(a);
+            out.appendChild(li);
+
+          if(this.childs.length &gt; 0){
+            ol = document.createElement('ol');
+            li.appendChild(ol);
+
+            this.each_child_to_html(ol);
+          }
+        } else {
+          ol = document.createElement('ol');
+          out.appendChild(ol);
+          this.each_child_to_html(ol);
+        }
+
+        return(out);
+      },
+
+      each_child_to_html: function(root){
+        for(child_i in this.childs){
+          this.childs[child_i].to_html(root);
+        }
+      }
+    };
+
+    return(obj);
+  },
+
+  elements_by_tag_names: function(list, given_doc){
+    var doc = (doc || document);
+    var tag_names = list.split(',');
+    var tags = [];
 
-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)
-          result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
-        iterate(i);
+    for(tag_names_i in tag_names){
+      var partials = doc.getElementsByTagName(tag_names[tag_names_i]);
+
+      for(i = 0; i &lt; partials.length; i++){
+        tags.push(partials[i]);
       }
     }
-  }
-  iterate(el);
-  return result;
-}
 
-// This function does the work. toclevels = 1..4.
-function generateToc(toclevels) {
-  var toc = document.getElementById(&quot;toc&quot;);
-  var entries = tocEntries(document.getElementsByTagName(&quot;body&quot;)[0], toclevels);
-  for (var i = 0; i &lt; entries.length; ++i) {
-    var entry = entries[i];
-    if (entry.element.id == &quot;&quot;)
-      entry.element.id = &quot;toc&quot; + i;
-    var a = document.createElement(&quot;a&quot;);
-    a.href = &quot;#&quot; + entry.element.id;
-    a.appendChild(document.createTextNode(entry.text));
-    var div = document.createElement(&quot;div&quot;);
-    div.appendChild(a);
-    div.className = &quot;toclevel&quot; + entry.toclevel;
-    toc.appendChild(div);
+    var test_node = tags[0];
+
+    if(!test_node){
+      return([]);
+    } else if(test_node.sourceIndex){
+      tags.sort(function(a, b){ return(a.sourceIndex - b.sourceIndex); });
+    } else if(test_node.compareDocumentPosition){
+      tags.sort(function(a, b){ return(3 - (a.compareDocumentPosition(b) &amp; 6)); });
+    }
+
+    return(tags);
+  },
+
+  collect_headers: function(given_levels, doc){
+    var levels = (given_levels || 'h1,h2,h3,h4,h5');
+    var headers = [];
+    var tags = this.elements_by_tag_names(levels, doc);
+
+    for(tag_i in tags){
+      var tag, level, text, id
+
+      tag = tags[tag_i];
+      level = tag.nodeName.match('H(\\d+)')[1];
+      text = tag.innerHTML;
+
+      if(tag.id){
+        id = tag.id;
+      } else {
+        id = 'toc_' + tag_i;
+        tag.id = id;
+      }
+
+      headers.push({toclevel: level, text: text, id: id});
+    }
+
+    return(headers);
+  },
+
+  generate_ast: function(doc){
+    var headers = this.collect_headers(doc);
+    var original_root = new this.Header(1, 'ROOT', false);
+    var root = original_root;
+    root.mother = root;
+
+    for(header_i in headers){
+      var element = headers[header_i];
+      var header = new this.Header(element.toclevel, element.text, true, element.id);
+      var temp = root;
+      var i;
+
+      if(header.level == root.level){
+        root.mother.add_child(header);
+      } else if(header.level &gt; root.level){
+        for(i = (header.level - 1); i &gt; root.level; i--){
+          var temp_child = new this.Header(i, 'TEMP', false);
+          temp.add_child(temp_child);
+          temp = temp_child;
+        }
+
+        temp.add_child(header);
+      } else if(header.level &lt; root.level){
+        for(i = header.level; i &lt;= root.level; i++){
+          var temp_mother = temp.mother;
+          temp = temp_mother;
+        }
+
+        temp.add_child(header);
+      }
+
+      root = header;
+    }
+
+    return(original_root);
   }
-  if (entries.length == 0)
-    document.getElementById(&quot;header&quot;).removeChild(toc);
+};
+
+function generateToc(n){
+  var root = document.getElementById('toc');
+  var ast = TOCCreator.generate_ast();
+  ast.to_html(root);
 }</diff>
      <filename>javascripts/toc.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>5a376616354e427ce35823ebb3bf278b08f4a6a4</id>
    </parent>
  </parents>
  <author>
    <name>Michael Fellinger</name>
    <email>m.fellinger@gmail.com</email>
  </author>
  <url>http://github.com/manveru/ramaze-book/commit/fbbdde3f7317ab92922fc9ef86e357f7acb21349</url>
  <id>fbbdde3f7317ab92922fc9ef86e357f7acb21349</id>
  <committed-date>2009-04-16T04:51:13-07:00</committed-date>
  <authored-date>2009-04-16T04:51:13-07:00</authored-date>
  <message>Created the ultimate TOC generator in javascript, build stylesheet from sass, improve rakefile by using rules</message>
  <tree>dcb101af0d82cb105a826b06f07a5df5930ee3c6</tree>
  <committer>
    <name>Michael Fellinger</name>
    <email>m.fellinger@gmail.com</email>
  </committer>
</commit>
