2 <!DOCTYPE xsl:stylesheet [
3 <!ENTITY lowercase "'abcdefghijklmnopqrstuvwxyz'">
4 <!ENTITY uppercase "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'">
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"
14 <!-- ********************************************************************
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.
20 ******************************************************************** -->
22 <doc:reference xmlns="" xml:id="base">
24 <title>Common » Base Template Reference</title>
25 <releaseinfo role="meta">
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
39 <!-- ==================================================================== -->
40 <!-- Establish strip/preserve whitespace rules -->
42 <xsl:preserve-space elements="*"/>
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
84 <!-- ====================================================================== -->
86 <doc:template name="is.component" xmlns="">
87 <refpurpose>Tests if a given node is a component-level element</refpurpose>
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>
94 <refparameter id="is.component-params">
96 <varlistentry><term>node</term>
98 <para>The node which is to be tested.</para>
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>
110 <xsl:template name="is.component">
111 <xsl:param name="node" select="."/>
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>
124 <!-- ====================================================================== -->
126 <doc:template name="is.section" xmlns="">
127 <refpurpose>Tests if a given node is a section-level element</refpurpose>
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>
134 <refparameter id="is.section-params">
136 <varlistentry><term>node</term>
138 <para>The node which is to be tested.</para>
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>
150 <xsl:template name="is.section">
151 <xsl:param name="node" select="."/>
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>
167 <!-- ====================================================================== -->
169 <doc:template name="section.level" xmlns="">
170 <refpurpose>Returns the hierarchical level of a section</refpurpose>
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>
177 <para>Recursive sections are calculated down to the fifth level.</para>
180 <refparameter id="section.level-params">
182 <varlistentry><term>node</term>
184 <para>The section node for which the level should be calculated.
185 Defaults to the context node.</para>
191 <refreturn id="section.level-returns">
192 <para>The section level, <quote>1</quote>, <quote>2</quote>, etc.
197 <xsl:template name="section.level">
198 <xsl:param name="node" select="."/>
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'">
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>
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"/>
224 <xsl:when test="local-name($node)='simplesect'">
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">
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>
239 <xsl:otherwise>1</xsl:otherwise>
242 <xsl:otherwise>1</xsl:otherwise>
244 </xsl:template><!-- section.level -->
246 <doc:template name="qanda.section.level" xmlns="">
247 <refpurpose>Returns the hierarchical level of a QandASet</refpurpose>
249 <refdescription id="qanda.section.level-desc">
250 <para>This template calculates the hierarchical level of a QandASet.
254 <refreturn id="qanda.section.level-returns">
255 <para>The level, <quote>1</quote>, <quote>2</quote>, etc.
260 <xsl:template name="qanda.section.level">
261 <xsl:variable name="section"
262 select="(ancestor::d:section
263 |ancestor::d:simplesect
269 |ancestor::d:refsect3
270 |ancestor::d:refsect2
271 |ancestor::d:refsect1)[last()]"/>
274 <xsl:when test="count($section) = '0'">1</xsl:when>
276 <xsl:variable name="slevel">
277 <xsl:call-template name="section.level">
278 <xsl:with-param name="node" select="$section"/>
281 <xsl:value-of select="$slevel + 1"/>
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="."/>
290 <xsl:variable name="RElevel">
291 <xsl:call-template name="refentry.level">
292 <xsl:with-param name="node" select="$node/ancestor::d:refentry[1]"/>
296 <xsl:variable name="levelinRE">
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'">
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>
314 <xsl:value-of select="$levelinRE + $RElevel"/>
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()]"/>
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"/>
335 <xsl:value-of select="$slevel + 1"/>
337 <xsl:otherwise>1</xsl:otherwise>
341 <xsl:template name="qandadiv.section.level">
342 <xsl:variable name="section.level">
343 <xsl:call-template name="qanda.section.level"/>
345 <xsl:variable name="anc.divs" select="ancestor::d:qandadiv"/>
347 <xsl:value-of select="count($anc.divs) + number($section.level)"/>
350 <xsl:template name="question.answer.label">
351 <xsl:variable name="deflabel">
353 <xsl:when test="ancestor-or-self::*[@defaultlabel]">
354 <xsl:value-of select="(ancestor-or-self::*[@defaultlabel])[last()]
358 <xsl:value-of select="$qanda.defaultlabel"/>
363 <xsl:variable name="label" select="@label"/>
366 (hnr (hierarchical-number-recursive (normalize "qandadiv") node))
368 (parsect (ancestor-member node (section-element-list)))
370 (defnum (if (and %qanda-inherit-numeration%
372 (if (node-list-empty? parsect)
373 (section-autolabel-prefix node)
374 (section-autolabel parsect))
377 (hnumber (let loop ((numlist hnr) (number defnum)
378 (sep (if (equal? defnum "") "" ".")))
382 (string-append number
384 (number->string (car numlist)))
386 (cnumber (child-number (parent node)))
387 (number (string-append hnumber
388 (if (equal? hnumber "")
391 (number->string cnumber))))
395 <xsl:when test="$deflabel = 'qanda'">
396 <xsl:call-template name="gentext">
397 <xsl:with-param name="key">
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>
407 <xsl:when test="$deflabel = 'label'">
408 <xsl:value-of select="$label"/>
410 <xsl:when test="$deflabel = 'number'
411 and local-name(.) = 'question'">
412 <xsl:apply-templates select="ancestor::d:qandaset[1]"
415 <xsl:when test="ancestor::d:qandadiv">
416 <xsl:apply-templates select="ancestor::d:qandadiv[1]"
418 <xsl:apply-templates select="ancestor::d:qandaentry"
422 <xsl:apply-templates select="ancestor::d:qandaentry"
433 <xsl:template match="d:qandaset" mode="number">
437 <xsl:template match="d:qandadiv" mode="number">
438 <xsl:number level="multiple" from="d:qandaset" format="1."/>
441 <xsl:template match="d:qandaentry" mode="number">
443 <xsl:when test="ancestor::d:qandadiv">
444 <xsl:number level="single" from="d:qandadiv" format="1."/>
447 <xsl:number level="single" from="d:qandaset" format="1."/>
452 <!-- ====================================================================== -->
454 <xsl:template name="object.id">
455 <xsl:param name="object" select="."/>
457 <xsl:when test="$object/@id">
458 <xsl:value-of select="$object/@id"/>
460 <xsl:when test="$object/@xml:id">
461 <xsl:value-of select="$object/@xml:id"/>
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="*"/>
471 <xsl:value-of select="generate-id($object)"/>
476 <xsl:template name="person.name">
477 <!-- Formats a personal name. Handles corpauthor as a special case. -->
478 <xsl:param name="node" select="."/>
480 <xsl:param name="style">
482 <xsl:when test="$node/@role">
483 <xsl:value-of select="$node/@role"/>
486 <xsl:call-template name="gentext.template">
487 <xsl:with-param name="context" select="'styles'"/>
488 <xsl:with-param name="name" select="'person-name'"/>
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"/>
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"/>
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()"/>
516 <xsl:when test="$style = 'family-given'">
517 <xsl:call-template name="person.name.family-given">
518 <xsl:with-param name="node" select="$node"/>
521 <xsl:when test="$style = 'last-first'">
522 <xsl:call-template name="person.name.last-first">
523 <xsl:with-param name="node" select="$node"/>
527 <xsl:call-template name="person.name.first-last">
528 <xsl:with-param name="node" select="$node"/>
536 <xsl:template name="person.name.family-given">
537 <xsl:param name="node" select="."/>
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]"/>
543 <xsl:if test="$node//d:surname and $node//d:firstname">
544 <xsl:text> </xsl:text>
547 <xsl:apply-templates select="$node//d:firstname[1]"/>
549 <xsl:text> [FAMILY Given]</xsl:text>
552 <xsl:template name="person.name.last-first">
553 <xsl:param name="node" select="."/>
555 <xsl:apply-templates select="$node//d:surname[1]"/>
557 <xsl:if test="$node//d:surname and $node//d:firstname">
558 <xsl:text>, </xsl:text>
561 <xsl:apply-templates select="$node//d:firstname[1]"/>
564 <xsl:template name="person.name.first-last">
565 <xsl:param name="node" select="."/>
567 <xsl:if test="$node//d:honorific">
568 <xsl:apply-templates select="$node//d:honorific[1]"/>
569 <xsl:value-of select="$punct.honorific"/>
572 <xsl:if test="$node//d:firstname">
573 <xsl:if test="$node//d:honorific">
574 <xsl:text> </xsl:text>
576 <xsl:apply-templates select="$node//d:firstname[1]"/>
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>
583 <xsl:apply-templates select="$node//d:othername[1]"/>
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>
591 <xsl:apply-templates select="$node//d:surname[1]"/>
594 <xsl:if test="$node//d:lineage">
595 <xsl:text>, </xsl:text>
596 <xsl:apply-templates select="$node//d:lineage[1]"/>
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.
607 John Doe and Jane Doe
609 John Doe, Jane Doe, and A. Nonymous
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"/>
617 <xsl:when test="$count > $person.count"></xsl:when>
619 <xsl:call-template name="person.name">
620 <xsl:with-param name="node" select="$person.list[position()=$count]"/>
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'"/>
630 <xsl:when test="$person.count > 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'"/>
636 <xsl:when test="$count < $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'"/>
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"/>
651 </xsl:template><!-- person.name.list -->
653 <!-- === synopsis ======================================================= -->
654 <!-- The following definitions match those given in the reference
655 documentation for DocBook V3.0
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>
672 <!-- ====================================================================== -->
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>
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)"/>
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"/>
693 <xsl:value-of select="$string"/>
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>
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"/>
710 <xsl:call-template name="title.xref">
711 <xsl:with-param name="target" select="$target"/>
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"/>
720 <xsl:call-template name="xref.g.subst">
721 <xsl:with-param name="string" select="$string"/>
722 <xsl:with-param name="target" select="$target"/>
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>
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"/>
740 <xsl:call-template name="number.xref">
741 <xsl:with-param name="target" select="$target"/>
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"/>
750 <xsl:call-template name="xref.t.subst">
751 <xsl:with-param name="string" select="$string"/>
752 <xsl:with-param name="target" select="$target"/>
758 <xsl:template name="subst.xref.text">
759 <xsl:param name="xref.text"></xsl:param>
760 <xsl:param name="target" select="."/>
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"/>
769 <!-- ====================================================================== -->
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()"/>
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()"/>
785 <xsl:value-of select="$filename"/>
790 <xsl:template name="filename-extension">
791 <xsl:param name="filename"></xsl:param>
792 <xsl:param name="recurse" select="false()"/>
794 <!-- Make sure we only look at the base name... -->
795 <xsl:variable name="basefn">
797 <xsl:when test="$recurse">
798 <xsl:value-of select="$filename"/>
801 <xsl:call-template name="filename-basename">
802 <xsl:with-param name="filename" select="$filename"/>
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()"/>
816 <xsl:when test="$recurse">
817 <xsl:value-of select="$basefn"/>
819 <xsl:otherwise></xsl:otherwise>
823 <!-- ====================================================================== -->
825 <doc:template name="select.mediaobject" xmlns="">
826 <refpurpose>Selects and processes an appropriate media object from a list</refpurpose>
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>
833 <para>This template relies on a template named
834 "select.mediaobject.index" to determine which object
835 in the list is appropriate.</para>
837 <para>If no acceptable object is located, nothing happens.</para>
840 <refparameter id="select.mediaobject-params">
842 <varlistentry><term>olist</term>
844 <para>The node list of potential objects to examine.</para>
850 <refreturn id="select.mediaobject-returns">
851 <para>Calls <xsl:apply-templates> on the selected object.</para>
855 <xsl:template name="select.mediaobject">
856 <xsl:param name="olist"
857 select="d:imageobject|d:imageobjectco
858 |d:videoobject|d:audioobject|d:textobject"/>
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"/>
867 <xsl:if test="$mediaobject.index != ''">
868 <xsl:apply-templates select="$olist[position() = $mediaobject.index]"/>
872 <!-- ====================================================================== -->
874 <doc:template name="select.mediaobject.index" xmlns="">
875 <refpurpose>Selects the position of the appropriate media object from a list</refpurpose>
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>
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>
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.
894 <para>If no acceptable object is located, no index is returned.</para>
897 <refparameter id="select.mediaobject.index-params">
899 <varlistentry><term>olist</term>
901 <para>The node list of potential objects to examine.</para>
904 <varlistentry><term>count</term>
906 <para>The position in the list currently being considered by the
907 recursive process.</para>
913 <refreturn id="select.mediaobject.index-returns">
914 <para>Returns the position in the original list of the selected object.</para>
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>
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]">
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()"/>
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()"/>
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()"/>
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"/>
968 <!-- Otherwise select first acceptable object -->
969 <xsl:if test="$count <= count($olist)">
970 <xsl:variable name="object" select="$olist[position()=$count]"/>
972 <xsl:variable name="useobject">
974 <!-- select videoobject or audioobject before textobject -->
975 <xsl:when test="local-name($object) = 'videoobject'">
976 <xsl:text>1</xsl:text>
978 <xsl:when test="local-name($object) = 'audioobject'">
979 <xsl:text>1</xsl:text>
981 <!-- skip textobject if also video, audio, or image out of order -->
982 <xsl:when test="local-name($object) = 'textobject' and
986 <xsl:text>0</xsl:text>
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>
994 <!-- The phrase is never used -->
995 <xsl:when test="local-name($object)='textobject' and $object/d:phrase">
996 <xsl:text>0</xsl:text>
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>
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>
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>
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>
1021 <!-- Otherwise, see if this one is a useable graphic -->
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>
1031 <xsl:call-template name="is.acceptable.mediaobject">
1032 <xsl:with-param name="object" select="$object"/>
1033 </xsl:call-template>
1041 <xsl:when test="$useobject='1'">
1042 <xsl:value-of select="$count"/>
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>
1056 <doc:template name="is.acceptable.mediaobject" xmlns="">
1057 <refpurpose>Returns '1' if the specified media object is recognized</refpurpose>
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>
1064 <refparameter id="is.acceptable.mediaobject-params">
1066 <varlistentry><term>object</term>
1068 <para>The media object to consider.</para>
1074 <refreturn id="is.acceptable.mediaobject-returns">
1079 <xsl:template name="is.acceptable.mediaobject">
1080 <xsl:param name="object"></xsl:param>
1082 <xsl:variable name="filename">
1083 <xsl:call-template name="mediaobject.filename">
1084 <xsl:with-param name="object" select="$object"/>
1085 </xsl:call-template>
1088 <xsl:variable name="ext">
1089 <xsl:call-template name="filename-extension">
1090 <xsl:with-param name="filename" select="$filename"/>
1091 </xsl:call-template>
1094 <!-- there will only be one -->
1095 <xsl:variable name="data" select="$object/d:videodata
1096 |$object/d:imagedata
1097 |$object/d:audiodata"/>
1099 <xsl:variable name="format" select="$data/@format"/>
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>
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>
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>
1127 <xsl:template name="mediaobject.filename">
1128 <xsl:param name="object"></xsl:param>
1130 <xsl:variable name="data" select="$object/d:videodata
1131 |$object/d:imagedata
1132 |$object/d:audiodata
1135 <xsl:variable name="filename">
1137 <xsl:when test="$data[@fileref]">
1138 <xsl:apply-templates select="$data/@fileref"/>
1140 <xsl:when test="$data[@entityref]">
1141 <xsl:value-of select="unparsed-entity-uri($data/@entityref)"/>
1143 <xsl:otherwise></xsl:otherwise>
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>
1153 <xsl:variable name="ext">
1155 <xsl:when test="$real.ext != ''">
1156 <xsl:value-of select="$real.ext"/>
1159 <xsl:value-of select="$graphic.default.extension"/>
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>
1171 <xsl:when test="$real.ext = ''">
1173 <xsl:when test="$ext != ''">
1174 <xsl:value-of select="$filename"/>
1175 <xsl:text>.</xsl:text>
1176 <xsl:value-of select="$ext"/>
1179 <xsl:value-of select="$filename"/>
1183 <xsl:when test="not($graphic.ext)">
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"/>
1191 <xsl:value-of select="$filename"/>
1196 <xsl:value-of select="$filename"/>
1201 <!-- ====================================================================== -->
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>
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]"/>
1219 <xsl:if test="count($targets)=0">
1221 <xsl:text>Error: no ID for constraint linkend: </xsl:text>
1222 <xsl:value-of select="concat('"', $linkend, '"')"/>
1223 <xsl:text>.</xsl:text>
1227 <xsl:text>If the ID exists in your document, did your </xsl:text>
1228 <xsl:text>XSLT Processor load the DTD?</xsl:text>
1233 <xsl:if test="count($targets)>1">
1235 <xsl:text>Warning: multiple "IDs" for constraint linkend: </xsl:text>
1236 <xsl:value-of select="$linkend"/>
1237 <xsl:text>.</xsl:text>
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>
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]"/>
1260 <xsl:if test="count($target) > 0">
1261 <xsl:if test="not(contains(concat(' ', $element-list, ' '), local-name($target)))">
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"/>
1275 <!-- ====================================================================== -->
1276 <!-- Procedure Step Numeration -->
1278 <xsl:param name="procedure.step.numeration.formats" select="'1aiAI'"/>
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)"/>
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"/>
1290 <xsl:when test="$sstype > $format.length">
1291 <xsl:value-of select="substring($procedure.step.numeration.formats,1,1)"/>
1294 <xsl:value-of select="substring($procedure.step.numeration.formats,$sstype,1)"/>
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)"/>
1306 <xsl:text>Unexpected context in procedure.step.numeration: </xsl:text>
1307 <xsl:value-of select="local-name($context)"/>
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"/>
1319 <xsl:variable name="num">
1320 <xsl:number count="d:step" format="{$format}"/>
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>
1329 <xsl:value-of select="concat($num, $rest)"/>
1334 <!-- ====================================================================== -->
1335 <!-- OrderedList Numeration -->
1336 <xsl:template name="output-orderedlist-starting-number">
1337 <xsl:param name="list"/>
1338 <xsl:param name="pi-start"/>
1340 <xsl:when test="not($list/@continuation = 'continues')">
1342 <xsl:when test="$list/@startingnumber">
1343 <xsl:value-of select="$list/@startingnumber"/>
1345 <xsl:when test="$pi-start != ''">
1346 <xsl:value-of select="$pi-start"/>
1348 <xsl:otherwise>1</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]"/>
1357 <xsl:when test="count($prevlist) = 0">2</xsl:when>
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>
1365 <xsl:value-of select="$prevstart + $prevlength"/>
1372 <xsl:template name="orderedlist-item-number">
1373 <!-- context node must be a listitem in an orderedlist -->
1374 <xsl:param name="node" select="."/>
1376 <xsl:when test="$node/@override">
1377 <xsl:value-of select="$node/@override"/>
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>
1385 <xsl:value-of select="$pnum + 1"/>
1388 <xsl:call-template name="orderedlist-starting-number">
1389 <xsl:with-param name="list" select="parent::*"/>
1390 </xsl:call-template>
1395 <xsl:template name="next.numeration">
1396 <xsl:param name="numeration" select="'default'"/>
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>
1408 <xsl:template name="list.numeration">
1409 <xsl:param name="node" select="."/>
1412 <xsl:when test="$node/@numeration">
1413 <xsl:value-of select="$node/@numeration"/>
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>
1424 </xsl:call-template>
1427 <xsl:call-template name="next.numeration"/>
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>
1441 <xsl:variable name="type">
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 -->
1451 <xsl:text>Unexpected numeration: </xsl:text>
1452 <xsl:value-of select="$numeration"/>
1454 <xsl:value-of select="1."/>
1459 <xsl:variable name="item-number">
1460 <xsl:call-template name="orderedlist-item-number"/>
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"/>
1469 <xsl:number value="$item-number" format="{$type}"/>
1472 <!-- ====================================================================== -->
1473 <!-- ItemizedList "Numeration" -->
1475 <xsl:template name="next.itemsymbol">
1476 <xsl:param name="itemsymbol" select="'default'"/>
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>
1485 <xsl:template name="list.itemsymbol">
1486 <xsl:param name="node" select="."/>
1489 <xsl:when test="@override">
1490 <xsl:value-of select="@override"/>
1492 <xsl:when test="$node/@mark">
1493 <xsl:value-of select="$node/@mark"/>
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>
1504 </xsl:call-template>
1507 <xsl:call-template name="next.itemsymbol"/>
1514 <!-- ====================================================================== -->
1516 <doc:template name="copyright.years" xmlns="">
1517 <refpurpose>Print a set of years with collapsed ranges</refpurpose>
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>
1523 <screen><![CDATA[<year>1992</year>
1525 <year>1994</year>]]></screen>
1527 <para>is printed <quote>1992-1994</quote>, whereas:</para>
1529 <screen><![CDATA[<year>1992</year>
1530 <year>1994</year>]]></screen>
1532 <para>is printed <quote>1992, 1994</quote>.</para>
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>
1541 <refparameter id="copyright.years-params">
1543 <varlistentry><term>years</term>
1545 <para>The initial set of year elements.</para>
1548 <varlistentry><term>print.ranges</term>
1550 <para>If non-zero, multi-year ranges are collapsed. If zero, all years
1551 are printed discretely.</para>
1554 <varlistentry><term>single.year.ranges</term>
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>
1565 <refreturn id="copyright.years-returns">
1566 <para>This template returns the formatted list of years.</para>
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"/>
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>
1596 <xsl:when test="$print.ranges = 0 and count($years) > 0">
1598 <xsl:when test="count($years) = 1">
1599 <xsl:apply-templates select="$years[1]" mode="titlepage.mode"/>
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() > 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>
1614 <xsl:when test="count($years) = 0">
1615 <xsl:variable name="lastyear" select="$nextyear - 1"/>
1617 <xsl:when test="$firstyear = 0">
1618 <!-- there weren't any years at all -->
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"/>
1624 <xsl:when test="$firstyear = $lastyear">
1625 <xsl:value-of select="$firstyear"/>
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"/>
1634 <xsl:value-of select="$firstyear"/>
1635 <xsl:text>-</xsl:text>
1636 <xsl:value-of select="$lastyear"/>
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>
1646 <xsl:call-template name="copyright.years">
1647 <xsl:with-param name="years"
1648 select="$years[position() > 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>
1656 <xsl:when test="$firstyear = 0">
1657 <xsl:call-template name="copyright.years">
1658 <xsl:with-param name="years"
1659 select="$years[position() > 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>
1667 <xsl:when test="$nextyear = $years[1]">
1668 <xsl:call-template name="copyright.years">
1669 <xsl:with-param name="years"
1670 select="$years[position() > 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>
1679 <!-- we have years left, but they aren't in the current range -->
1681 <xsl:when test="$nextyear = $firstyear + 1">
1682 <xsl:value-of select="$firstyear"/>
1683 <xsl:text>, </xsl:text>
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>
1693 <xsl:value-of select="$firstyear"/>
1694 <xsl:text>-</xsl:text>
1695 <xsl:value-of select="$nextyear - 1"/>
1696 <xsl:text>, </xsl:text>
1699 <xsl:call-template name="copyright.years">
1700 <xsl:with-param name="years"
1701 select="$years[position() > 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>
1712 <!-- ====================================================================== -->
1714 <doc:template name="find.path.params" xmlns="">
1715 <refpurpose>Search in a table for the "best" match for the node</refpurpose>
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>
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>
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>
1741 <xsl:when test="$value != ''">
1742 <xsl:value-of select="$value"/>
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>
1754 <xsl:template name="relative-uri">
1755 <xsl:param name="filename" select="."/>
1756 <xsl:param name="destdir" select="''"/>
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"/>
1768 </xsl:call-template>
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>
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>
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>
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"/>
1801 <!-- ===================================== -->
1803 <xsl:template name="xml.base.dirs">
1804 <xsl:param name="base.elem" select="NONODE"/>
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>
1815 <xsl:call-template name="getdir">
1816 <xsl:with-param name="filename" select="$base.elem/@xml:base"/>
1817 </xsl:call-template>
1821 <!-- ===================================== -->
1823 <xsl:template name="strippath">
1824 <xsl:param name="filename" select="''"/>
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>
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, '/../')"/>
1841 </xsl:call-template>
1844 <xsl:value-of select="$filename"/>
1849 <!-- ===================================== -->
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>
1862 <!-- ===================================== -->
1864 <doc:template name="string.upper" xmlns="">
1865 <refpurpose>Converts a string to all uppercase letters</refpurpose>
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
1878 <refparameter id="string.upper-params">
1880 <varlistentry><term>string</term>
1882 <para>The string to convert to uppercase.</para>
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>
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>
1900 <xsl:value-of select="translate($string,$lowercase.alpha,$uppercase.alpha)"/>
1903 <!-- ===================================== -->
1905 <doc:template name="string.lower" xmlns="">
1906 <refpurpose>Converts a string to all lowercase letters</refpurpose>
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
1919 <refparameter id="string.lower-params">
1921 <varlistentry><term>string</term>
1923 <para>The string to convert to lowercase.</para>
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>
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>
1941 <xsl:value-of select="translate($string,$uppercase.alpha,$lowercase.alpha)"/>
1944 <!-- ===================================== -->
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 <?dbchoice choice="foo"?> :
1957 <simpara>if the value of the <tag>choice</tag>
1958 pseudo-attribute is "and" or "or", returns a localized "and"
1962 <simpara>otherwise returns the literal value of the
1963 <tag>choice</tag> pseudo-attribute</simpara>
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
1971 <literallayout><?dbchoice choice="ou"?></literallayout>
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>
1981 <xsl:template name="select.choice.separator">
1982 <xsl:variable name="choice">
1983 <xsl:call-template name="pi.dbchoice_choice"/>
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>
1993 <!-- otherwise, just output value of $choice, whatever it is -->
1995 <xsl:value-of select="$choice"/>
2000 <!-- ===================================== -->
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>
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>
2019 <refparameter id="evaluate.info.profile-params">
2022 <term>profile</term>
2024 <para>A string representing an XPath expression </para>
2030 <para>A set of *info nodes</para>
2036 <refreturn id="evaluate.info.profile-returns">
2037 <para>Returns a node (the result of evaluating the
2038 <parameter>profile</parameter> parameter)</para>
2041 <xsl:template name="evaluate.info.profile">
2042 <xsl:param name="profile"/>
2043 <xsl:param name="info"/>
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"/>
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"/>
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.
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>
2074 <xsl:template name="graphic.format.content-type">
2075 <xsl:param name="format"/>
2076 <xsl:variable name="upperformat" select="translate($format,&lowercase;,&uppercase;)"/>
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>
2103 <xsl:value-of select="concat('image/', $upperformat)"/>
2108 <xsl:template match="*" mode="xrefstyle">
2109 <xsl:param name="referrer" select="."/>
2110 <xsl:param name="target"/>
2111 <xsl:param name="olink.key"/>
2113 <!-- normally uses the @xrefstyle attribute in xref, but could
2114 be customized based on the target element type -->
2116 <xsl:when test="@role and not(@xrefstyle)
2117 and $use.role.as.xrefstyle != 0">
2118 <xsl:value-of select="@role"/>
2121 <xsl:value-of select="@xrefstyle"/>