The DocBook stylesheets have several features for generating tables of contents. In addition to the traditional list of chapters and sections at the beginning of a book or article, you can optionally generate lists of figures, tables, examples, equations, and procedures. You can also generate mini tables of contents for each chapter or even each section, down to a section level of your choice.
Some aspects of customizing tables of contents can be controlled with parameters, and other require a customization layer.
The DocBook XSL stylesheets use the generate.toc
parameter to determine which elements have a
TOC
generated at the beginning of the element in the output. For print
output or non-chunked HTML output, a single TOC at the beginning may
suffice. But when you are generating chunked HTML files, you may want
certain sublevels to provide TOCs to help orient the reader.
Although generate.toc
is a parameter
that can be set on the command line, it is a bit awkward to use that
way because it can contain a lot of information. The default value of
generate.toc
(HTML version) is:
<xsl:param name="generate.toc"> appendix toc,title article/appendix nop article toc,title book toc,title,figure,table,example,equation chapter toc,title part toc,title preface toc,title qandadiv toc qandaset toc reference toc,title sect1 toc sect2 toc sect3 toc sect4 toc sect5 toc section toc set toc,title </xsl:param>
The parameter value is read as white-space separated pairs (leading whitespace is trimmed off). The first word of each pair is an element name, and the second word is a comma-separated list that specifies what kind of TOCs it should have. Most of them just use toc
, which is a list of section titles. But the entry for the book
element will also generate tables of figures, tables, examples, and equations. The word title
triggers printing a title for the list, such as "Table of Contents". Use a value of nop
to turn off all TOCs for an element. You can also turn off a TOC by removing the element entirely from the parameter.
You can change which elements have TOCs by putting a new version of this parameter in your customization layer. For example, to remove the TOC from the elements preface
, part
, qandadiv
, qandaset
, appendix
, and sections
, and remove the TOC title from chapter
, use this parameter value:
<xsl:param name="generate.toc"> appendix nop article toc,title book toc,title,figure,table,example,equation chapter toc part nop preface nop qandadiv nop qandaset nop reference toc,title section nop set toc </xsl:param>
If your document is a book and you only want a book-level TOC and no others, then you can use a very simple value:
<xsl:param name="generate.toc" select="'book toc'"/>
That is a space between book
and toc
, and don't forget the single quotes to make it a string. You can even set this simple value on the command line:
xsltproc --stringparam generate.toc "book toc" ...
Because the list uses white space to separate items in the list, and then counts through the list to establish pairs of items, you have to follow a few rules with this parameter:
A "white space" includes any sequence of blanks spaces, tabs, and carriage returns. So you could put all the information on one line with single blanks between items. In fact, that is what the processor does using the normalize-space
XSL function.
Don't leave a value blank, because that messes up the pairing. Either remove the element name or enter nop
to turn off an element you leave in the list.
Don't insert spaces in a comma separated list like toc,figure,table
. The spaces will mess up the pairing.
You can get even finer control of when TOCs are used by adding context information. For example, an article in a book can be treated differently from an article as a whole document. See the reference page for the generate.toc
parameter for more information.
Section TOCs are also controlled by the generate.section.toc.level
parameter, which is by default set to zero. See
the section “Turning on section TOCs”.
You can control how many nested levels of headings a TOC list should have. A book TOC always lists the titles for part
and chapter
elements, as well as any other components at the chapter level such as preface
, appendix
, glossary
and index
. A book TOC may also contain titles of sections within the chapters, depending on the value of the toc.section.depth
parameter. If chapter TOCs are turned on by the generate.toc
parameter, then what appears in the chapter TOC is
completely controlled by the toc.section.depth
parameter. The following table summarizes its effect on
book and chapter TOCs.
Use the toc.section.depth
parameter to indicate how many levels of
section titles should
appear in the TOCs. If you set it to a value of 3, for example, then
TOCs will include up to sect3
titles. The default value is 2. The following table summarizes the
effect of the parameter.
Table 9.1. How toc.section.depth affects book and chapter TOCs
toc.section.depth | Book TOC includes: | Chapter TOC includes: |
---|---|---|
0 |
chapter | No TOC |
1 |
chapter sect1 |
sect1 |
2 (default) |
chapter sect1 sect2 |
sect1 sect2 |
3 |
chapter sect1 sect2 sect3 |
sect1 sect2 sect3 |
If you use bridgehead
titles in your document, you also have the option of including those titles in your TOCs. To do so, set the bridgehead.in.toc
parameter to 1. Then all
bridgehead
titles will be included
at the appropriate level in the TOC.
There is a different style of hierarchy for TOCs that the toc.max.depth
parameter controls. In this style, each TOC regardless
of where it is located has the same number of levels (if the content
is there and the TOC is enabled with the generate.toc
parameter). The toc.max.depth
parameter controls the maximum number of levels in any
TOC. This parameter first appeared in version 1.61 of the
stylesheets, and only applies to HTML output. The following table
summarizes the effect of the parameter.
Table 9.2. How toc.max.depth affects book and chapter TOCs (HTML output only)
toc.max.depth | Book TOC includes: | Chapter TOC includes: |
---|---|---|
0 | No TOC | No TOC |
1 |
chapter |
sect1 |
2 |
chapter sect1 |
sect1 sect2 |
3 |
chapter sect1 sect2 |
sect1 sect2 sect3 |
You will notice that both the book and chapter TOCs contain the same number of levels for each value of the parameter. The table assumes that the toc.section.depth
parameter has been increased to at least 3. If not, then
the default value of 2 would limit the chapter TOC in the last row to
sect1
and sect2
entries. The default value of toc.max.depth
is 7, so normally the toc.section.depth
parameter is the limiting factor in a given TOC's
depth.
The stylesheet parameters described in the section “Levels in book and chapter TOCs” give you some control of what levels of headings appear in a book, chapter, and section TOCs. There are some combinations that cannot be achieved with just parameters and require template customization.
For example, you might want your book TOC in HTML to just list the chapter titles, and then rely on complete TOCs in each chapter to provide section titles. The following short customization does that.
<xsl:template match="preface|chapter|appendix|article" mode="toc"> <xsl:param name="toc-context" select="."/> <xsl:choose> <xsl:when test="local-name($toc-context) = 'book'"> <xsl:call-template name="subtoc"> <xsl:with-param name="toc-context" select="$toc-context"/> <xsl:with-param name="nodes" select="foo"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="subtoc"> <xsl:with-param name="toc-context" select="$toc-context"/> <xsl:with-param name="nodes" select="section|sect1|glossary|bibliography|index |bridgehead[$bridgehead.in.toc != 0]"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template>
It is a copy of a template in html/autotoc.xsl
, modified to add a
choose statement. It processes the chapter element (and other elements) in mode="toc"
to generate lines in your TOC. The $toc-context
template parameter
contains the element in which the TOC is appearing. So if
you take the local-name()
of that element and compare it to
'book', the template can take a different action. In this
case, you tell it to select foo
children of the chapter element,
which will be an empty node set since there is no such element. Then the depth of the
chapter toc can be controlled by the toc.section.depth
parameter.
By default, sections do not have their own TOCs. But you can use parameters to turn on TOCs for sections and control what levels are listed. Section TOCs are particularly useful with chunked HTML output for which the user might need some context for complex documents.
Two parameters control which section levels have a TOC: generate.toc
and generate.section.toc.level
. You will notice that the default value of the generate.toc
parameter described in the section “Which components have a TOC”
includes entries for all the
section levels, yet the default output does not have section TOCs.
That is because a second parameter generate.section.toc.level
also controls which section levels have a TOC. For
example, if you set generate.section.toc.level
to a value of 2, then you will get a TOC for all
sect1
and sect2
elements, or their equivalents in
nested section
elements. Why two
parameters? This arrangement lets you establish a style for which
TOCs could appear at various section levels by modifying the complex generate.toc
parameter in your customization layer. Then you can
select the actual output level at runtime with the simple generate.section.toc.level
parameter. Both parameters must enable a section level
for its TOC to appear.
The depth of section levels that appear in a given section TOC is usually controlled by the toc.section.depth
parameter. This parameter indicates the deepest section
level that can appear in any TOC. It's default value of 2 means only
sections up to sect2
will appear
in any TOC. For HTML output, a second parameter toc.max.depth
can be used to produce a different style of TOC
hierarchy. This parameter indicates the maximum number of levels that
appear in any TOC. A value of 2 means only up to two levels of titles
will appear in any TOC, regardless of where the TOC appears.
The following two tables show how these two parameters affect section TOCs for various values of the generate.section.toc.level
parameter.
Table 9.3. Section TOCs with toc.section.depth
generate.section.toc.level | toc.section.depth | sect1 TOC includes: | sect2 TOC includes: | sect3 TOC includes: | sect4 TOC includes: |
---|---|---|---|---|---|
1 | 2 |
sect2 | No TOC | No TOC | No TOC |
3 |
sect2 sect3 | No TOC | No TOC | No TOC | |
4 |
sect2 sect3 sect4 | No TOC | No TOC | No TOC | |
2 | 2 |
sect2 | No TOC | No TOC | No TOC |
3 |
sect2 sect3 |
sect3 | No TOC | No TOC | |
4 |
sect2 sect3 sect4 |
sect3 sect4 | No TOC | No TOC | |
3 | 2 |
sect2 | No TOC | No TOC | No TOC |
3 |
sect2 sect3 |
sect3 | No TOC | No TOC | |
4 |
sect2 sect3 sect4 |
sect3 sect4 |
sect4 | No TOC |
In some cases, there is no TOC because the TOC would be in a section level outside the range of the generate.section.toc.level
parameter. In other cases, there is no TOC because the toc.section.depth
parameter prevents it from having any entries. This
table assumes the other parameter, toc.max.depth
, has a value high enough to not interfere with the
selection of levels.
Table 9.4. Section TOCs with toc.max.depth (HTML only)
generate.section.toc.level | toc.max.depth | sect1 TOC includes: | sect2 TOC includes: | sect3 TOC includes: | sect4 TOC includes: |
---|---|---|---|---|---|
1 | 1 |
sect2 | No TOC | No TOC | No TOC |
2 |
sect2 sect3 | No TOC | No TOC | No TOC | |
3 |
sect2 sect3 sect4 | No TOC | No TOC | No TOC | |
2 | 1 |
sect2 |
sect3 | No TOC | No TOC |
2 |
sect2 sect3 |
sect3 sect4 | No TOC | No TOC | |
3 |
sect2 sect3 sect4 |
sect3 sect4 sect5 | No TOC | No TOC | |
3 | 1 |
sect2 |
sect3 |
sect4 | No TOC |
2 |
sect2 sect3 |
sect3 sect4 |
sect4 sect5 | No TOC | |
3 |
sect2 sect3 sect4 |
sect3 sect4 sect5 |
sect4 sect5 [sect6] | No TOC |
Using toc.max.depth
, you will notice that if a TOC exists, then it has the
same number of levels as every other TOC (if the content is there).
This table assumes that the other parameter, toc.section.depth
, has a high enough value to not interfere with the
selection of levels. If it is not changed from its default value of
2, then none of these examples would show titles beyond
sect2
.
There may be situations where you want to exclude certain titles from the table of contents. This may be because they are of minor importance, or perhaps they are meant to be only accessed using an online help system. You can assign a role
attribute to such elements, and then add a small template to your customization layer. For example, you might use the attribute value NotInToc
to designate elements that should not be in the TOC. The following template would work.
<xsl:template match="sect1[@role = 'NotInToc']" mode="toc" />
Normally an element's title appears in the toc because the element is processed with a template in mode="toc"
to generate the title. In this customization, the template is empty, which means it does nothing. So any element matching it will not appear in the TOC. In this case, it is matching on any sect1
element with the role="NotInToc"
attribute. Create similar templates for other elements you might want to exclude.
If you use profiling using the role
attribute, you must include NotInToc
in your selected values. If you don't, then those elements with that attribute value will not appear in your output at all because they will be excluded in the profiling step. This is another reason why it is not a good idea to use the role
attribute for profiling.
If you need to further customize how TOCs are presented, you may need to modify some of the XSL templates. Here is an example of adding the word "Appendix" to appendix
entries in the HTML table of contents (which by default just shows the appendix letter).
For print output, you can customize the template named toc.line
which can be found in fo/autotoc.xsl
. See the section “Styling print TOC entries” for details. For HTML output, there is little opportunity to customize
individual lines in the TOC in versions 1.61 and earlier of the DocBook XSL stylesheets. Starting with version 1.62, the HTML stylesheets also implement a toc.line
template that can be customized in a manner similar to that for print output.
For HTML processing in versions 1.61 and earlier, the toc lists are generated
using the subtoc
template in html/autotoc.xsl
. The template is used
recursively to get nesting, but it doesn't vary
per element type. The following lines from subtoc
show the problem:
<xsl:element name="{$toc.listitem.type}"> <xsl:variable name="label"> <xsl:apply-templates select="." mode="label.markup"/> </xsl:variable> <xsl:copy-of select="$label"/>
The first line starts a dt
element (in html output)
and the rest output the appendix number (called a label
in the stylesheets). If you want the word Appendix
included,
then it has to be inserted between them. Something like
the following modified version:
<xsl:element name="{$toc.listitem.type}"> <xsl:if test="self::appendix"> <xsl:call-template name="gentext"> <xsl:with-param name="key" select="'Appendix'"/> </xsl:call-template> <xsl:text> </xsl:text> </xsl:if> <xsl:variable name="label"> <xsl:apply-templates select="." mode="label.markup"/> </xsl:variable> <xsl:copy-of select="$label"/>
The added test checks for the element name appendix
, and then calls the gentext
template with its key
parameter set to the string Appendix
to get the uppercase name for the element in the appropriate language. Then it adds a space after the word to separate it from the appendix letter that follows. Unfortunately, to get this in there you have to copy
the entire subtoc
template to your customization layer.
If a later release of the stylesheets changes that template, you may need to update your customization.
DocBook XSL: The Complete Guide - 3rd Edition | PDF version available | Copyright © 2002-2005 Sagehill Enterprises |