Rocco Rutte:
[apps/madmutt.git] / doc / xslt / common / common.xsl
1 <?xml version='1.0'?>
2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3                 xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
4                 xmlns:dyn="http://exslt.org/dynamic"
5                 xmlns:saxon="http://icl.com/saxon"
6                 exclude-result-prefixes="doc dyn saxon"
7                 version='1.0'>
8
9 <!-- ********************************************************************
10      $Id$
11      ********************************************************************
12
13      This file is part of the XSL DocBook Stylesheet distribution.
14      See ../README or http://nwalsh.com/docbook/xsl/ for copyright
15      and other information.
16
17      This file contains general templates common to both the HTML and FO
18      versions of the DocBook stylesheets.
19      ******************************************************************** -->
20
21 <doc:reference xmlns="">
22 <referenceinfo>
23 <releaseinfo role="meta">
24 $Id$
25 </releaseinfo>
26 <author><surname>Walsh</surname>
27 <firstname>Norman</firstname></author>
28 <copyright><year>1999</year><year>2000</year>
29 <holder>Norman Walsh</holder>
30 </copyright>
31 </referenceinfo>
32 <title>Common Template Reference</title>
33
34 <partintro>
35 <section><title>Introduction</title>
36
37 <para>This is technical reference documentation for the DocBook XSL
38 Stylesheets; it documents (some of) the parameters, templates, and
39 other elements of the stylesheets.</para>
40
41 <para>This is not intended to be <quote>user</quote> documentation.
42 It is provided for developers writing customization layers for the
43 stylesheets, and for anyone who's interested in <quote>how it
44 works</quote>.</para>
45
46 <para>Although I am trying to be thorough, this documentation is known
47 to be incomplete. Don't forget to read the source, too :-)</para>
48 </section>
49 </partintro>
50
51 </doc:reference>
52
53 <!-- ==================================================================== -->
54 <!-- Establish strip/preserve whitespace rules -->
55
56 <xsl:preserve-space elements="*"/>
57
58 <xsl:strip-space elements="
59 abstract affiliation anchor answer appendix area areaset areaspec
60 artheader article audiodata audioobject author authorblurb authorgroup
61 beginpage bibliodiv biblioentry bibliography biblioset blockquote book
62 bookbiblio bookinfo callout calloutlist caption caution chapter
63 citerefentry cmdsynopsis co collab colophon colspec confgroup
64 copyright dedication docinfo editor entrytbl epigraph equation
65 example figure footnote footnoteref formalpara funcprototype
66 funcsynopsis glossary glossdef glossdiv glossentry glosslist graphicco
67 group highlights imagedata imageobject imageobjectco important index
68 indexdiv indexentry indexterm informalequation informalexample
69 informalfigure informaltable inlineequation inlinemediaobject
70 itemizedlist itermset keycombo keywordset legalnotice listitem lot
71 mediaobject mediaobjectco menuchoice msg msgentry msgexplan msginfo
72 msgmain msgrel msgset msgsub msgtext note objectinfo
73 orderedlist othercredit part partintro preface printhistory procedure
74 programlistingco publisher qandadiv qandaentry qandaset question
75 refentry reference refmeta refnamediv refsection refsect1 refsect1info refsect2
76 refsect2info refsect3 refsect3info refsynopsisdiv refsynopsisdivinfo
77 revhistory revision row sbr screenco screenshot sect1 sect1info sect2
78 sect2info sect3 sect3info sect4 sect4info sect5 sect5info section
79 sectioninfo seglistitem segmentedlist seriesinfo set setindex setinfo
80 shortcut sidebar simplelist simplesect spanspec step subject
81 subjectset substeps synopfragment table tbody textobject tfoot tgroup
82 thead tip toc tocchap toclevel1 toclevel2 toclevel3 toclevel4
83 toclevel5 tocpart varargs variablelist varlistentry videodata
84 videoobject void warning subjectset
85
86 classsynopsis
87 constructorsynopsis
88 destructorsynopsis
89 fieldsynopsis
90 methodparam
91 methodsynopsis
92 ooclass
93 ooexception
94 oointerface
95 simplemsgentry
96 manvolnum
97 "/>
98
99 <!-- ====================================================================== -->
100
101 <doc:template name="is.component" xmlns="">
102 <refpurpose>Tests if a given node is a component-level element</refpurpose>
103
104 <refdescription>
105 <para>This template returns '1' if the specified node is a component
106 (Chapter, Appendix, etc.), and '0' otherwise.</para>
107 </refdescription>
108
109 <refparameter>
110 <variablelist>
111 <varlistentry><term>node</term>
112 <listitem>
113 <para>The node which is to be tested.</para>
114 </listitem>
115 </varlistentry>
116 </variablelist>
117 </refparameter>
118
119 <refreturn>
120 <para>This template returns '1' if the specified node is a component
121 (Chapter, Appendix, etc.), and '0' otherwise.</para>
122 </refreturn>
123 </doc:template>
124
125 <xsl:template name="is.component">
126   <xsl:param name="node" select="."/>
127   <xsl:choose>
128     <xsl:when test="local-name($node) = 'appendix'
129                     or local-name($node) = 'article'
130                     or local-name($node) = 'chapter'
131                     or local-name($node) = 'preface'
132                     or local-name($node) = 'bibliography'
133                     or local-name($node) = 'glossary'
134                     or local-name($node) = 'index'">1</xsl:when>
135     <xsl:otherwise>0</xsl:otherwise>
136   </xsl:choose>
137 </xsl:template>
138
139 <!-- ====================================================================== -->
140
141 <doc:template name="is.section" xmlns="">
142 <refpurpose>Tests if a given node is a section-level element</refpurpose>
143
144 <refdescription>
145 <para>This template returns '1' if the specified node is a section
146 (Section, Sect1, Sect2, etc.), and '0' otherwise.</para>
147 </refdescription>
148
149 <refparameter>
150 <variablelist>
151 <varlistentry><term>node</term>
152 <listitem>
153 <para>The node which is to be tested.</para>
154 </listitem>
155 </varlistentry>
156 </variablelist>
157 </refparameter>
158
159 <refreturn>
160 <para>This template returns '1' if the specified node is a section
161 (Section, Sect1, Sect2, etc.), and '0' otherwise.</para>
162 </refreturn>
163 </doc:template>
164
165 <xsl:template name="is.section">
166   <xsl:param name="node" select="."/>
167   <xsl:choose>
168     <xsl:when test="local-name($node) = 'section'
169                     or local-name($node) = 'sect1'
170                     or local-name($node) = 'sect2'
171                     or local-name($node) = 'sect3'
172                     or local-name($node) = 'sect4'
173                     or local-name($node) = 'sect5'
174                     or local-name($node) = 'refsect1'
175                     or local-name($node) = 'refsect2'
176                     or local-name($node) = 'refsect3'
177                     or local-name($node) = 'simplesect'">1</xsl:when>
178     <xsl:otherwise>0</xsl:otherwise>
179   </xsl:choose>
180 </xsl:template>
181
182 <!-- ====================================================================== -->
183
184 <doc:template name="section.level" xmlns="">
185 <refpurpose>Returns the hierarchical level of a section</refpurpose>
186
187 <refdescription>
188 <para>This template calculates the hierarchical level of a section.
189 The element <sgmltag>sect1</sgmltag> is at level 1, <sgmltag>sect2</sgmltag> is
190 at level 2, etc.</para>
191
192 <para>Recursive sections are calculated down to the fifth level.</para>
193 </refdescription>
194
195 <refparameter>
196 <variablelist>
197 <varlistentry><term>node</term>
198 <listitem>
199 <para>The section node for which the level should be calculated.
200 Defaults to the context node.</para>
201 </listitem>
202 </varlistentry>
203 </variablelist>
204 </refparameter>
205
206 <refreturn>
207 <para>The section level, <quote>1</quote>, <quote>2</quote>, etc.
208 </para>
209 </refreturn>
210 </doc:template>
211
212 <xsl:template name="section.level">
213   <xsl:param name="node" select="."/>
214   <xsl:choose>
215     <xsl:when test="name($node)='sect1'">1</xsl:when>
216     <xsl:when test="name($node)='sect2'">2</xsl:when>
217     <xsl:when test="name($node)='sect3'">3</xsl:when>
218     <xsl:when test="name($node)='sect4'">4</xsl:when>
219     <xsl:when test="name($node)='sect5'">5</xsl:when>
220     <xsl:when test="name($node)='section'">
221       <xsl:choose>
222         <xsl:when test="$node/../../../../../../section">6</xsl:when>
223         <xsl:when test="$node/../../../../../section">5</xsl:when>
224         <xsl:when test="$node/../../../../section">4</xsl:when>
225         <xsl:when test="$node/../../../section">3</xsl:when>
226         <xsl:when test="$node/../../section">2</xsl:when>
227         <xsl:otherwise>1</xsl:otherwise>
228       </xsl:choose>
229     </xsl:when>
230     <xsl:when test="name($node)='refsect1' or
231                     name($node)='refsect2' or
232                     name($node)='refsect3' or
233                     name($node)='refsection' or
234                     name($node)='refsynopsisdiv'">
235       <xsl:call-template name="refentry.section.level">
236         <xsl:with-param name="node" select="$node"/>
237       </xsl:call-template>
238     </xsl:when>
239     <xsl:when test="name($node)='simplesect'">
240       <xsl:choose>
241         <xsl:when test="$node/../../sect1">2</xsl:when>
242         <xsl:when test="$node/../../sect2">3</xsl:when>
243         <xsl:when test="$node/../../sect3">4</xsl:when>
244         <xsl:when test="$node/../../sect4">5</xsl:when>
245         <xsl:when test="$node/../../sect5">5</xsl:when>
246         <xsl:when test="$node/../../section">
247           <xsl:choose>
248             <xsl:when test="$node/../../../../../section">5</xsl:when>
249             <xsl:when test="$node/../../../../section">4</xsl:when>
250             <xsl:when test="$node/../../../section">3</xsl:when>
251             <xsl:otherwise>2</xsl:otherwise>
252           </xsl:choose>
253         </xsl:when>
254         <xsl:otherwise>1</xsl:otherwise>
255       </xsl:choose>
256     </xsl:when>
257     <xsl:otherwise>1</xsl:otherwise>
258   </xsl:choose>
259 </xsl:template><!-- section.level -->
260
261 <doc:template name="qanda.section.level" xmlns="">
262 <refpurpose>Returns the hierarchical level of a QandASet</refpurpose>
263
264 <refdescription>
265 <para>This template calculates the hierarchical level of a QandASet.
266 </para>
267 </refdescription>
268
269 <refreturn>
270 <para>The level, <quote>1</quote>, <quote>2</quote>, etc.
271 </para>
272 </refreturn>
273 </doc:template>
274
275 <xsl:template name="qanda.section.level">
276   <xsl:variable name="section"
277                 select="(ancestor::section
278                          |ancestor::simplesect
279                          |ancestor::sect5
280                          |ancestor::sect4
281                          |ancestor::sect3
282                          |ancestor::sect2
283                          |ancestor::sect1
284                          |ancestor::refsect3
285                          |ancestor::refsect2
286                          |ancestor::refsect1)[last()]"/>
287
288   <xsl:choose>
289     <xsl:when test="count($section) = '0'">1</xsl:when>
290     <xsl:otherwise>
291       <xsl:variable name="slevel">
292         <xsl:call-template name="section.level">
293           <xsl:with-param name="node" select="$section"/>
294         </xsl:call-template>
295       </xsl:variable>
296       <xsl:value-of select="$slevel + 1"/>
297     </xsl:otherwise>
298   </xsl:choose>
299 </xsl:template>
300
301 <!-- Finds the total section depth of a section in a refentry -->
302 <xsl:template name="refentry.section.level">
303   <xsl:param name="node" select="."/>
304
305   <xsl:variable name="RElevel">
306     <xsl:call-template name="refentry.level">
307       <xsl:with-param name="node" select="$node/ancestor::refentry[1]"/>
308     </xsl:call-template>
309   </xsl:variable>
310
311   <xsl:variable name="levelinRE">
312     <xsl:choose>
313       <xsl:when test="name($node)='refsynopsisdiv'">1</xsl:when>
314       <xsl:when test="name($node)='refsect1'">1</xsl:when>
315       <xsl:when test="name($node)='refsect2'">2</xsl:when>
316       <xsl:when test="name($node)='refsect3'">3</xsl:when>
317       <xsl:when test="name($node)='refsection'">
318         <xsl:choose>
319           <xsl:when test="$node/../../../../../refsection">5</xsl:when>
320           <xsl:when test="$node/../../../../refsection">4</xsl:when>
321           <xsl:when test="$node/../../../refsection">3</xsl:when>
322           <xsl:when test="$node/../../refsection">2</xsl:when>
323           <xsl:otherwise>1</xsl:otherwise>
324         </xsl:choose>
325       </xsl:when>
326     </xsl:choose>
327   </xsl:variable>
328
329   <xsl:value-of select="$levelinRE + $RElevel"/>
330 </xsl:template>
331
332 <!-- Finds the section depth of a refentry -->
333 <xsl:template name="refentry.level">
334   <xsl:param name="node" select="."/>
335   <xsl:variable name="container"
336                 select="($node/ancestor::section |
337                         $node/ancestor::sect1 |
338                         $node/ancestor::sect2 |
339                         $node/ancestor::sect3 |
340                         $node/ancestor::sect4 |
341                         $node/ancestor::sect5)[last()]"/>
342
343   <xsl:choose>
344     <xsl:when test="$container">
345       <xsl:variable name="slevel">
346         <xsl:call-template name="section.level">
347           <xsl:with-param name="node" select="$container"/>
348         </xsl:call-template>
349       </xsl:variable>
350       <xsl:value-of select="$slevel + 1"/>
351     </xsl:when>
352     <xsl:otherwise>1</xsl:otherwise>
353   </xsl:choose>
354 </xsl:template>
355
356 <xsl:template name="qandadiv.section.level">
357   <xsl:variable name="section.level">
358     <xsl:call-template name="qanda.section.level"/>
359   </xsl:variable>
360   <xsl:variable name="anc.divs" select="ancestor::qandadiv"/>
361
362   <xsl:value-of select="count($anc.divs) + number($section.level)"/>
363 </xsl:template>
364
365 <xsl:template name="question.answer.label">
366   <xsl:variable name="deflabel">
367     <xsl:choose>
368       <xsl:when test="ancestor-or-self::*[@defaultlabel]">
369         <xsl:value-of select="(ancestor-or-self::*[@defaultlabel])[last()]
370                               /@defaultlabel"/>
371       </xsl:when>
372       <xsl:otherwise>
373         <xsl:value-of select="$qanda.defaultlabel"/>
374       </xsl:otherwise>
375     </xsl:choose>
376   </xsl:variable>
377
378   <xsl:variable name="label" select="@label"/>
379
380 <!--
381  (hnr      (hierarchical-number-recursive (normalize "qandadiv") node))
382
383          (parsect  (ancestor-member node (section-element-list)))
384
385          (defnum   (if (and %qanda-inherit-numeration% 
386                             %section-autolabel%)
387                        (if (node-list-empty? parsect)
388                            (section-autolabel-prefix node)
389                            (section-autolabel parsect))
390                        ""))
391
392          (hnumber  (let loop ((numlist hnr) (number defnum) 
393                               (sep (if (equal? defnum "") "" ".")))
394                      (if (null? numlist)
395                          number
396                          (loop (cdr numlist) 
397                                (string-append number
398                                               sep
399                                               (number->string (car numlist)))
400                                "."))))
401          (cnumber  (child-number (parent node)))
402          (number   (string-append hnumber 
403                                   (if (equal? hnumber "")
404                                       ""
405                                       ".")
406                                   (number->string cnumber))))
407 -->
408
409   <xsl:choose>
410     <xsl:when test="$deflabel = 'qanda'">
411       <xsl:call-template name="gentext">
412         <xsl:with-param name="key">
413           <xsl:choose>
414             <xsl:when test="local-name(.) = 'question'">question</xsl:when>
415             <xsl:when test="local-name(.) = 'answer'">answer</xsl:when>
416             <xsl:when test="local-name(.) = 'qandadiv'">qandadiv</xsl:when>
417             <xsl:otherwise>qandaset</xsl:otherwise>
418           </xsl:choose>
419         </xsl:with-param>
420       </xsl:call-template>
421     </xsl:when>
422     <xsl:when test="$deflabel = 'label'">
423       <xsl:value-of select="$label"/>
424     </xsl:when>
425     <xsl:when test="$deflabel = 'number'
426                     and local-name(.) = 'question'">
427       <xsl:apply-templates select="ancestor::qandaset[1]"
428                            mode="number"/>
429       <xsl:choose>
430         <xsl:when test="ancestor::qandadiv">
431           <xsl:apply-templates select="ancestor::qandadiv[1]"
432                                mode="number"/>
433           <xsl:apply-templates select="ancestor::qandaentry"
434                                mode="number"/>
435         </xsl:when>
436         <xsl:otherwise>
437           <xsl:apply-templates select="ancestor::qandaentry"
438                                mode="number"/>
439         </xsl:otherwise>
440       </xsl:choose>
441     </xsl:when>
442     <xsl:otherwise>
443       <!-- nothing -->
444     </xsl:otherwise>
445   </xsl:choose>
446 </xsl:template>
447
448 <xsl:template match="qandaset" mode="number">
449   <!-- FIXME: -->
450 </xsl:template>
451
452 <xsl:template match="qandadiv" mode="number">
453   <xsl:number level="multiple" from="qandaset" format="1."/>
454 </xsl:template>
455
456 <xsl:template match="qandaentry" mode="number">
457   <xsl:choose>
458     <xsl:when test="ancestor::qandadiv">
459       <xsl:number level="single" from="qandadiv" format="1."/>
460     </xsl:when>
461     <xsl:otherwise>
462       <xsl:number level="single" from="qandaset" format="1."/>
463     </xsl:otherwise>
464   </xsl:choose>
465 </xsl:template>
466
467 <!-- ====================================================================== -->
468
469 <xsl:template name="object.id">
470   <xsl:param name="object" select="."/>
471   <xsl:choose>
472     <xsl:when test="$object/@id">
473       <xsl:value-of select="$object/@id"/>
474     </xsl:when>
475     <xsl:when test="$object/@xml:id">
476       <xsl:value-of select="$object/@xml:id"/>
477     </xsl:when>
478     <xsl:otherwise>
479       <xsl:value-of select="generate-id($object)"/>
480     </xsl:otherwise>
481   </xsl:choose>
482 </xsl:template>
483
484 <xsl:template name="person.name">
485   <!-- Formats a personal name. Handles corpauthor as a special case. -->
486   <xsl:param name="node" select="."/>
487
488   <xsl:variable name="style">
489     <xsl:choose>
490       <xsl:when test="$node/@role">
491         <xsl:value-of select="$node/@role"/>
492       </xsl:when>
493       <xsl:otherwise>
494         <xsl:call-template name="gentext.template">
495           <xsl:with-param name="context" select="'styles'"/>
496           <xsl:with-param name="name" select="'person-name'"/>
497         </xsl:call-template>
498       </xsl:otherwise>
499     </xsl:choose>
500   </xsl:variable>
501
502   <xsl:choose>
503     <!-- the personname element is a specialcase -->
504     <xsl:when test="$node/personname">
505       <xsl:call-template name="person.name">
506         <xsl:with-param name="node" select="$node/personname"/>
507       </xsl:call-template>
508     </xsl:when>
509
510     <!-- handle corpauthor as a special case...-->
511     <xsl:when test="name($node)='corpauthor'">
512       <xsl:apply-templates select="$node"/>
513     </xsl:when>
514
515     <xsl:otherwise>
516       <xsl:choose>
517         <xsl:when test="$style = 'family-given'">
518           <xsl:call-template name="person.name.family-given">
519             <xsl:with-param name="node" select="$node"/>
520           </xsl:call-template>
521         </xsl:when>
522         <xsl:when test="$style = 'last-first'">
523           <xsl:call-template name="person.name.last-first">
524             <xsl:with-param name="node" select="$node"/>
525           </xsl:call-template>
526         </xsl:when>
527         <xsl:otherwise>
528           <xsl:call-template name="person.name.first-last">
529             <xsl:with-param name="node" select="$node"/>
530           </xsl:call-template>
531         </xsl:otherwise>
532       </xsl:choose>
533     </xsl:otherwise>
534   </xsl:choose>
535 </xsl:template>
536
537 <xsl:template name="person.name.family-given">
538   <xsl:param name="node" select="."/>
539
540   <!-- The family-given style applies a convention for identifying given -->
541   <!-- and family names in locales where it may be ambiguous -->
542   <xsl:apply-templates select="$node//surname[1]"/>
543
544   <xsl:if test="$node//surname and $node//firstname">
545     <xsl:text> </xsl:text>
546   </xsl:if>
547
548   <xsl:apply-templates select="$node//firstname[1]"/>
549
550   <xsl:text> [FAMILY Given]</xsl:text>
551 </xsl:template>
552
553 <xsl:template name="person.name.last-first">
554   <xsl:param name="node" select="."/>
555
556   <xsl:apply-templates select="$node//surname[1]"/>
557
558   <xsl:if test="$node//surname and $node//firstname">
559     <xsl:text>, </xsl:text>
560   </xsl:if>
561
562   <xsl:apply-templates select="$node//firstname[1]"/>
563 </xsl:template>
564
565 <xsl:template name="person.name.first-last">
566   <xsl:param name="node" select="."/>
567
568   <xsl:if test="$node//honorific">
569     <xsl:apply-templates select="$node//honorific[1]"/>
570     <xsl:value-of select="$punct.honorific"/>
571   </xsl:if>
572
573   <xsl:if test="$node//firstname">
574     <xsl:if test="$node//honorific">
575       <xsl:text> </xsl:text>
576     </xsl:if>
577     <xsl:apply-templates select="$node//firstname[1]"/>
578   </xsl:if>
579
580   <xsl:if test="$node//othername and $author.othername.in.middle != 0">
581     <xsl:if test="$node//honorific or $node//firstname">
582       <xsl:text> </xsl:text>
583     </xsl:if>
584     <xsl:apply-templates select="$node//othername[1]"/>
585   </xsl:if>
586
587   <xsl:if test="$node//surname">
588     <xsl:if test="$node//honorific or $node//firstname
589                   or ($node//othername and $author.othername.in.middle != 0)">
590       <xsl:text> </xsl:text>
591     </xsl:if>
592     <xsl:apply-templates select="$node//surname[1]"/>
593   </xsl:if>
594
595   <xsl:if test="$node//lineage">
596     <xsl:text>, </xsl:text>
597     <xsl:apply-templates select="$node//lineage[1]"/>
598   </xsl:if>
599 </xsl:template>
600
601 <xsl:template name="person.name.list">
602   <!-- Return a formatted string representation of the contents of
603        the current element. The current element must contain one or
604        more AUTHORs, CORPAUTHORs, OTHERCREDITs, and/or EDITORs.
605
606        John Doe
607      or
608        John Doe and Jane Doe
609      or
610        John Doe, Jane Doe, and A. Nonymous
611   -->
612   <xsl:param name="person.list"
613              select="author|corpauthor|othercredit|editor"/>
614   <xsl:param name="person.count" select="count($person.list)"/>
615   <xsl:param name="count" select="1"/>
616
617   <xsl:choose>
618     <xsl:when test="$count &gt; $person.count"></xsl:when>
619     <xsl:otherwise>
620       <xsl:call-template name="person.name">
621         <xsl:with-param name="node" select="$person.list[position()=$count]"/>
622       </xsl:call-template>
623
624       <xsl:choose>
625         <xsl:when test="$person.count = 2 and $count = 1">
626           <xsl:call-template name="gentext.template">
627             <xsl:with-param name="context" select="'authorgroup'"/>
628             <xsl:with-param name="name" select="'sep2'"/>
629           </xsl:call-template>
630         </xsl:when>
631         <xsl:when test="$person.count &gt; 2 and $count+1 = $person.count">
632           <xsl:call-template name="gentext.template">
633             <xsl:with-param name="context" select="'authorgroup'"/>
634             <xsl:with-param name="name" select="'seplast'"/>
635           </xsl:call-template>
636         </xsl:when>
637         <xsl:when test="$count &lt; $person.count">
638           <xsl:call-template name="gentext.template">
639             <xsl:with-param name="context" select="'authorgroup'"/>
640             <xsl:with-param name="name" select="'sep'"/>
641           </xsl:call-template>
642         </xsl:when>
643       </xsl:choose>
644
645       <xsl:call-template name="person.name.list">
646         <xsl:with-param name="person.list" select="$person.list"/>
647         <xsl:with-param name="person.count" select="$person.count"/>
648         <xsl:with-param name="count" select="$count+1"/>
649       </xsl:call-template>
650     </xsl:otherwise>
651   </xsl:choose>
652 </xsl:template><!-- person.name.list -->
653
654 <!-- === synopsis ======================================================= -->
655 <!-- The following definitions match those given in the reference
656      documentation for DocBook V3.0
657 -->
658
659 <xsl:variable name="arg.choice.opt.open.str">[</xsl:variable>
660 <xsl:variable name="arg.choice.opt.close.str">]</xsl:variable>
661 <xsl:variable name="arg.choice.req.open.str">{</xsl:variable>
662 <xsl:variable name="arg.choice.req.close.str">}</xsl:variable>
663 <xsl:variable name="arg.choice.plain.open.str"><xsl:text> </xsl:text></xsl:variable>
664 <xsl:variable name="arg.choice.plain.close.str"><xsl:text> </xsl:text></xsl:variable>
665 <xsl:variable name="arg.choice.def.open.str">[</xsl:variable>
666 <xsl:variable name="arg.choice.def.close.str">]</xsl:variable>
667 <xsl:variable name="arg.rep.repeat.str">...</xsl:variable>
668 <xsl:variable name="arg.rep.norepeat.str"></xsl:variable>
669 <xsl:variable name="arg.rep.def.str"></xsl:variable>
670 <xsl:variable name="arg.or.sep"> | </xsl:variable>
671 <xsl:variable name="cmdsynopsis.hanging.indent">4pi</xsl:variable>
672
673 <!-- ====================================================================== -->
674
675 <!--
676 <xsl:template name="xref.g.subst">
677   <xsl:param name="string"></xsl:param>
678   <xsl:param name="target" select="."/>
679   <xsl:variable name="subst">%g</xsl:variable>
680
681   <xsl:choose>
682     <xsl:when test="contains($string, $subst)">
683       <xsl:value-of select="substring-before($string, $subst)"/>
684       <xsl:call-template name="gentext.element.name">
685         <xsl:with-param name="element.name" select="name($target)"/>
686       </xsl:call-template>
687       <xsl:call-template name="xref.g.subst">
688         <xsl:with-param name="string"
689                         select="substring-after($string, $subst)"/>
690         <xsl:with-param name="target" select="$target"/>
691       </xsl:call-template>
692     </xsl:when>
693     <xsl:otherwise>
694       <xsl:value-of select="$string"/>
695     </xsl:otherwise>
696   </xsl:choose>
697 </xsl:template>
698
699 <xsl:template name="xref.t.subst">
700   <xsl:param name="string"></xsl:param>
701   <xsl:param name="target" select="."/>
702   <xsl:variable name="subst">%t</xsl:variable>
703
704   <xsl:choose>
705     <xsl:when test="contains($string, $subst)">
706       <xsl:call-template name="xref.g.subst">
707         <xsl:with-param name="string"
708                         select="substring-before($string, $subst)"/>
709         <xsl:with-param name="target" select="$target"/>
710       </xsl:call-template>
711       <xsl:call-template name="title.xref">
712         <xsl:with-param name="target" select="$target"/>
713       </xsl:call-template>
714       <xsl:call-template name="xref.t.subst">
715         <xsl:with-param name="string"
716                         select="substring-after($string, $subst)"/>
717         <xsl:with-param name="target" select="$target"/>
718       </xsl:call-template>
719     </xsl:when>
720     <xsl:otherwise>
721       <xsl:call-template name="xref.g.subst">
722         <xsl:with-param name="string" select="$string"/>
723         <xsl:with-param name="target" select="$target"/>
724       </xsl:call-template>
725     </xsl:otherwise>
726   </xsl:choose>
727 </xsl:template>
728
729 <xsl:template name="xref.n.subst">
730   <xsl:param name="string"></xsl:param>
731   <xsl:param name="target" select="."/>
732   <xsl:variable name="subst">%n</xsl:variable>
733
734   <xsl:choose>
735     <xsl:when test="contains($string, $subst)">
736       <xsl:call-template name="xref.t.subst">
737         <xsl:with-param name="string"
738                         select="substring-before($string, $subst)"/>
739         <xsl:with-param name="target" select="$target"/>
740       </xsl:call-template>
741       <xsl:call-template name="number.xref">
742         <xsl:with-param name="target" select="$target"/>
743       </xsl:call-template>
744       <xsl:call-template name="xref.t.subst">
745         <xsl:with-param name="string"
746                         select="substring-after($string, $subst)"/>
747         <xsl:with-param name="target" select="$target"/>
748       </xsl:call-template>
749     </xsl:when>
750     <xsl:otherwise>
751       <xsl:call-template name="xref.t.subst">
752         <xsl:with-param name="string" select="$string"/>
753         <xsl:with-param name="target" select="$target"/>
754       </xsl:call-template>
755     </xsl:otherwise>
756   </xsl:choose>
757 </xsl:template>
758
759 <xsl:template name="subst.xref.text">
760   <xsl:param name="xref.text"></xsl:param>
761   <xsl:param name="target" select="."/>
762
763   <xsl:call-template name="xref.n.subst">
764     <xsl:with-param name="string" select="$xref.text"/>
765     <xsl:with-param name="target" select="$target"/>
766   </xsl:call-template>
767 </xsl:template>
768 -->
769
770 <!-- ====================================================================== -->
771
772 <xsl:template name="filename-basename">
773   <!-- We assume all filenames are really URIs and use "/" -->
774   <xsl:param name="filename"></xsl:param>
775   <xsl:param name="recurse" select="false()"/>
776
777   <xsl:choose>
778     <xsl:when test="substring-after($filename, '/') != ''">
779       <xsl:call-template name="filename-basename">
780         <xsl:with-param name="filename"
781                         select="substring-after($filename, '/')"/>
782         <xsl:with-param name="recurse" select="true()"/>
783       </xsl:call-template>
784     </xsl:when>
785     <xsl:otherwise>
786       <xsl:value-of select="$filename"/>
787     </xsl:otherwise>
788   </xsl:choose>
789 </xsl:template>
790
791 <xsl:template name="filename-extension">
792   <xsl:param name="filename"></xsl:param>
793   <xsl:param name="recurse" select="false()"/>
794
795   <!-- Make sure we only look at the base name... -->
796   <xsl:variable name="basefn">
797     <xsl:choose>
798       <xsl:when test="$recurse">
799         <xsl:value-of select="$filename"/>
800       </xsl:when>
801       <xsl:otherwise>
802         <xsl:call-template name="filename-basename">
803           <xsl:with-param name="filename" select="$filename"/>
804         </xsl:call-template>
805       </xsl:otherwise>
806     </xsl:choose>
807   </xsl:variable>
808
809   <xsl:choose>
810     <xsl:when test="substring-after($basefn, '.') != ''">
811       <xsl:call-template name="filename-extension">
812         <xsl:with-param name="filename"
813                         select="substring-after($basefn, '.')"/>
814         <xsl:with-param name="recurse" select="true()"/>
815       </xsl:call-template>
816     </xsl:when>
817     <xsl:when test="$recurse">
818       <xsl:value-of select="$basefn"/>
819     </xsl:when>
820     <xsl:otherwise></xsl:otherwise>
821   </xsl:choose>
822 </xsl:template>
823
824 <!-- ====================================================================== -->
825
826 <doc:template name="select.mediaobject" xmlns="">
827 <refpurpose>Selects and processes an appropriate media object from a list</refpurpose>
828
829 <refdescription>
830 <para>This template takes a list of media objects (usually the
831 children of a mediaobject or inlinemediaobject) and processes
832 the "right" object.</para>
833
834 <para>This template relies on a template named 
835 "select.mediaobject.index" to determine which object
836 in the list is appropriate.</para>
837
838 <para>If no acceptable object is located, nothing happens.</para>
839 </refdescription>
840
841 <refparameter>
842 <variablelist>
843 <varlistentry><term>olist</term>
844 <listitem>
845 <para>The node list of potential objects to examine.</para>
846 </listitem>
847 </varlistentry>
848 </variablelist>
849 </refparameter>
850
851 <refreturn>
852 <para>Calls &lt;xsl:apply-templates&gt; on the selected object.</para>
853 </refreturn>
854 </doc:template>
855
856 <xsl:template name="select.mediaobject">
857   <xsl:param name="olist"
858              select="imageobject|imageobjectco
859                      |videoobject|audioobject|textobject"/>
860   
861   <xsl:variable name="mediaobject.index">
862     <xsl:call-template name="select.mediaobject.index">
863       <xsl:with-param name="olist" select="$olist"/>
864       <xsl:with-param name="count" select="1"/>
865     </xsl:call-template>
866   </xsl:variable>
867
868   <xsl:if test="$mediaobject.index != ''">
869     <xsl:apply-templates select="$olist[position() = $mediaobject.index]"/>
870   </xsl:if>
871 </xsl:template>
872
873 <!-- ====================================================================== -->
874
875 <doc:template name="select.mediaobject.index" xmlns="">
876 <refpurpose>Selects the position of the appropriate media object from a list</refpurpose>
877
878 <refdescription>
879 <para>This template takes a list of media objects (usually the
880 children of a mediaobject or inlinemediaobject) and determines
881 the "right" object. It returns the position of that object
882 to be used by the calling template.</para>
883
884 <para>If the parameter <parameter>use.role.for.mediaobject</parameter>
885 is nonzero, then it first checks for an object with
886 a role attribute of the appropriate value.  It takes the first
887 of those.  Otherwise, it takes the first acceptable object
888 through a recursive pass through the list.</para>
889
890 <para>This template relies on a template named "is.acceptable.mediaobject"
891 to determine if a given object is an acceptable graphic. The semantics
892 of media objects is that the first acceptable graphic should be used.
893 </para>
894
895 <para>If no acceptable object is located, no index is returned.</para>
896 </refdescription>
897
898 <refparameter>
899 <variablelist>
900 <varlistentry><term>olist</term>
901 <listitem>
902 <para>The node list of potential objects to examine.</para>
903 </listitem>
904 </varlistentry>
905 <varlistentry><term>count</term>
906 <listitem>
907 <para>The position in the list currently being considered by the 
908 recursive process.</para>
909 </listitem>
910 </varlistentry>
911 </variablelist>
912 </refparameter>
913
914 <refreturn>
915 <para>Returns the position in the original list of the selected object.</para>
916 </refreturn>
917 </doc:template>
918
919 <xsl:template name="select.mediaobject.index">
920   <xsl:param name="olist"
921              select="imageobject|imageobjectco
922                      |videoobject|audioobject|textobject"/>
923   <xsl:param name="count">1</xsl:param>
924
925   <xsl:choose>
926     <!-- Test for objects preferred by role -->
927     <xsl:when test="$use.role.for.mediaobject != 0 
928                and $preferred.mediaobject.role != ''
929                and $olist[@role = $preferred.mediaobject.role]"> 
930       
931       <!-- Get the first hit's position index -->
932       <xsl:for-each select="$olist">
933         <xsl:if test="@role = $preferred.mediaobject.role and
934              not(preceding-sibling::*[@role = $preferred.mediaobject.role])"> 
935           <xsl:value-of select="position()"/> 
936         </xsl:if>
937       </xsl:for-each>
938     </xsl:when>
939
940     <xsl:when test="$use.role.for.mediaobject != 0 
941                and $olist[@role = $stylesheet.result.type]">
942       <!-- Get the first hit's position index -->
943       <xsl:for-each select="$olist">
944         <xsl:if test="@role = $stylesheet.result.type and 
945               not(preceding-sibling::*[@role = $stylesheet.result.type])"> 
946           <xsl:value-of select="position()"/> 
947         </xsl:if>
948       </xsl:for-each>
949     </xsl:when>
950     <!-- Accept 'html' for $stylesheet.result.type = 'xhtml' -->
951     <xsl:when test="$use.role.for.mediaobject != 0 
952                and $stylesheet.result.type = 'xhtml'
953                and $olist[@role = 'html']">
954       <!-- Get the first hit's position index -->
955       <xsl:for-each select="$olist">
956         <xsl:if test="@role = 'html' and 
957               not(preceding-sibling::*[@role = 'html'])"> 
958           <xsl:value-of select="position()"/> 
959         </xsl:if>
960       </xsl:for-each>
961     </xsl:when>
962     <xsl:otherwise>
963       <!-- Otherwise select first acceptable object -->
964       <xsl:if test="$count &lt;= count($olist)">
965         <xsl:variable name="object" select="$olist[position()=$count]"/>
966     
967         <xsl:variable name="useobject">
968           <xsl:choose>
969             <!-- The phrase is used only when contains TeX Math and output is FO -->
970             <xsl:when test="name($object)='textobject' and $object/phrase
971                             and $object/@role='tex' and $stylesheet.result.type = 'fo'
972                             and $tex.math.in.alt != ''">
973               <xsl:text>1</xsl:text> 
974             </xsl:when>
975             <!-- The phrase is never used -->
976             <xsl:when test="name($object)='textobject' and $object/phrase">
977               <xsl:text>0</xsl:text>
978             </xsl:when>
979             <xsl:when test="name($object)='textobject'
980                             and $object/ancestor::equation ">
981             <!-- The first textobject is not a reasonable fallback
982                  for equation image -->
983               <xsl:text>0</xsl:text>
984             </xsl:when>
985             <!-- The first textobject is a reasonable fallback -->
986             <xsl:when test="name($object)='textobject'
987                             and $object[not(@role) or @role!='tex']">
988               <xsl:text>1</xsl:text>
989             </xsl:when>
990             <!-- don't use graphic when output is FO, TeX Math is used 
991                  and there is math in alt element -->
992             <xsl:when test="$object/ancestor::equation and 
993                             $object/ancestor::equation/alt[@role='tex']
994                             and $stylesheet.result.type = 'fo'
995                             and $tex.math.in.alt != ''">
996               <xsl:text>0</xsl:text>
997             </xsl:when>
998             <!-- If there's only one object, use it -->
999             <xsl:when test="$count = 1 and count($olist) = 1">
1000                <xsl:text>1</xsl:text>
1001             </xsl:when>
1002             <!-- Otherwise, see if this one is a useable graphic -->
1003             <xsl:otherwise>
1004               <xsl:choose>
1005                 <!-- peek inside imageobjectco to simplify the test -->
1006                 <xsl:when test="local-name($object) = 'imageobjectco'">
1007                   <xsl:call-template name="is.acceptable.mediaobject">
1008                     <xsl:with-param name="object" select="$object/imageobject"/>
1009                   </xsl:call-template>
1010                 </xsl:when>
1011                 <xsl:otherwise>
1012                   <xsl:call-template name="is.acceptable.mediaobject">
1013                     <xsl:with-param name="object" select="$object"/>
1014                   </xsl:call-template>
1015                 </xsl:otherwise>
1016               </xsl:choose>
1017             </xsl:otherwise>
1018           </xsl:choose>
1019         </xsl:variable>
1020     
1021         <xsl:choose>
1022           <xsl:when test="$useobject='1'">
1023             <xsl:value-of select="$count"/>
1024           </xsl:when>
1025           <xsl:otherwise>
1026             <xsl:call-template name="select.mediaobject.index">
1027               <xsl:with-param name="olist" select="$olist"/>
1028               <xsl:with-param name="count" select="$count + 1"/>
1029             </xsl:call-template>
1030           </xsl:otherwise>
1031         </xsl:choose>
1032       </xsl:if>
1033     </xsl:otherwise>
1034   </xsl:choose>
1035 </xsl:template>
1036
1037 <doc:template name="is.acceptable.mediaobject" xmlns="">
1038 <refpurpose>Returns '1' if the specified media object is recognized</refpurpose>
1039
1040 <refdescription>
1041 <para>This template examines a media object and returns '1' if the
1042 object is recognized as a graphic.</para>
1043 </refdescription>
1044
1045 <refparameter>
1046 <variablelist>
1047 <varlistentry><term>object</term>
1048 <listitem>
1049 <para>The media object to consider.</para>
1050 </listitem>
1051 </varlistentry>
1052 </variablelist>
1053 </refparameter>
1054
1055 <refreturn>
1056 <para>0 or 1</para>
1057 </refreturn>
1058 </doc:template>
1059
1060 <xsl:template name="is.acceptable.mediaobject">
1061   <xsl:param name="object"></xsl:param>
1062
1063   <xsl:variable name="filename">
1064     <xsl:call-template name="mediaobject.filename">
1065       <xsl:with-param name="object" select="$object"/>
1066     </xsl:call-template>
1067   </xsl:variable>
1068
1069   <xsl:variable name="ext">
1070     <xsl:call-template name="filename-extension">
1071       <xsl:with-param name="filename" select="$filename"/>
1072     </xsl:call-template>
1073   </xsl:variable>
1074
1075   <!-- there will only be one -->
1076   <xsl:variable name="data" select="$object/videodata
1077                                     |$object/imagedata
1078                                     |$object/audiodata"/>
1079
1080   <xsl:variable name="format" select="$data/@format"/>
1081
1082   <xsl:variable name="graphic.format">
1083     <xsl:if test="$format">
1084       <xsl:call-template name="is.graphic.format">
1085         <xsl:with-param name="format" select="$format"/>
1086       </xsl:call-template>
1087     </xsl:if>
1088   </xsl:variable>
1089
1090   <xsl:variable name="graphic.ext">
1091     <xsl:if test="$ext">
1092       <xsl:call-template name="is.graphic.extension">
1093         <xsl:with-param name="ext" select="$ext"/>
1094       </xsl:call-template>
1095     </xsl:if>
1096   </xsl:variable>
1097
1098   <xsl:choose>
1099     <xsl:when test="$use.svg = 0 and $format = 'SVG'">0</xsl:when>
1100     <xsl:when xmlns:svg="http://www.w3.org/2000/svg"
1101               test="$use.svg != 0 and $object/svg:*">1</xsl:when>
1102     <xsl:when test="$graphic.format = '1'">1</xsl:when>
1103     <xsl:when test="$graphic.ext = '1'">1</xsl:when>
1104     <xsl:otherwise>0</xsl:otherwise>
1105   </xsl:choose>
1106 </xsl:template>
1107
1108 <xsl:template name="mediaobject.filename">
1109   <xsl:param name="object"></xsl:param>
1110
1111   <xsl:variable name="data" select="$object/videodata
1112                                     |$object/imagedata
1113                                     |$object/audiodata
1114                                     |$object"/>
1115
1116   <xsl:variable name="filename">
1117     <xsl:choose>
1118       <xsl:when test="$data[@fileref]">
1119         <xsl:apply-templates select="$data/@fileref"/>
1120       </xsl:when>
1121       <xsl:when test="$data[@entityref]">
1122         <xsl:value-of select="unparsed-entity-uri($data/@entityref)"/>
1123       </xsl:when>
1124       <xsl:otherwise></xsl:otherwise>
1125     </xsl:choose>
1126   </xsl:variable>
1127
1128   <xsl:variable name="real.ext">
1129     <xsl:call-template name="filename-extension">
1130       <xsl:with-param name="filename" select="$filename"/>
1131     </xsl:call-template>
1132   </xsl:variable>
1133
1134   <xsl:variable name="ext">
1135     <xsl:choose>
1136       <xsl:when test="$real.ext != ''">
1137         <xsl:value-of select="$real.ext"/>
1138       </xsl:when>
1139       <xsl:otherwise>
1140         <xsl:value-of select="$graphic.default.extension"/>
1141       </xsl:otherwise>
1142     </xsl:choose>
1143   </xsl:variable>
1144
1145   <xsl:variable name="graphic.ext">
1146     <xsl:call-template name="is.graphic.extension">
1147       <xsl:with-param name="ext" select="$ext"/>
1148     </xsl:call-template>
1149   </xsl:variable>
1150
1151   <xsl:choose>
1152     <xsl:when test="$real.ext = ''">
1153       <xsl:choose>
1154         <xsl:when test="$ext != ''">
1155           <xsl:value-of select="$filename"/>
1156           <xsl:text>.</xsl:text>
1157           <xsl:value-of select="$ext"/>
1158         </xsl:when>
1159         <xsl:otherwise>
1160           <xsl:value-of select="$filename"/>
1161         </xsl:otherwise>
1162       </xsl:choose>
1163     </xsl:when>
1164     <xsl:when test="not($graphic.ext)">
1165       <xsl:choose>
1166         <xsl:when test="$graphic.default.extension != ''">
1167           <xsl:value-of select="$filename"/>
1168           <xsl:text>.</xsl:text>
1169           <xsl:value-of select="$graphic.default.extension"/>
1170         </xsl:when>
1171         <xsl:otherwise>
1172           <xsl:value-of select="$filename"/>
1173         </xsl:otherwise>
1174       </xsl:choose>
1175     </xsl:when>
1176     <xsl:otherwise>
1177       <xsl:value-of select="$filename"/>
1178     </xsl:otherwise>
1179   </xsl:choose>
1180 </xsl:template>
1181
1182 <!-- ====================================================================== -->
1183
1184 <doc:template name="check.id.unique" xmlns="">
1185 <refpurpose>Warn users about references to non-unique IDs</refpurpose>
1186 <refdescription>
1187 <para>If passed an ID in <varname>linkend</varname>,
1188 <function>check.id.unique</function> prints
1189 a warning message to the user if either the ID does not exist or
1190 the ID is not unique.</para>
1191 </refdescription>
1192 </doc:template>
1193
1194 <xsl:template name="check.id.unique">
1195   <xsl:param name="linkend"></xsl:param>
1196   <xsl:if test="$linkend != ''">
1197     <xsl:variable name="targets" select="key('id',$linkend)"/>
1198     <xsl:variable name="target" select="$targets[1]"/>
1199
1200     <xsl:if test="count($targets)=0">
1201       <xsl:message>
1202         <xsl:text>Error: no ID for constraint linkend: </xsl:text>
1203         <xsl:value-of select="$linkend"/>
1204         <xsl:text>.</xsl:text>
1205       </xsl:message>
1206       <!--
1207       <xsl:message>
1208         <xsl:text>If the ID exists in your document, did your </xsl:text>
1209         <xsl:text>XSLT Processor load the DTD?</xsl:text>
1210       </xsl:message>
1211       -->
1212     </xsl:if>
1213
1214     <xsl:if test="count($targets)>1">
1215       <xsl:message>
1216         <xsl:text>Warning: multiple "IDs" for constraint linkend: </xsl:text>
1217         <xsl:value-of select="$linkend"/>
1218         <xsl:text>.</xsl:text>
1219       </xsl:message>
1220     </xsl:if>
1221   </xsl:if>
1222 </xsl:template>
1223
1224 <doc:template name="check.idref.targets" xmlns="">
1225 <refpurpose>Warn users about incorrectly typed references</refpurpose>
1226 <refdescription>
1227 <para>If passed an ID in <varname>linkend</varname>,
1228 <function>check.idref.targets</function> makes sure that the element
1229 pointed to by the link is one of the elements listed in
1230 <varname>element-list</varname> and warns the user otherwise.</para>
1231 </refdescription>
1232 </doc:template>
1233
1234 <xsl:template name="check.idref.targets">
1235   <xsl:param name="linkend"></xsl:param>
1236   <xsl:param name="element-list"></xsl:param>
1237   <xsl:if test="$linkend != ''">
1238     <xsl:variable name="targets" select="key('id',$linkend)"/>
1239     <xsl:variable name="target" select="$targets[1]"/>
1240
1241     <xsl:if test="count($target) &gt; 0">
1242       <xsl:if test="not(contains(concat(' ', $element-list, ' '), name($target)))">
1243         <xsl:message>
1244           <xsl:text>Error: linkend (</xsl:text>
1245           <xsl:value-of select="$linkend"/>
1246           <xsl:text>) points to "</xsl:text>
1247           <xsl:value-of select="name($target)"/>
1248           <xsl:text>" not (one of): </xsl:text>
1249           <xsl:value-of select="$element-list"/>
1250         </xsl:message>
1251       </xsl:if>
1252     </xsl:if>
1253   </xsl:if>
1254 </xsl:template>
1255
1256 <!-- ====================================================================== -->
1257 <!-- Procedure Step Numeration -->
1258
1259 <xsl:param name="procedure.step.numeration.formats" select="'1aiAI'"/>
1260
1261 <xsl:template name="procedure.step.numeration">
1262   <xsl:param name="context" select="."/>
1263   <xsl:variable name="format.length"
1264                 select="string-length($procedure.step.numeration.formats)"/>
1265   <xsl:choose>
1266     <xsl:when test="local-name($context) = 'substeps'">
1267       <xsl:variable name="ssdepth"
1268                     select="count($context/ancestor::substeps)"/>
1269       <xsl:variable name="sstype" select="($ssdepth mod $format.length)+2"/>
1270       <xsl:choose>
1271         <xsl:when test="$sstype &gt; $format.length">
1272           <xsl:value-of select="substring($procedure.step.numeration.formats,1,1)"/>
1273         </xsl:when>
1274         <xsl:otherwise>
1275           <xsl:value-of select="substring($procedure.step.numeration.formats,$sstype,1)"/>
1276         </xsl:otherwise>
1277       </xsl:choose>
1278     </xsl:when>
1279     <xsl:when test="local-name($context) = 'step'">
1280       <xsl:variable name="sdepth"
1281                     select="count($context/ancestor::substeps)"/>
1282       <xsl:variable name="stype" select="($sdepth mod $format.length)+1"/>
1283       <xsl:value-of select="substring($procedure.step.numeration.formats,$stype,1)"/>
1284     </xsl:when>
1285     <xsl:otherwise>
1286       <xsl:message>
1287         <xsl:text>Unexpected context in procedure.step.numeration: </xsl:text>
1288         <xsl:value-of select="local-name($context)"/>
1289       </xsl:message>
1290     </xsl:otherwise>
1291   </xsl:choose>
1292 </xsl:template>
1293
1294 <xsl:template match="step" mode="number">
1295   <xsl:param name="rest" select="''"/>
1296   <xsl:param name="recursive" select="1"/>
1297   <xsl:variable name="format">
1298     <xsl:call-template name="procedure.step.numeration"/>
1299   </xsl:variable>
1300   <xsl:variable name="num">
1301     <xsl:number count="step" format="{$format}"/>
1302   </xsl:variable>
1303   <xsl:choose>
1304     <xsl:when test="$recursive != 0 and ancestor::step">
1305       <xsl:apply-templates select="ancestor::step[1]" mode="number">
1306         <xsl:with-param name="rest" select="concat('.', $num, $rest)"/>
1307       </xsl:apply-templates>
1308     </xsl:when>
1309     <xsl:otherwise>
1310       <xsl:value-of select="concat($num, $rest)"/>
1311     </xsl:otherwise>
1312   </xsl:choose>
1313 </xsl:template>
1314
1315 <!-- ====================================================================== -->
1316 <!-- OrderedList Numeration -->
1317
1318 <xsl:template name="orderedlist-starting-number">
1319   <xsl:param name="list" select="."/>
1320   <xsl:choose>
1321     <xsl:when test="not($list/@continuation = 'continues')">1</xsl:when>
1322     <xsl:otherwise>
1323       <xsl:variable name="prevlist"
1324                     select="$list/preceding::orderedlist[1]"/>
1325       <xsl:choose>
1326         <xsl:when test="count($prevlist) = 0">2</xsl:when>
1327         <xsl:otherwise>
1328           <xsl:variable name="prevlength" select="count($prevlist/listitem)"/>
1329           <xsl:variable name="prevstart">
1330             <xsl:call-template name="orderedlist-starting-number">
1331               <xsl:with-param name="list" select="$prevlist"/>
1332             </xsl:call-template>
1333           </xsl:variable>
1334           <xsl:value-of select="$prevstart + $prevlength"/>
1335         </xsl:otherwise>
1336       </xsl:choose>
1337     </xsl:otherwise>
1338   </xsl:choose>
1339 </xsl:template>
1340
1341 <xsl:template name="orderedlist-item-number">
1342   <!-- context node must be a listitem in an orderedlist -->
1343   <xsl:param name="node" select="."/>
1344
1345   <xsl:choose>
1346     <xsl:when test="$node/@override">
1347       <xsl:value-of select="$node/@override"/>
1348     </xsl:when>
1349     <xsl:when test="$node/preceding-sibling::listitem">
1350       <xsl:variable name="pnum">
1351         <xsl:call-template name="orderedlist-item-number">
1352           <xsl:with-param name="node" select="$node/preceding-sibling::listitem[1]"/>
1353         </xsl:call-template>
1354       </xsl:variable>
1355       <xsl:value-of select="$pnum + 1"/>
1356     </xsl:when>
1357     <xsl:otherwise>
1358       <xsl:call-template name="orderedlist-starting-number">
1359         <xsl:with-param name="list" select="parent::*"/>
1360       </xsl:call-template>
1361     </xsl:otherwise>
1362   </xsl:choose>
1363 </xsl:template>
1364
1365 <xsl:template name="next.numeration">
1366   <xsl:param name="numeration" select="'default'"/>
1367   <xsl:choose>
1368     <!-- Change this list if you want to change the order of numerations -->
1369     <xsl:when test="$numeration = 'arabic'">loweralpha</xsl:when>
1370     <xsl:when test="$numeration = 'loweralpha'">lowerroman</xsl:when>
1371     <xsl:when test="$numeration = 'lowerroman'">upperalpha</xsl:when>
1372     <xsl:when test="$numeration = 'upperalpha'">upperroman</xsl:when>
1373     <xsl:when test="$numeration = 'upperroman'">arabic</xsl:when>
1374     <xsl:otherwise>arabic</xsl:otherwise>
1375   </xsl:choose>
1376 </xsl:template>
1377
1378 <xsl:template name="list.numeration">
1379   <xsl:param name="node" select="."/>
1380
1381   <xsl:choose>
1382     <xsl:when test="$node/@numeration">
1383       <xsl:value-of select="$node/@numeration"/>
1384     </xsl:when>
1385     <xsl:otherwise>
1386       <xsl:choose>
1387         <xsl:when test="$node/ancestor::orderedlist">
1388           <xsl:call-template name="next.numeration">
1389             <xsl:with-param name="numeration">
1390               <xsl:call-template name="list.numeration">
1391                 <xsl:with-param name="node" select="$node/ancestor::orderedlist[1]"/>
1392               </xsl:call-template>
1393             </xsl:with-param>
1394           </xsl:call-template>
1395         </xsl:when>
1396         <xsl:otherwise>
1397           <xsl:call-template name="next.numeration"/>
1398         </xsl:otherwise>
1399       </xsl:choose>
1400     </xsl:otherwise>
1401   </xsl:choose>
1402 </xsl:template>
1403
1404 <!-- ====================================================================== -->
1405 <!-- ItemizedList "Numeration" -->
1406
1407 <xsl:template name="next.itemsymbol">
1408   <xsl:param name="itemsymbol" select="'default'"/>
1409   <xsl:choose>
1410     <!-- Change this list if you want to change the order of symbols -->
1411     <xsl:when test="$itemsymbol = 'disc'">circle</xsl:when>
1412     <xsl:when test="$itemsymbol = 'circle'">square</xsl:when>
1413     <xsl:otherwise>disc</xsl:otherwise>
1414   </xsl:choose>
1415 </xsl:template>
1416
1417 <xsl:template name="list.itemsymbol">
1418   <xsl:param name="node" select="."/>
1419
1420   <xsl:choose>
1421     <xsl:when test="@override">
1422       <xsl:value-of select="@override"/>
1423     </xsl:when>
1424     <xsl:when test="$node/@mark">
1425       <xsl:value-of select="$node/@mark"/>
1426     </xsl:when>
1427     <xsl:otherwise>
1428       <xsl:choose>
1429         <xsl:when test="$node/ancestor::itemizedlist">
1430           <xsl:call-template name="next.itemsymbol">
1431             <xsl:with-param name="itemsymbol">
1432               <xsl:call-template name="list.itemsymbol">
1433                 <xsl:with-param name="node" select="$node/ancestor::itemizedlist[1]"/>
1434               </xsl:call-template>
1435             </xsl:with-param>
1436           </xsl:call-template>
1437         </xsl:when>
1438         <xsl:otherwise>
1439           <xsl:call-template name="next.itemsymbol"/>
1440         </xsl:otherwise>
1441       </xsl:choose>
1442     </xsl:otherwise>
1443   </xsl:choose>
1444 </xsl:template>
1445
1446 <!-- ====================================================================== -->
1447
1448 <doc:template name="copyright.years" xmlns="">
1449 <refpurpose>Print a set of years with collapsed ranges</refpurpose>
1450
1451 <refdescription>
1452 <para>This template prints a list of year elements with consecutive
1453 years printed as a range. In other words:</para>
1454
1455 <screen><![CDATA[<year>1992</year>
1456 <year>1993</year>
1457 <year>1994</year>]]></screen>
1458
1459 <para>is printed <quote>1992-1994</quote>, whereas:</para>
1460
1461 <screen><![CDATA[<year>1992</year>
1462 <year>1994</year>]]></screen>
1463
1464 <para>is printed <quote>1992, 1994</quote>.</para>
1465
1466 <para>This template assumes that all the year elements contain only
1467 decimal year numbers, that the elements are sorted in increasing
1468 numerical order, that there are no duplicates, and that all the years
1469 are expressed in full <quote>century+year</quote>
1470 (<quote>1999</quote> not <quote>99</quote>) notation.</para>
1471 </refdescription>
1472
1473 <refparameter>
1474 <variablelist>
1475 <varlistentry><term>years</term>
1476 <listitem>
1477 <para>The initial set of year elements.</para>
1478 </listitem>
1479 </varlistentry>
1480 <varlistentry><term>print.ranges</term>
1481 <listitem>
1482 <para>If non-zero, multi-year ranges are collapsed. If zero, all years
1483 are printed discretely.</para>
1484 </listitem>
1485 </varlistentry>
1486 <varlistentry><term>single.year.ranges</term>
1487 <listitem>
1488 <para>If non-zero, two consecutive years will be printed as a range,
1489 otherwise, they will be printed discretely. In other words, a single
1490 year range is <quote>1991-1992</quote> but discretely it's
1491 <quote>1991, 1992</quote>.</para>
1492 </listitem>
1493 </varlistentry>
1494 </variablelist>
1495 </refparameter>
1496
1497 <refreturn>
1498 <para>This template returns the formatted list of years.</para>
1499 </refreturn>
1500 </doc:template>
1501
1502 <xsl:template name="copyright.years">
1503   <xsl:param name="years"/>
1504   <xsl:param name="print.ranges" select="1"/>
1505   <xsl:param name="single.year.ranges" select="0"/>
1506   <xsl:param name="firstyear" select="0"/>
1507   <xsl:param name="nextyear" select="0"/>
1508
1509   <!--
1510   <xsl:message terminate="no">
1511     <xsl:text>CY: </xsl:text>
1512     <xsl:value-of select="count($years)"/>
1513     <xsl:text>, </xsl:text>
1514     <xsl:value-of select="$firstyear"/>
1515     <xsl:text>, </xsl:text>
1516     <xsl:value-of select="$nextyear"/>
1517     <xsl:text>, </xsl:text>
1518     <xsl:value-of select="$print.ranges"/>
1519     <xsl:text>, </xsl:text>
1520     <xsl:value-of select="$single.year.ranges"/>
1521     <xsl:text> (</xsl:text>
1522     <xsl:value-of select="$years[1]"/>
1523     <xsl:text>)</xsl:text>
1524   </xsl:message>
1525   -->
1526
1527   <xsl:choose>
1528     <xsl:when test="$print.ranges = 0 and count($years) &gt; 0">
1529       <xsl:choose>
1530         <xsl:when test="count($years) = 1">
1531           <xsl:apply-templates select="$years[1]" mode="titlepage.mode"/>
1532         </xsl:when>
1533         <xsl:otherwise>
1534           <xsl:apply-templates select="$years[1]" mode="titlepage.mode"/>
1535           <xsl:text>, </xsl:text>
1536           <xsl:call-template name="copyright.years">
1537             <xsl:with-param name="years"
1538                             select="$years[position() &gt; 1]"/>
1539             <xsl:with-param name="print.ranges" select="$print.ranges"/>
1540             <xsl:with-param name="single.year.ranges"
1541                             select="$single.year.ranges"/>
1542           </xsl:call-template>
1543         </xsl:otherwise>
1544       </xsl:choose>
1545     </xsl:when>
1546     <xsl:when test="count($years) = 0">
1547       <xsl:variable name="lastyear" select="$nextyear - 1"/>
1548       <xsl:choose>
1549         <xsl:when test="$firstyear = 0">
1550           <!-- there weren't any years at all -->
1551         </xsl:when>
1552         <xsl:when test="$firstyear = $lastyear">
1553           <xsl:value-of select="$firstyear"/>
1554         </xsl:when>
1555         <xsl:when test="$single.year.ranges = 0
1556                         and $lastyear = $firstyear + 1">
1557           <xsl:value-of select="$firstyear"/>
1558           <xsl:text>, </xsl:text>
1559           <xsl:value-of select="$lastyear"/>
1560         </xsl:when>
1561         <xsl:otherwise>
1562           <xsl:value-of select="$firstyear"/>
1563           <xsl:text>-</xsl:text>
1564           <xsl:value-of select="$lastyear"/>
1565         </xsl:otherwise>
1566       </xsl:choose>
1567     </xsl:when>
1568     <xsl:when test="$firstyear = 0">
1569       <xsl:call-template name="copyright.years">
1570         <xsl:with-param name="years"
1571                         select="$years[position() &gt; 1]"/>
1572         <xsl:with-param name="firstyear" select="$years[1]"/>
1573         <xsl:with-param name="nextyear" select="$years[1] + 1"/>
1574         <xsl:with-param name="print.ranges" select="$print.ranges"/>
1575         <xsl:with-param name="single.year.ranges"
1576                         select="$single.year.ranges"/>
1577       </xsl:call-template>
1578     </xsl:when>
1579     <xsl:when test="$nextyear = $years[1]">
1580       <xsl:call-template name="copyright.years">
1581         <xsl:with-param name="years"
1582                         select="$years[position() &gt; 1]"/>
1583         <xsl:with-param name="firstyear" select="$firstyear"/>
1584         <xsl:with-param name="nextyear" select="$nextyear + 1"/>
1585         <xsl:with-param name="print.ranges" select="$print.ranges"/>
1586         <xsl:with-param name="single.year.ranges"
1587                         select="$single.year.ranges"/>
1588       </xsl:call-template>
1589     </xsl:when>
1590     <xsl:otherwise>
1591       <!-- we have years left, but they aren't in the current range -->
1592       <xsl:choose>
1593         <xsl:when test="$nextyear = $firstyear + 1">
1594           <xsl:value-of select="$firstyear"/>
1595           <xsl:text>, </xsl:text>
1596         </xsl:when>
1597         <xsl:when test="$single.year.ranges = 0
1598                         and $nextyear = $firstyear + 2">
1599           <xsl:value-of select="$firstyear"/>
1600           <xsl:text>, </xsl:text>
1601           <xsl:value-of select="$nextyear - 1"/>
1602           <xsl:text>, </xsl:text>
1603         </xsl:when>
1604         <xsl:otherwise>
1605           <xsl:value-of select="$firstyear"/>
1606           <xsl:text>-</xsl:text>
1607           <xsl:value-of select="$nextyear - 1"/>
1608           <xsl:text>, </xsl:text>
1609         </xsl:otherwise>
1610       </xsl:choose>
1611       <xsl:call-template name="copyright.years">
1612         <xsl:with-param name="years"
1613                         select="$years[position() &gt; 1]"/>
1614         <xsl:with-param name="firstyear" select="$years[1]"/>
1615         <xsl:with-param name="nextyear" select="$years[1] + 1"/>
1616         <xsl:with-param name="print.ranges" select="$print.ranges"/>
1617         <xsl:with-param name="single.year.ranges"
1618                         select="$single.year.ranges"/>
1619       </xsl:call-template>
1620     </xsl:otherwise>
1621   </xsl:choose>
1622 </xsl:template>
1623
1624 <!-- ====================================================================== -->
1625
1626 <doc:template name="find.path.params" xmlns="">
1627 <refpurpose>Search in a table for the "best" match for the node</refpurpose>
1628
1629 <refdescription>
1630 <para>This template searches in a table for the value that most-closely
1631 (in the typical best-match sense of XSLT) matches the current (element)
1632 node location.</para>
1633 </refdescription>
1634 </doc:template>
1635
1636 <xsl:template name="find.path.params">
1637   <xsl:param name="node" select="."/>
1638   <xsl:param name="table" select="''"/>
1639   <xsl:param name="location">
1640     <xsl:call-template name="xpath.location">
1641       <xsl:with-param name="node" select="$node"/>
1642     </xsl:call-template>
1643   </xsl:param>
1644
1645   <xsl:variable name="value">
1646     <xsl:call-template name="lookup.key">
1647       <xsl:with-param name="key" select="$location"/>
1648       <xsl:with-param name="table" select="$table"/>
1649     </xsl:call-template>
1650   </xsl:variable>
1651
1652   <xsl:choose>
1653     <xsl:when test="$value != ''">
1654       <xsl:value-of select="$value"/>
1655     </xsl:when>
1656     <xsl:when test="contains($location, '/')">
1657       <xsl:call-template name="find.path.params">
1658         <xsl:with-param name="node" select="$node"/>
1659         <xsl:with-param name="table" select="$table"/>
1660         <xsl:with-param name="location" select="substring-after($location, '/')"/>
1661       </xsl:call-template>
1662     </xsl:when>
1663   </xsl:choose>
1664 </xsl:template>
1665
1666 <xsl:template name="relative-uri">
1667   <xsl:param name="filename" select="."/>
1668   <xsl:param name="destdir" select="''"/>
1669   
1670   <xsl:variable name="srcurl">
1671     <xsl:call-template name="strippath">
1672       <xsl:with-param name="filename">
1673         <xsl:call-template name="xml.base.dirs">
1674           <xsl:with-param name="base.elem" 
1675                           select="$filename/ancestor-or-self::*
1676                                    [@xml:base != ''][1]"/>
1677         </xsl:call-template>
1678         <xsl:value-of select="$filename"/>
1679       </xsl:with-param>
1680     </xsl:call-template>
1681   </xsl:variable>
1682
1683   <xsl:variable name="srcurl.trimmed">
1684     <xsl:call-template name="trim.common.uri.paths">
1685       <xsl:with-param name="uriA" select="$srcurl"/>
1686       <xsl:with-param name="uriB" select="$destdir"/>
1687       <xsl:with-param name="return" select="'A'"/>
1688     </xsl:call-template>
1689   </xsl:variable>
1690
1691   <xsl:variable name="destdir.trimmed">
1692     <xsl:call-template name="trim.common.uri.paths">
1693       <xsl:with-param name="uriA" select="$srcurl"/>
1694       <xsl:with-param name="uriB" select="$destdir"/>
1695       <xsl:with-param name="return" select="'B'"/>
1696     </xsl:call-template>
1697   </xsl:variable>
1698
1699   <xsl:variable name="depth">
1700     <xsl:call-template name="count.uri.path.depth">
1701       <xsl:with-param name="filename" select="$destdir.trimmed"/>
1702     </xsl:call-template>
1703   </xsl:variable>
1704
1705   <xsl:call-template name="copy-string">
1706     <xsl:with-param name="string" select="'../'"/>
1707     <xsl:with-param name="count" select="$depth"/>
1708   </xsl:call-template>
1709   <xsl:value-of select="$srcurl.trimmed"/>
1710
1711 </xsl:template>
1712
1713 <!-- ===================================== -->
1714
1715 <xsl:template name="xml.base.dirs">
1716   <xsl:param name="base.elem" select="NONODE"/>
1717
1718   <!-- Recursively resolve xml:base attributes -->
1719   <xsl:if test="$base.elem/ancestor::*[@xml:base != '']">
1720     <xsl:call-template name="xml.base.dirs">
1721       <xsl:with-param name="base.elem" 
1722                       select="$base.elem/ancestor::*[@xml:base != ''][1]"/>
1723     </xsl:call-template>
1724   </xsl:if>
1725   <xsl:call-template name="getdir">
1726     <xsl:with-param name="filename" select="$base.elem/@xml:base"/>
1727   </xsl:call-template>
1728
1729 </xsl:template>
1730
1731 <!-- ===================================== -->
1732
1733 <xsl:template name="strippath">
1734   <xsl:param name="filename" select="''"/>
1735   <xsl:choose>
1736     <!-- Leading .. are not eliminated -->
1737     <xsl:when test="starts-with($filename, '../')">
1738       <xsl:value-of select="'../'"/>
1739       <xsl:call-template name="strippath">
1740         <xsl:with-param name="filename" select="substring-after($filename, '../')"/>
1741       </xsl:call-template>
1742     </xsl:when>
1743     <xsl:when test="contains($filename, '/../')">
1744       <xsl:call-template name="strippath">
1745         <xsl:with-param name="filename">
1746           <xsl:call-template name="getdir">
1747             <xsl:with-param name="filename" select="substring-before($filename, '/../')"/>
1748           </xsl:call-template>
1749           <xsl:value-of select="substring-after($filename, '/../')"/>
1750         </xsl:with-param>
1751       </xsl:call-template>
1752     </xsl:when>
1753     <xsl:otherwise>
1754       <xsl:value-of select="$filename"/>
1755     </xsl:otherwise>
1756   </xsl:choose>
1757 </xsl:template>
1758
1759 <!-- ===================================== -->
1760
1761 <xsl:template name="getdir">
1762   <xsl:param name="filename" select="''"/>
1763   <xsl:if test="contains($filename, '/')">
1764     <xsl:value-of select="substring-before($filename, '/')"/>
1765     <xsl:text>/</xsl:text>
1766     <xsl:call-template name="getdir">
1767       <xsl:with-param name="filename" select="substring-after($filename, '/')"/>
1768     </xsl:call-template>
1769   </xsl:if>
1770 </xsl:template>
1771
1772 <!-- ===================================== -->
1773
1774 <doc:template name="string.upper" xmlns="">
1775 <refpurpose>Converts a string to all uppercase letters</refpurpose>
1776
1777 <refdescription>
1778 <para>Given a string, this template does a language-aware conversion
1779 of that string to all uppercase letters, based on the values of the
1780 <literal>lowercase.alpha</literal> and
1781 <literal>uppercase.alpha</literal> gentext keys for the current
1782 locale. It affects only those characters found in the values of
1783 <literal>lowercase.alpha</literal> and
1784 <literal>uppercase.alpha</literal>. All other characters are left
1785 unchanged.</para>
1786 </refdescription>
1787
1788 <refparameter>
1789 <variablelist>
1790 <varlistentry><term>string</term>
1791 <listitem>
1792 <para>The string to convert to uppercase.</para>
1793 </listitem>
1794 </varlistentry>
1795 </variablelist>
1796 </refparameter>
1797 </doc:template>
1798
1799 <xsl:template name="string.upper">
1800   <xsl:param name="string" select="''"/>
1801   <xsl:variable name="lowercase.alpha">
1802     <xsl:call-template name="gentext">
1803       <xsl:with-param name="key" select="'lowercase.alpha'"/>
1804     </xsl:call-template>
1805   </xsl:variable>
1806   <xsl:variable name="uppercase.alpha">
1807     <xsl:call-template name="gentext">
1808       <xsl:with-param name="key" select="'uppercase.alpha'"/>
1809     </xsl:call-template>
1810   </xsl:variable>
1811   <xsl:value-of select="translate($string,$lowercase.alpha,$uppercase.alpha)"/>
1812 </xsl:template>
1813
1814 <!-- ===================================== -->
1815
1816 <doc:template name="select.choice.separator" xmlns="">
1817   <refpurpose>Returns localized choice separator</refpurpose>
1818   <refdescription>
1819     <para>This template enables auto-generation of an appropriate
1820     localized "choice" separator (for example, "and" or "or") before
1821     the final item in an inline list (though it could also be useful
1822     for generating choice separators for non-inline lists).</para>
1823
1824     <para>It currently works by evaluating a processing instruction
1825     (PI) of the form &lt;?dbchoice&#xa0;choice="foo"?> :
1826
1827     <itemizedlist>
1828       <listitem>
1829         <simpara>if the value of the <sgmltag>choice</sgmltag>
1830         pseudo-attribute is "and" or "or", returns a localized "and"
1831         or "or"</simpara>
1832       </listitem>
1833       <listitem>
1834         <simpara>otherwise returns the literal value of the
1835         <sgmltag>choice</sgmltag> pseudo-attribute</simpara>
1836       </listitem>
1837     </itemizedlist>
1838
1839     The latter is provided only as a temporary workaround because the
1840     locale files do not currently have translations for the word
1841     <wordasword>or</wordasword>. So if you want to generate a a
1842     logical "or" separator in French (for example), you currently need
1843     to do this:
1844
1845     <literallayout>&lt;?dbchoice choice="ou"?></literallayout>
1846     </para>
1847
1848     <warning>
1849       <para>The <sgmltag>dbchoice</sgmltag> processing instruction is
1850       an unfortunate hack; support for it may disappear in the future
1851       (particularly if and when a more appropriate means for marking
1852       up "choice" lists becomes available in DocBook).</para>
1853     </warning>
1854   </refdescription>
1855 </doc:template>
1856
1857 <xsl:template name="select.choice.separator">
1858   
1859   <xsl:variable name="choice">
1860     <xsl:call-template name="pi-attribute">
1861       <xsl:with-param name="pis" select="processing-instruction('dbchoice')"/>
1862       <xsl:with-param name="attribute">choice</xsl:with-param>
1863     </xsl:call-template>
1864   </xsl:variable>
1865   
1866   <xsl:choose>
1867     <!-- if value of $choice is "and" or "or", translate to equivalent in -->
1868     <!-- current locale -->
1869     <xsl:when test="$choice = 'and' or $choice = 'or'">
1870       <xsl:call-template name="gentext">
1871         <xsl:with-param name="key" select="$choice"/>
1872       </xsl:call-template>
1873     </xsl:when>
1874     <!--  otherwise, just output value of $choice, whatever it is -->
1875     <xsl:otherwise>
1876       <xsl:value-of select="$choice"/>
1877     </xsl:otherwise>
1878   </xsl:choose>
1879 </xsl:template>
1880
1881 <!-- ===================================== -->
1882
1883 <doc:template name="evaluate.info.profile" xmlns="">
1884   <refpurpose>Evaluates an info profile</refpurpose>
1885   <refdescription>
1886     <para>This function evaluates an "info profile" matching the XPath
1887     expression given by the <parameter>profile</parameter>
1888     parameter. It relies on the XSLT <function>evaluate()</function>
1889     extension function.</para>
1890
1891     <para>The value of the <parameter>profile</parameter> parameter
1892     can include the strings <literal>$info</literal> and
1893     <literal>$parentinfo</literal>. If found in the value of the
1894     <parameter>profile</parameter> parameter, those strings are
1895     evaluated using the <parameter>info</parameter> and
1896     <parameter>parentinfo</parameter> parameters, the values of which
1897     should be DocBook <replaceable>*info</replaceable> element node
1898     sets.</para>
1899   </refdescription>
1900   <refparameter>
1901     <variablelist>
1902        <varlistentry>
1903         <term>profile</term>
1904         <listitem>
1905           <para>A string representing an XPath expression </para>
1906         </listitem>
1907       </varlistentry>
1908        <varlistentry>
1909         <term>info</term>
1910         <listitem>
1911           <para>A DocBook info node</para>
1912         </listitem>
1913       </varlistentry>
1914       <varlistentry>
1915         <term>parentinfo</term>
1916         <listitem>
1917           <para>A DocBook info node (from a parent element)</para>
1918         </listitem>
1919       </varlistentry>
1920     </variablelist>
1921   </refparameter>
1922
1923   <refreturn>
1924     <para>Returns a node (the result of evaluating the
1925     <parameter>profile</parameter> parameter)</para>
1926   </refreturn>
1927 </doc:template>
1928
1929   <xsl:template name="evaluate.info.profile">
1930     <xsl:param name="profile"/>
1931     <xsl:param name="info"/>
1932     <xsl:param name="parentinfo"/>
1933     <xsl:choose>
1934       <!-- xsltproc and Xalan both support dyn:evaluate() -->
1935       <xsl:when test="function-available('dyn:evaluate')">
1936         <xsl:apply-templates
1937             select="dyn:evaluate($profile)"/>
1938       </xsl:when>
1939       <!-- Saxon has its own evaluate() & doesn't support dyn:evaluate() -->
1940       <xsl:when test="function-available('saxon:evaluate')">
1941         <xsl:apply-templates
1942             select="saxon:evaluate($profile)"/>
1943       </xsl:when>
1944       <xsl:otherwise>
1945         <xsl:message terminate="yes">
1946 Error: The "info profiling" mechanism currently requires an XSLT
1947 engine that supports the evaluate() XSLT extension function. Your XSLT
1948 engine does not support it.
1949 </xsl:message>
1950       </xsl:otherwise>
1951     </xsl:choose>
1952   </xsl:template>
1953
1954 </xsl:stylesheet>