Difficulty: ★☆☆ (easy)
Keywords: titles, numbering, appendix.autolabel, chapter.autolabel, part.autolabel, preface.autolabel, qandadiv.autolabel, reference.autolabel, section.autolabel, section.label.includes.component.label, component.label.includes.part.label, label.from.part, section.autolabel.max.depth

Problem

You want a number in front of your structural elements like appendix, chapter, section, etc.

Solution

The DocBook XSL stylesheets provide already a decent numbering scheme for high level divisions like parts, appendices, chapters, and references. The most common use is numbering section. If you want to automatically number section titles, set the section.autolabel parameter either manually or through a customization layer, for example:

<xsl:param name="section.autolabel" select="1"/>

Discussion

The DocBook XSL stylesheets contain autolabel parameters for the common elements appendix, chapter, part, preface, qandadiv, reference, and section. These can be set individually to change the numbering of for the same elements. The default values are shown in Table 4.1, “Autolabel Parameters and their Default Values”.

Table 4.1. Autolabel Parameters and their Default Values
ParameterDefaultExample
appendix.autolabelAAppendix A. Python 3
chapter.autolabel1Chapter 1. A Tutorial Introduction
part.autolabelIPart I. The Python Language
preface.autolabel0Prefaces are usually not numbered
qandadiv.autolabel13.1 Installation Questions
reference.autolabelII. Python Reference
section.autolabel0Not numbered by default

The autolabel parameters can contain the following values:

Value 0

A value of zero disables the automatic numbering. For example, if you want to disable automatic numbering for appendix elements, use this:

<xsl:param name="appendix.autolabel" select="0"/>
Value 1

A value of one enables the automatic numbering and uses arabic numerals. For example, section numbering is disabled by default. Use the code in the Solution section.

String

A string enables a different automatic numbering schema, for example roman numerals. See the following table to get an overview.

Table 4.2. Possible Formats for Autolabel Parameters
ValueAlternative ValueStyleExample
1arabicArabic numerals1, 2, 3, 4, …
IupperromanUppercase roman numeralsI, II, III, IV, …
ilowerromanLowercase roman numeralsi, ii, iii, iv, …
AupperalphaUppercase lettersA, B, C, D, …
aloweralphaLowercase lettersa, b, c, d, …
&#x661;arabicindicArabic-Indic numerals١, ٢, ٣, ٤, …

Mostly you will probably want sections to be numbered including its parent numbering. If you do not touch chapter.autolabel, use the parameter section.label.includes.component.label and set it to 1:

<xsl:param name="section.autolabel" select="1"/>
<xsl:param name="section.label.includes.component.label" select="1"/>

With the following parameters you can further customize your numbering:

component.label.includes.part.label

Controls if appendix or chapter number labels are prefixed with their contained part label.

label.from.part

Defines if the components inside a part is renumbered or not. A value of non-zero restarts the chapter number and counts again from one. Use this numbering if you want unambiguous numerals.

The value zero (the default) restarts the component number throughout each book.

section.autolabel.max.depth

Controls which sections get a number. By default, all sections are get numbered (default value is 8.) If you want to number only sections at level 1, set the parameter to the value 1.

Let us assume the following structure in a book:

Part: The Python Language
  Chapter: A Tutorial Introduction
     Section: Running Python
     Section: Variables

  Chapter: Lexical Conventions and Syntax
     Section: Line Structure and Indentation
     Section: Identifiers and Reserved Words

Part: The Python Library
  Chapter: Build-In Functions
     Section: Build-In Functions and Types
     Section: Build-In Exceptions
  Chapter: Python Runtime Services
     Section: atext
     Section: copy
Table 4.3. Parameter Combinations
ParametersResult
No parameters set, using the default settings
I. The Python Language
  1. A Tutorial Introduction
      Running Python
      Variables
  2. Lexical Conventions and Syntax
      Line Structure and Indentation
      Identifiers and Reserved Words
II. The Python Library
  3. Build-In Functions
      Build-In Functions and Types
      Build-In Exceptions
  4. Python Runtime Services
      atext
      copy
section.autolabel=1
I. The Python Language
  1. A Tutorial Introduction
      1. Running Python
      2. Variables
  2. Lexical Conventions and Syntax
      1. Line Structure and Indentation
      2. Identifiers and Reserved Words
II. The Python Library
  3. Build-In Functions
      1. Build-In Functions and Types
      2. Build-In Exceptions
  4. Python Runtime Services
      1. atexit
      2. copy
section.autolabel=1
section.label.includes.component.label=1
I. The Python Language
  1. A Tutorial Introduction
      1.1. Running Python
      1.2. Variables
  2. Lexical Conventions and Syntax
      2.1. Line Structure and Indentation
      2.2. Identifiers and Reserved Words
II. The Python Library
  3. Build-In Functions
      3.1. Build-In Functions and Types
      3.2. Build-In Exceptions
  4. Python Runtime Services
      4.1. atexit
      4.2. copy
section.autolabel=1
section.label.includes.component.label=1
component.label.includes.part.label
I. The Python Language
  I.1. A Tutorial Introduction
      I.1.1. Running Python
      I.1.2. Variables
  I.2. Lexical Conventions and Syntax
      I.2.1. Line Structure and Indentation
      I.2.2. Identifiers and Reserved Words
II. The Python Library
  II.3. Build-In Functions
      II.3.1. Build-In Functions and Types
      II.3.2. Build-In Exceptions
  II.4. Python Runtime Services
      II.4.1. atexit
      II.4.2. copy
section.autolabel=1
section.label.includes.component.label=1
component.label.includes.part.label
label.from.part=1
I. The Python Language
  I.1. A Tutorial Introduction
      I.1.1. Running Python
      I.1.2. Variables
  I.2. Lexical Conventions and Syntax
      I.2.1. Line Structure and Indentation
      I.2.2. Identifiers and Reserved Words
II. The Python Library
  II.1. Build-In Functions
      II.1.1. Build-In Functions and Types
      II.1.2. Build-In Exceptions
  II.2. Python Runtime Services
      II.2.1. atexit
      II.2.2. copy

However, when dealing with other numbering systems, the above parameters are not enough. To support, for example, Japanese numbering, you need to customize the named template autolabel.format from common/labels.xsl.

Example 4.3. Extending autolabel.format
<xsl:template name="autolabel.format">
  <xsl:param name="context" select="."/>
  <xsl:param name="format"/>

  <xsl:choose>
    <xsl:when test="string($format) != 0">
      <xsl:choose>
        <xsl:when test="string($format)='001'">
          <xsl:value-of select="$format"/>
        </xsl:when>
        <xsl:when test="$format='loweralpha' or $format='a'">
          <xsl:value-of select="'a'"/>
        </xsl:when>
        <xsl:when test="$format='lowerroman' or $format='i'">
          <xsl:value-of select="'i'"/>
        </xsl:when>
        <xsl:when test="$format='upperalpha' or $format='A'">
          <xsl:value-of select="'A'"/>
        </xsl:when>
        <xsl:when test="$format='upperroman' or $format='I'">
          <xsl:value-of select="'I'"/>
        </xsl:when>
        <xsl:when test="$format='arabicindic' or $format='١'">
          <xsl:value-of select="'١'"/>
        </xsl:when>
        <xsl:when test="$format='japanese' or $format='&#x4e00;'">
          <xsl:value-of select="'&#x4e00;'"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:message>
            <xsl:text>Unexpected </xsl:text>
            <xsl:value-of select="local-name(.)"/>
            <xsl:text>.autolabel value: </xsl:text>
            <xsl:value-of select="$format"/>
            <xsl:text>; using default.</xsl:text>
          </xsl:message>
          <xsl:call-template name="default.autolabel.format"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
  </xsl:choose>
</xsl:template>

Unfortunately, the xsltproc processor does not support this currently (as in version 1.1.24). Only Saxon does it correct.

See Also


Project@GitHubIssue#9