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:doc="http://nwalsh.com/xsl/documentation/1.0"
8 xmlns:dyn="http://exslt.org/dynamic"
9 xmlns:saxon="http://icl.com/saxon"
10 exclude-result-prefixes="doc dyn saxon"
13 <!-- ********************************************************************
14 $Id: common.xsl 9965 2015-06-29 14:38:09Z tom_schr $
15 ********************************************************************
17 This file is part of the XSL DocBook Stylesheet distribution.
18 See ../README or http://docbook.sf.net/release/xsl/current/ for
19 copyright and other information.
21 ******************************************************************** -->
23 <doc:reference xmlns="" xml:id="base">
25 <title>Common » Base Template Reference</title>
26 <releaseinfo role="meta">
27 $Id: common.xsl 9965 2015-06-29 14:38:09Z tom_schr $
30 <!-- * yes, partintro is a valid child of a reference... -->
31 <partintro xml:id="partintro">
32 <title>Introduction</title>
33 <para>This is technical reference documentation for the “base”
34 set of common templates in the DocBook XSL Stylesheets.</para>
35 <para>This is not intended to be user documentation. It is
36 provided for developers writing customization layers for the
41 <!-- ==================================================================== -->
42 <!-- Establish strip/preserve whitespace rules -->
44 <xsl:preserve-space elements="*"/>
46 <xsl:strip-space elements="
47 abstract affiliation anchor answer appendix area areaset areaspec
48 artheader article audiodata audioobject author authorblurb authorgroup
49 beginpage bibliodiv biblioentry bibliography biblioset blockquote book
50 bookinfo callout calloutlist caption caution chapter
51 citerefentry cmdsynopsis co collab colophon colspec confgroup
52 copyright dedication docinfo editor entrytbl epigraph equation
53 example figure footnote footnoteref formalpara funcprototype
54 funcsynopsis glossary glossdef glossdiv glossentry glosslist graphicco
55 group highlights imagedata imageobject imageobjectco important index
56 indexdiv indexentry indexterm info informalequation informalexample
57 informalfigure informaltable inlineequation inlinemediaobject
58 itemizedlist itermset keycombo keywordset legalnotice listitem lot
59 mediaobject mediaobjectco menuchoice msg msgentry msgexplan msginfo
60 msgmain msgrel msgset msgsub msgtext note objectinfo
61 orderedlist othercredit part partintro preface printhistory procedure
62 programlistingco publisher qandadiv qandaentry qandaset question
63 refentry reference refmeta refnamediv refsection refsect1 refsect1info refsect2
64 refsect2info refsect3 refsect3info refsynopsisdiv refsynopsisdivinfo
65 revhistory revision row sbr screenco screenshot sect1 sect1info sect2
66 sect2info sect3 sect3info sect4 sect4info sect5 sect5info section
67 sectioninfo seglistitem segmentedlist seriesinfo set setindex setinfo
68 shortcut sidebar simplelist simplesect spanspec step subject
69 subjectset substeps synopfragment table tbody textobject tfoot tgroup
70 thead tip toc tocchap toclevel1 toclevel2 toclevel3 toclevel4
71 toclevel5 tocpart topic varargs variablelist varlistentry videodata
72 videoobject void warning subjectset
86 <!-- ====================================================================== -->
88 <doc:template name="is.component" xmlns="">
89 <refpurpose>Tests if a given node is a component-level element</refpurpose>
91 <refdescription id="is.component-desc">
92 <para>This template returns '1' if the specified node is a component
93 (Chapter, Appendix, etc.), and '0' otherwise.</para>
96 <refparameter id="is.component-params">
98 <varlistentry><term>node</term>
100 <para>The node which is to be tested.</para>
106 <refreturn id="is.component-returns">
107 <para>This template returns '1' if the specified node is a component
108 (Chapter, Appendix, etc.), and '0' otherwise.</para>
112 <xsl:template name="is.component">
113 <xsl:param name="node" select="."/>
115 <xsl:when test="local-name($node) = 'appendix'
116 or local-name($node) = 'article'
117 or local-name($node) = 'chapter'
118 or local-name($node) = 'preface'
119 or local-name($node) = 'bibliography'
120 or local-name($node) = 'glossary'
121 or local-name($node) = 'index'">1</xsl:when>
122 <xsl:otherwise>0</xsl:otherwise>
126 <!-- ====================================================================== -->
128 <doc:template name="is.section" xmlns="">
129 <refpurpose>Tests if a given node is a section-level element</refpurpose>
131 <refdescription id="is.section-desc">
132 <para>This template returns '1' if the specified node is a section
133 (Section, Sect1, Sect2, etc.), and '0' otherwise.</para>
136 <refparameter id="is.section-params">
138 <varlistentry><term>node</term>
140 <para>The node which is to be tested.</para>
146 <refreturn id="is.section-returns">
147 <para>This template returns '1' if the specified node is a section
148 (Section, Sect1, Sect2, etc.), and '0' otherwise.</para>
152 <xsl:template name="is.section">
153 <xsl:param name="node" select="."/>
155 <xsl:when test="local-name($node) = 'section'
156 or local-name($node) = 'sect1'
157 or local-name($node) = 'sect2'
158 or local-name($node) = 'sect3'
159 or local-name($node) = 'sect4'
160 or local-name($node) = 'sect5'
161 or local-name($node) = 'refsect1'
162 or local-name($node) = 'refsect2'
163 or local-name($node) = 'refsect3'
164 or local-name($node) = 'simplesect'">1</xsl:when>
165 <xsl:otherwise>0</xsl:otherwise>
169 <!-- ====================================================================== -->
171 <doc:template name="section.level" xmlns="">
172 <refpurpose>Returns the hierarchical level of a section</refpurpose>
174 <refdescription id="section.level-desc">
175 <para>This template calculates the hierarchical level of a section.
176 The element <tag>sect1</tag> is at level 1, <tag>sect2</tag> is
177 at level 2, etc.</para>
179 <para>Recursive sections are calculated down to the fifth level.</para>
182 <refparameter id="section.level-params">
184 <varlistentry><term>node</term>
186 <para>The section node for which the level should be calculated.
187 Defaults to the context node.</para>
193 <refreturn id="section.level-returns">
194 <para>The section level, <quote>1</quote>, <quote>2</quote>, etc.
199 <xsl:template name="section.level">
200 <xsl:param name="node" select="."/>
202 <xsl:when test="local-name($node)='sect1'">1</xsl:when>
203 <xsl:when test="local-name($node)='sect2'">2</xsl:when>
204 <xsl:when test="local-name($node)='sect3'">3</xsl:when>
205 <xsl:when test="local-name($node)='sect4'">4</xsl:when>
206 <xsl:when test="local-name($node)='sect5'">5</xsl:when>
207 <xsl:when test="local-name($node)='section'">
209 <xsl:when test="$node/../../../../../../section">6</xsl:when>
210 <xsl:when test="$node/../../../../../section">5</xsl:when>
211 <xsl:when test="$node/../../../../section">4</xsl:when>
212 <xsl:when test="$node/../../../section">3</xsl:when>
213 <xsl:when test="$node/../../section">2</xsl:when>
214 <xsl:otherwise>1</xsl:otherwise>
217 <xsl:when test="local-name($node)='refsect1' or
218 local-name($node)='refsect2' or
219 local-name($node)='refsect3' or
220 local-name($node)='refsection' or
221 local-name($node)='refsynopsisdiv'">
222 <xsl:call-template name="refentry.section.level">
223 <xsl:with-param name="node" select="$node"/>
226 <xsl:when test="local-name($node)='simplesect'">
228 <xsl:when test="$node/../../sect1">2</xsl:when>
229 <xsl:when test="$node/../../sect2">3</xsl:when>
230 <xsl:when test="$node/../../sect3">4</xsl:when>
231 <xsl:when test="$node/../../sect4">5</xsl:when>
232 <xsl:when test="$node/../../sect5">5</xsl:when>
233 <xsl:when test="$node/../../section">
235 <xsl:when test="$node/../../../../../section">5</xsl:when>
236 <xsl:when test="$node/../../../../section">4</xsl:when>
237 <xsl:when test="$node/../../../section">3</xsl:when>
238 <xsl:otherwise>2</xsl:otherwise>
241 <xsl:otherwise>1</xsl:otherwise>
244 <xsl:otherwise>1</xsl:otherwise>
246 </xsl:template><!-- section.level -->
248 <doc:template name="qanda.section.level" xmlns="">
249 <refpurpose>Returns the hierarchical level of a QandASet</refpurpose>
251 <refdescription id="qanda.section.level-desc">
252 <para>This template calculates the hierarchical level of a QandASet.
256 <refreturn id="qanda.section.level-returns">
257 <para>The level, <quote>1</quote>, <quote>2</quote>, etc.
262 <xsl:template name="qanda.section.level">
263 <xsl:variable name="section"
264 select="(ancestor::section
265 |ancestor::simplesect
273 |ancestor::refsect1)[last()]"/>
276 <xsl:when test="count($section) = '0'">1</xsl:when>
278 <xsl:variable name="slevel">
279 <xsl:call-template name="section.level">
280 <xsl:with-param name="node" select="$section"/>
283 <xsl:value-of select="$slevel + 1"/>
288 <!-- Finds the total section depth of a section in a refentry -->
289 <xsl:template name="refentry.section.level">
290 <xsl:param name="node" select="."/>
292 <xsl:variable name="RElevel">
293 <xsl:call-template name="refentry.level">
294 <xsl:with-param name="node" select="$node/ancestor::refentry[1]"/>
298 <xsl:variable name="levelinRE">
300 <xsl:when test="local-name($node)='refsynopsisdiv'">1</xsl:when>
301 <xsl:when test="local-name($node)='refsect1'">1</xsl:when>
302 <xsl:when test="local-name($node)='refsect2'">2</xsl:when>
303 <xsl:when test="local-name($node)='refsect3'">3</xsl:when>
304 <xsl:when test="local-name($node)='refsection'">
306 <xsl:when test="$node/../../../../../refsection">5</xsl:when>
307 <xsl:when test="$node/../../../../refsection">4</xsl:when>
308 <xsl:when test="$node/../../../refsection">3</xsl:when>
309 <xsl:when test="$node/../../refsection">2</xsl:when>
310 <xsl:otherwise>1</xsl:otherwise>
316 <xsl:value-of select="$levelinRE + $RElevel"/>
319 <!-- Finds the section depth of a refentry -->
320 <xsl:template name="refentry.level">
321 <xsl:param name="node" select="."/>
322 <xsl:variable name="container"
323 select="($node/ancestor::section |
324 $node/ancestor::sect1 |
325 $node/ancestor::sect2 |
326 $node/ancestor::sect3 |
327 $node/ancestor::sect4 |
328 $node/ancestor::sect5)[last()]"/>
331 <xsl:when test="$container">
332 <xsl:variable name="slevel">
333 <xsl:call-template name="section.level">
334 <xsl:with-param name="node" select="$container"/>
337 <xsl:value-of select="$slevel + 1"/>
339 <xsl:otherwise>1</xsl:otherwise>
343 <xsl:template name="qandadiv.section.level">
344 <xsl:variable name="section.level">
345 <xsl:call-template name="qanda.section.level"/>
347 <xsl:variable name="anc.divs" select="ancestor::qandadiv"/>
349 <xsl:value-of select="count($anc.divs) + number($section.level)"/>
352 <xsl:template name="question.answer.label">
353 <xsl:variable name="deflabel">
355 <xsl:when test="ancestor-or-self::*[@defaultlabel]">
356 <xsl:value-of select="(ancestor-or-self::*[@defaultlabel])[last()]
360 <xsl:value-of select="$qanda.defaultlabel"/>
365 <xsl:variable name="label" select="@label"/>
368 (hnr (hierarchical-number-recursive (normalize "qandadiv") node))
370 (parsect (ancestor-member node (section-element-list)))
372 (defnum (if (and %qanda-inherit-numeration%
374 (if (node-list-empty? parsect)
375 (section-autolabel-prefix node)
376 (section-autolabel parsect))
379 (hnumber (let loop ((numlist hnr) (number defnum)
380 (sep (if (equal? defnum "") "" ".")))
384 (string-append number
386 (number->string (car numlist)))
388 (cnumber (child-number (parent node)))
389 (number (string-append hnumber
390 (if (equal? hnumber "")
393 (number->string cnumber))))
397 <xsl:when test="$deflabel = 'qanda'">
398 <xsl:call-template name="gentext">
399 <xsl:with-param name="key">
401 <xsl:when test="local-name(.) = 'question'">question</xsl:when>
402 <xsl:when test="local-name(.) = 'answer'">answer</xsl:when>
403 <xsl:when test="local-name(.) = 'qandadiv'">qandadiv</xsl:when>
404 <xsl:otherwise>qandaset</xsl:otherwise>
409 <xsl:when test="$deflabel = 'label'">
410 <xsl:value-of select="$label"/>
412 <xsl:when test="$deflabel = 'number'
413 and local-name(.) = 'question'">
414 <xsl:apply-templates select="ancestor::qandaset[1]"
417 <xsl:when test="ancestor::qandadiv">
418 <xsl:apply-templates select="ancestor::qandadiv[1]"
420 <xsl:apply-templates select="ancestor::qandaentry"
424 <xsl:apply-templates select="ancestor::qandaentry"
435 <xsl:template match="qandaset" mode="number">
439 <xsl:template match="qandadiv" mode="number">
440 <xsl:number level="multiple" from="qandaset" format="1."/>
443 <xsl:template match="qandaentry" mode="number">
445 <xsl:when test="ancestor::qandadiv">
446 <xsl:number level="single" from="qandadiv" format="1."/>
449 <xsl:number level="single" from="qandaset" format="1."/>
454 <!-- ====================================================================== -->
456 <xsl:template name="object.id">
457 <xsl:param name="object" select="."/>
459 <xsl:when test="$object/@id">
460 <xsl:value-of select="$object/@id"/>
462 <xsl:when test="$object/@xml:id">
463 <xsl:value-of select="$object/@xml:id"/>
465 <xsl:when test="$generate.consistent.ids != 0">
466 <!-- Make $object the current node -->
467 <xsl:for-each select="$object">
468 <xsl:text>id-</xsl:text>
469 <xsl:number level="multiple" count="*"/>
473 <xsl:value-of select="generate-id($object)"/>
478 <xsl:template name="person.name">
479 <!-- Formats a personal name. Handles corpauthor as a special case. -->
480 <xsl:param name="node" select="."/>
482 <xsl:param name="style">
484 <xsl:when test="$node/@role">
485 <xsl:value-of select="$node/@role"/>
488 <xsl:call-template name="gentext.template">
489 <xsl:with-param name="context" select="'styles'"/>
490 <xsl:with-param name="name" select="'person-name'"/>
497 <!-- the personname element is a specialcase -->
498 <xsl:when test="$node/personname">
499 <xsl:call-template name="person.name">
500 <xsl:with-param name="node" select="$node/personname"/>
504 <!-- handle corpauthor as a special case...-->
505 <!-- * MikeSmith 2007-06: I'm wondering if the person.name template -->
506 <!-- * actually ever gets called to handle corpauthor.. maybe -->
507 <!-- * we don't actually need to check for corpauthor here. -->
508 <xsl:when test="local-name($node)='corpauthor'">
509 <xsl:apply-templates select="$node"/>
514 <!-- Handle case when personname contains only general markup (DocBook 5.0) -->
515 <xsl:when test="$node/self::personname and not($node/firstname or $node/honorific or $node/lineage or $node/othername or $node/surname)">
516 <xsl:apply-templates select="$node/node()"/>
518 <xsl:when test="$style = 'family-given'">
519 <xsl:call-template name="person.name.family-given">
520 <xsl:with-param name="node" select="$node"/>
523 <xsl:when test="$style = 'last-first'">
524 <xsl:call-template name="person.name.last-first">
525 <xsl:with-param name="node" select="$node"/>
529 <xsl:call-template name="person.name.first-last">
530 <xsl:with-param name="node" select="$node"/>
538 <xsl:template name="person.name.family-given">
539 <xsl:param name="node" select="."/>
541 <!-- The family-given style applies a convention for identifying given -->
542 <!-- and family names in locales where it may be ambiguous -->
543 <xsl:apply-templates select="$node//surname[1]"/>
545 <xsl:if test="$node//surname and $node//firstname">
546 <xsl:text> </xsl:text>
549 <xsl:apply-templates select="$node//firstname[1]"/>
551 <xsl:text> [FAMILY Given]</xsl:text>
554 <xsl:template name="person.name.last-first">
555 <xsl:param name="node" select="."/>
557 <xsl:apply-templates select="$node//surname[1]"/>
559 <xsl:if test="$node//surname and $node//firstname">
560 <xsl:text>, </xsl:text>
563 <xsl:apply-templates select="$node//firstname[1]"/>
566 <xsl:template name="person.name.first-last">
567 <xsl:param name="node" select="."/>
569 <xsl:if test="$node//honorific">
570 <xsl:apply-templates select="$node//honorific[1]"/>
571 <xsl:value-of select="$punct.honorific"/>
574 <xsl:if test="$node//firstname">
575 <xsl:if test="$node//honorific">
576 <xsl:text> </xsl:text>
578 <xsl:apply-templates select="$node//firstname[1]"/>
581 <xsl:if test="$node//othername and $author.othername.in.middle != 0">
582 <xsl:if test="$node//honorific or $node//firstname">
583 <xsl:text> </xsl:text>
585 <xsl:apply-templates select="$node//othername[1]"/>
588 <xsl:if test="$node//surname">
589 <xsl:if test="$node//honorific or $node//firstname
590 or ($node//othername and $author.othername.in.middle != 0)">
591 <xsl:text> </xsl:text>
593 <xsl:apply-templates select="$node//surname[1]"/>
596 <xsl:if test="$node//lineage">
597 <xsl:text>, </xsl:text>
598 <xsl:apply-templates select="$node//lineage[1]"/>
602 <xsl:template name="person.name.list">
603 <!-- Return a formatted string representation of the contents of
604 the current element. The current element must contain one or
605 more AUTHORs, CORPAUTHORs, OTHERCREDITs, and/or EDITORs.
609 John Doe and Jane Doe
611 John Doe, Jane Doe, and A. Nonymous
613 <xsl:param name="person.list"
614 select="author|corpauthor|othercredit|editor"/>
615 <xsl:param name="person.count" select="count($person.list)"/>
616 <xsl:param name="count" select="1"/>
619 <xsl:when test="$count > $person.count"></xsl:when>
621 <xsl:call-template name="person.name">
622 <xsl:with-param name="node" select="$person.list[position()=$count]"/>
626 <xsl:when test="$person.count = 2 and $count = 1">
627 <xsl:call-template name="gentext.template">
628 <xsl:with-param name="context" select="'authorgroup'"/>
629 <xsl:with-param name="name" select="'sep2'"/>
632 <xsl:when test="$person.count > 2 and $count+1 = $person.count">
633 <xsl:call-template name="gentext.template">
634 <xsl:with-param name="context" select="'authorgroup'"/>
635 <xsl:with-param name="name" select="'seplast'"/>
638 <xsl:when test="$count < $person.count">
639 <xsl:call-template name="gentext.template">
640 <xsl:with-param name="context" select="'authorgroup'"/>
641 <xsl:with-param name="name" select="'sep'"/>
646 <xsl:call-template name="person.name.list">
647 <xsl:with-param name="person.list" select="$person.list"/>
648 <xsl:with-param name="person.count" select="$person.count"/>
649 <xsl:with-param name="count" select="$count+1"/>
653 </xsl:template><!-- person.name.list -->
655 <!-- === synopsis ======================================================= -->
656 <!-- The following definitions match those given in the reference
657 documentation for DocBook V3.0
660 <xsl:param name="arg.choice.opt.open.str">[</xsl:param>
661 <xsl:param name="arg.choice.opt.close.str">]</xsl:param>
662 <xsl:param name="arg.choice.req.open.str">{</xsl:param>
663 <xsl:param name="arg.choice.req.close.str">}</xsl:param>
664 <xsl:param name="arg.choice.plain.open.str"><xsl:text> </xsl:text></xsl:param>
665 <xsl:param name="arg.choice.plain.close.str"><xsl:text> </xsl:text></xsl:param>
666 <xsl:param name="arg.choice.def.open.str">[</xsl:param>
667 <xsl:param name="arg.choice.def.close.str">]</xsl:param>
668 <xsl:param name="arg.rep.repeat.str">...</xsl:param>
669 <xsl:param name="arg.rep.norepeat.str"></xsl:param>
670 <xsl:param name="arg.rep.def.str"></xsl:param>
671 <xsl:param name="arg.or.sep"> | </xsl:param>
672 <xsl:param name="cmdsynopsis.hanging.indent">4pi</xsl:param>
674 <!-- ====================================================================== -->
677 <xsl:template name="xref.g.subst">
678 <xsl:param name="string"></xsl:param>
679 <xsl:param name="target" select="."/>
680 <xsl:variable name="subst">%g</xsl:variable>
683 <xsl:when test="contains($string, $subst)">
684 <xsl:value-of select="substring-before($string, $subst)"/>
685 <xsl:call-template name="gentext.element.name">
686 <xsl:with-param name="element.name" select="local-name($target)"/>
688 <xsl:call-template name="xref.g.subst">
689 <xsl:with-param name="string"
690 select="substring-after($string, $subst)"/>
691 <xsl:with-param name="target" select="$target"/>
695 <xsl:value-of select="$string"/>
700 <xsl:template name="xref.t.subst">
701 <xsl:param name="string"></xsl:param>
702 <xsl:param name="target" select="."/>
703 <xsl:variable name="subst">%t</xsl:variable>
706 <xsl:when test="contains($string, $subst)">
707 <xsl:call-template name="xref.g.subst">
708 <xsl:with-param name="string"
709 select="substring-before($string, $subst)"/>
710 <xsl:with-param name="target" select="$target"/>
712 <xsl:call-template name="title.xref">
713 <xsl:with-param name="target" select="$target"/>
715 <xsl:call-template name="xref.t.subst">
716 <xsl:with-param name="string"
717 select="substring-after($string, $subst)"/>
718 <xsl:with-param name="target" select="$target"/>
722 <xsl:call-template name="xref.g.subst">
723 <xsl:with-param name="string" select="$string"/>
724 <xsl:with-param name="target" select="$target"/>
730 <xsl:template name="xref.n.subst">
731 <xsl:param name="string"></xsl:param>
732 <xsl:param name="target" select="."/>
733 <xsl:variable name="subst">%n</xsl:variable>
736 <xsl:when test="contains($string, $subst)">
737 <xsl:call-template name="xref.t.subst">
738 <xsl:with-param name="string"
739 select="substring-before($string, $subst)"/>
740 <xsl:with-param name="target" select="$target"/>
742 <xsl:call-template name="number.xref">
743 <xsl:with-param name="target" select="$target"/>
745 <xsl:call-template name="xref.t.subst">
746 <xsl:with-param name="string"
747 select="substring-after($string, $subst)"/>
748 <xsl:with-param name="target" select="$target"/>
752 <xsl:call-template name="xref.t.subst">
753 <xsl:with-param name="string" select="$string"/>
754 <xsl:with-param name="target" select="$target"/>
760 <xsl:template name="subst.xref.text">
761 <xsl:param name="xref.text"></xsl:param>
762 <xsl:param name="target" select="."/>
764 <xsl:call-template name="xref.n.subst">
765 <xsl:with-param name="string" select="$xref.text"/>
766 <xsl:with-param name="target" select="$target"/>
771 <!-- ====================================================================== -->
773 <xsl:template name="filename-basename">
774 <!-- We assume all filenames are really URIs and use "/" -->
775 <xsl:param name="filename"></xsl:param>
776 <xsl:param name="recurse" select="false()"/>
779 <xsl:when test="substring-after($filename, '/') != ''">
780 <xsl:call-template name="filename-basename">
781 <xsl:with-param name="filename"
782 select="substring-after($filename, '/')"/>
783 <xsl:with-param name="recurse" select="true()"/>
787 <xsl:value-of select="$filename"/>
792 <xsl:template name="filename-extension">
793 <xsl:param name="filename"></xsl:param>
794 <xsl:param name="recurse" select="false()"/>
796 <!-- Make sure we only look at the base name... -->
797 <xsl:variable name="basefn">
799 <xsl:when test="$recurse">
800 <xsl:value-of select="$filename"/>
803 <xsl:call-template name="filename-basename">
804 <xsl:with-param name="filename" select="$filename"/>
811 <xsl:when test="substring-after($basefn, '.') != ''">
812 <xsl:call-template name="filename-extension">
813 <xsl:with-param name="filename"
814 select="substring-after($basefn, '.')"/>
815 <xsl:with-param name="recurse" select="true()"/>
818 <xsl:when test="$recurse">
819 <xsl:value-of select="$basefn"/>
821 <xsl:otherwise></xsl:otherwise>
825 <!-- ====================================================================== -->
827 <doc:template name="select.mediaobject" xmlns="">
828 <refpurpose>Selects and processes an appropriate media object from a list</refpurpose>
830 <refdescription id="select.mediaobject-desc">
831 <para>This template takes a list of media objects (usually the
832 children of a mediaobject or inlinemediaobject) and processes
833 the "right" object.</para>
835 <para>This template relies on a template named
836 "select.mediaobject.index" to determine which object
837 in the list is appropriate.</para>
839 <para>If no acceptable object is located, nothing happens.</para>
842 <refparameter id="select.mediaobject-params">
844 <varlistentry><term>olist</term>
846 <para>The node list of potential objects to examine.</para>
852 <refreturn id="select.mediaobject-returns">
853 <para>Calls <xsl:apply-templates> on the selected object.</para>
857 <xsl:template name="select.mediaobject">
858 <xsl:param name="olist"
859 select="imageobject|imageobjectco
860 |videoobject|audioobject|textobject"/>
862 <xsl:variable name="mediaobject.index">
863 <xsl:call-template name="select.mediaobject.index">
864 <xsl:with-param name="olist" select="$olist"/>
865 <xsl:with-param name="count" select="1"/>
869 <xsl:if test="$mediaobject.index != ''">
870 <xsl:apply-templates select="$olist[position() = $mediaobject.index]"/>
874 <!-- ====================================================================== -->
876 <doc:template name="select.mediaobject.index" xmlns="">
877 <refpurpose>Selects the position of the appropriate media object from a list</refpurpose>
879 <refdescription id="select.mediaobject.index-desc">
880 <para>This template takes a list of media objects (usually the
881 children of a mediaobject or inlinemediaobject) and determines
882 the "right" object. It returns the position of that object
883 to be used by the calling template.</para>
885 <para>If the parameter <parameter>use.role.for.mediaobject</parameter>
886 is nonzero, then it first checks for an object with
887 a role attribute of the appropriate value. It takes the first
888 of those. Otherwise, it takes the first acceptable object
889 through a recursive pass through the list.</para>
891 <para>This template relies on a template named "is.acceptable.mediaobject"
892 to determine if a given object is an acceptable graphic. The semantics
893 of media objects is that the first acceptable graphic should be used.
896 <para>If no acceptable object is located, no index is returned.</para>
899 <refparameter id="select.mediaobject.index-params">
901 <varlistentry><term>olist</term>
903 <para>The node list of potential objects to examine.</para>
906 <varlistentry><term>count</term>
908 <para>The position in the list currently being considered by the
909 recursive process.</para>
915 <refreturn id="select.mediaobject.index-returns">
916 <para>Returns the position in the original list of the selected object.</para>
920 <xsl:template name="select.mediaobject.index">
921 <xsl:param name="olist"
922 select="imageobject|imageobjectco
923 |videoobject|audioobject|textobject"/>
924 <xsl:param name="count">1</xsl:param>
927 <!-- Test for objects preferred by role -->
928 <xsl:when test="$use.role.for.mediaobject != 0
929 and $preferred.mediaobject.role != ''
930 and $olist[@role = $preferred.mediaobject.role]">
932 <!-- Get the first hit's position index -->
933 <xsl:for-each select="$olist">
934 <xsl:if test="@role = $preferred.mediaobject.role and
935 not(preceding-sibling::*[@role = $preferred.mediaobject.role])">
936 <xsl:value-of select="position()"/>
941 <xsl:when test="$use.role.for.mediaobject != 0
942 and $olist[@role = $stylesheet.result.type]">
943 <!-- Get the first hit's position index -->
944 <xsl:for-each select="$olist">
945 <xsl:if test="@role = $stylesheet.result.type and
946 not(preceding-sibling::*[@role = $stylesheet.result.type])">
947 <xsl:value-of select="position()"/>
951 <!-- Accept 'html' for $stylesheet.result.type = 'xhtml' -->
952 <xsl:when test="$use.role.for.mediaobject != 0
953 and $stylesheet.result.type = 'xhtml'
954 and $olist[@role = 'html']">
955 <!-- Get the first hit's position index -->
956 <xsl:for-each select="$olist">
957 <xsl:if test="@role = 'html' and
958 not(preceding-sibling::*[@role = 'html'])">
959 <xsl:value-of select="position()"/>
964 <!-- If no selection by role, and there is only one object, use it -->
965 <xsl:when test="count($olist) = 1 and $count = 1">
966 <xsl:value-of select="$count"/>
970 <!-- Otherwise select first acceptable object -->
971 <xsl:if test="$count <= count($olist)">
972 <xsl:variable name="object" select="$olist[position()=$count]"/>
974 <xsl:variable name="useobject">
976 <!-- select videoobject or audioobject before textobject -->
977 <xsl:when test="local-name($object) = 'videoobject'">
978 <xsl:text>1</xsl:text>
980 <xsl:when test="local-name($object) = 'audioobject'">
981 <xsl:text>1</xsl:text>
983 <!-- skip textobject if also video, audio, or image out of order -->
984 <xsl:when test="local-name($object) = 'textobject' and
988 <xsl:text>0</xsl:text>
990 <!-- The phrase is used only when contains TeX Math and output is FO -->
991 <xsl:when test="local-name($object)='textobject' and $object/phrase
992 and $object/@role='tex' and $stylesheet.result.type = 'fo'
993 and $tex.math.in.alt != ''">
994 <xsl:text>1</xsl:text>
996 <!-- The phrase is never used -->
997 <xsl:when test="local-name($object)='textobject' and $object/phrase">
998 <xsl:text>0</xsl:text>
1000 <xsl:when test="local-name($object)='textobject'
1001 and $object/ancestor::equation ">
1002 <!-- The first textobject is not a reasonable fallback
1003 for equation image -->
1004 <xsl:text>0</xsl:text>
1006 <!-- The first textobject is a reasonable fallback -->
1007 <xsl:when test="local-name($object)='textobject'
1008 and $object[not(@role) or @role!='tex']">
1009 <xsl:text>1</xsl:text>
1011 <!-- don't use graphic when output is FO, TeX Math is used
1012 and there is math in alt element -->
1013 <xsl:when test="$object/ancestor::equation and
1014 $object/ancestor::equation/alt[@role='tex']
1015 and $stylesheet.result.type = 'fo'
1016 and $tex.math.in.alt != ''">
1017 <xsl:text>0</xsl:text>
1019 <!-- If there's only one object, use it -->
1020 <xsl:when test="$count = 1 and count($olist) = 1">
1021 <xsl:text>1</xsl:text>
1023 <!-- Otherwise, see if this one is a useable graphic -->
1026 <!-- peek inside imageobjectco to simplify the test -->
1027 <xsl:when test="local-name($object) = 'imageobjectco'">
1028 <xsl:call-template name="is.acceptable.mediaobject">
1029 <xsl:with-param name="object" select="$object/imageobject"/>
1030 </xsl:call-template>
1033 <xsl:call-template name="is.acceptable.mediaobject">
1034 <xsl:with-param name="object" select="$object"/>
1035 </xsl:call-template>
1043 <xsl:when test="$useobject='1'">
1044 <xsl:value-of select="$count"/>
1047 <xsl:call-template name="select.mediaobject.index">
1048 <xsl:with-param name="olist" select="$olist"/>
1049 <xsl:with-param name="count" select="$count + 1"/>
1050 </xsl:call-template>
1058 <doc:template name="is.acceptable.mediaobject" xmlns="">
1059 <refpurpose>Returns '1' if the specified media object is recognized</refpurpose>
1061 <refdescription id="is.acceptable.mediaobject-desc">
1062 <para>This template examines a media object and returns '1' if the
1063 object is recognized as a graphic.</para>
1066 <refparameter id="is.acceptable.mediaobject-params">
1068 <varlistentry><term>object</term>
1070 <para>The media object to consider.</para>
1076 <refreturn id="is.acceptable.mediaobject-returns">
1081 <xsl:template name="is.acceptable.mediaobject">
1082 <xsl:param name="object"></xsl:param>
1084 <xsl:variable name="filename">
1085 <xsl:call-template name="mediaobject.filename">
1086 <xsl:with-param name="object" select="$object"/>
1087 </xsl:call-template>
1090 <xsl:variable name="ext">
1091 <xsl:call-template name="filename-extension">
1092 <xsl:with-param name="filename" select="$filename"/>
1093 </xsl:call-template>
1096 <!-- there will only be one -->
1097 <xsl:variable name="data" select="$object/videodata
1099 |$object/audiodata"/>
1101 <xsl:variable name="format" select="$data/@format"/>
1103 <xsl:variable name="graphic.format">
1104 <xsl:if test="$format">
1105 <xsl:call-template name="is.graphic.format">
1106 <xsl:with-param name="format" select="$format"/>
1107 </xsl:call-template>
1111 <xsl:variable name="graphic.ext">
1112 <xsl:if test="$ext">
1113 <xsl:call-template name="is.graphic.extension">
1114 <xsl:with-param name="ext" select="$ext"/>
1115 </xsl:call-template>
1120 <xsl:when test="$use.svg = 0 and $format = 'SVG'">0</xsl:when>
1121 <xsl:when xmlns:svg="http://www.w3.org/2000/svg"
1122 test="$use.svg != 0 and $object/svg:*">1</xsl:when>
1123 <xsl:when test="$graphic.format = '1'">1</xsl:when>
1124 <xsl:when test="$graphic.ext = '1'">1</xsl:when>
1125 <xsl:otherwise>0</xsl:otherwise>
1129 <xsl:template name="mediaobject.filename">
1130 <xsl:param name="object"></xsl:param>
1132 <xsl:variable name="data" select="$object/videodata
1137 <xsl:variable name="filename">
1139 <xsl:when test="$data[@fileref]">
1140 <xsl:apply-templates select="$data/@fileref"/>
1142 <xsl:when test="$data[@entityref]">
1143 <xsl:value-of select="unparsed-entity-uri($data/@entityref)"/>
1145 <xsl:otherwise></xsl:otherwise>
1149 <xsl:variable name="real.ext">
1150 <xsl:call-template name="filename-extension">
1151 <xsl:with-param name="filename" select="$filename"/>
1152 </xsl:call-template>
1155 <xsl:variable name="ext">
1157 <xsl:when test="$real.ext != ''">
1158 <xsl:value-of select="$real.ext"/>
1161 <xsl:value-of select="$graphic.default.extension"/>
1166 <xsl:variable name="graphic.ext">
1167 <xsl:call-template name="is.graphic.extension">
1168 <xsl:with-param name="ext" select="$ext"/>
1169 </xsl:call-template>
1173 <xsl:when test="$real.ext = ''">
1175 <xsl:when test="$ext != ''">
1176 <xsl:value-of select="$filename"/>
1177 <xsl:text>.</xsl:text>
1178 <xsl:value-of select="$ext"/>
1181 <xsl:value-of select="$filename"/>
1185 <xsl:when test="not($graphic.ext)">
1187 <xsl:when test="$graphic.default.extension != ''">
1188 <xsl:value-of select="$filename"/>
1189 <xsl:text>.</xsl:text>
1190 <xsl:value-of select="$graphic.default.extension"/>
1193 <xsl:value-of select="$filename"/>
1198 <xsl:value-of select="$filename"/>
1203 <!-- ====================================================================== -->
1205 <doc:template name="check.id.unique" xmlns="">
1206 <refpurpose>Warn users about references to non-unique IDs</refpurpose>
1207 <refdescription id="check.id.unique-desc">
1208 <para>If passed an ID in <varname>linkend</varname>,
1209 <function>check.id.unique</function> prints
1210 a warning message to the user if either the ID does not exist or
1211 the ID is not unique.</para>
1215 <xsl:template name="check.id.unique">
1216 <xsl:param name="linkend"></xsl:param>
1217 <xsl:if test="$linkend != ''">
1218 <xsl:variable name="targets" select="key('id',$linkend)"/>
1219 <xsl:variable name="target" select="$targets[1]"/>
1221 <xsl:if test="count($targets)=0">
1223 <xsl:text>Error: no ID for constraint linkend: </xsl:text>
1224 <xsl:value-of select="concat('"', $linkend, '"')"/>
1225 <xsl:text>.</xsl:text>
1229 <xsl:text>If the ID exists in your document, did your </xsl:text>
1230 <xsl:text>XSLT Processor load the DTD?</xsl:text>
1235 <xsl:if test="count($targets)>1">
1237 <xsl:text>Warning: multiple "IDs" for constraint linkend: </xsl:text>
1238 <xsl:value-of select="$linkend"/>
1239 <xsl:text>.</xsl:text>
1245 <doc:template name="check.idref.targets" xmlns="">
1246 <refpurpose>Warn users about incorrectly typed references</refpurpose>
1247 <refdescription id="check.idref.targets-desc">
1248 <para>If passed an ID in <varname>linkend</varname>,
1249 <function>check.idref.targets</function> makes sure that the element
1250 pointed to by the link is one of the elements listed in
1251 <varname>element-list</varname> and warns the user otherwise.</para>
1255 <xsl:template name="check.idref.targets">
1256 <xsl:param name="linkend"></xsl:param>
1257 <xsl:param name="element-list"></xsl:param>
1258 <xsl:if test="$linkend != ''">
1259 <xsl:variable name="targets" select="key('id',$linkend)"/>
1260 <xsl:variable name="target" select="$targets[1]"/>
1262 <xsl:if test="count($target) > 0">
1263 <xsl:if test="not(contains(concat(' ', $element-list, ' '), local-name($target)))">
1265 <xsl:text>Error: linkend (</xsl:text>
1266 <xsl:value-of select="$linkend"/>
1267 <xsl:text>) points to "</xsl:text>
1268 <xsl:value-of select="local-name($target)"/>
1269 <xsl:text>" not (one of): </xsl:text>
1270 <xsl:value-of select="$element-list"/>
1277 <!-- ====================================================================== -->
1278 <!-- Procedure Step Numeration -->
1280 <xsl:param name="procedure.step.numeration.formats" select="'1aiAI'"/>
1282 <xsl:template name="procedure.step.numeration">
1283 <xsl:param name="context" select="."/>
1284 <xsl:variable name="format.length"
1285 select="string-length($procedure.step.numeration.formats)"/>
1287 <xsl:when test="local-name($context) = 'substeps'">
1288 <xsl:variable name="ssdepth"
1289 select="count($context/ancestor::substeps)"/>
1290 <xsl:variable name="sstype" select="($ssdepth mod $format.length)+2"/>
1292 <xsl:when test="$sstype > $format.length">
1293 <xsl:value-of select="substring($procedure.step.numeration.formats,1,1)"/>
1296 <xsl:value-of select="substring($procedure.step.numeration.formats,$sstype,1)"/>
1300 <xsl:when test="local-name($context) = 'step'">
1301 <xsl:variable name="sdepth"
1302 select="count($context/ancestor::substeps)"/>
1303 <xsl:variable name="stype" select="($sdepth mod $format.length)+1"/>
1304 <xsl:value-of select="substring($procedure.step.numeration.formats,$stype,1)"/>
1308 <xsl:text>Unexpected context in procedure.step.numeration: </xsl:text>
1309 <xsl:value-of select="local-name($context)"/>
1315 <xsl:template match="step" mode="number">
1316 <xsl:param name="rest" select="''"/>
1317 <xsl:param name="recursive" select="1"/>
1318 <xsl:variable name="format">
1319 <xsl:call-template name="procedure.step.numeration"/>
1321 <xsl:variable name="num">
1322 <xsl:number count="step" format="{$format}"/>
1325 <xsl:when test="$recursive != 0 and ancestor::step">
1326 <xsl:apply-templates select="ancestor::step[1]" mode="number">
1327 <xsl:with-param name="rest" select="concat('.', $num, $rest)"/>
1328 </xsl:apply-templates>
1331 <xsl:value-of select="concat($num, $rest)"/>
1336 <!-- ====================================================================== -->
1337 <!-- OrderedList Numeration -->
1338 <xsl:template name="output-orderedlist-starting-number">
1339 <xsl:param name="list"/>
1340 <xsl:param name="pi-start"/>
1342 <xsl:when test="not($list/@continuation = 'continues')">
1344 <xsl:when test="$list/@startingnumber">
1345 <xsl:value-of select="$list/@startingnumber"/>
1347 <xsl:when test="$pi-start != ''">
1348 <xsl:value-of select="$pi-start"/>
1350 <xsl:otherwise>1</xsl:otherwise>
1354 <!-- match on previous list at same nesting level -->
1355 <xsl:variable name="prevlist"
1356 select="$list/preceding::orderedlist
1357 [count($list/ancestor::orderedlist) = count(ancestor::orderedlist)][1]"/>
1359 <xsl:when test="count($prevlist) = 0">2</xsl:when>
1361 <xsl:variable name="prevlength" select="count($prevlist/listitem)"/>
1362 <xsl:variable name="prevstart">
1363 <xsl:call-template name="orderedlist-starting-number">
1364 <xsl:with-param name="list" select="$prevlist"/>
1365 </xsl:call-template>
1367 <xsl:value-of select="$prevstart + $prevlength"/>
1374 <xsl:template name="orderedlist-item-number">
1375 <!-- context node must be a listitem in an orderedlist -->
1376 <xsl:param name="node" select="."/>
1378 <xsl:when test="$node/@override">
1379 <xsl:value-of select="$node/@override"/>
1381 <xsl:when test="$node/preceding-sibling::listitem">
1382 <xsl:variable name="pnum">
1383 <xsl:call-template name="orderedlist-item-number">
1384 <xsl:with-param name="node" select="$node/preceding-sibling::listitem[1]"/>
1385 </xsl:call-template>
1387 <xsl:value-of select="$pnum + 1"/>
1390 <xsl:call-template name="orderedlist-starting-number">
1391 <xsl:with-param name="list" select="parent::*"/>
1392 </xsl:call-template>
1397 <xsl:template name="next.numeration">
1398 <xsl:param name="numeration" select="'default'"/>
1400 <!-- Change this list if you want to change the order of numerations -->
1401 <xsl:when test="$numeration = 'arabic'">loweralpha</xsl:when>
1402 <xsl:when test="$numeration = 'loweralpha'">lowerroman</xsl:when>
1403 <xsl:when test="$numeration = 'lowerroman'">upperalpha</xsl:when>
1404 <xsl:when test="$numeration = 'upperalpha'">upperroman</xsl:when>
1405 <xsl:when test="$numeration = 'upperroman'">arabic</xsl:when>
1406 <xsl:otherwise>arabic</xsl:otherwise>
1410 <xsl:template name="list.numeration">
1411 <xsl:param name="node" select="."/>
1414 <xsl:when test="$node/@numeration">
1415 <xsl:value-of select="$node/@numeration"/>
1419 <xsl:when test="$node/ancestor::orderedlist">
1420 <xsl:call-template name="next.numeration">
1421 <xsl:with-param name="numeration">
1422 <xsl:call-template name="list.numeration">
1423 <xsl:with-param name="node" select="$node/ancestor::orderedlist[1]"/>
1424 </xsl:call-template>
1426 </xsl:call-template>
1429 <xsl:call-template name="next.numeration"/>
1436 <xsl:template match="orderedlist/listitem" mode="item-number">
1437 <xsl:variable name="numeration">
1438 <xsl:call-template name="list.numeration">
1439 <xsl:with-param name="node" select="parent::orderedlist"/>
1440 </xsl:call-template>
1443 <xsl:variable name="type">
1445 <xsl:when test="$numeration='arabic'">1.</xsl:when>
1446 <xsl:when test="$numeration='loweralpha'">a.</xsl:when>
1447 <xsl:when test="$numeration='lowerroman'">i.</xsl:when>
1448 <xsl:when test="$numeration='upperalpha'">A.</xsl:when>
1449 <xsl:when test="$numeration='upperroman'">I.</xsl:when>
1450 <!-- What!? This should never happen -->
1453 <xsl:text>Unexpected numeration: </xsl:text>
1454 <xsl:value-of select="$numeration"/>
1456 <xsl:value-of select="1."/>
1461 <xsl:variable name="item-number">
1462 <xsl:call-template name="orderedlist-item-number"/>
1465 <xsl:if test="parent::orderedlist/@inheritnum='inherit'
1466 and ancestor::listitem[parent::orderedlist]">
1467 <xsl:apply-templates select="ancestor::listitem[parent::orderedlist][1]"
1468 mode="item-number"/>
1471 <xsl:number value="$item-number" format="{$type}"/>
1474 <!-- ====================================================================== -->
1475 <!-- ItemizedList "Numeration" -->
1477 <xsl:template name="next.itemsymbol">
1478 <xsl:param name="itemsymbol" select="'default'"/>
1480 <!-- Change this list if you want to change the order of symbols -->
1481 <xsl:when test="$itemsymbol = 'disc'">circle</xsl:when>
1482 <xsl:when test="$itemsymbol = 'circle'">square</xsl:when>
1483 <xsl:otherwise>disc</xsl:otherwise>
1487 <xsl:template name="list.itemsymbol">
1488 <xsl:param name="node" select="."/>
1491 <xsl:when test="@override">
1492 <xsl:value-of select="@override"/>
1494 <xsl:when test="$node/@mark">
1495 <xsl:value-of select="$node/@mark"/>
1499 <xsl:when test="$node/ancestor::itemizedlist">
1500 <xsl:call-template name="next.itemsymbol">
1501 <xsl:with-param name="itemsymbol">
1502 <xsl:call-template name="list.itemsymbol">
1503 <xsl:with-param name="node" select="$node/ancestor::itemizedlist[1]"/>
1504 </xsl:call-template>
1506 </xsl:call-template>
1509 <xsl:call-template name="next.itemsymbol"/>
1516 <!-- ====================================================================== -->
1518 <doc:template name="copyright.years" xmlns="">
1519 <refpurpose>Print a set of years with collapsed ranges</refpurpose>
1521 <refdescription id="copyright.years-desc">
1522 <para>This template prints a list of year elements with consecutive
1523 years printed as a range. In other words:</para>
1525 <screen><![CDATA[<year>1992</year>
1527 <year>1994</year>]]></screen>
1529 <para>is printed <quote>1992-1994</quote>, whereas:</para>
1531 <screen><![CDATA[<year>1992</year>
1532 <year>1994</year>]]></screen>
1534 <para>is printed <quote>1992, 1994</quote>.</para>
1536 <para>This template assumes that all the year elements contain only
1537 decimal year numbers, that the elements are sorted in increasing
1538 numerical order, that there are no duplicates, and that all the years
1539 are expressed in full <quote>century+year</quote>
1540 (<quote>1999</quote> not <quote>99</quote>) notation.</para>
1543 <refparameter id="copyright.years-params">
1545 <varlistentry><term>years</term>
1547 <para>The initial set of year elements.</para>
1550 <varlistentry><term>print.ranges</term>
1552 <para>If non-zero, multi-year ranges are collapsed. If zero, all years
1553 are printed discretely.</para>
1556 <varlistentry><term>single.year.ranges</term>
1558 <para>If non-zero, two consecutive years will be printed as a range,
1559 otherwise, they will be printed discretely. In other words, a single
1560 year range is <quote>1991-1992</quote> but discretely it's
1561 <quote>1991, 1992</quote>.</para>
1567 <refreturn id="copyright.years-returns">
1568 <para>This template returns the formatted list of years.</para>
1572 <xsl:template name="copyright.years">
1573 <xsl:param name="years"/>
1574 <xsl:param name="print.ranges" select="1"/>
1575 <xsl:param name="single.year.ranges" select="0"/>
1576 <xsl:param name="firstyear" select="0"/>
1577 <xsl:param name="nextyear" select="0"/>
1580 <xsl:message terminate="no">
1581 <xsl:text>CY: </xsl:text>
1582 <xsl:value-of select="count($years)"/>
1583 <xsl:text>, </xsl:text>
1584 <xsl:value-of select="$firstyear"/>
1585 <xsl:text>, </xsl:text>
1586 <xsl:value-of select="$nextyear"/>
1587 <xsl:text>, </xsl:text>
1588 <xsl:value-of select="$print.ranges"/>
1589 <xsl:text>, </xsl:text>
1590 <xsl:value-of select="$single.year.ranges"/>
1591 <xsl:text> (</xsl:text>
1592 <xsl:value-of select="$years[1]"/>
1593 <xsl:text>)</xsl:text>
1598 <xsl:when test="$print.ranges = 0 and count($years) > 0">
1600 <xsl:when test="count($years) = 1">
1601 <xsl:apply-templates select="$years[1]" mode="titlepage.mode"/>
1604 <xsl:apply-templates select="$years[1]" mode="titlepage.mode"/>
1605 <xsl:text>, </xsl:text>
1606 <xsl:call-template name="copyright.years">
1607 <xsl:with-param name="years"
1608 select="$years[position() > 1]"/>
1609 <xsl:with-param name="print.ranges" select="$print.ranges"/>
1610 <xsl:with-param name="single.year.ranges"
1611 select="$single.year.ranges"/>
1612 </xsl:call-template>
1616 <xsl:when test="count($years) = 0">
1617 <xsl:variable name="lastyear" select="$nextyear - 1"/>
1619 <xsl:when test="$firstyear = 0">
1620 <!-- there weren't any years at all -->
1622 <!-- Just output a year with range in its text -->
1623 <xsl:when test="contains($firstyear, '-') or contains($firstyear, ',')">
1624 <xsl:value-of select="$firstyear"/>
1626 <xsl:when test="$firstyear = $lastyear">
1627 <xsl:value-of select="$firstyear"/>
1629 <xsl:when test="$single.year.ranges = 0
1630 and $lastyear = $firstyear + 1">
1631 <xsl:value-of select="$firstyear"/>
1632 <xsl:text>, </xsl:text>
1633 <xsl:value-of select="$lastyear"/>
1636 <xsl:value-of select="$firstyear"/>
1637 <xsl:text>-</xsl:text>
1638 <xsl:value-of select="$lastyear"/>
1642 <xsl:when test="contains($firstyear, '-') or contains($firstyear, ',')">
1643 <!-- Just output a year with range in its text -->
1644 <xsl:value-of select="$firstyear"/>
1645 <xsl:if test="count($years) != 0">
1646 <xsl:text>, </xsl:text>
1648 <xsl:call-template name="copyright.years">
1649 <xsl:with-param name="years"
1650 select="$years[position() > 1]"/>
1651 <xsl:with-param name="firstyear" select="$years[1]"/>
1652 <xsl:with-param name="nextyear" select="$years[1] + 1"/>
1653 <xsl:with-param name="print.ranges" select="$print.ranges"/>
1654 <xsl:with-param name="single.year.ranges"
1655 select="$single.year.ranges"/>
1656 </xsl:call-template>
1658 <xsl:when test="$firstyear = 0">
1659 <xsl:call-template name="copyright.years">
1660 <xsl:with-param name="years"
1661 select="$years[position() > 1]"/>
1662 <xsl:with-param name="firstyear" select="$years[1]"/>
1663 <xsl:with-param name="nextyear" select="$years[1] + 1"/>
1664 <xsl:with-param name="print.ranges" select="$print.ranges"/>
1665 <xsl:with-param name="single.year.ranges"
1666 select="$single.year.ranges"/>
1667 </xsl:call-template>
1669 <xsl:when test="$nextyear = $years[1]">
1670 <xsl:call-template name="copyright.years">
1671 <xsl:with-param name="years"
1672 select="$years[position() > 1]"/>
1673 <xsl:with-param name="firstyear" select="$firstyear"/>
1674 <xsl:with-param name="nextyear" select="$nextyear + 1"/>
1675 <xsl:with-param name="print.ranges" select="$print.ranges"/>
1676 <xsl:with-param name="single.year.ranges"
1677 select="$single.year.ranges"/>
1678 </xsl:call-template>
1681 <!-- we have years left, but they aren't in the current range -->
1683 <xsl:when test="$nextyear = $firstyear + 1">
1684 <xsl:value-of select="$firstyear"/>
1685 <xsl:text>, </xsl:text>
1687 <xsl:when test="$single.year.ranges = 0
1688 and $nextyear = $firstyear + 2">
1689 <xsl:value-of select="$firstyear"/>
1690 <xsl:text>, </xsl:text>
1691 <xsl:value-of select="$nextyear - 1"/>
1692 <xsl:text>, </xsl:text>
1695 <xsl:value-of select="$firstyear"/>
1696 <xsl:text>-</xsl:text>
1697 <xsl:value-of select="$nextyear - 1"/>
1698 <xsl:text>, </xsl:text>
1701 <xsl:call-template name="copyright.years">
1702 <xsl:with-param name="years"
1703 select="$years[position() > 1]"/>
1704 <xsl:with-param name="firstyear" select="$years[1]"/>
1705 <xsl:with-param name="nextyear" select="$years[1] + 1"/>
1706 <xsl:with-param name="print.ranges" select="$print.ranges"/>
1707 <xsl:with-param name="single.year.ranges"
1708 select="$single.year.ranges"/>
1709 </xsl:call-template>
1714 <!-- ====================================================================== -->
1716 <doc:template name="find.path.params" xmlns="">
1717 <refpurpose>Search in a table for the "best" match for the node</refpurpose>
1719 <refdescription id="find.path.params-desc">
1720 <para>This template searches in a table for the value that most-closely
1721 (in the typical best-match sense of XSLT) matches the current (element)
1722 node location.</para>
1726 <xsl:template name="find.path.params">
1727 <xsl:param name="node" select="."/>
1728 <xsl:param name="table" select="''"/>
1729 <xsl:param name="location">
1730 <xsl:call-template name="xpath.location">
1731 <xsl:with-param name="node" select="$node"/>
1732 </xsl:call-template>
1735 <xsl:variable name="value">
1736 <xsl:call-template name="lookup.key">
1737 <xsl:with-param name="key" select="$location"/>
1738 <xsl:with-param name="table" select="$table"/>
1739 </xsl:call-template>
1743 <xsl:when test="$value != ''">
1744 <xsl:value-of select="$value"/>
1746 <xsl:when test="contains($location, '/')">
1747 <xsl:call-template name="find.path.params">
1748 <xsl:with-param name="node" select="$node"/>
1749 <xsl:with-param name="table" select="$table"/>
1750 <xsl:with-param name="location" select="substring-after($location, '/')"/>
1751 </xsl:call-template>
1756 <xsl:template name="relative-uri">
1757 <xsl:param name="filename" select="."/>
1758 <xsl:param name="destdir" select="''"/>
1760 <xsl:variable name="srcurl">
1761 <xsl:call-template name="strippath">
1762 <xsl:with-param name="filename">
1763 <xsl:call-template name="xml.base.dirs">
1764 <xsl:with-param name="base.elem"
1765 select="$filename/ancestor-or-self::*
1766 [@xml:base != ''][1]"/>
1767 </xsl:call-template>
1768 <xsl:value-of select="$filename"/>
1770 </xsl:call-template>
1773 <xsl:variable name="srcurl.trimmed">
1774 <xsl:call-template name="trim.common.uri.paths">
1775 <xsl:with-param name="uriA" select="$srcurl"/>
1776 <xsl:with-param name="uriB" select="$destdir"/>
1777 <xsl:with-param name="return" select="'A'"/>
1778 </xsl:call-template>
1781 <xsl:variable name="destdir.trimmed">
1782 <xsl:call-template name="trim.common.uri.paths">
1783 <xsl:with-param name="uriA" select="$srcurl"/>
1784 <xsl:with-param name="uriB" select="$destdir"/>
1785 <xsl:with-param name="return" select="'B'"/>
1786 </xsl:call-template>
1789 <xsl:variable name="depth">
1790 <xsl:call-template name="count.uri.path.depth">
1791 <xsl:with-param name="filename" select="$destdir.trimmed"/>
1792 </xsl:call-template>
1795 <xsl:call-template name="copy-string">
1796 <xsl:with-param name="string" select="'../'"/>
1797 <xsl:with-param name="count" select="$depth"/>
1798 </xsl:call-template>
1799 <xsl:value-of select="$srcurl.trimmed"/>
1803 <!-- ===================================== -->
1805 <xsl:template name="xml.base.dirs">
1806 <xsl:param name="base.elem" select="NONODE"/>
1808 <!-- Recursively resolve xml:base attributes, up to a
1809 full path with : in uri -->
1810 <xsl:if test="$base.elem/ancestor::*[@xml:base != ''] and
1811 not(contains($base.elem/@xml:base, ':'))">
1812 <xsl:call-template name="xml.base.dirs">
1813 <xsl:with-param name="base.elem"
1814 select="$base.elem/ancestor::*[@xml:base != ''][1]"/>
1815 </xsl:call-template>
1817 <xsl:call-template name="getdir">
1818 <xsl:with-param name="filename" select="$base.elem/@xml:base"/>
1819 </xsl:call-template>
1823 <!-- ===================================== -->
1825 <xsl:template name="strippath">
1826 <xsl:param name="filename" select="''"/>
1828 <!-- Leading .. are not eliminated -->
1829 <xsl:when test="starts-with($filename, '../')">
1830 <xsl:value-of select="'../'"/>
1831 <xsl:call-template name="strippath">
1832 <xsl:with-param name="filename" select="substring-after($filename, '../')"/>
1833 </xsl:call-template>
1835 <xsl:when test="contains($filename, '/../')">
1836 <xsl:call-template name="strippath">
1837 <xsl:with-param name="filename">
1838 <xsl:call-template name="getdir">
1839 <xsl:with-param name="filename" select="substring-before($filename, '/../')"/>
1840 </xsl:call-template>
1841 <xsl:value-of select="substring-after($filename, '/../')"/>
1843 </xsl:call-template>
1846 <xsl:value-of select="$filename"/>
1851 <!-- ===================================== -->
1853 <xsl:template name="getdir">
1854 <xsl:param name="filename" select="''"/>
1855 <xsl:if test="contains($filename, '/')">
1856 <xsl:value-of select="substring-before($filename, '/')"/>
1857 <xsl:text>/</xsl:text>
1858 <xsl:call-template name="getdir">
1859 <xsl:with-param name="filename" select="substring-after($filename, '/')"/>
1860 </xsl:call-template>
1864 <!-- ===================================== -->
1866 <doc:template name="string.upper" xmlns="">
1867 <refpurpose>Converts a string to all uppercase letters</refpurpose>
1869 <refdescription id="string.upper-desc">
1870 <para>Given a string, this template does a language-aware conversion
1871 of that string to all uppercase letters, based on the values of the
1872 <literal>lowercase.alpha</literal> and
1873 <literal>uppercase.alpha</literal> gentext keys for the current
1874 locale. It affects only those characters found in the values of
1875 <literal>lowercase.alpha</literal> and
1876 <literal>uppercase.alpha</literal>. All other characters are left
1880 <refparameter id="string.upper-params">
1882 <varlistentry><term>string</term>
1884 <para>The string to convert to uppercase.</para>
1890 <xsl:template name="string.upper">
1891 <xsl:param name="string" select="''"/>
1892 <xsl:variable name="lowercase.alpha">
1893 <xsl:call-template name="gentext">
1894 <xsl:with-param name="key" select="'lowercase.alpha'"/>
1895 </xsl:call-template>
1897 <xsl:variable name="uppercase.alpha">
1898 <xsl:call-template name="gentext">
1899 <xsl:with-param name="key" select="'uppercase.alpha'"/>
1900 </xsl:call-template>
1902 <xsl:value-of select="translate($string,$lowercase.alpha,$uppercase.alpha)"/>
1905 <!-- ===================================== -->
1907 <doc:template name="string.lower" xmlns="">
1908 <refpurpose>Converts a string to all lowercase letters</refpurpose>
1910 <refdescription id="string.lower-desc">
1911 <para>Given a string, this template does a language-aware conversion
1912 of that string to all lowercase letters, based on the values of the
1913 <literal>uppercase.alpha</literal> and
1914 <literal>lowercase.alpha</literal> gentext keys for the current
1915 locale. It affects only those characters found in the values of
1916 <literal>uppercase.alpha</literal> and
1917 <literal>lowercase.alpha</literal>. All other characters are left
1921 <refparameter id="string.lower-params">
1923 <varlistentry><term>string</term>
1925 <para>The string to convert to lowercase.</para>
1931 <xsl:template name="string.lower">
1932 <xsl:param name="string" select="''"/>
1933 <xsl:variable name="uppercase.alpha">
1934 <xsl:call-template name="gentext">
1935 <xsl:with-param name="key" select="'uppercase.alpha'"/>
1936 </xsl:call-template>
1938 <xsl:variable name="lowercase.alpha">
1939 <xsl:call-template name="gentext">
1940 <xsl:with-param name="key" select="'lowercase.alpha'"/>
1941 </xsl:call-template>
1943 <xsl:value-of select="translate($string,$uppercase.alpha,$lowercase.alpha)"/>
1946 <!-- ===================================== -->
1948 <doc:template name="select.choice.separator" xmlns="">
1949 <refpurpose>Returns localized choice separator</refpurpose>
1950 <refdescription id="select.choice.separator-desc">
1951 <para>This template enables auto-generation of an appropriate
1952 localized "choice" separator (for example, "and" or "or") before
1953 the final item in an inline list (though it could also be useful
1954 for generating choice separators for non-inline lists).</para>
1955 <para>It currently works by evaluating a processing instruction
1956 (PI) of the form <?dbchoice choice="foo"?> :
1959 <simpara>if the value of the <tag>choice</tag>
1960 pseudo-attribute is "and" or "or", returns a localized "and"
1964 <simpara>otherwise returns the literal value of the
1965 <tag>choice</tag> pseudo-attribute</simpara>
1968 The latter is provided only as a temporary workaround because the
1969 locale files do not currently have translations for the word
1970 <wordasword>or</wordasword>. So if you want to generate a a
1971 logical "or" separator in French (for example), you currently need
1973 <literallayout><?dbchoice choice="ou"?></literallayout>
1976 <para>The <tag>dbchoice</tag> processing instruction is
1977 an unfortunate hack; support for it may disappear in the future
1978 (particularly if and when a more appropriate means for marking
1979 up "choice" lists becomes available in DocBook).</para>
1983 <xsl:template name="select.choice.separator">
1984 <xsl:variable name="choice">
1985 <xsl:call-template name="pi.dbchoice_choice"/>
1988 <!-- if value of $choice is "and" or "or", translate to equivalent in -->
1989 <!-- current locale -->
1990 <xsl:when test="$choice = 'and' or $choice = 'or'">
1991 <xsl:call-template name="gentext">
1992 <xsl:with-param name="key" select="$choice"/>
1993 </xsl:call-template>
1995 <!-- otherwise, just output value of $choice, whatever it is -->
1997 <xsl:value-of select="$choice"/>
2002 <!-- ===================================== -->
2004 <doc:template name="evaluate.info.profile" xmlns="">
2005 <refpurpose>Evaluates an info profile</refpurpose>
2006 <refdescription id="evaluate.info.profile-desc">
2007 <para>This template evaluates an "info profile" matching the XPath
2008 expression given by the <parameter>profile</parameter>
2009 parameter. It relies on the XSLT <function>evaluate()</function>
2010 extension function.</para>
2012 <para>The value of the <parameter>profile</parameter> parameter
2013 can include the literal string <literal>$info</literal>. If found
2014 in the value of the <parameter>profile</parameter> parameter, the
2015 literal string <literal>$info</literal> string is replaced with
2016 the value of the <parameter>info</parameter> parameter, which
2017 should be a set of <replaceable>*info</replaceable> nodes; the
2018 expression is then evaluated using the XSLT
2019 <function>evaluate()</function> extension function.</para>
2021 <refparameter id="evaluate.info.profile-params">
2024 <term>profile</term>
2026 <para>A string representing an XPath expression </para>
2032 <para>A set of *info nodes</para>
2038 <refreturn id="evaluate.info.profile-returns">
2039 <para>Returns a node (the result of evaluating the
2040 <parameter>profile</parameter> parameter)</para>
2043 <xsl:template name="evaluate.info.profile">
2044 <xsl:param name="profile"/>
2045 <xsl:param name="info"/>
2047 <!-- * xsltproc and Xalan both support dyn:evaluate() -->
2048 <xsl:when test="function-available('dyn:evaluate')">
2049 <xsl:apply-templates
2050 select="dyn:evaluate($profile)" mode="get.refentry.metadata"/>
2052 <!-- * Saxon has its own evaluate() & doesn't support dyn:evaluate() -->
2053 <xsl:when test="function-available('saxon:evaluate')">
2054 <xsl:apply-templates
2055 select="saxon:evaluate($profile)" mode="get.refentry.metadata"/>
2058 <xsl:message terminate="yes">
2059 Error: The "info profiling" mechanism currently requires an XSLT
2060 engine that supports the evaluate() XSLT extension function. Your XSLT
2061 engine does not support it.
2068 <doc:template name="graphic.format.content-type" xmlns="">
2069 <refpurpose>Returns mimetype for media format</refpurpose>
2070 <refdescription id="graphic.format.content-type-desc">
2071 <para>This takes as input a 'format' param and returns
2072 a mimetype string. It uses an xsl:choose after first
2073 converting the input to all uppercase.</para>
2076 <xsl:template name="graphic.format.content-type">
2077 <xsl:param name="format"/>
2078 <xsl:variable name="upperformat" select="translate($format,&lowercase;,&uppercase;)"/>
2080 <xsl:when test="$upperformat = ''"></xsl:when>
2081 <xsl:when test="$upperformat = 'linespecific'"></xsl:when>
2082 <xsl:when test="$upperformat = 'PS'">application/postscript</xsl:when>
2083 <xsl:when test="$upperformat = 'PDF'">application/pdf</xsl:when>
2084 <xsl:when test="$upperformat = 'PNG'">image/png</xsl:when>
2085 <xsl:when test="$upperformat = 'SVG'">image/svg+xml</xsl:when>
2086 <xsl:when test="$upperformat = 'JPG'">image/jpeg</xsl:when>
2087 <xsl:when test="$upperformat = 'JPEG'">image/jpeg</xsl:when>
2088 <xsl:when test="$upperformat = 'GIF'">image/gif</xsl:when>
2089 <xsl:when test="$upperformat = 'GIF87A'">image/gif</xsl:when>
2090 <xsl:when test="$upperformat = 'GIF89A'">image/gif</xsl:when>
2091 <xsl:when test="$upperformat = 'ACC'">audio/acc</xsl:when>
2092 <xsl:when test="$upperformat = 'MPG'">audio/mpeg</xsl:when>
2093 <xsl:when test="$upperformat = 'MP1'">audio/mpeg</xsl:when>
2094 <xsl:when test="$upperformat = 'MP2'">audio/mpeg</xsl:when>
2095 <xsl:when test="$upperformat = 'MP3'">audio/mpeg</xsl:when>
2096 <xsl:when test="$upperformat = 'M4A'">audio/mp4</xsl:when>
2097 <xsl:when test="$upperformat = 'MPEG'">audio/mpeg</xsl:when>
2098 <xsl:when test="$upperformat = 'WAV'">audio/wav</xsl:when>
2099 <xsl:when test="$upperformat = 'MP4'">video/mp4</xsl:when>
2100 <xsl:when test="$upperformat = 'M4V'">video/mp4</xsl:when>
2101 <xsl:when test="$upperformat = 'OGV'">video/ogg</xsl:when>
2102 <xsl:when test="$upperformat = 'OGG'">video/ogg</xsl:when>
2103 <xsl:when test="$upperformat = 'WEBM'">video/webm</xsl:when>
2105 <xsl:value-of select="concat('image/', $upperformat)"/>
2110 <xsl:template match="*" mode="xrefstyle">
2111 <xsl:param name="referrer" select="."/>
2112 <xsl:param name="target"/>
2113 <xsl:param name="olink.key"/>
2115 <!-- normally uses the @xrefstyle attribute in xref, but could
2116 be customized based on the target element type -->
2118 <xsl:when test="@role and not(@xrefstyle)
2119 and $use.role.as.xrefstyle != 0">
2120 <xsl:value-of select="@role"/>
2123 <xsl:value-of select="@xrefstyle"/>