PageNumberPrefixes

Norman Walsh edited this page Oct 1, 2015 · 1 revision
Clone this wiki locally

Page Number Prefixes

This is a customization layer for the DocBook XSL Stylesheets. It was written for use with the 1.60.1 version of the XSL-FO stylesheets. It allows authors and publishers to number pages in an FO document with "prefixes" (e.g. chapter numbers)

Usage

You should be able to copy the contents of the stylesheet (below) into an XSL file and import it into your own customization layer. The templates this stylesheet customizes are:

  • name="toc.line" -- put page number prefixes in the TOC
  • match="indexterm" mode="reference" -- put page number prefixes in the Index
  • name="reference" -- put page number prefixes in the Index
  • match="indexterm" mode="reference-markup" -- put page number prefixes in the Index
  • match="reference-markup" -- put page number prefixes in the Index
  • name="footer.content" -- put page number prefixes on each page
  • match="chapter" -- Restart page numbering at chapters
  • match="book/index|part/index" -- Restart page numbering at Index

This customization also adds an extra mode: page-number-prefix. In the templates that put in an fo:page-number-citation/, the customizations just call this mode. The default template for this mode (match="*") does nothing. The customization has templates that match on elements or their descendants to specify a prefix.

If you use appendix, bibliography, or glossary in your documents, you will probably want to do some additional customizations so the page numbering restarts at these elements, also. (Add initial-page-number="1" to the fo:page-sequence/ created for these elements. See the templates matching chapter and index for examples.) You may also want to do something different with references, parts, and refentry's than this customization currently does. (For the ANSYS documentation, the page-number-prefix for these elements comes from the chapter preceding the reference material.)

Stylesheet

{{{

]> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">

<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:with-param name="purpose" select="'toc'"/> </xsl:apply-templates> </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"> <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}"> <xsl:apply-templates mode="page-number-prefix" select="."/> <fo:page-number-citation ref-id="{$id}"/> </fo:basic-link> </fo:inline> </fo:block> </xsl:template>

<xsl:template match="indexterm" mode="reference"> <xsl:param name="scope" select="."/> <xsl:param name="separator" select="', '"/>

<xsl:if test="$passivetex.extensions = '0'"> <xsl:value-of select="$separator"/> </xsl:if>

xsl:choose <xsl:when test="@zone and string(@zone)"> <xsl:call-template name="reference"> <xsl:with-param name="zones" select="normalize-space(@zone)"/> <xsl:with-param name="scope" select="$scope"/> </xsl:call-template> </xsl:when> xsl:otherwise <xsl:variable name="id"> <xsl:call-template name="object.id"/> </xsl:variable>

<fo:basic-link internal-destination="{$id}"> <xsl:apply-templates mode="page-number-prefix" select="."/> <fo:page-number-citation ref-id="{$id}"/> </fo:basic-link>

<xsl:if test="key('endofrange', @id)[&scope;]"> <xsl:apply-templates select="key('endofrange', @id)[&scope;][last()]" mode="reference"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="separator" select="'-'"/> </xsl:apply-templates> </xsl:if> </xsl:otherwise> </xsl:choose> </xsl:template>

<xsl:template name="reference"> <xsl:param name="scope" select="."/> <xsl:param name="zones"/>

xsl:choose <xsl:when test="contains($zones, ' ')"> <xsl:variable name="zone" select="substring-before($zones, ' ')"/> <xsl:variable name="target" select="key('id', $zone)[&scope;]"/>

<xsl:variable name="id"> <xsl:call-template name="object.id"> <xsl:with-param name="object" select="$target[1]"/> </xsl:call-template> </xsl:variable>

<fo:basic-link internal-destination="{$id}"> <xsl:apply-templates mode="page-number-prefix" select="$target[1]"/> <fo:page-number-citation ref-id="{$id}"/> </fo:basic-link>

<xsl:if test="$passivetex.extensions = '0'"> xsl:text, </xsl:text> </xsl:if> <xsl:call-template name="reference"> <xsl:with-param name="zones" select="substring-after($zones, ' ')"/> <xsl:with-param name="scope" select="$scope"/> </xsl:call-template> </xsl:when> xsl:otherwise <xsl:variable name="zone" select="$zones"/> <xsl:variable name="target" select="key('id', $zone)[&scope;]"/>

<xsl:variable name="id"> <xsl:call-template name="object.id"> <xsl:with-param name="object" select="$target[1]"/> </xsl:call-template> </xsl:variable>

<fo:basic-link internal-destination="{$id}"> <xsl:apply-templates mode="page-number-prefix" select="$target[1]"/> <fo:page-number-citation ref-id="{$id}"/> </fo:basic-link> </xsl:otherwise> </xsl:choose> </xsl:template>

<xsl:template match="indexterm" mode="reference-markup"> <xsl:param name="scope" select="."/> xsl:choose <xsl:when test="@zone and string(@zone)"> <xsl:call-template name="reference-markup"> <xsl:with-param name="zones" select="normalize-space(@zone)"/> <xsl:with-param name="scope" select="$scope"/> </xsl:call-template> </xsl:when> xsl:otherwise <xsl:variable name="id"> <xsl:call-template name="object.id"/> </xsl:variable>

xsl:choose <xsl:when test="@startref and @class='endofrange'"> xsl:text<phrase role="pageno"></xsl:text> xsl:text<link linkend="</xsl:text> <xsl:value-of select="@startref"/> xsl:text"></xsl:text> <fo:basic-link internal-destination="{@startref}"> <xsl:apply-templates mode="page-number-prefix" select="."/> <fo:page-number-citation ref-id="{@startref}"/> xsl:text-</xsl:text> <fo:page-number-citation ref-id="{$id}"/> </fo:basic-link> xsl:text</link></xsl:text> xsl:text</phrase> </xsl:text> </xsl:when> xsl:otherwise xsl:text<phrase role="pageno"></xsl:text> <xsl:if test="@id"> xsl:text<link linkend="</xsl:text> <xsl:value-of select="$id"/> xsl:text"></xsl:text> </xsl:if> <fo:basic-link internal-destination="{$id}"> <xsl:apply-templates mode="page-number-prefix" select="."/> <fo:page-number-citation ref-id="{$id}"/> </fo:basic-link> <xsl:if test="@id"> xsl:text</link></xsl:text> </xsl:if> xsl:text</phrase> </xsl:text> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template>

<xsl:template name="reference-markup"> <xsl:param name="scope" select="."/> <xsl:param name="zones"/> xsl:choose <xsl:when test="contains($zones, ' ')"> <xsl:variable name="zone" select="substring-before($zones, ' ')"/> <xsl:variable name="target" select="key('id', $zone)[&scope;]"/>

<xsl:variable name="id"> <xsl:call-template name="object.id"> <xsl:with-param name="object" select="$target[1]"/> </xsl:call-template> </xsl:variable>

xsl:text<phrase fole="pageno"></xsl:text> <xsl:if test="$target[1]/@id"> xsl:text<link linkend="</xsl:text> <xsl:value-of select="$id"/> xsl:text"></xsl:text> </xsl:if> <fo:basic-link internal-destination="{$id}"> <xsl:apply-templates mode="page-number-prefix" select="$target[1]"/> <fo:page-number-citation ref-id="{$id}"/> </fo:basic-link> <xsl:if test="$target[1]/@id"> xsl:text</link></xsl:text> </xsl:if> xsl:text</phrase> </xsl:text>

<xsl:call-template name="reference"> <xsl:with-param name="zones" select="substring-after($zones, ' ')"/> <xsl:with-param name="scope" select="$scope"/> </xsl:call-template> </xsl:when> xsl:otherwise <xsl:variable name="zone" select="$zones"/> <xsl:variable name="target" select="key('id', $zone)[&scope;]"/>

<xsl:variable name="id"> <xsl:call-template name="object.id"> <xsl:with-param name="object" select="$target[1]"/> </xsl:call-template> </xsl:variable>

xsl:text<phrase role="pageno"></xsl:text> <xsl:if test="$target[1]/@id"> xsl:text<link linkend="</xsl:text> <xsl:value-of select="$id"/> xsl:text"></xsl:text> </xsl:if> <fo:basic-link internal-destination="{$id}"> <xsl:apply-templates mode="page-number-prefix" select="$target[1]"/> <fo:page-number-citation ref-id="{$id}"/> </fo:basic-link> <xsl:if test="$target[1]/@id"> xsl:text</link></xsl:text> </xsl:if> xsl:text</phrase> </xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template>

<xsl:template name="footer.content"> <xsl:param name="pageclass" select="''"/> <xsl:param name="sequence" select="''"/> <xsl:param name="position" select="''"/> <xsl:param name="gentext-key" select="''"/>

fo:block

xsl:choose <xsl:when test="$pageclass='titlepage'">

</xsl:when> <xsl:when test="$pageclass='lot' and $position = 'first'"> <xsl:apply-templates mode="page-number-prefix" select="."/> fo:page-number/ </xsl:when>

<xsl:when test="$sequence='blank'"> xsl:choose <xsl:when test="$double.sided != 0 and $position = 'left'"> <xsl:apply-templates mode="page-number-prefix" select="."/> fo:page-number/ </xsl:when> <xsl:when test="$double.sided = 0 and $position = 'center'"> <xsl:apply-templates mode="page-number-prefix" select="."/> fo:page-number/ </xsl:when> xsl:otherwise

</xsl:otherwise> </xsl:choose> </xsl:when>

<xsl:when test="starts-with($gentext-key,'refentry') and $sequence='first' and $position='right'"> <xsl:apply-templates mode="page-number-prefix" select="."/> fo:page-number/ </xsl:when>

<xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='left'"> <xsl:apply-templates mode="page-number-prefix" select="."/> fo:page-number/ </xsl:when>

<xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='right'"> <xsl:apply-templates mode="page-number-prefix" select="."/> fo:page-number/ </xsl:when>

xsl:otherwise

</xsl:otherwise> </xsl:choose> </fo:block> </xsl:template>

<xsl:template match="chapter"> <xsl:variable name="id"> <xsl:call-template name="object.id"/> </xsl:variable>

<xsl:variable name="master-reference"> <xsl:call-template name="select.pagemaster"/> </xsl:variable>

<fo:page-sequence id="{$id}" hyphenate="{$hyphenate}" master-reference="{$master-reference}"> <xsl:attribute name="language"> <xsl:call-template name="l10n.language"/> </xsl:attribute> <xsl:attribute name="format"> <xsl:call-template name="page.number.format"/> </xsl:attribute> xsl:choose <xsl:when test="not(preceding::chapter or preceding::appendix or preceding::article or preceding::dedication or parent::part or parent::reference)">

<xsl:attribute name="initial-page-number">1</xsl:attribute> </xsl:when> <xsl:when test="$double.sided != 0"> <xsl:attribute name="initial-page-number">1</xsl:attribute> </xsl:when> </xsl:choose>

<xsl:apply-templates select="." mode="running.head.mode"> <xsl:with-param name="master-reference" select="$master-reference"/> </xsl:apply-templates>

<xsl:apply-templates select="." mode="running.foot.mode"> <xsl:with-param name="master-reference" select="$master-reference"/> </xsl:apply-templates>

<fo:flow flow-name="xsl-region-body"> <xsl:call-template name="chapter.titlepage"/>

<xsl:variable name="toc.params"> <xsl:call-template name="find.path.params"> <xsl:with-param name="table" select="normalize-space($generate.toc)"/> </xsl:call-template> </xsl:variable> <xsl:if test="contains($toc.params, 'toc')"> <xsl:call-template name="component.toc"/> </xsl:if> xsl:apply-templates/ </fo:flow> </fo:page-sequence> </xsl:template>

<xsl:template match="book/index|part/index"> <xsl:variable name="id"> <xsl:call-template name="object.id"/> </xsl:variable>

<xsl:if test="$generate.index != 0"> <xsl:variable name="master-reference"> <xsl:call-template name="select.pagemaster"> <xsl:with-param name="pageclass"> <xsl:if test="$make.index.markup != 0">body</xsl:if> </xsl:with-param> </xsl:call-template> </xsl:variable>

<fo:page-sequence id="{$id}" hyphenate="{$hyphenate}" master-reference="{$master-reference}"> <xsl:attribute name="language"> <xsl:call-template name="l10n.language"/> </xsl:attribute> <xsl:attribute name="format"> <xsl:call-template name="page.number.format"/> </xsl:attribute> <xsl:attribute name="initial-page-number">1</xsl:attribute>

<xsl:apply-templates select="." mode="running.head.mode"> <xsl:with-param name="master-reference" select="$master-reference"/> </xsl:apply-templates> <xsl:apply-templates select="." mode="running.foot.mode"> <xsl:with-param name="master-reference" select="$master-reference"/> </xsl:apply-templates>

<fo:flow flow-name="xsl-region-body"> <xsl:call-template name="index.titlepage"/> xsl:apply-templates/ <xsl:if test="count(indexentry) = 0 and count(indexdiv) = 0">

xsl:choose <xsl:when test="$make.index.markup != 0"> <fo:block wrap-option='no-wrap' white-space-collapse='false' xsl:use-attribute-sets="monospace.verbatim.properties" linefeed-treatment="preserve"> <xsl:call-template name="generate-index-markup"> <xsl:with-param name="scope" select="(ancestor::book|/)[last()]"/> </xsl:call-template> </fo:block> </xsl:when> <xsl:when test="indexentry|indexdiv/indexentry"> xsl:apply-templates/ </xsl:when> xsl:otherwise <xsl:call-template name="generate-index"> <xsl:with-param name="scope" select="(ancestor::book|/)[last()]"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:if> </fo:flow> </fo:page-sequence> </xsl:if> </xsl:template>

<xsl:template match="chapter|chapter//*" mode="page-number-prefix"> <xsl:number count="chapter" from="book" level="any"/> xsl:text–</xsl:text> </xsl:template>

<xsl:template match="appendix|appendix//*" mode="page-number-prefix"> <xsl:number count="appendix" from="book" level="single" format="A"/> xsl:text–</xsl:text> </xsl:template>

<xsl:template match="glossary|glossary//*" mode="page-number-prefix"> <xsl:variable name="glossname"> <xsl:call-template name="gentext"> <xsl:with-param name="key" select="'glossary'"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="substring($glossname,1,1)"/> xsl:text–</xsl:text> </xsl:template>

<xsl:template match="index|index//*" mode="page-number-prefix"> <xsl:call-template name="gentext"> <xsl:with-param name="key" select="'index'"/> </xsl:call-template> xsl:text–</xsl:text> </xsl:template>

<xsl:template match="reference|reference//*" mode="page-number-prefix"> <xsl:apply-templates select="preceding::chapter[1]" mode="page-number-prefix"/> </xsl:template>

<xsl:template match="refentry|refentry//*" mode="page-number-prefix"> <xsl:apply-templates select="preceding::chapter[1]" mode="page-number-prefix"/> </xsl:template>

<xsl:template match="*" mode="page-number-prefix"/>

</xsl:stylesheet>

}}}