Chapter 9. General customizations

Table of Contents

Custom section numbering
Label punctuation
Tables of contents (TOC)
Which components have a TOC
Levels in book and chapter TOCs
Customized TOC levels
Turning on section TOCs
Keeping selected titles out of the toc
Customizing TOC presentation
Figure, table, and other titles
Formal title placement
Person names

Many customizations can be applied to both HTML and FO (print) output because the stylesheets share some code and processing styles. See the section “Customizing both HTML and FO” for a technique of sharing such customizations.

Custom section numbering

As described in the section “Chapter and section numbering”, you can turn on standard section numbering with stylesheet parameters. But you may want to further refine the numbering style.

The number label for an element is generated using the label.markup mode. That is, the element needing the number is processed with:

<xsl:apply-templates select="." mode="label.markup"/>

The XSL processor finds the template with mode="label.markup" that best matches the current element. The templates with this mode are in the stylesheet file common/labels.xsl for all the elements that might get numbered. They are in common so the same templates can be used for both HTML and FO output. Templates with mode label.markup return just the number. The same templates are used to generate the numbers that appear in any tables of contents and cross references.

Section labeling such as 2.1.4 uses several of the label.markup mode templates, because the number is assembled from ancestor elements as well as the current element. Those templates apply templates on their parent element, selected as ".." in the template. The following example is how a sect1 label is generated:

Example 9.1. Applying label.markup mode to sect1

<xsl:template match="sect1" mode="label.markup">  1
  <!-- if the parent is a component, maybe label that too -->
  <xsl:variable name="parent.is.component">
    <xsl:call-template name="is.component">  2
      <xsl:with-param name="node" select=".."/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="component.label">
    <xsl:if test="$section.label.includes.component.label != 0  3
                  and $parent.is.component != 0">  
      <xsl:variable name="parent.label">
        <xsl:apply-templates select=".." mode="label.markup"/>  
      </xsl:variable>
      <xsl:if test="$parent.label != ''">
        <xsl:apply-templates select=".." mode="label.markup"/>  4
        <xsl:apply-templates select=".." mode="intralabel.punctuation"/>  
      </xsl:if>
    </xsl:if>
  </xsl:variable>

  <xsl:variable name="is.numbered">
    <xsl:call-template name="label.this.section"/>  5
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="@label">
      <xsl:value-of select="@label"/>  6
    </xsl:when>
    <xsl:when test="$is.numbered != 0">
      <xsl:copy-of select="$component.label"/>
      <xsl:number count="sect1"/>  7
    </xsl:when>
  </xsl:choose>
</xsl:template>
1

Applying a template using mode="label.markup" just returns the number of an element, if it has one.

2

It calls the template named parent.is.component, which returns true if the parent element is a DocBook component (chapter, appendix, etc.).

3

Then if the parameter section.label.includes.component.label is turned on, and the parent is a component, it generates the parent element's label and inserts the separator punctuation.

4

Get the parent label by using label.markup mode on “..”, which selects the parent element.

5

It checks to see if the current section level is numbered by calling the template named label.this.section. A section may not be numbered if its level is greater than the value set by the section.autolabel.max.depth parameter (see the section “Depth of section numbering”).

6

Before using the section number, though, it checks to see if the current section element has a literal label attribute, which manually overrides the automatic label.

7

The automatic number for this sect1 is generated using the XSLT xsl:number element, set to count sibling sect1 elements.

Label punctuation

When a label has several components, such as 2.1.4, each of the components is separated by some punctuation. Since the label is generated by the stylesheet, the punctuation also must be generated. You might think the character used for punctuation is controlled by a stylesheet parameter, but it isn't. Rather, the punctuation is generated by templates in a special mode, the intralabel.punctuation mode. Here is the default template included with the stylesheets (from common/labels.xsl):

<xsl:template match="*" mode="intralabel.punctuation">
  <xsl:text>.</xsl:text>
</xsl:template>

So the default label separator is the period within the <xsl:text> element in the template.

Why use a mode? Because the stylesheet can provide different punctuation for different elements, depending on your style. As a label is built up from its components, the stylesheet applies templates in this mode to generate the punctuation. For example, a number label for a figure such as 3.2 is made up of the chapter number and punctuation prepended to the figure count within the chapter. These two lines generate the prefix:

<xsl:apply-templates select="$pchap" mode="label.markup"/>
 <xsl:apply-templates select="$pchap" mode="intralabel.punctuation"/>

The first line applies templates in mode="label.markup", which generates the number for the chapter node contained in the $pchap variable. The second line applies templates to the chapter node in mode="intralabel.punctuation. In the stock stylesheets, the chapter node is matched by the "*" pattern and the period is generated.

If you want the chapter number to be followed by a dash instead of a period, you could add this template to your customization layer:

<xsl:template match="chapter|appendix" mode="intralabel.punctuation">
  <xsl:text>-</xsl:text>
</xsl:template>

Now your figure labels will look like 3-2 if that is your style.