You need a simple navigation for your single HTML file. The navigation should contain for each chapter a link to the next and previous chapters including an up link pointing to the enclosing part or book. This is depicted in the following graphic:

The following file defines the named template
generate.simple.navigation:
simple-navigation.xsl<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:d="http://docbook.org/ns/docbook"
xmlns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="d">
<xsl:template name="generate.simple.navigation">
<xsl:param name="node" select="."/>
<xsl:variable name="prev" select="$node/preceding-sibling::d:chapter"/>
<xsl:variable name="next" select="$node/following-sibling::d:chapter"/>
<xsl:variable name="up" select="$node/parent::d:*"/>
<div class="chapter-navigation">
<ul>
<xsl:if test="count($next) >0">
<li class="next">
<xsl:call-template name="gentext.nav.next"/>
<xsl:text>: </xsl:text>
<a>
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$next"/>
</xsl:call-template>
</xsl:attribute>
<xsl:value-of select="$next/d:title"/>
</a>
</li>
</xsl:if>
<xsl:if test="count($prev) >0">
<li class="prev">
<xsl:call-template name="gentext.nav.prev"/>
<xsl:text>: </xsl:text>
<a>
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$prev"/>
</xsl:call-template>
</xsl:attribute>
<xsl:value-of select="$prev/d:title"/>
</a>
</li>
</xsl:if>
<xsl:if test="count($up) >0">
<li class="up">
<xsl:call-template name="gentext.nav.up"/>
<xsl:text>: </xsl:text>
<a>
<xsl:attribute name="href">
<xsl:call-template name="href.target">
<xsl:with-param name="object" select="$up"/>
</xsl:call-template>
</xsl:attribute>
<xsl:value-of select="$up/d:title"/>
</a>
</li>
</xsl:if>
</ul>
</div>
</xsl:template>
</xsl:stylesheet>This is not enough, of course. Use the following steps to include it into your customization layers:
Create a customization layer as shown in Section 2.3, “Writing Customization Layers”.
Include the stylesheet from Example 5.2, “simple-navigation.xsl” into your customization
layer:
db-simple-navigation.xsl<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY db "https://cdn.docbook.org/release/xsl/current">
]>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:d="http://docbook.org/ns/docbook"
xmlns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="d">
<xsl:import href="&db;/xhtml/docbook.xsl"/>
<xsl:import href="simple-navigation.xsl"/>
<xsl:param name="generate.simple.navigation" select="1"/>
<xsl:param name="html.stylesheet">book.css</xsl:param>
<xsl:template name="chapter.titlepage.before.recto">
<xsl:if test="$generate.simple.navigation != 0">
<xsl:call-template name="generate.simple.navigation"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>Use the file db-simple-navigation.xsl
to transform your documents.
If you want to switch on or off the above behaviour, use the
parameter generate.simple.navigation[9] and set it to 0.
The named template
generate.simple.navigation works as
follows:
Three variables are definied for the previous, next, and
up links. All depends on the node parameter
which is by default the context node. This is useful as you
can change the behaviour very easily by just changing the
context node when calling the template with
xsl:call-template.
The prev and next
variables are filled with the previous or next chapter
elements along their sibling axis. In comparison, the
up variable needs to find its enclosing
element; it uses the parent axis
for this purpose.
If there are no previous or next chapters, the node set will
be empty. For the up variable, this depends
on where a chapter belongs; usually it is enclosed in a
book or part element. As we need only
the parent element As such this variable can not be empty
(only if the chapter would be the root element.)
The simple navigation is implemented as an unordered list
inside a div element. The enclosing div
element is used to make styling with CSS easier.
With xsl:if we check the amount of nodes in our
prev and next
variables. Only if the variable contains more than zero nodes
it will a listitem created.
If we create a listitem, we want to insert a text to help
our readers and to distinguish the different directions. The
text has to be independent from the used language; so
hard-coding the text would not be sufficient. For this reason,
the DocBook stylesheets contains named templates to generate
localized text. The next, previous, and up link texts are
created through the named templates
generate.nav.next,
generate.nav.prev, and
generate.nav.up.
As the generated localized text contains only the text without interpunctations, we append “: ”.
We create the link with the a link. The needed
href attribute is created by
calling href.target (origin
html.xsl). This template is responsible
for the correct linking value.
The content of the a element is inserted from
the title element of the corresponding node. As we
are only interested in the string value, we can use
xsl:value-of.
The generate.simple.navigation template
matches only chapters along the sibling axis. As such it can not
find a glossary or appendix after a chapter. If you want to create
links for any component elements, not only
chapters, you need to change the variables prev
and next. A first attempt would lead to
this:
<xsl:variable name="prev" select="$node/preceding-sibling::d:*[1]"/> <xsl:variable name="next" select="$node/following-sibling::d:*[1]"/>
This works for the next variables. However,
our expression for the prev variable contains a
bug. Consider the following structure:
book
title
info
chapter
...The preceding-sibling axis returns the
info and title elements. This is not what
you want as these are no component elements for our
prev link. In that case we need an expression
to filter out the unwanted elements. This is done with an
predicate:
<xsl:variable name="prev" select="$node/preceding-sibling::d:*[not(self::d:title|self::d:info)][1]"/>
That expression first creates a node set with
all preceding elements. In a second step
they are check against the term
not(self::d:title|self::d:info); only those
elements remain in the node set which are not title or
info elements. In our above example, this leads to a
node set with zero nodes and is exactly what we wanted to
achieve.
With the previous change, we allow any
structural element to be included in a next or previous link.
However, we show our navigation links only in chapter titlepages
at the moment (the named template
chapter.titlepage.before.recto.) We need to
extend the stylesheet
db-simple-navigation.xsl to allow elements
like appendix, glossary, etc. Refer to the
content modell of DocBook´s book element for details. For an appendix this
looks like this:
<xsl:template name="appendix.titlepage.before.recto">
<xsl:if test="$generate.simple.navigation != 0">
<xsl:call-template name="generate.simple.navigation"/>
</xsl:if>
</xsl:template>For the other elements this is exactly the same except the
name. Just use the element name and append
.titlepage.before.recto.
[9] It is not an error to have a parameter with the same name as a named template.
| Project@GitHub | Issue#10 |