]> git.stg.codes - stg.git/blob - doc/xslt/fo/toc.xsl
Moved common code to a single file.
[stg.git] / doc / xslt / fo / toc.xsl
1 <?xml version='1.0'?>
2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3                 xmlns:fo="http://www.w3.org/1999/XSL/Format"
4                 version='1.0'>
5
6 <!-- ********************************************************************
7      $Id: toc.xsl 8323 2009-03-12 22:52:17Z bobstayton $
8      ********************************************************************
9
10      This file is part of the XSL DocBook Stylesheet distribution.
11      See ../README or http://docbook.sf.net/release/xsl/current/ for
12      copyright and other information.
13
14      ******************************************************************** -->
15
16 <!-- ==================================================================== -->
17
18 <!-- only set, book and part puts toc in its own page sequence -->
19
20 <xsl:template match="set/toc | book/toc | part/toc">
21   <xsl:variable name="toc.params">
22     <xsl:call-template name="find.path.params">
23       <xsl:with-param name="node" select="parent::*"/>
24       <xsl:with-param name="table" select="normalize-space($generate.toc)"/>
25     </xsl:call-template>
26   </xsl:variable>
27
28   <!-- Do not output the toc element if one is already generated
29        by the use of $generate.toc parameter, or if
30        generating a source toc is turned off -->
31   <xsl:if test="not(contains($toc.params, 'toc')) and
32                 ($process.source.toc != 0 or $process.empty.source.toc != 0)">
33     <!-- Don't generate a page sequence unless there is content -->
34     <xsl:variable name="content">
35       <xsl:choose>
36         <xsl:when test="* and $process.source.toc != 0">
37           <xsl:apply-templates />
38         </xsl:when>
39         <xsl:when test="count(*) = 0 and $process.empty.source.toc != 0">
40           <!-- trick to switch context node to parent element -->
41           <xsl:for-each select="parent::*">
42             <xsl:choose>
43               <xsl:when test="self::set">
44                 <xsl:call-template name="set.toc">
45                   <xsl:with-param name="toc.title.p" 
46                                   select="contains($toc.params, 'title')"/>
47                 </xsl:call-template>
48               </xsl:when>
49               <xsl:when test="self::book">
50                 <xsl:call-template name="division.toc">
51                   <xsl:with-param name="toc.title.p" 
52                                   select="contains($toc.params, 'title')"/>
53                 </xsl:call-template>
54               </xsl:when>
55               <xsl:when test="self::part">
56                 <xsl:call-template name="division.toc">
57                   <xsl:with-param name="toc.title.p" 
58                                   select="contains($toc.params, 'title')"/>
59                 </xsl:call-template>
60               </xsl:when>
61             </xsl:choose>
62           </xsl:for-each>
63         </xsl:when>
64       </xsl:choose>
65     </xsl:variable>
66
67     <xsl:if test="string-length(normalize-space($content)) != 0">
68       <xsl:variable name="lot-master-reference">
69         <xsl:call-template name="select.pagemaster">
70           <xsl:with-param name="pageclass" select="'lot'"/>
71         </xsl:call-template>
72       </xsl:variable>
73     
74       <xsl:call-template name="page.sequence">
75         <xsl:with-param name="master-reference"
76                         select="$lot-master-reference"/>
77         <xsl:with-param name="element" select="'toc'"/>
78         <xsl:with-param name="gentext-key" select="'TableofContents'"/>
79         <xsl:with-param name="content" select="$content"/>
80       </xsl:call-template>
81     </xsl:if>
82   </xsl:if>
83 </xsl:template>
84   
85 <xsl:template match="chapter/toc | appendix/toc | preface/toc | article/toc">
86   <xsl:variable name="toc.params">
87     <xsl:call-template name="find.path.params">
88       <xsl:with-param name="node" select="parent::*"/>
89       <xsl:with-param name="table" select="normalize-space($generate.toc)"/>
90     </xsl:call-template>
91   </xsl:variable>
92
93   <!-- Do not output the toc element if one is already generated
94        by the use of $generate.toc parameter, or if
95        generating a source toc is turned off -->
96   <xsl:if test="not(contains($toc.params, 'toc')) and
97                 ($process.source.toc != 0 or $process.empty.source.toc != 0)">
98     <xsl:choose>
99       <xsl:when test="* and $process.source.toc != 0">
100         <fo:block>
101           <xsl:apply-templates/> 
102         </fo:block>
103       </xsl:when>
104       <xsl:when test="count(*) = 0 and $process.empty.source.toc != 0">
105         <!-- trick to switch context node to section element -->
106         <xsl:for-each select="parent::*">
107           <xsl:call-template name="component.toc">
108             <xsl:with-param name="toc.title.p" 
109                             select="contains($toc.params, 'title')"/>
110           </xsl:call-template>
111         </xsl:for-each>
112       </xsl:when>
113     </xsl:choose>
114     <xsl:call-template name="component.toc.separator"/>
115   </xsl:if>
116 </xsl:template>
117
118 <xsl:template match="section/toc
119                     |sect1/toc
120                     |sect2/toc
121                     |sect3/toc
122                     |sect4/toc
123                     |sect5/toc">
124
125   <xsl:variable name="toc.params">
126     <xsl:call-template name="find.path.params">
127       <xsl:with-param name="node" select="parent::*"/>
128       <xsl:with-param name="table" select="normalize-space($generate.toc)"/>
129     </xsl:call-template>
130   </xsl:variable>
131
132   <!-- Do not output the toc element if one is already generated
133        by the use of $generate.toc parameter, or if
134        generating a source toc is turned off -->
135   <xsl:if test="not(contains($toc.params, 'toc')) and
136                 ($process.source.toc != 0 or $process.empty.source.toc != 0)">
137     <xsl:choose>
138       <xsl:when test="* and $process.source.toc != 0">
139         <fo:block>
140           <xsl:apply-templates/> 
141         </fo:block>
142       </xsl:when>
143       <xsl:when test="count(*) = 0 and $process.empty.source.toc != 0">
144         <!-- trick to switch context node to section element -->
145         <xsl:for-each select="parent::*">
146           <xsl:call-template name="section.toc">
147             <xsl:with-param name="toc.title.p" 
148                             select="contains($toc.params, 'title')"/>
149           </xsl:call-template>
150         </xsl:for-each>
151       </xsl:when>
152     </xsl:choose>
153     <xsl:call-template name="section.toc.separator"/>
154   </xsl:if>
155 </xsl:template>
156
157 <!-- ==================================================================== -->
158
159 <xsl:template match="tocpart|tocchap
160                      |toclevel1|toclevel2|toclevel3|toclevel4|toclevel5">
161   <xsl:apply-templates select="tocentry"/>
162   <xsl:if test="tocchap|toclevel1|toclevel2|toclevel3|toclevel4|toclevel5">
163     <fo:block start-indent="{count(ancestor::*)*2}pc">
164       <xsl:apply-templates select="tocchap|toclevel1|toclevel2|toclevel3|toclevel4|toclevel5"/>
165     </fo:block>
166   </xsl:if>
167 </xsl:template>
168
169 <xsl:template match="tocentry|lotentry|tocdiv|tocfront|tocback">
170   <fo:block text-align-last="justify"
171             end-indent="2pc"
172             last-line-end-indent="-2pc">
173     <fo:inline keep-with-next.within-line="always">
174       <xsl:choose>
175         <xsl:when test="@linkend">
176           <fo:basic-link internal-destination="{@linkend}">
177             <xsl:apply-templates/>
178           </fo:basic-link>
179         </xsl:when>
180         <xsl:otherwise>
181           <xsl:apply-templates/>
182         </xsl:otherwise>
183       </xsl:choose>
184     </fo:inline>
185
186     <xsl:choose>
187       <xsl:when test="@linkend">
188         <fo:inline keep-together.within-line="always">
189           <xsl:text> </xsl:text>
190           <fo:leader leader-pattern="dots"
191                      keep-with-next.within-line="always"/>
192           <xsl:text> </xsl:text>
193           <fo:basic-link internal-destination="{@linkend}">
194             <xsl:choose>
195               <xsl:when test="@pagenum">
196                 <xsl:value-of select="@pagenum"/>
197               </xsl:when>
198               <xsl:otherwise>
199                 <fo:page-number-citation ref-id="{@linkend}"/>
200               </xsl:otherwise>
201             </xsl:choose>
202           </fo:basic-link>
203         </fo:inline>
204       </xsl:when>
205       <xsl:when test="@pagenum">
206         <fo:inline keep-together.within-line="always">
207           <xsl:text> </xsl:text>
208           <fo:leader leader-pattern="dots"
209                      keep-with-next.within-line="always"/>
210           <xsl:text> </xsl:text>
211           <xsl:value-of select="@pagenum"/>
212         </fo:inline>
213       </xsl:when>
214       <xsl:otherwise>
215         <!-- just the leaders, what else can I do? -->
216         <fo:inline keep-together.within-line="always">
217           <xsl:text> </xsl:text>
218           <fo:leader leader-pattern="space"
219                      keep-with-next.within-line="always"/>
220         </fo:inline>
221       </xsl:otherwise>
222     </xsl:choose>
223   </fo:block>
224 </xsl:template>
225
226 <xsl:template match="toc/title">
227   <fo:block font-weight="bold">
228     <xsl:apply-templates/>
229   </fo:block>
230 </xsl:template>
231
232 <xsl:template match="toc/subtitle">
233   <fo:block font-weight="bold">
234     <xsl:apply-templates/>
235   </fo:block>
236 </xsl:template>
237
238 <xsl:template match="toc/titleabbrev">
239 </xsl:template>
240
241 <!-- ==================================================================== -->
242
243 <!-- A lot element must have content, because there is no attribute
244      to select what kind of list should be generated -->
245 <xsl:template match="book/lot | part/lot">
246   <!-- Don't generate a page sequence unless there is content -->
247   <xsl:variable name="content">
248     <xsl:choose>
249       <xsl:when test="* and $process.source.toc != 0">
250         <xsl:apply-templates />
251       </xsl:when>
252       <xsl:when test="not(child::*) and $process.empty.source.toc != 0">
253         <xsl:call-template name="process.empty.lot"/>
254       </xsl:when>
255     </xsl:choose>
256   </xsl:variable>
257
258   <xsl:if test="string-length(normalize-space($content)) != 0">
259     <xsl:variable name="lot-master-reference">
260       <xsl:call-template name="select.pagemaster">
261         <xsl:with-param name="pageclass" select="'lot'"/>
262       </xsl:call-template>
263     </xsl:variable>
264   
265     <xsl:call-template name="page.sequence">
266       <xsl:with-param name="master-reference"
267                       select="$lot-master-reference"/>
268       <xsl:with-param name="element" select="'toc'"/>
269       <xsl:with-param name="content" select="$content"/>
270     </xsl:call-template>
271   </xsl:if>
272 </xsl:template>
273   
274 <xsl:template match="chapter/lot | appendix/lot | preface/lot | article/lot">
275   <xsl:choose>
276     <xsl:when test="* and $process.source.toc != 0">
277       <fo:block>
278         <xsl:apply-templates/> 
279       </fo:block>
280       <xsl:call-template name="component.toc.separator"/>
281     </xsl:when>
282     <xsl:when test="not(child::*) and $process.empty.source.toc != 0">
283       <xsl:call-template name="process.empty.lot"/>
284     </xsl:when>
285   </xsl:choose>
286 </xsl:template>
287
288 <xsl:template match="section/lot
289                     |sect1/lot
290                     |sect2/lot
291                     |sect3/lot
292                     |sect4/lot
293                     |sect5/lot">
294   <xsl:choose>
295     <xsl:when test="* and $process.source.toc != 0">
296       <fo:block>
297         <xsl:apply-templates/> 
298       </fo:block>
299       <xsl:call-template name="section.toc.separator"/>
300     </xsl:when>
301     <xsl:when test="not(child::*) and $process.empty.source.toc != 0">
302       <xsl:call-template name="process.empty.lot"/>
303     </xsl:when>
304   </xsl:choose>
305 </xsl:template>
306
307 <xsl:template name="process.empty.lot">
308   <!-- An empty lot element does not provide any information to indicate
309        what should be included in it.  You can customize this
310        template to generate a lot based on @role or something -->
311   <xsl:message>
312     <xsl:text>Warning: don't know what to generate for </xsl:text>
313     <xsl:text>lot that has no children.</xsl:text>
314   </xsl:message>
315 </xsl:template>
316
317 <xsl:template match="lot/title">
318   <fo:block font-weight="bold">
319     <xsl:apply-templates/>
320   </fo:block>
321 </xsl:template>
322
323 <xsl:template match="lot/subtitle">
324   <fo:block font-weight="bold">
325     <xsl:apply-templates/>
326   </fo:block>
327 </xsl:template>
328
329 <xsl:template match="lot/titleabbrev">
330 </xsl:template>
331
332 </xsl:stylesheet>