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