The main features for controlling tables of contents are described in the section “Tables of contents (TOC)”. This section describes features specific to print output.
You can adjust the page margins for a table of contents by customizing the toc.margin.properties
attribute set. Here is what the default looks like:
<xsl:attribute-set name="toc.margin.properties"> <xsl:attribute name="space-before.minimum">0.5em</xsl:attribute> <xsl:attribute name="space-before.optimum">1em</xsl:attribute> <xsl:attribute name="space-before.maximum">2em</xsl:attribute> <xsl:attribute name="space-after.minimum">0.5em</xsl:attribute> <xsl:attribute name="space-after.optimum">1em</xsl:attribute> <xsl:attribute name="space-after.maximum">2em</xsl:attribute> </xsl:attribute-set>
These properties don't change the margins for the page-master, but for the fo:block
that contains the table of contents on the page. The space-before
values add space above the TOC and space-after
add space below the toc. You would use start-indent
to indent from left, and end-indent
to indent from the right. A customized version might look like the following:
<xsl:attribute-set name="toc.margin.properties"> <xsl:attribute name="start-indent">0.5in</xsl:attribute> <xsl:attribute name="end-indent">0.5in</xsl:attribute> </xsl:attribute-set>
As with all attribute-sets, your customized properties are merged with the default set. You could add other properties that would apply to the whole TOC block. For example, a TOC in an article
does not have a page break after it by default. This example would add that page break.
<xsl:attribute-set name="toc.margin.properties"> <xsl:attribute name="break-after">page</xsl:attribute> </xsl:attribute-set>
If you want to change the page layout beyond these properties, you will need to add a customized page-master, in this case for the lot
(list of titles) page class. See the section “Custom page design” for a description of how to do that. In addition to a new page master, you will need to customize the select.user.pagemaster
template to select your new page master file during processing.
The Table of Contents
title that appears at the top of a TOC is turned on or off with the generate.toc
parameter. See the section “Which components have a TOC” to see
how to change that parameter.
The title text in a table of contents is generated text, using the TableofContents
key word. For English, the text comes from the gentext file common/en.xml
, where the text associated with the key word is "Table of Contents". You can change it for a given language in a customization layer with something like this:
<xsl:param name="local.l10n.xml" select="document('')"/> <l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0"> <l:l10n language="en"> <l:gentext key="TableofContents" text="Contents"/> </l:l10n> </l:i18n>
The formatting of the title is controlled by the same machinery that controls title pages. While a TOC could have a complete title page, the default behavior is just to start a page and put the title at the top. If you want to change how the title is formatted, then you will need to customize the titlepage spec file and generate a new titlepage stylesheet module. See the section “Title page spec file” information on how to do that. Specifically, you will want to change the following entry in the spec file:
<t:titlepage element="table.of.contents" wrapper="fo:block"> <t:titlepage-content side="recto"> <title force="1" named-template="gentext" param:key="'TableofContents'" fo:space-before.minimum="1em" fo:space-before.optimum="1.5em" fo:space-before.maximum="2em" fo:space-after="0.5em" fo:margin-left="{$title.margin.left}" fo:font-size="&hsize3;" fo:font-weight="bold" fo:font-family="{$title.font.family}"/> </t:titlepage-content>
The spec file needs to be processed into a stylesheet module that gets included in your customization layer.
If you don't want to generate a new titlepage spec file just to modify the table of contents title, you can instead replace the template named table.of.contents.titlepage
. If your customization has a template of this name, then it will override the processing done by the regular title page machinery. You may need to give your version a priority
attribute with a value of greater than zero, in case there is a problem with import precedence. The template must get the title using the gentext
template, and then generate an fo:block
with the appropriate properties. After outputting the title, it must close the fo:block
. For example:
<xsl:template name="table.of.contents.titlepage" priority="1"> <fo:block xsl:use-attribute-sets="section.title.level1.properties" space-before="1in" space-before.conditionality="retain" space-after="12pt" border-bottom="0.5pt solid black"> <xsl:call-template name="gentext"> <xsl:with-param name="key" select="'TableofContents'"/> </xsl:call-template> </fo:block> </xsl:template>
The space-before.conditionality="retain"
property forces the formatter to use the specified space-before
value, even though it is at the top of the page where it would normally be ignored.
An entry in a table of contents is produced by applying templates that have mode="toc"
and that match the element associated with that entry. So the template that formats an entry for a sect1
title would start with:
<xsl:template match="sect1" mode="toc">
These templates are located in the fo/autotoc.xsl
stylesheet file. They are not good candidates for customization because they are pretty complex. The complexity comes from the recursive nature of processing all the elements in the document in the toc
mode. Each mode="toc"
template generates the entry for its element, and then checks to see if the element has children that should appear in the TOC. If so, then it increments the indent by the amount of the parameter toc.indent.width
and applies templates in toc
mode to process the children.
If you want to change the way indenting of entries is handled (beyond just adjusting the parameter value), then you would need to customize the mode="toc"
template that matches the element whose children you want to change.
The template that can be customized more easily is named toc.line
, because it formats a single entry of a TOC. By default, it formats all TOC lines the same, since the left indent has been set by the template that called toc.line
. If you want to customize certain TOC entries, then your customization would need to test for the name of the context node and act accordingly. For example, if you wanted just chapter titles in the TOC to appear in bold, then add the following version of toc.line
to your customization:
<xsl:template name="toc.line">
<xsl:variable name="id">
<xsl:call-template name="object.id"/>
</xsl:variable>
<xsl:variable name="label">
<xsl:apply-templates select="." mode="label.markup"/>
</xsl:variable>
<fo:block text-align-last="justify"
end-indent="{$toc.indent.width}pt"
last-line-end-indent="-{$toc.indent.width}pt">
<fo:inline keep-with-next.within-line="always">
<xsl:choose>
<xsl:when test="self::chapter">
<xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:when>
</xsl:choose>
<fo:basic-link internal-destination="{$id}">
<xsl:if test="$label != ''">
<xsl:copy-of select="$label"/>
<xsl:value-of select="$autotoc.label.separator"/>
</xsl:if>
<xsl:apply-templates select="." mode="title.markup"/>
</fo:basic-link>
</fo:inline>
<fo:inline keep-together.within-line="always">
<xsl:text> </xsl:text>
<fo:leader leader-pattern="dots"
leader-pattern-width="3pt"
leader-alignment="reference-area"
keep-with-next.within-line="always"/>
<xsl:text> </xsl:text>
<fo:basic-link internal-destination="{$id}">
<fo:page-number-citation ref-id="{$id}"/>
</fo:basic-link>
</fo:inline>
</fo:block>
</xsl:template>
The highlighted addition to the template tests for the element name, and adds the bold property if it is a chapter.
When a TOC page is started, it is assigned a format for its own page numbers. It gets the format by calling the template named page.number.format
. That is a simple template that can be customized in a customization layer. Here is an example that changes the page numbering style of the TOC to 1, 2, 3
etc.
<xsl:template name="page.number.format"> <xsl:param name="element" select="local-name(.)"/> <xsl:choose> <xsl:when test="$element = 'toc'">1</xsl:when> <xsl:when test="$element = 'preface'">i</xsl:when> <xsl:when test="$element = 'dedication'">i</xsl:when> <xsl:otherwise>1</xsl:otherwise> </xsl:choose> </xsl:template>
You may need more control over a table of contents than is provided with the customization features in the stylesheets. In those situations, you may need to create a table of contents as an XML file that you can edit and process as part of your document. You can do this for the main table of contents in HTML processing, but not currently for FO output. Fortunately, you don't have write the TOC from scratch.
The extra stylesheet file html/maketoc.xsl
will output a TOC document that has a main toc
element that contains a set of tocentry
elements. If you output that to a file, you can edit it and feed it back into the processing of your document. Here are steps to do that.
Using an editable table of contents
Generate a table of contents XML file from your document. For example:
xsltproc -o customtoc.xml html/maketoc.xsl mybook.xml
Edit the TOC file customtoc.xml
as needed.
Generate your document output by processing your document with the manual.toc
parameter:
xsltproc -o mybook.html \ --stringparam manual.toc customtoc.xml \ html/docbook.xsl mybook.xml
The stylesheet parameter manual.toc
identifies the filename of your editable XML TOC file.
If you pass this parameter to the stylesheet during processing, it
will use that file in place of the automatically generated
TOC.
If you regenerate your document, you may also have to re-edit the table of contents. Unless you can automate the changes with a script, using an editable TOC is efficient only for documents that rarely change.
DocBook XSL: The Complete Guide - 3rd Edition | PDF version available | Copyright © 2002-2005 Sagehill Enterprises |