1<html><head> 2 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 3 <title>Customizing DocBook XSL stylesheets</title><link rel="stylesheet" href="reference.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.37"><link rel="home" href="index.html" title="DocBook XSL Stylesheet Documentation"><link rel="up" href="publishing.html" title="Chapter 1. DocBook XSL"><link rel="previous" href="ch01s03.html" title="XSL processing model"><link rel="next" href="extensions.html" title="Chapter 2. Saxon Extensions"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Customizing DocBook XSL stylesheets</th></tr><tr><td width="20%" align="left"><a href="ch01s03.html">Prev</a> </td><th width="60%" align="center">Chapter 1. DocBook XSL</th><td width="20%" align="right"> <a href="extensions.html">Next</a></td></tr></table><hr></div><p>The DocBook XSL stylesheets are written in a modular 4fashion. Each of the HTML and FO stylesheets starts with a 5driver file that assembles a collection of component files 6into a complete stylesheet. This modular design puts similar things together into smaller files that are easier to write and maintain than one big stylesheet. The modular stylesheet files 7are distributed among four directories:</p><div class="variablelist"><dl><dt><a name="c44b1b3b7b3b1"></a><span class="term">common/</span></dt><dd><p><a name="c44b1b3b7b3b1b2"></a>contains code common to both stylesheets, including localization data 8</p></dd><dt><a name="c44b1b3b7b3b2"></a><span class="term">fo/</span></dt><dd><p><a name="c44b1b3b7b3b2b2"></a>a stylesheet that produces XSL FO result trees 9</p></dd><dt><a name="c44b1b3b7b3b3"></a><span class="term">html/</span></dt><dd><p><a name="c44b1b3b7b3b3b2"></a>a stylesheet that produces HTML/XHTML result trees 10</p></dd><dt><a name="c44b1b3b7b3b4"></a><span class="term">lib/</span></dt><dd><p><a name="c44b1b3b7b3b4b2"></a>contains schema-independent functions 11</p></dd></dl></div><p>The driver files for each of HTML and FO stylesheets 12are <tt>html/docbook.xsl</tt> and <tt>fo/docbook.xsl</tt>, 13respectively. A driver file consists mostly of a bunch 14of <tt><xsl:include></tt> instructions to 15pull in the component templates, and then defines some 16top-level templates. For example:</p><pre class="programlisting"><xsl:include href="/VERSION"/> 17<xsl:include href="/lib/lib.xsl"/> 18<xsl:include href="/common/l10n.xsl"/> 19<xsl:include href="/common/common.xsl"/> 20<xsl:include href="autotoc.xsl"/> 21<xsl:include href="lists.xsl"/> 22<xsl:include href="callout.xsl"/> 23... 24<xsl:include href="param.xsl"/> 25<xsl:include href="pi.xsl"/> 26</pre><p>The first four modules are shared with the FO 27stylesheet and are referenced using relative pathnames to 28the common directories. Then the long list of component 29stylesheets starts. Pathnames in include statements are 30always taken to be relative to the including file. Each 31included file must be a valid XSL stylesheet, which means 32its root element must 33be <tt><xsl:stylesheet></tt>.</p><div class="sect2"><a name="c44b1b3b7b7"></a><div class="titlepage"><div><h3 class="title"><a name="c44b1b3b7b7"></a>Stylesheet inclusion vs. importing</h3></div></div><p>XSL actually provides two inclusion 34mechanisms: <tt><xsl:include></tt> and <tt><xsl:import></tt>. 35Of the two, <tt><xsl:include></tt> is 36the simpler. It treats the included content as if it were 37actually typed into the file at that point, and doesn't 38give it any more or less precedence relative to the 39surrounding text. It is best used when assembling 40dissimilar templates that don't overlap what they match. 41The DocBook driver files use this instruction to assemble a 42set of modules into a stylesheet.</p><p>In contrast, <tt><xsl:import></tt> lets 43you manage the precedence of templates and variables. It is 44the preferred mode of customizing another stylesheet because 45it lets you override definitions in the distributed 46stylesheet with your own, without altering the distribution 47files at all. You simply import the whole stylesheet and 48add whatever changes you want.</p><p>The precedence rules for import are detailed and 49rigorously defined in the XSL standard. The basic rule is 50that any templates and variables in the importing 51stylesheet have precedence over equivalent templates and 52variables in the imported stylesheet. Think of the imported stylesheet elements as a fallback collection, to be used only if a match is not found in the current stylesheet. You can customize the templates you want to change in your stylesheet file, and let the imported stylesheet handle the rest.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title"><a name="c44b1b3b7b7b5"></a>Note</h3><p>Customizing a DocBook XSL stylesheet is the opposite 53of customizing a DocBook DTD. When you customize a DocBook 54DTD, the rules of XML and SGML dictate that 55the <i>first</i> of any duplicate declarations 56wins. Any subsequent declarations of the same element or 57entity are ignored. The architecture of the DTD provides 58slots for inserting your own custom declarations early 59enough in the DTD for them to override the standard 60declarations. In contrast, customizing an XSL stylesheet is 61simpler because your definitions have precedence over imported ones.</p></div><p>You can carry modularization to deeper levels because 62module files can also include or import other modules. 63You'll need to be careful to maintain the precedence that 64you want as the modules get rolled up into a complete 65stylesheet. </p></div><div class="sect2"><a name="c44b1b3b7b8"></a><div class="titlepage"><div><h3 class="title"><a name="c44b1b3b7b8"></a>Customizing 66with <tt><xsl:import></tt></h3></div></div><p>There is currently one example of customizing 67with <tt><xsl:import></tt> in the HTML 68version of the DocBook stylesheets. 69The <tt>xtchunk.xsl</tt> stylesheet modifies the 70HTML processing to output many smaller HTML files rather 71than a single large file per input document. It uses XSL 72extensions defined only in the XSL 73processor <b>XT</b>. In the driver 74file <tt>xtchunk.xsl</tt>, the first instruction 75is <tt><xsl:import 76href="docbook.xsl"/></tt>. That instruction imports 77the original driver file, which in turn uses 78many <tt><xsl:include></tt> instructions to 79include all the modules. That single import instruction 80gives the new stylesheet the complete set of DocBook 81templates to start with.</p><p>After the 82import, <tt>xtchunk.xsl</tt> redefines some of 83the templates and adds some new ones. Here is one example 84of a redefined template:</p><pre class="programlisting">Original template in autotoc.xsl 85<xsl:template name="href.target"> 86 <xsl:param name="object" select="."/> 87 <xsl:text>#</xsl:text> 88 <xsl:call-template name="object.id"> 89 <xsl:with-param name="object" select="$object"/> 90 </xsl:call-template> 91</xsl:template> 92 93New template in xtchunk.xsl 94<xsl:template name="href.target"> 95 <xsl:param name="object" select="."/> 96 <xsl:variable name="ischunk"> 97 <xsl:call-template name="chunk"> 98 <xsl:with-param name="node" select="$object"/> 99 </xsl:call-template> 100 </xsl:variable> 101 102 <xsl:apply-templates mode="chunk-filename" select="$object"/> 103 104 <xsl:if test="$ischunk='0'"> 105 <xsl:text>#</xsl:text> 106 <xsl:call-template name="object.id"> 107 <xsl:with-param name="object" select="$object"/> 108 </xsl:call-template> 109 </xsl:if> 110</xsl:template> 111</pre><p>The new template handles the more complex processing 112of HREFs when the output is split into many HTML files. 113Where the old template could simply 114output <tt>#<i><tt>object.id</tt></i></tt>, 115the new one outputs <tt><i><tt>filename</tt></i>#<i><tt>object.id</tt></i></tt>.</p></div><div class="sect2"><a name="c44b1b3b7b9"></a><div class="titlepage"><div><h3 class="title"><a name="c44b1b3b7b9"></a>Setting stylesheet variables</h3></div></div><p>You may not have to define any new templates, 116however. The DocBook stylesheets are parameterized using 117XSL variables rather than hard-coded values for many of the 118formatting features. Since 119the <tt><xsl:import></tt> mechanism also 120lets you redefine global variables, this gives you an easy 121way to customize many features of the DocBook 122stylesheets. Over time, more features will be parameterized to permit customization. If you find hardcoded values in the stylesheets that would be useful to customize, please let the maintainer know.</p><p>Near the end of the list of includes in the main 123DocBook driver file is the 124instruction <tt><xsl:include 125href="param.xsl"/></tt>. 126The <tt>param.xsl</tt> file is the most 127important module for customizing a DocBook XSL stylesheet. 128This module contains no templates, only definitions of 129stylesheet variables. Since these variables are defined 130outside of any template, they are global variables and 131apply to the entire stylesheet. By redefining these 132variables in an importing stylesheet, you can change the 133behavior of the stylesheet.</p><p>To create a customized DocBook stylesheet, you simply 134create a new stylesheet file such 135as <tt>mystyle.xsl</tt> that imports the standard 136stylesheet and adds your own new variable definitions. Here 137is an example of a complete custom stylesheet that changes 138the depth of sections listed in the table of contents from 139two to three:</p><pre class="programlisting"><?xml version='1.0'?> 140<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 141 version='1.0' 142 xmlns="http://www.w3.org/TR/xhtml1/transitional" 143 exclude-result-prefixes="#default"> 144 145<xsl:import href="docbook.xsl"/> 146 147<xsl:variable name="toc.section.depth">3</xsl:variable> 148<!-- Add other variable definitions here --> 149 150</xsl:stylesheet> 151</pre><p>Following the opening stylesheet element are the 152import instruction and one variable definition. The 153variable <tt>toc.section.depth</tt> was defined 154in <tt>param.xsl</tt> with value "2", and here 155it is defined as "3". Since the importing stylesheet takes 156precedence, this new value is used. Thus documents 157processed with <tt>mystyle.xsl</tt> instead 158of <tt>docbook.xsl</tt> will have three levels 159of sections in the tables of contents, and all other 160processing will be the same.</p><p>Use the list of variables 161in <tt>param.xsl</tt> as your guide for creating 162a custom stylesheet. If the changes you want are controlled 163by a variable there, then customizing is easy. </p></div><div class="sect2"><a name="c44b1b3b7c10"></a><div class="titlepage"><div><h3 class="title"><a name="c44b1b3b7c10"></a>Writing your own templates</h3></div></div><p>If the changes you want are more extensive than what 164is supported by variables, you can write new templates. You 165can put your new templates directly in your importing 166stylesheet, or you can modularize your importing stylesheet 167as well. You can write your own stylesheet module 168containing a collection of templates for processing lists, 169for example, and put them in a file 170named <tt>mylists.xsl</tt>. Then your importing 171stylesheet can pull in your list templates with 172a <tt><xsl:include 173href="mylists.xsl"/></tt> instruction. Since your 174included template definitions appear after the main import 175instruction, your templates will take precedence.</p><p>You'll need to make sure your new templates are 176compatible with the remaining modules, which means:</p><div class="itemizedlist"><ul><li><p><a name="c44b1b3b7c10b4b1"></a>Any named templates should use the same name so 177calling templates in other modules can find them.</p></li><li><p><a name="c44b1b3b7c10b4b2"></a>Your template set should process the same elements 178matched by templates in the original module, to ensure 179complete coverage.</p></li><li><p><a name="c44b1b3b7c10b4b3"></a>Include the same set 180of <tt><xsl:param></tt> elements in each 181template to interface properly with any calling templates, 182although you can set different values for your 183parameters.</p></li><li><p><a name="c44b1b3b7c10b4b4"></a>Any templates that are used like subroutines to 184return a value should return the same data type.</p></li></ul></div></div><div class="sect2"><a name="c44b1b3b7c11"></a><div class="titlepage"><div><h3 class="title"><a name="c44b1b3b7c11"></a>Writing your own driver</h3></div></div><p>Another approach to customizing the stylesheets is to 185write your own driver file. Instead of 186using <tt><xsl:import 187href="docbook.xsl"/></tt>, you copy that file to a 188new name and rewrite any of 189the <tt><xsl:include/></tt> instructions to 190assemble a custom collection of stylesheet modules. One 191reason to do this is to speed up processing by reducing the 192size of the stylesheet. If you are using a customized 193DocBook DTD that omits many elements you never use, you 194might be able to omit those modules of the 195stylesheet.</p></div><div class="sect2"><a name="c44b1b3b7c12"></a><div class="titlepage"><div><h3 class="title"><a name="c44b1b3b7c12"></a>Localization</h3></div></div><p>The DocBook stylesheets include features for 196localizing generated text, that is, printing any generated 197text in a language other than the default English. In 198general, the stylesheets will switch to the language 199identified by a <tt>lang</tt> attribute when 200processing elements in your documents. If your documents 201use the <tt>lang</tt> attribute, then you don't 202need to customize the stylesheets at all for 203localization.</p><p>As far as the stylesheets go, 204a <tt>lang</tt> attribute is inherited by the 205descendents of a document element. The stylesheet searches 206for a <tt>lang</tt> attribute using this XPath 207expression:</p><pre class="programlisting"><xsl:variable name="lang-attr" 208 select="($target/ancestor-or-self::*/@lang 209 |$target/ancestor-or-self::*/@xml:lang)[last()]"/></pre><p>This locates the attribute on the current element or 210its most recent ancestor. Thus 211a <tt>lang</tt> attribute is in effect for an 212element and all of its descendents, unless it is reset in 213one of those descendents. If you define it in only your 214document root element, then it applies to the whole 215document:</p><pre class="programlisting"><?xml version="1.0"?> 216<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN" "docbook.dtd"> 217<book lang="fr"> 218... 219</book></pre><p>When text is being generated, the stylesheet checks 220the most recent <tt>lang</tt> attribute and looks 221up the generated text strings for that language in a 222localization XML file. These are located in 223the <tt>common</tt> directory of the 224stylesheets, one file per language. Here is the top of the 225file <tt>fr.xml</tt>:</p><pre class="programlisting"><localization language="fr"> 226 227<gentext key="abstract" text="R&#x00E9;sum&#x00E9;"/> 228<gentext key="answer" text="R:"/> 229<gentext key="appendix" text="Annexe"/> 230<gentext key="article" text="Article"/> 231<gentext key="bibliography" text="Bibliographie"/> 232... 233</pre><p>The stylesheet templates use the gentext key names, 234and then the stylesheet looks up the associated text value 235when the document is processed with that lang setting. The 236file <tt>l10n.xml</tt> (note 237the <tt>.xml</tt> suffix) lists the filenames of 238all the supported languages.</p><p>You can also create a custom stylesheet that sets the 239language. That might be useful if your documents don't make 240appropriate use of the <tt>lang</tt> attribute. 241The module <tt>l10n.xsl</tt> defines two global 242variables that can be overridden with an importing 243stylesheet as described above. Here are their default 244definitions:</p><pre class="programlisting"><xsl:variable name="l10n.gentext.language"></xsl:variable> 245<xsl:variable name="l10n.gentext.default.language">en</xsl:variable> 246</pre><p>The first one sets the language for all elements, 247regardless of an element's <tt>lang</tt> attribute 248value. The second just sets a default language for any 249elements that haven't got a <tt>lang</tt> setting 250of their own (or their ancestors).</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a href="ch01s03.html">Prev</a> </td><td width="20%" align="center"><a href="index.html">Home</a></td><td width="40%" align="right"> <a href="extensions.html">Next</a></td></tr><tr><td width="40%" align="left">XSL processing model </td><td width="20%" align="center"><a href="publishing.html">Up</a></td><td width="40%" align="right"> Chapter 2. Saxon Extensions</td></tr></table></div></body></html>