xsltdocbookdocbook-xsl

How do you get DocBook XSL's chunking to generate a full TOC for each page?


I have a bunch of DocBook XML files that all get merged into a single DocBook file for conversion into HTML. Each individual document is a reference page (for a function or similar construct). I use chunked HTML generation, so that each reference page becomes its own HTML page.

The problem is this: I want a table of contents on each page. But I don't want the table of contents for that page. I want the full TOC for the entire reference manual.

That is, from any page, I want to be able to jump to any other page by using the TOC. I can use CSS styling to stick the TOC on the left side (and even hide it for mobile viewing or whatever).

There's an obvious way to handle this. I could extract the main TOC via a post-process script and have the script copy this into each of the output HTML documents. What I'm looking for is a way to do it that works within DocBook XSL.

I want the results to look rather like DocBook XSL's newer webhelp, but with less overt JavaScript involvement.


Solution

  • There’s a relatively easy way to get that, though I’m pretty sure you can’t without either creating a DocBook XSL customization layer or just directly modifying the installed (system) stylesheets.

    Either way, I think the actual docbook-xsl template you need to modify or override is named make.toc, located in the stylesheets distribution in the file html/autotoc.xsl.

    It’s a big template—nearly a hundred lines—but you only need to make a one-line change to it:

    --- /usr/share/xml/docbook/stylesheet/docbook-xsl/html/autotoc.xsl  2012-12-16 11:35:12.000000000 +0900
    +++ /opt/workspace/autotoc.xsl  2015-12-26 09:19:36.000000000 +0900
    @@ -28,7 +28,7 @@
     </xsl:variable>
    
     <xsl:template name="make.toc">
    -  <xsl:param name="toc-context" select="."/>
    +  <xsl:param name="toc-context" select="/"/>
       <xsl:param name="toc.title.p" select="true()"/>
       <xsl:param name="nodes" select="/NOT-AN-ELEMENT"/>
    

    That is, you need to call that template with the toc-context param set to "/" (instead of ".").

    The default "." value tells the template that, when creating a TOC for a chunk, it should only look at the (child) content of whatever element it’s currently processing (that is, the root of that particular chunk); for example, if it’s processing a section it looks only at the children of that section.

    But if you instead change that value to "/", you’re telling the template to (re)look at the entire content of the source document each time. So if your document is a book, it’ll give you the entire TOC for the whole book each time, or if your document is an article, the entire article, etc.

    So I think that should give you what you’re wanting.

    If you decide to just modify the installed stylesheets and you’ve installed them from any OS-specific package manager you use, you need to find where the html/autotoc.xsl file is installed.

    On my Debian Linux system the html/autotoc.xsl file is here:

    /usr/share/xml/docbook/stylesheet/docbook-xsl/html/autotoc.xsl
    

    And on my OS X system, installed from a homebrew package, it’s here:

    /usr/local/opt/docbook-xsl/docbook-xsl/html/autotoc.xsl
    

    If you decide to instead create a customization layer, you’ll need to copy that entire make.toc template into your customization layer (but with that toc-context param changed to "/").