Add table of contents to documentation pages
authorMike Cardwell <mike.cardwell@grepular.com>
Sat, 3 Jul 2010 09:47:48 +0000 (10:47 +0100)
committerNigel Metheringham <nigel.metheringham@dev.intechnology.co.uk>
Sat, 3 Jul 2010 09:47:48 +0000 (10:47 +0100)
templates/doc/chapter.xsl
templates/doc/toc.xsl [new file with mode: 0644]
templates/gen.pl
templates/web/doc/chapter.css
templates/web/doc/chapter.js [new file with mode: 0644]
templates/web/doc/contents.png [new file with mode: 0644]
templates/web/doc/index.js
templates/web/index.xsl
templates/wrapper.xsl

index 430a6d3bde2f79a3dc59919d7713f14b7fa0005f..13a7c91e73ec7279be142752c97363fbfa574422 100644 (file)
          <script type="text/javascript" src="{$docroot}/doc/chapter.js"/>
       </xsl:variable>
 
+   <!-- Table of Contents -->
+      <xsl:variable name="html.body.outer.append">
+         <div id="toc">
+            <ul class="hidden"/>
+            <img src="../../../../doc/contents.png" width="16" height="155"/>
+         </div>
+      </xsl:variable>
+
    <!-- CONTENT -->
       <xsl:template match="/chapter">
 
diff --git a/templates/doc/toc.xsl b/templates/doc/toc.xsl
new file mode 100644 (file)
index 0000000..31d7bc1
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+   <!-- Define display/content information -->
+      <xsl:output indent="no"/>
+      <xsl:output encoding="UTF-8"/>
+      <xsl:output media-type="text/xml"/>
+      <xsl:output omit-xml-declaration="no"/>
+   
+   <!-- CONTENT -->
+      <xsl:template match="/">
+         <toc>
+            <xsl:apply-templates select="book/chapter"/>
+         </toc>
+      </xsl:template>
+
+   <!-- Chapter -->
+      <xsl:template match="/book/chapter">
+
+         <!-- Calculate the URL to the chapter. Store in $chapter_url -->
+            <xsl:variable name="chapter_url">
+               <xsl:choose>
+                  <xsl:when test="position()&lt;10">
+                     <xsl:value-of select="concat(/book/prepend_chapter,'ch',0,position(),'.html')"/>
+                  </xsl:when>
+                  <xsl:otherwise>
+                     <xsl:value-of select="concat(/book/prepend_chapter,'ch',position(),'.html')"/>
+                  </xsl:otherwise>
+               </xsl:choose>
+            </xsl:variable>
+
+         <!-- Chapter info -->
+            <c>
+               <u>
+                  <xsl:value-of select="$chapter_url"/>
+               </u>
+               <t>
+                     <xsl:apply-templates select="title"/>
+               </t>
+            </c>
+      </xsl:template>
+
+   <!-- Chapter/Section Title -->
+      <xsl:template match="title|chapter/title">
+         <xsl:apply-templates/>
+      </xsl:template>
+
+</xsl:stylesheet>
index 427df581369aff0d67850cc98a9f6b562f060e55..d6ebf006bcc3a335a935219331ec26bd281f1433 100755 (executable)
@@ -9,10 +9,6 @@ use XML::LibXSLT;
 
 my $canonical_url = 'http://www.exim.org/';
 
-# ./gen.pl --web    --latest 4.72 --tmpl /var/www/mike/exim.grepular.com/template --docroot /var/www/mike/exim.grepular.com/htdocs
-# ./gen.pl --spec   --latest 4.72 --tmpl /var/www/mike/exim.grepular.com/template --docroot /var/www/mike/exim.grepular.com/htdocs spec.xml
-# ./gen.pl --filter --latest 4.72 --tmpl /var/www/mike/exim.grepular.com/template --docroot /var/www/mike/exim.grepular.com/htdocs filter.xml
-
 ## Parse arguments
   my %opt = parse_arguments();
 
@@ -95,6 +91,16 @@ my $canonical_url = 'http://www.exim.org/';
           );
        }
 
+     ## Generate a Table of Contents XML file
+       {
+          my $path = "exim-html-$version/doc/html/spec_html/".($type eq 'filter'?'filter_toc':'index_toc').".xml";
+          print "Generating  : docroot:/$path\n";
+          transform( $xml,
+             "$opt{tmpl}/doc/toc.xsl",
+             "$opt{docroot}/$path",
+          );
+       }
+
      ## Generate the chapters
        my $counter = 0;
        foreach my $chapter ( map {$_->cloneNode(1)} $xml->findnodes('/book/chapter') ){
index 0fb173e1cbf6b1a6d36269176bedf2ae1104a8bb..9c883ef64676173dde3c1be541e6ede81f4bbcb4 100644 (file)
 #chapter table td {
        padding-left:                   1em;
 }
+
+// Side Table of Contents
+
+       #outer > #toc {
+               position:                       fixed;
+               top:                            35%;
+               left:                           0;
+               z-index:                        3000;
+       }
+
+       #outer > #toc img {
+               position:                       fixed;
+               top:                            35%;
+               left:                           0;
+               background-color:               #304b66;
+               padding:                        0.5em;
+               z-index:                        3000;
+               display:                        none;
+       }
+
+       #outer > #toc img:hover {
+               cursor:                         pointer;
+               background-color:               #000;
+       }
+
+       #outer > #toc > ul {
+               position:                       fixed;
+               top:                            30%;
+               background-color:               #fff;
+               min-height:                     200px;
+               max-height:                     65%;
+               overflow-y:                     auto;
+               padding:                        0.5em 0;
+               border-top:                     1px solid #bbb;
+               border-bottom:                  1px solid #bbb;
+               z-index:                        3000;
+       }
+       #outer > #toc a {
+               font-size:                      1.2em;
+               color:                          #304b67;
+               text-decoration:                none;
+               padding:                        0 0.5em;
+       }
+       #outer > #toc a:hover {
+               color:                          #000;
+       }
+
+       @media all and ( max-width: 640px ){
+               #outer > #toc {
+                       display:                none;
+               }
+       }
diff --git a/templates/web/doc/chapter.js b/templates/web/doc/chapter.js
new file mode 100644 (file)
index 0000000..204f924
--- /dev/null
@@ -0,0 +1,54 @@
+// Sidebar table of contents
+       (function( $ ){
+               
+               var click_func = function(e){
+                       if( $('#toc').data('opened') ){
+                               $('#toc > *').animate({ left: '-=' + $('#toc > ul').width() + 'px' },'fast');
+                               $('#toc').removeData('opened');
+                       } else {
+                               $('#toc > *').animate({ left: '+=' + $('#toc > ul').width() + 'px' },'fast');
+                               $('#toc').data('opened',1);
+                       }
+               };
+
+                var type = document.location.pathname.match(/\/doc\/html\/spec_html\/filter/) ? 'filter' : 'spec';
+               
+               // Get the relevant table of contents
+               $.get( type === 'spec' ? 'index_toc.xml' : 'filter_toc.xml',
+                       function( xml ){
+
+                               // Remove the main list from the DOM for performance
+                               var $ul = $('#toc > ul').remove();
+
+                               // Traverse chapters
+                               var chapter_id = 0;
+                               $(xml).find('c').each(function(){
+                                       ++chapter_id;
+                                               var chapter_title = $(this).children('t').text();
+                                       var chapter_url   = $(this).children('u').text();
+
+                                       var chapter_li = $('<li/>').append(
+                                               $('<a/>').attr({
+                                                       href:   chapter_url,
+                                                       title:  chapter_title
+                                               }).text( chapter_id + '. ' + chapter_title ),
+                                               $('<ul/>').hide()
+                                       ).appendTo( $ul );
+                                });
+
+                               $('#toc img').fadeIn('slow',function(){
+                                       // Add the main list back to the DOM
+                                       $ul
+                                               .removeClass( 'hidden' )
+                                               .css( 'visibility', 'hidden' )
+                                               .appendTo( '#toc' )
+                                               .css( 'left', '-' + $ul.width() + 'px' )
+                                               .css( 'visibility', 'visible' );
+                                               $('#toc > img').mousedown(click_func);
+                                               $('#toc > ul').click(click_func);
+                                               $('#toc a').click(function(e){e.stopPropagation()});
+                               });
+                       }
+                );
+        })( jQuery );
+
diff --git a/templates/web/doc/contents.png b/templates/web/doc/contents.png
new file mode 100644 (file)
index 0000000..03a6d22
Binary files /dev/null and b/templates/web/doc/contents.png differ
index 9ba9546174ea654bf1f1636990a001c30314b9ae..c656046af923c51917ee05089dcdce2d73ce49e0 100644 (file)
@@ -1,18 +1,10 @@
-$('#chapters')
-       .addClass('expandable')
-       .find('.button')
-       .click(function(){
-               $(this).parent().toggleClass('open');
-       });
-
-$('#options img.expand')
-       .click(function(){
-               $('.chapter').addClass('open')
-       });
-
-$('#options img.collapse')
-       .click(function(){
-               $('.chapter').removeClass('open')
-       });
-
-$('#options').removeClass('hidden');
+// Add the expand/collapse functionality
+       $('#chapters')
+               .addClass('expandable')
+               .find('.button')
+               .click(function(){
+                       $(this).parent().toggleClass('open');
+               });
+       $('#options img.expand').click(function(){ $('.chapter').addClass('open'); });
+       $('#options img.collapse').click(function(){ $('.chapter').removeClass('open') });
+       $('#options').removeClass('hidden');
index 64f36943e7581aa565623e424bdf552460e2290c..80e1771092602cc78405d1658a11b8856a89c174 100644 (file)
 
        </xsl:variable>
  
-       <!-- JavaScript -->
-               <xsl:variable name="html.body.append">
-                       <script type="text/javascript" src="{$docroot}/index.js"/>
-               </xsl:variable>
-               
        <!-- CONTENT -->
                <xsl:template name="content">
 
index 82fed80ce448982d0c2ff4de973099fabfff75a9..ba0c6345d141a99ef60e18ab63d68e38b40218df 100644 (file)
@@ -17,6 +17,7 @@
       <xsl:variable name="html.head.robots" select="'noodp,noydir,index,follow'"/>
       <xsl:variable name="html.head.append"/>
       <xsl:variable name="html.body.append"/>
+      <xsl:variable name="html.body.outer.append"/>
 
    <!-- The main template code -->
       <xsl:template match="/">
@@ -95,6 +96,8 @@
                          <div class="left_bar"/>
                          <div class="right_bar"/>
 
+                      <!-- Append anything to the outer container? -->
+                         <xsl:copy-of select="$html.body.outer.append"/>
                    </div>
 
                 <!-- Load latest version of jQuery 1.4 from the Google CDN -->