2 <xsl:stylesheet xmlns:
xsl=
"http://www.w3.org/1999/XSL/Transform"
3 xmlns:
doc=
"http://nwalsh.com/xsl/documentation/1.0"
4 xmlns:
dyn=
"http://exslt.org/dynamic"
5 xmlns:
saxon=
"http://icl.com/saxon"
6 exclude-result-prefixes=
"doc dyn saxon"
9 <!-- ********************************************************************
10 $Id: common.xsl,v 1.1 2007/03/10 05:14:55 scott Exp $
11 ********************************************************************
13 This file is part of the XSL DocBook Stylesheet distribution.
14 See ../README or http://nwalsh.com/docbook/xsl/ for copyright
15 and other information.
17 This file contains general templates common to both the HTML and FO
18 versions of the DocBook stylesheets.
19 ******************************************************************** -->
21 <doc:reference xmlns=
"">
23 <releaseinfo role=
"meta">
24 $Id: common.xsl,v
1.1 2007/
03/
10 05:
14:
55 scott Exp $
26 <author><surname>Walsh
</surname>
27 <firstname>Norman
</firstname></author>
28 <copyright><year>1999</year><year>2000</year>
29 <holder>Norman Walsh
</holder>
32 <title>Common Template Reference
</title>
34 <partintro id=
"partintro">
35 <title>Introduction
</title>
37 <para>This is technical reference documentation for the DocBook XSL
38 Stylesheets; it documents (some of) the parameters, templates, and
39 other elements of the stylesheets.
</para>
41 <para>This is not intended to be
<quote>user
</quote> documentation.
42 It is provided for developers writing customization layers for the
43 stylesheets, and for anyone who's interested in
<quote>how it
46 <para>Although I am trying to be thorough, this documentation is known
47 to be incomplete. Don't forget to read the source, too :-)
</para>
52 <!-- ==================================================================== -->
53 <!-- Establish strip/preserve whitespace rules -->
55 <xsl:preserve-space elements=
"*"/>
57 <xsl:strip-space elements=
"
58 abstract affiliation anchor answer appendix area areaset areaspec
59 artheader article audiodata audioobject author authorblurb authorgroup
60 beginpage bibliodiv biblioentry bibliography biblioset blockquote book
61 bookbiblio bookinfo callout calloutlist caption caution chapter
62 citerefentry cmdsynopsis co collab colophon colspec confgroup
63 copyright dedication docinfo editor entrytbl epigraph equation
64 example figure footnote footnoteref formalpara funcprototype
65 funcsynopsis glossary glossdef glossdiv glossentry glosslist graphicco
66 group highlights imagedata imageobject imageobjectco important index
67 indexdiv indexentry indexterm info informalequation informalexample
68 informalfigure informaltable inlineequation inlinemediaobject
69 itemizedlist itermset keycombo keywordset legalnotice listitem lot
70 mediaobject mediaobjectco menuchoice msg msgentry msgexplan msginfo
71 msgmain msgrel msgset msgsub msgtext note objectinfo
72 orderedlist othercredit part partintro preface printhistory procedure
73 programlistingco publisher qandadiv qandaentry qandaset question
74 refentry reference refmeta refnamediv refsection refsect1 refsect1info refsect2
75 refsect2info refsect3 refsect3info refsynopsisdiv refsynopsisdivinfo
76 revhistory revision row sbr screenco screenshot sect1 sect1info sect2
77 sect2info sect3 sect3info sect4 sect4info sect5 sect5info section
78 sectioninfo seglistitem segmentedlist seriesinfo set setindex setinfo
79 shortcut sidebar simplelist simplesect spanspec step subject
80 subjectset substeps synopfragment table tbody textobject tfoot tgroup
81 thead tip toc tocchap toclevel1 toclevel2 toclevel3 toclevel4
82 toclevel5 tocpart varargs variablelist varlistentry videodata
83 videoobject void warning subjectset
97 <!-- ====================================================================== -->
99 <doc:template name=
"is.component" xmlns=
"">
100 <refpurpose>Tests if a given node is a component-level element
</refpurpose>
103 <para>This template returns '
1' if the specified node is a component
104 (Chapter, Appendix, etc.), and '
0' otherwise.
</para>
109 <varlistentry><term>node
</term>
111 <para>The node which is to be tested.
</para>
118 <para>This template returns '
1' if the specified node is a component
119 (Chapter, Appendix, etc.), and '
0' otherwise.
</para>
123 <xsl:template name=
"is.component">
124 <xsl:param name=
"node" select=
"."/>
126 <xsl:when test=
"local-name($node) = 'appendix'
127 or local-name($node) = 'article'
128 or local-name($node) = 'chapter'
129 or local-name($node) = 'preface'
130 or local-name($node) = 'bibliography'
131 or local-name($node) = 'glossary'
132 or local-name($node) = 'index'">1</xsl:when>
133 <xsl:otherwise>0</xsl:otherwise>
137 <!-- ====================================================================== -->
139 <doc:template name=
"is.section" xmlns=
"">
140 <refpurpose>Tests if a given node is a section-level element
</refpurpose>
143 <para>This template returns '
1' if the specified node is a section
144 (Section, Sect1, Sect2, etc.), and '
0' otherwise.
</para>
149 <varlistentry><term>node
</term>
151 <para>The node which is to be tested.
</para>
158 <para>This template returns '
1' if the specified node is a section
159 (Section, Sect1, Sect2, etc.), and '
0' otherwise.
</para>
163 <xsl:template name=
"is.section">
164 <xsl:param name=
"node" select=
"."/>
166 <xsl:when test=
"local-name($node) = 'section'
167 or local-name($node) = 'sect1'
168 or local-name($node) = 'sect2'
169 or local-name($node) = 'sect3'
170 or local-name($node) = 'sect4'
171 or local-name($node) = 'sect5'
172 or local-name($node) = 'refsect1'
173 or local-name($node) = 'refsect2'
174 or local-name($node) = 'refsect3'
175 or local-name($node) = 'simplesect'">1</xsl:when>
176 <xsl:otherwise>0</xsl:otherwise>
180 <!-- ====================================================================== -->
182 <doc:template name=
"section.level" xmlns=
"">
183 <refpurpose>Returns the hierarchical level of a section
</refpurpose>
186 <para>This template calculates the hierarchical level of a section.
187 The element
<sgmltag>sect1
</sgmltag> is at level
1,
<sgmltag>sect2
</sgmltag> is
188 at level
2, etc.
</para>
190 <para>Recursive sections are calculated down to the fifth level.
</para>
195 <varlistentry><term>node
</term>
197 <para>The section node for which the level should be calculated.
198 Defaults to the context node.
</para>
205 <para>The section level,
<quote>1</quote>,
<quote>2</quote>, etc.
210 <xsl:template name=
"section.level">
211 <xsl:param name=
"node" select=
"."/>
213 <xsl:when test=
"local-name($node)='sect1'">1</xsl:when>
214 <xsl:when test=
"local-name($node)='sect2'">2</xsl:when>
215 <xsl:when test=
"local-name($node)='sect3'">3</xsl:when>
216 <xsl:when test=
"local-name($node)='sect4'">4</xsl:when>
217 <xsl:when test=
"local-name($node)='sect5'">5</xsl:when>
218 <xsl:when test=
"local-name($node)='section'">
220 <xsl:when test=
"$node/../../../../../../section">6</xsl:when>
221 <xsl:when test=
"$node/../../../../../section">5</xsl:when>
222 <xsl:when test=
"$node/../../../../section">4</xsl:when>
223 <xsl:when test=
"$node/../../../section">3</xsl:when>
224 <xsl:when test=
"$node/../../section">2</xsl:when>
225 <xsl:otherwise>1</xsl:otherwise>
228 <xsl:when test=
"local-name($node)='refsect1' or
229 local-name($node)='refsect2' or
230 local-name($node)='refsect3' or
231 local-name($node)='refsection' or
232 local-name($node)='refsynopsisdiv'">
233 <xsl:call-template name=
"refentry.section.level">
234 <xsl:with-param name=
"node" select=
"$node"/>
237 <xsl:when test=
"local-name($node)='simplesect'">
239 <xsl:when test=
"$node/../../sect1">2</xsl:when>
240 <xsl:when test=
"$node/../../sect2">3</xsl:when>
241 <xsl:when test=
"$node/../../sect3">4</xsl:when>
242 <xsl:when test=
"$node/../../sect4">5</xsl:when>
243 <xsl:when test=
"$node/../../sect5">5</xsl:when>
244 <xsl:when test=
"$node/../../section">
246 <xsl:when test=
"$node/../../../../../section">5</xsl:when>
247 <xsl:when test=
"$node/../../../../section">4</xsl:when>
248 <xsl:when test=
"$node/../../../section">3</xsl:when>
249 <xsl:otherwise>2</xsl:otherwise>
252 <xsl:otherwise>1</xsl:otherwise>
255 <xsl:otherwise>1</xsl:otherwise>
257 </xsl:template><!-- section.level -->
259 <doc:template name=
"qanda.section.level" xmlns=
"">
260 <refpurpose>Returns the hierarchical level of a QandASet
</refpurpose>
263 <para>This template calculates the hierarchical level of a QandASet.
268 <para>The level,
<quote>1</quote>,
<quote>2</quote>, etc.
273 <xsl:template name=
"qanda.section.level">
274 <xsl:variable name=
"section"
275 select=
"(ancestor::section
276 |ancestor::simplesect
284 |ancestor::refsect1)[last()]"/>
287 <xsl:when test=
"count($section) = '0'">1</xsl:when>
289 <xsl:variable name=
"slevel">
290 <xsl:call-template name=
"section.level">
291 <xsl:with-param name=
"node" select=
"$section"/>
294 <xsl:value-of select=
"$slevel + 1"/>
299 <!-- Finds the total section depth of a section in a refentry -->
300 <xsl:template name=
"refentry.section.level">
301 <xsl:param name=
"node" select=
"."/>
303 <xsl:variable name=
"RElevel">
304 <xsl:call-template name=
"refentry.level">
305 <xsl:with-param name=
"node" select=
"$node/ancestor::refentry[1]"/>
309 <xsl:variable name=
"levelinRE">
311 <xsl:when test=
"local-name($node)='refsynopsisdiv'">1</xsl:when>
312 <xsl:when test=
"local-name($node)='refsect1'">1</xsl:when>
313 <xsl:when test=
"local-name($node)='refsect2'">2</xsl:when>
314 <xsl:when test=
"local-name($node)='refsect3'">3</xsl:when>
315 <xsl:when test=
"local-name($node)='refsection'">
317 <xsl:when test=
"$node/../../../../../refsection">5</xsl:when>
318 <xsl:when test=
"$node/../../../../refsection">4</xsl:when>
319 <xsl:when test=
"$node/../../../refsection">3</xsl:when>
320 <xsl:when test=
"$node/../../refsection">2</xsl:when>
321 <xsl:otherwise>1</xsl:otherwise>
327 <xsl:value-of select=
"$levelinRE + $RElevel"/>
330 <!-- Finds the section depth of a refentry -->
331 <xsl:template name=
"refentry.level">
332 <xsl:param name=
"node" select=
"."/>
333 <xsl:variable name=
"container"
334 select=
"($node/ancestor::section |
335 $node/ancestor::sect1 |
336 $node/ancestor::sect2 |
337 $node/ancestor::sect3 |
338 $node/ancestor::sect4 |
339 $node/ancestor::sect5)[last()]"/>
342 <xsl:when test=
"$container">
343 <xsl:variable name=
"slevel">
344 <xsl:call-template name=
"section.level">
345 <xsl:with-param name=
"node" select=
"$container"/>
348 <xsl:value-of select=
"$slevel + 1"/>
350 <xsl:otherwise>1</xsl:otherwise>
354 <xsl:template name=
"qandadiv.section.level">
355 <xsl:variable name=
"section.level">
356 <xsl:call-template name=
"qanda.section.level"/>
358 <xsl:variable name=
"anc.divs" select=
"ancestor::qandadiv"/>
360 <xsl:value-of select=
"count($anc.divs) + number($section.level)"/>
363 <xsl:template name=
"question.answer.label">
364 <xsl:variable name=
"deflabel">
366 <xsl:when test=
"ancestor-or-self::*[@defaultlabel]">
367 <xsl:value-of select=
"(ancestor-or-self::*[@defaultlabel])[last()]
371 <xsl:value-of select=
"$qanda.defaultlabel"/>
376 <xsl:variable name=
"label" select=
"@label"/>
379 (hnr (hierarchical-number-recursive (normalize "qandadiv") node))
381 (parsect (ancestor-member node (section-element-list)))
383 (defnum (if (and %qanda-inherit-numeration%
385 (if (node-list-empty? parsect)
386 (section-autolabel-prefix node)
387 (section-autolabel parsect))
390 (hnumber (let loop ((numlist hnr) (number defnum)
391 (sep (if (equal? defnum "") "" ".")))
395 (string-append number
397 (number->string (car numlist)))
399 (cnumber (child-number (parent node)))
400 (number (string-append hnumber
401 (if (equal? hnumber "")
404 (number->string cnumber))))
408 <xsl:when test=
"$deflabel = 'qanda'">
409 <xsl:call-template name=
"gentext">
410 <xsl:with-param name=
"key">
412 <xsl:when test=
"local-name(.) = 'question'">question
</xsl:when>
413 <xsl:when test=
"local-name(.) = 'answer'">answer
</xsl:when>
414 <xsl:when test=
"local-name(.) = 'qandadiv'">qandadiv
</xsl:when>
415 <xsl:otherwise>qandaset
</xsl:otherwise>
420 <xsl:when test=
"$deflabel = 'label'">
421 <xsl:value-of select=
"$label"/>
423 <xsl:when test=
"$deflabel = 'number'
424 and local-name(.) = 'question'">
425 <xsl:apply-templates select=
"ancestor::qandaset[1]"
428 <xsl:when test=
"ancestor::qandadiv">
429 <xsl:apply-templates select=
"ancestor::qandadiv[1]"
431 <xsl:apply-templates select=
"ancestor::qandaentry"
435 <xsl:apply-templates select=
"ancestor::qandaentry"
446 <xsl:template match=
"qandaset" mode=
"number">
450 <xsl:template match=
"qandadiv" mode=
"number">
451 <xsl:number level=
"multiple" from=
"qandaset" format=
"1."/>
454 <xsl:template match=
"qandaentry" mode=
"number">
456 <xsl:when test=
"ancestor::qandadiv">
457 <xsl:number level=
"single" from=
"qandadiv" format=
"1."/>
460 <xsl:number level=
"single" from=
"qandaset" format=
"1."/>
465 <!-- ====================================================================== -->
467 <xsl:template name=
"object.id">
468 <xsl:param name=
"object" select=
"."/>
470 <xsl:when test=
"$object/@id">
471 <xsl:value-of select=
"$object/@id"/>
473 <xsl:when test=
"$object/@xml:id">
474 <xsl:value-of select=
"$object/@xml:id"/>
477 <xsl:value-of select=
"generate-id($object)"/>
482 <xsl:template name=
"person.name">
483 <!-- Formats a personal name. Handles corpauthor as a special case. -->
484 <xsl:param name=
"node" select=
"."/>
486 <xsl:variable name=
"style">
488 <xsl:when test=
"$node/@role">
489 <xsl:value-of select=
"$node/@role"/>
492 <xsl:call-template name=
"gentext.template">
493 <xsl:with-param name=
"context" select=
"'styles'"/>
494 <xsl:with-param name=
"name" select=
"'person-name'"/>
501 <!-- the personname element is a specialcase -->
502 <xsl:when test=
"$node/personname">
503 <xsl:call-template name=
"person.name">
504 <xsl:with-param name=
"node" select=
"$node/personname"/>
508 <!-- handle corpauthor as a special case...-->
509 <xsl:when test=
"local-name($node)='corpauthor'">
510 <xsl:apply-templates select=
"$node"/>
515 <!-- Handle case when personname contains only general markup (DocBook 5.0) -->
516 <xsl:when test=
"$node/self::personname and not($node/firstname or $node/honorific or $node/lineage or $node/othername or $node/surname)">
517 <xsl:apply-templates select=
"$node/node()"/>
519 <xsl:when test=
"$style = 'family-given'">
520 <xsl:call-template name=
"person.name.family-given">
521 <xsl:with-param name=
"node" select=
"$node"/>
524 <xsl:when test=
"$style = 'last-first'">
525 <xsl:call-template name=
"person.name.last-first">
526 <xsl:with-param name=
"node" select=
"$node"/>
530 <xsl:call-template name=
"person.name.first-last">
531 <xsl:with-param name=
"node" select=
"$node"/>
539 <xsl:template name=
"person.name.family-given">
540 <xsl:param name=
"node" select=
"."/>
542 <!-- The family-given style applies a convention for identifying given -->
543 <!-- and family names in locales where it may be ambiguous -->
544 <xsl:apply-templates select=
"$node//surname[1]"/>
546 <xsl:if test=
"$node//surname and $node//firstname">
547 <xsl:text> </xsl:text>
550 <xsl:apply-templates select=
"$node//firstname[1]"/>
552 <xsl:text> [FAMILY Given]
</xsl:text>
555 <xsl:template name=
"person.name.last-first">
556 <xsl:param name=
"node" select=
"."/>
558 <xsl:apply-templates select=
"$node//surname[1]"/>
560 <xsl:if test=
"$node//surname and $node//firstname">
561 <xsl:text>,
</xsl:text>
564 <xsl:apply-templates select=
"$node//firstname[1]"/>
567 <xsl:template name=
"person.name.first-last">
568 <xsl:param name=
"node" select=
"."/>
570 <xsl:if test=
"$node//honorific">
571 <xsl:apply-templates select=
"$node//honorific[1]"/>
572 <xsl:value-of select=
"$punct.honorific"/>
575 <xsl:if test=
"$node//firstname">
576 <xsl:if test=
"$node//honorific">
577 <xsl:text> </xsl:text>
579 <xsl:apply-templates select=
"$node//firstname[1]"/>
582 <xsl:if test=
"$node//othername and $author.othername.in.middle != 0">
583 <xsl:if test=
"$node//honorific or $node//firstname">
584 <xsl:text> </xsl:text>
586 <xsl:apply-templates select=
"$node//othername[1]"/>
589 <xsl:if test=
"$node//surname">
590 <xsl:if test=
"$node//honorific or $node//firstname
591 or ($node//othername and $author.othername.in.middle != 0)">
592 <xsl:text> </xsl:text>
594 <xsl:apply-templates select=
"$node//surname[1]"/>
597 <xsl:if test=
"$node//lineage">
598 <xsl:text>,
</xsl:text>
599 <xsl:apply-templates select=
"$node//lineage[1]"/>
603 <xsl:template name=
"person.name.list">
604 <!-- Return a formatted string representation of the contents of
605 the current element. The current element must contain one or
606 more AUTHORs, CORPAUTHORs, OTHERCREDITs, and/or EDITORs.
610 John Doe and Jane Doe
612 John Doe, Jane Doe, and A. Nonymous
614 <xsl:param name=
"person.list"
615 select=
"author|corpauthor|othercredit|editor"/>
616 <xsl:param name=
"person.count" select=
"count($person.list)"/>
617 <xsl:param name=
"count" select=
"1"/>
620 <xsl:when test=
"$count > $person.count"></xsl:when>
622 <xsl:call-template name=
"person.name">
623 <xsl:with-param name=
"node" select=
"$person.list[position()=$count]"/>
627 <xsl:when test=
"$person.count = 2 and $count = 1">
628 <xsl:call-template name=
"gentext.template">
629 <xsl:with-param name=
"context" select=
"'authorgroup'"/>
630 <xsl:with-param name=
"name" select=
"'sep2'"/>
633 <xsl:when test=
"$person.count > 2 and $count+1 = $person.count">
634 <xsl:call-template name=
"gentext.template">
635 <xsl:with-param name=
"context" select=
"'authorgroup'"/>
636 <xsl:with-param name=
"name" select=
"'seplast'"/>
639 <xsl:when test=
"$count < $person.count">
640 <xsl:call-template name=
"gentext.template">
641 <xsl:with-param name=
"context" select=
"'authorgroup'"/>
642 <xsl:with-param name=
"name" select=
"'sep'"/>
647 <xsl:call-template name=
"person.name.list">
648 <xsl:with-param name=
"person.list" select=
"$person.list"/>
649 <xsl:with-param name=
"person.count" select=
"$person.count"/>
650 <xsl:with-param name=
"count" select=
"$count+1"/>
654 </xsl:template><!-- person.name.list -->
656 <!-- === synopsis ======================================================= -->
657 <!-- The following definitions match those given in the reference
658 documentation for DocBook V3.0
661 <xsl:variable name=
"arg.choice.opt.open.str">[
</xsl:variable>
662 <xsl:variable name=
"arg.choice.opt.close.str">]
</xsl:variable>
663 <xsl:variable name=
"arg.choice.req.open.str">{
</xsl:variable>
664 <xsl:variable name=
"arg.choice.req.close.str">}
</xsl:variable>
665 <xsl:variable name=
"arg.choice.plain.open.str"><xsl:text> </xsl:text></xsl:variable>
666 <xsl:variable name=
"arg.choice.plain.close.str"><xsl:text> </xsl:text></xsl:variable>
667 <xsl:variable name=
"arg.choice.def.open.str">[
</xsl:variable>
668 <xsl:variable name=
"arg.choice.def.close.str">]
</xsl:variable>
669 <xsl:variable name=
"arg.rep.repeat.str">...
</xsl:variable>
670 <xsl:variable name=
"arg.rep.norepeat.str"></xsl:variable>
671 <xsl:variable name=
"arg.rep.def.str"></xsl:variable>
672 <xsl:variable name=
"arg.or.sep"> |
</xsl:variable>
673 <xsl:variable name=
"cmdsynopsis.hanging.indent">4pi
</xsl:variable>
675 <!-- ====================================================================== -->
678 <xsl:template name="xref.g.subst">
679 <xsl:param name="string"></xsl:param>
680 <xsl:param name="target" select="."/>
681 <xsl:variable name="subst">%g</xsl:variable>
684 <xsl:when test="contains($string, $subst)">
685 <xsl:value-of select="substring-before($string, $subst)"/>
686 <xsl:call-template name="gentext.element.name">
687 <xsl:with-param name="element.name" select="local-name($target)"/>
689 <xsl:call-template name="xref.g.subst">
690 <xsl:with-param name="string"
691 select="substring-after($string, $subst)"/>
692 <xsl:with-param name="target" select="$target"/>
696 <xsl:value-of select="$string"/>
701 <xsl:template name="xref.t.subst">
702 <xsl:param name="string"></xsl:param>
703 <xsl:param name="target" select="."/>
704 <xsl:variable name="subst">%t</xsl:variable>
707 <xsl:when test="contains($string, $subst)">
708 <xsl:call-template name="xref.g.subst">
709 <xsl:with-param name="string"
710 select="substring-before($string, $subst)"/>
711 <xsl:with-param name="target" select="$target"/>
713 <xsl:call-template name="title.xref">
714 <xsl:with-param name="target" select="$target"/>
716 <xsl:call-template name="xref.t.subst">
717 <xsl:with-param name="string"
718 select="substring-after($string, $subst)"/>
719 <xsl:with-param name="target" select="$target"/>
723 <xsl:call-template name="xref.g.subst">
724 <xsl:with-param name="string" select="$string"/>
725 <xsl:with-param name="target" select="$target"/>
731 <xsl:template name="xref.n.subst">
732 <xsl:param name="string"></xsl:param>
733 <xsl:param name="target" select="."/>
734 <xsl:variable name="subst">%n</xsl:variable>
737 <xsl:when test="contains($string, $subst)">
738 <xsl:call-template name="xref.t.subst">
739 <xsl:with-param name="string"
740 select="substring-before($string, $subst)"/>
741 <xsl:with-param name="target" select="$target"/>
743 <xsl:call-template name="number.xref">
744 <xsl:with-param name="target" select="$target"/>
746 <xsl:call-template name="xref.t.subst">
747 <xsl:with-param name="string"
748 select="substring-after($string, $subst)"/>
749 <xsl:with-param name="target" select="$target"/>
753 <xsl:call-template name="xref.t.subst">
754 <xsl:with-param name="string" select="$string"/>
755 <xsl:with-param name="target" select="$target"/>
761 <xsl:template name="subst.xref.text">
762 <xsl:param name="xref.text"></xsl:param>
763 <xsl:param name="target" select="."/>
765 <xsl:call-template name="xref.n.subst">
766 <xsl:with-param name="string" select="$xref.text"/>
767 <xsl:with-param name="target" select="$target"/>
772 <!-- ====================================================================== -->
774 <xsl:template name=
"filename-basename">
775 <!-- We assume all filenames are really URIs and use "/" -->
776 <xsl:param name=
"filename"></xsl:param>
777 <xsl:param name=
"recurse" select=
"false()"/>
780 <xsl:when test=
"substring-after($filename, '/') != ''">
781 <xsl:call-template name=
"filename-basename">
782 <xsl:with-param name=
"filename"
783 select=
"substring-after($filename, '/')"/>
784 <xsl:with-param name=
"recurse" select=
"true()"/>
788 <xsl:value-of select=
"$filename"/>
793 <xsl:template name=
"filename-extension">
794 <xsl:param name=
"filename"></xsl:param>
795 <xsl:param name=
"recurse" select=
"false()"/>
797 <!-- Make sure we only look at the base name... -->
798 <xsl:variable name=
"basefn">
800 <xsl:when test=
"$recurse">
801 <xsl:value-of select=
"$filename"/>
804 <xsl:call-template name=
"filename-basename">
805 <xsl:with-param name=
"filename" select=
"$filename"/>
812 <xsl:when test=
"substring-after($basefn, '.') != ''">
813 <xsl:call-template name=
"filename-extension">
814 <xsl:with-param name=
"filename"
815 select=
"substring-after($basefn, '.')"/>
816 <xsl:with-param name=
"recurse" select=
"true()"/>
819 <xsl:when test=
"$recurse">
820 <xsl:value-of select=
"$basefn"/>
822 <xsl:otherwise></xsl:otherwise>
826 <!-- ====================================================================== -->
828 <doc:template name=
"select.mediaobject" xmlns=
"">
829 <refpurpose>Selects and processes an appropriate media object from a list
</refpurpose>
832 <para>This template takes a list of media objects (usually the
833 children of a mediaobject or inlinemediaobject) and processes
834 the
"right" object.
</para>
836 <para>This template relies on a template named
837 "select.mediaobject.index" to determine which object
838 in the list is appropriate.
</para>
840 <para>If no acceptable object is located, nothing happens.
</para>
845 <varlistentry><term>olist
</term>
847 <para>The node list of potential objects to examine.
</para>
854 <para>Calls
<xsl:apply-templates
> on the selected object.
</para>
858 <xsl:template name=
"select.mediaobject">
859 <xsl:param name=
"olist"
860 select=
"imageobject|imageobjectco
861 |videoobject|audioobject|textobject"/>
863 <xsl:variable name=
"mediaobject.index">
864 <xsl:call-template name=
"select.mediaobject.index">
865 <xsl:with-param name=
"olist" select=
"$olist"/>
866 <xsl:with-param name=
"count" select=
"1"/>
870 <xsl:if test=
"$mediaobject.index != ''">
871 <xsl:apply-templates select=
"$olist[position() = $mediaobject.index]"/>
875 <!-- ====================================================================== -->
877 <doc:template name=
"select.mediaobject.index" xmlns=
"">
878 <refpurpose>Selects the position of the appropriate media object from a list
</refpurpose>
881 <para>This template takes a list of media objects (usually the
882 children of a mediaobject or inlinemediaobject) and determines
883 the
"right" object. It returns the position of that object
884 to be used by the calling template.
</para>
886 <para>If the parameter
<parameter>use.role.for.mediaobject
</parameter>
887 is nonzero, then it first checks for an object with
888 a role attribute of the appropriate value. It takes the first
889 of those. Otherwise, it takes the first acceptable object
890 through a recursive pass through the list.
</para>
892 <para>This template relies on a template named
"is.acceptable.mediaobject"
893 to determine if a given object is an acceptable graphic. The semantics
894 of media objects is that the first acceptable graphic should be used.
897 <para>If no acceptable object is located, no index is returned.
</para>
902 <varlistentry><term>olist
</term>
904 <para>The node list of potential objects to examine.
</para>
907 <varlistentry><term>count
</term>
909 <para>The position in the list currently being considered by the
910 recursive process.
</para>
917 <para>Returns the position in the original list of the selected object.
</para>
921 <xsl:template name=
"select.mediaobject.index">
922 <xsl:param name=
"olist"
923 select=
"imageobject|imageobjectco
924 |videoobject|audioobject|textobject"/>
925 <xsl:param name=
"count">1</xsl:param>
928 <!-- Test for objects preferred by role -->
929 <xsl:when test=
"$use.role.for.mediaobject != 0
930 and $preferred.mediaobject.role != ''
931 and $olist[@role = $preferred.mediaobject.role]">
933 <!-- Get the first hit's position index -->
934 <xsl:for-each select=
"$olist">
935 <xsl:if test=
"@role = $preferred.mediaobject.role and
936 not(preceding-sibling::*[@role = $preferred.mediaobject.role])">
937 <xsl:value-of select=
"position()"/>
942 <xsl:when test=
"$use.role.for.mediaobject != 0
943 and $olist[@role = $stylesheet.result.type]">
944 <!-- Get the first hit's position index -->
945 <xsl:for-each select=
"$olist">
946 <xsl:if test=
"@role = $stylesheet.result.type and
947 not(preceding-sibling::*[@role = $stylesheet.result.type])">
948 <xsl:value-of select=
"position()"/>
952 <!-- Accept 'html' for $stylesheet.result.type = 'xhtml' -->
953 <xsl:when test=
"$use.role.for.mediaobject != 0
954 and $stylesheet.result.type = 'xhtml'
955 and $olist[@role = 'html']">
956 <!-- Get the first hit's position index -->
957 <xsl:for-each select=
"$olist">
958 <xsl:if test=
"@role = 'html' and
959 not(preceding-sibling::*[@role = 'html'])">
960 <xsl:value-of select=
"position()"/>
965 <!-- If no selection by role, and there is only one object, use it -->
966 <xsl:when test=
"count($olist) = 1 and $count = 1">
967 <xsl:value-of select=
"$count"/>
971 <!-- Otherwise select first acceptable object -->
972 <xsl:if test=
"$count <= count($olist)">
973 <xsl:variable name=
"object" select=
"$olist[position()=$count]"/>
975 <xsl:variable name=
"useobject">
977 <!-- The phrase is used only when contains TeX Math and output is FO -->
978 <xsl:when test=
"local-name($object)='textobject' and $object/phrase
979 and $object/@role='tex' and $stylesheet.result.type = 'fo'
980 and $tex.math.in.alt != ''">
981 <xsl:text>1</xsl:text>
983 <!-- The phrase is never used -->
984 <xsl:when test=
"local-name($object)='textobject' and $object/phrase">
985 <xsl:text>0</xsl:text>
987 <xsl:when test=
"local-name($object)='textobject'
988 and $object/ancestor::equation ">
989 <!-- The first textobject is not a reasonable fallback
990 for equation image -->
991 <xsl:text>0</xsl:text>
993 <!-- The first textobject is a reasonable fallback -->
994 <xsl:when test=
"local-name($object)='textobject'
995 and $object[not(@role) or @role!='tex']">
996 <xsl:text>1</xsl:text>
998 <!-- don't use graphic when output is FO, TeX Math is used
999 and there is math in alt element -->
1000 <xsl:when test=
"$object/ancestor::equation and
1001 $object/ancestor::equation/alt[@role='tex']
1002 and $stylesheet.result.type = 'fo'
1003 and $tex.math.in.alt != ''">
1004 <xsl:text>0</xsl:text>
1006 <!-- If there's only one object, use it -->
1007 <xsl:when test=
"$count = 1 and count($olist) = 1">
1008 <xsl:text>1</xsl:text>
1010 <!-- Otherwise, see if this one is a useable graphic -->
1013 <!-- peek inside imageobjectco to simplify the test -->
1014 <xsl:when test=
"local-name($object) = 'imageobjectco'">
1015 <xsl:call-template name=
"is.acceptable.mediaobject">
1016 <xsl:with-param name=
"object" select=
"$object/imageobject"/>
1017 </xsl:call-template>
1020 <xsl:call-template name=
"is.acceptable.mediaobject">
1021 <xsl:with-param name=
"object" select=
"$object"/>
1022 </xsl:call-template>
1030 <xsl:when test=
"$useobject='1'">
1031 <xsl:value-of select=
"$count"/>
1034 <xsl:call-template name=
"select.mediaobject.index">
1035 <xsl:with-param name=
"olist" select=
"$olist"/>
1036 <xsl:with-param name=
"count" select=
"$count + 1"/>
1037 </xsl:call-template>
1045 <doc:template name=
"is.acceptable.mediaobject" xmlns=
"">
1046 <refpurpose>Returns '
1' if the specified media object is recognized
</refpurpose>
1049 <para>This template examines a media object and returns '
1' if the
1050 object is recognized as a graphic.
</para>
1055 <varlistentry><term>object
</term>
1057 <para>The media object to consider.
</para>
1068 <xsl:template name=
"is.acceptable.mediaobject">
1069 <xsl:param name=
"object"></xsl:param>
1071 <xsl:variable name=
"filename">
1072 <xsl:call-template name=
"mediaobject.filename">
1073 <xsl:with-param name=
"object" select=
"$object"/>
1074 </xsl:call-template>
1077 <xsl:variable name=
"ext">
1078 <xsl:call-template name=
"filename-extension">
1079 <xsl:with-param name=
"filename" select=
"$filename"/>
1080 </xsl:call-template>
1083 <!-- there will only be one -->
1084 <xsl:variable name=
"data" select=
"$object/videodata
1086 |$object/audiodata"/>
1088 <xsl:variable name=
"format" select=
"$data/@format"/>
1090 <xsl:variable name=
"graphic.format">
1091 <xsl:if test=
"$format">
1092 <xsl:call-template name=
"is.graphic.format">
1093 <xsl:with-param name=
"format" select=
"$format"/>
1094 </xsl:call-template>
1098 <xsl:variable name=
"graphic.ext">
1099 <xsl:if test=
"$ext">
1100 <xsl:call-template name=
"is.graphic.extension">
1101 <xsl:with-param name=
"ext" select=
"$ext"/>
1102 </xsl:call-template>
1107 <xsl:when test=
"$use.svg = 0 and $format = 'SVG'">0</xsl:when>
1108 <xsl:when xmlns:
svg=
"http://www.w3.org/2000/svg"
1109 test=
"$use.svg != 0 and $object/svg:*">1</xsl:when>
1110 <xsl:when test=
"$graphic.format = '1'">1</xsl:when>
1111 <xsl:when test=
"$graphic.ext = '1'">1</xsl:when>
1112 <xsl:otherwise>0</xsl:otherwise>
1116 <xsl:template name=
"mediaobject.filename">
1117 <xsl:param name=
"object"></xsl:param>
1119 <xsl:variable name=
"data" select=
"$object/videodata
1124 <xsl:variable name=
"filename">
1126 <xsl:when test=
"$data[@fileref]">
1127 <xsl:apply-templates select=
"$data/@fileref"/>
1129 <xsl:when test=
"$data[@entityref]">
1130 <xsl:value-of select=
"unparsed-entity-uri($data/@entityref)"/>
1132 <xsl:otherwise></xsl:otherwise>
1136 <xsl:variable name=
"real.ext">
1137 <xsl:call-template name=
"filename-extension">
1138 <xsl:with-param name=
"filename" select=
"$filename"/>
1139 </xsl:call-template>
1142 <xsl:variable name=
"ext">
1144 <xsl:when test=
"$real.ext != ''">
1145 <xsl:value-of select=
"$real.ext"/>
1148 <xsl:value-of select=
"$graphic.default.extension"/>
1153 <xsl:variable name=
"graphic.ext">
1154 <xsl:call-template name=
"is.graphic.extension">
1155 <xsl:with-param name=
"ext" select=
"$ext"/>
1156 </xsl:call-template>
1160 <xsl:when test=
"$real.ext = ''">
1162 <xsl:when test=
"$ext != ''">
1163 <xsl:value-of select=
"$filename"/>
1164 <xsl:text>.
</xsl:text>
1165 <xsl:value-of select=
"$ext"/>
1168 <xsl:value-of select=
"$filename"/>
1172 <xsl:when test=
"not($graphic.ext)">
1174 <xsl:when test=
"$graphic.default.extension != ''">
1175 <xsl:value-of select=
"$filename"/>
1176 <xsl:text>.
</xsl:text>
1177 <xsl:value-of select=
"$graphic.default.extension"/>
1180 <xsl:value-of select=
"$filename"/>
1185 <xsl:value-of select=
"$filename"/>
1190 <!-- ====================================================================== -->
1192 <doc:template name=
"check.id.unique" xmlns=
"">
1193 <refpurpose>Warn users about references to non-unique IDs
</refpurpose>
1195 <para>If passed an ID in
<varname>linkend
</varname>,
1196 <function>check.id.unique
</function> prints
1197 a warning message to the user if either the ID does not exist or
1198 the ID is not unique.
</para>
1202 <xsl:template name=
"check.id.unique">
1203 <xsl:param name=
"linkend"></xsl:param>
1204 <xsl:if test=
"$linkend != ''">
1205 <xsl:variable name=
"targets" select=
"key('id',$linkend)"/>
1206 <xsl:variable name=
"target" select=
"$targets[1]"/>
1208 <xsl:if test=
"count($targets)=0">
1210 <xsl:text>Error: no ID for constraint linkend:
</xsl:text>
1211 <xsl:value-of select=
"$linkend"/>
1212 <xsl:text>.
</xsl:text>
1216 <xsl:text>If the ID exists in your document, did your </xsl:text>
1217 <xsl:text>XSLT Processor load the DTD?</xsl:text>
1222 <xsl:if test=
"count($targets)>1">
1224 <xsl:text>Warning: multiple
"IDs" for constraint linkend:
</xsl:text>
1225 <xsl:value-of select=
"$linkend"/>
1226 <xsl:text>.
</xsl:text>
1232 <doc:template name=
"check.idref.targets" xmlns=
"">
1233 <refpurpose>Warn users about incorrectly typed references
</refpurpose>
1235 <para>If passed an ID in
<varname>linkend
</varname>,
1236 <function>check.idref.targets
</function> makes sure that the element
1237 pointed to by the link is one of the elements listed in
1238 <varname>element-list
</varname> and warns the user otherwise.
</para>
1242 <xsl:template name=
"check.idref.targets">
1243 <xsl:param name=
"linkend"></xsl:param>
1244 <xsl:param name=
"element-list"></xsl:param>
1245 <xsl:if test=
"$linkend != ''">
1246 <xsl:variable name=
"targets" select=
"key('id',$linkend)"/>
1247 <xsl:variable name=
"target" select=
"$targets[1]"/>
1249 <xsl:if test=
"count($target) > 0">
1250 <xsl:if test=
"not(contains(concat(' ', $element-list, ' '), local-name($target)))">
1252 <xsl:text>Error: linkend (
</xsl:text>
1253 <xsl:value-of select=
"$linkend"/>
1254 <xsl:text>) points to
"</xsl:text>
1255 <xsl:value-of select="local-name($target)
"/>
1256 <xsl:text>" not (one of):
</xsl:text>
1257 <xsl:value-of select=
"$element-list"/>
1264 <!-- ====================================================================== -->
1265 <!-- Procedure Step Numeration -->
1267 <xsl:param name=
"procedure.step.numeration.formats" select=
"'1aiAI'"/>
1269 <xsl:template name=
"procedure.step.numeration">
1270 <xsl:param name=
"context" select=
"."/>
1271 <xsl:variable name=
"format.length"
1272 select=
"string-length($procedure.step.numeration.formats)"/>
1274 <xsl:when test=
"local-name($context) = 'substeps'">
1275 <xsl:variable name=
"ssdepth"
1276 select=
"count($context/ancestor::substeps)"/>
1277 <xsl:variable name=
"sstype" select=
"($ssdepth mod $format.length)+2"/>
1279 <xsl:when test=
"$sstype > $format.length">
1280 <xsl:value-of select=
"substring($procedure.step.numeration.formats,1,1)"/>
1283 <xsl:value-of select=
"substring($procedure.step.numeration.formats,$sstype,1)"/>
1287 <xsl:when test=
"local-name($context) = 'step'">
1288 <xsl:variable name=
"sdepth"
1289 select=
"count($context/ancestor::substeps)"/>
1290 <xsl:variable name=
"stype" select=
"($sdepth mod $format.length)+1"/>
1291 <xsl:value-of select=
"substring($procedure.step.numeration.formats,$stype,1)"/>
1295 <xsl:text>Unexpected context in procedure.step.numeration:
</xsl:text>
1296 <xsl:value-of select=
"local-name($context)"/>
1302 <xsl:template match=
"step" mode=
"number">
1303 <xsl:param name=
"rest" select=
"''"/>
1304 <xsl:param name=
"recursive" select=
"1"/>
1305 <xsl:variable name=
"format">
1306 <xsl:call-template name=
"procedure.step.numeration"/>
1308 <xsl:variable name=
"num">
1309 <xsl:number count=
"step" format=
"{$format}"/>
1312 <xsl:when test=
"$recursive != 0 and ancestor::step">
1313 <xsl:apply-templates select=
"ancestor::step[1]" mode=
"number">
1314 <xsl:with-param name=
"rest" select=
"concat('.', $num, $rest)"/>
1315 </xsl:apply-templates>
1318 <xsl:value-of select=
"concat($num, $rest)"/>
1323 <!-- ====================================================================== -->
1324 <!-- OrderedList Numeration -->
1326 <xsl:template name=
"orderedlist-starting-number">
1327 <xsl:param name=
"list" select=
"."/>
1329 <!-- Need a neutral dbxxx -->
1330 <xsl:variable name=
"pi-html-start">
1331 <xsl:call-template name=
"pi-attribute">
1332 <xsl:with-param name=
"pis"
1333 select=
"$list/processing-instruction('dbhtml')"/>
1334 <xsl:with-param name=
"attribute" select=
"'start'"/>
1335 </xsl:call-template>
1338 <xsl:variable name=
"pi-fo-start">
1339 <xsl:call-template name=
"pi-attribute">
1340 <xsl:with-param name=
"pis"
1341 select=
"$list/processing-instruction('dbfo')"/>
1342 <xsl:with-param name=
"attribute" select=
"'start'"/>
1343 </xsl:call-template>
1347 <xsl:when test=
"not($list/@continuation = 'continues')">
1349 <xsl:when test=
"@startingnumber">
1350 <xsl:value-of select=
"@startingnumber"/>
1352 <xsl:when test=
"$pi-html-start != ''">
1353 <xsl:value-of select=
"$pi-html-start"/>
1355 <xsl:when test=
"$pi-fo-start != ''">
1356 <xsl:value-of select=
"$pi-fo-start"/>
1358 <xsl:otherwise>1</xsl:otherwise>
1362 <xsl:variable name=
"prevlist"
1363 select=
"$list/preceding::orderedlist[1]"/>
1365 <xsl:when test=
"count($prevlist) = 0">2</xsl:when>
1367 <xsl:variable name=
"prevlength" select=
"count($prevlist/listitem)"/>
1368 <xsl:variable name=
"prevstart">
1369 <xsl:call-template name=
"orderedlist-starting-number">
1370 <xsl:with-param name=
"list" select=
"$prevlist"/>
1371 </xsl:call-template>
1373 <xsl:value-of select=
"$prevstart + $prevlength"/>
1380 <xsl:template name=
"orderedlist-item-number">
1381 <!-- context node must be a listitem in an orderedlist -->
1382 <xsl:param name=
"node" select=
"."/>
1385 <xsl:when test=
"$node/@override">
1386 <xsl:value-of select=
"$node/@override"/>
1388 <xsl:when test=
"$node/preceding-sibling::listitem">
1389 <xsl:variable name=
"pnum">
1390 <xsl:call-template name=
"orderedlist-item-number">
1391 <xsl:with-param name=
"node" select=
"$node/preceding-sibling::listitem[1]"/>
1392 </xsl:call-template>
1394 <xsl:value-of select=
"$pnum + 1"/>
1397 <xsl:call-template name=
"orderedlist-starting-number">
1398 <xsl:with-param name=
"list" select=
"parent::*"/>
1399 </xsl:call-template>
1404 <xsl:template name=
"next.numeration">
1405 <xsl:param name=
"numeration" select=
"'default'"/>
1407 <!-- Change this list if you want to change the order of numerations -->
1408 <xsl:when test=
"$numeration = 'arabic'">loweralpha
</xsl:when>
1409 <xsl:when test=
"$numeration = 'loweralpha'">lowerroman
</xsl:when>
1410 <xsl:when test=
"$numeration = 'lowerroman'">upperalpha
</xsl:when>
1411 <xsl:when test=
"$numeration = 'upperalpha'">upperroman
</xsl:when>
1412 <xsl:when test=
"$numeration = 'upperroman'">arabic
</xsl:when>
1413 <xsl:otherwise>arabic
</xsl:otherwise>
1417 <xsl:template name=
"list.numeration">
1418 <xsl:param name=
"node" select=
"."/>
1421 <xsl:when test=
"$node/@numeration">
1422 <xsl:value-of select=
"$node/@numeration"/>
1426 <xsl:when test=
"$node/ancestor::orderedlist">
1427 <xsl:call-template name=
"next.numeration">
1428 <xsl:with-param name=
"numeration">
1429 <xsl:call-template name=
"list.numeration">
1430 <xsl:with-param name=
"node" select=
"$node/ancestor::orderedlist[1]"/>
1431 </xsl:call-template>
1433 </xsl:call-template>
1436 <xsl:call-template name=
"next.numeration"/>
1443 <!-- ====================================================================== -->
1444 <!-- ItemizedList "Numeration" -->
1446 <xsl:template name=
"next.itemsymbol">
1447 <xsl:param name=
"itemsymbol" select=
"'default'"/>
1449 <!-- Change this list if you want to change the order of symbols -->
1450 <xsl:when test=
"$itemsymbol = 'disc'">circle
</xsl:when>
1451 <xsl:when test=
"$itemsymbol = 'circle'">square
</xsl:when>
1452 <xsl:otherwise>disc
</xsl:otherwise>
1456 <xsl:template name=
"list.itemsymbol">
1457 <xsl:param name=
"node" select=
"."/>
1460 <xsl:when test=
"@override">
1461 <xsl:value-of select=
"@override"/>
1463 <xsl:when test=
"$node/@mark">
1464 <xsl:value-of select=
"$node/@mark"/>
1468 <xsl:when test=
"$node/ancestor::itemizedlist">
1469 <xsl:call-template name=
"next.itemsymbol">
1470 <xsl:with-param name=
"itemsymbol">
1471 <xsl:call-template name=
"list.itemsymbol">
1472 <xsl:with-param name=
"node" select=
"$node/ancestor::itemizedlist[1]"/>
1473 </xsl:call-template>
1475 </xsl:call-template>
1478 <xsl:call-template name=
"next.itemsymbol"/>
1485 <!-- ====================================================================== -->
1487 <doc:template name=
"copyright.years" xmlns=
"">
1488 <refpurpose>Print a set of years with collapsed ranges
</refpurpose>
1491 <para>This template prints a list of year elements with consecutive
1492 years printed as a range. In other words:
</para>
1494 <screen><![CDATA[
<year>1992</year>
1496 <year>1994</year>]]
></screen>
1498 <para>is printed
<quote>1992-
1994</quote>, whereas:
</para>
1500 <screen><![CDATA[
<year>1992</year>
1501 <year>1994</year>]]
></screen>
1503 <para>is printed
<quote>1992,
1994</quote>.
</para>
1505 <para>This template assumes that all the year elements contain only
1506 decimal year numbers, that the elements are sorted in increasing
1507 numerical order, that there are no duplicates, and that all the years
1508 are expressed in full
<quote>century+year
</quote>
1509 (
<quote>1999</quote> not
<quote>99</quote>) notation.
</para>
1514 <varlistentry><term>years
</term>
1516 <para>The initial set of year elements.
</para>
1519 <varlistentry><term>print.ranges
</term>
1521 <para>If non-zero, multi-year ranges are collapsed. If zero, all years
1522 are printed discretely.
</para>
1525 <varlistentry><term>single.year.ranges
</term>
1527 <para>If non-zero, two consecutive years will be printed as a range,
1528 otherwise, they will be printed discretely. In other words, a single
1529 year range is
<quote>1991-
1992</quote> but discretely it's
1530 <quote>1991,
1992</quote>.
</para>
1537 <para>This template returns the formatted list of years.
</para>
1541 <xsl:template name=
"copyright.years">
1542 <xsl:param name=
"years"/>
1543 <xsl:param name=
"print.ranges" select=
"1"/>
1544 <xsl:param name=
"single.year.ranges" select=
"0"/>
1545 <xsl:param name=
"firstyear" select=
"0"/>
1546 <xsl:param name=
"nextyear" select=
"0"/>
1549 <xsl:message terminate="no">
1550 <xsl:text>CY: </xsl:text>
1551 <xsl:value-of select="count($years)"/>
1552 <xsl:text>, </xsl:text>
1553 <xsl:value-of select="$firstyear"/>
1554 <xsl:text>, </xsl:text>
1555 <xsl:value-of select="$nextyear"/>
1556 <xsl:text>, </xsl:text>
1557 <xsl:value-of select="$print.ranges"/>
1558 <xsl:text>, </xsl:text>
1559 <xsl:value-of select="$single.year.ranges"/>
1560 <xsl:text> (</xsl:text>
1561 <xsl:value-of select="$years[1]"/>
1562 <xsl:text>)</xsl:text>
1567 <xsl:when test=
"$print.ranges = 0 and count($years) > 0">
1569 <xsl:when test=
"count($years) = 1">
1570 <xsl:apply-templates select=
"$years[1]" mode=
"titlepage.mode"/>
1573 <xsl:apply-templates select=
"$years[1]" mode=
"titlepage.mode"/>
1574 <xsl:text>,
</xsl:text>
1575 <xsl:call-template name=
"copyright.years">
1576 <xsl:with-param name=
"years"
1577 select=
"$years[position() > 1]"/>
1578 <xsl:with-param name=
"print.ranges" select=
"$print.ranges"/>
1579 <xsl:with-param name=
"single.year.ranges"
1580 select=
"$single.year.ranges"/>
1581 </xsl:call-template>
1585 <xsl:when test=
"count($years) = 0">
1586 <xsl:variable name=
"lastyear" select=
"$nextyear - 1"/>
1588 <xsl:when test=
"$firstyear = 0">
1589 <!-- there weren't any years at all -->
1591 <xsl:when test=
"$firstyear = $lastyear">
1592 <xsl:value-of select=
"$firstyear"/>
1594 <xsl:when test=
"$single.year.ranges = 0
1595 and $lastyear = $firstyear + 1">
1596 <xsl:value-of select=
"$firstyear"/>
1597 <xsl:text>,
</xsl:text>
1598 <xsl:value-of select=
"$lastyear"/>
1601 <xsl:value-of select=
"$firstyear"/>
1602 <xsl:text>-
</xsl:text>
1603 <xsl:value-of select=
"$lastyear"/>
1607 <xsl:when test=
"$firstyear = 0">
1608 <xsl:call-template name=
"copyright.years">
1609 <xsl:with-param name=
"years"
1610 select=
"$years[position() > 1]"/>
1611 <xsl:with-param name=
"firstyear" select=
"$years[1]"/>
1612 <xsl:with-param name=
"nextyear" select=
"$years[1] + 1"/>
1613 <xsl:with-param name=
"print.ranges" select=
"$print.ranges"/>
1614 <xsl:with-param name=
"single.year.ranges"
1615 select=
"$single.year.ranges"/>
1616 </xsl:call-template>
1618 <xsl:when test=
"$nextyear = $years[1]">
1619 <xsl:call-template name=
"copyright.years">
1620 <xsl:with-param name=
"years"
1621 select=
"$years[position() > 1]"/>
1622 <xsl:with-param name=
"firstyear" select=
"$firstyear"/>
1623 <xsl:with-param name=
"nextyear" select=
"$nextyear + 1"/>
1624 <xsl:with-param name=
"print.ranges" select=
"$print.ranges"/>
1625 <xsl:with-param name=
"single.year.ranges"
1626 select=
"$single.year.ranges"/>
1627 </xsl:call-template>
1630 <!-- we have years left, but they aren't in the current range -->
1632 <xsl:when test=
"$nextyear = $firstyear + 1">
1633 <xsl:value-of select=
"$firstyear"/>
1634 <xsl:text>,
</xsl:text>
1636 <xsl:when test=
"$single.year.ranges = 0
1637 and $nextyear = $firstyear + 2">
1638 <xsl:value-of select=
"$firstyear"/>
1639 <xsl:text>,
</xsl:text>
1640 <xsl:value-of select=
"$nextyear - 1"/>
1641 <xsl:text>,
</xsl:text>
1644 <xsl:value-of select=
"$firstyear"/>
1645 <xsl:text>-
</xsl:text>
1646 <xsl:value-of select=
"$nextyear - 1"/>
1647 <xsl:text>,
</xsl:text>
1650 <xsl:call-template name=
"copyright.years">
1651 <xsl:with-param name=
"years"
1652 select=
"$years[position() > 1]"/>
1653 <xsl:with-param name=
"firstyear" select=
"$years[1]"/>
1654 <xsl:with-param name=
"nextyear" select=
"$years[1] + 1"/>
1655 <xsl:with-param name=
"print.ranges" select=
"$print.ranges"/>
1656 <xsl:with-param name=
"single.year.ranges"
1657 select=
"$single.year.ranges"/>
1658 </xsl:call-template>
1663 <!-- ====================================================================== -->
1665 <doc:template name=
"find.path.params" xmlns=
"">
1666 <refpurpose>Search in a table for the
"best" match for the node
</refpurpose>
1669 <para>This template searches in a table for the value that most-closely
1670 (in the typical best-match sense of XSLT) matches the current (element)
1671 node location.
</para>
1675 <xsl:template name=
"find.path.params">
1676 <xsl:param name=
"node" select=
"."/>
1677 <xsl:param name=
"table" select=
"''"/>
1678 <xsl:param name=
"location">
1679 <xsl:call-template name=
"xpath.location">
1680 <xsl:with-param name=
"node" select=
"$node"/>
1681 </xsl:call-template>
1684 <xsl:variable name=
"value">
1685 <xsl:call-template name=
"lookup.key">
1686 <xsl:with-param name=
"key" select=
"$location"/>
1687 <xsl:with-param name=
"table" select=
"$table"/>
1688 </xsl:call-template>
1692 <xsl:when test=
"$value != ''">
1693 <xsl:value-of select=
"$value"/>
1695 <xsl:when test=
"contains($location, '/')">
1696 <xsl:call-template name=
"find.path.params">
1697 <xsl:with-param name=
"node" select=
"$node"/>
1698 <xsl:with-param name=
"table" select=
"$table"/>
1699 <xsl:with-param name=
"location" select=
"substring-after($location, '/')"/>
1700 </xsl:call-template>
1705 <xsl:template name=
"relative-uri">
1706 <xsl:param name=
"filename" select=
"."/>
1707 <xsl:param name=
"destdir" select=
"''"/>
1709 <xsl:variable name=
"srcurl">
1710 <xsl:call-template name=
"strippath">
1711 <xsl:with-param name=
"filename">
1712 <xsl:call-template name=
"xml.base.dirs">
1713 <xsl:with-param name=
"base.elem"
1714 select=
"$filename/ancestor-or-self::*
1715 [@xml:base != ''][1]"/>
1716 </xsl:call-template>
1717 <xsl:value-of select=
"$filename"/>
1719 </xsl:call-template>
1722 <xsl:variable name=
"srcurl.trimmed">
1723 <xsl:call-template name=
"trim.common.uri.paths">
1724 <xsl:with-param name=
"uriA" select=
"$srcurl"/>
1725 <xsl:with-param name=
"uriB" select=
"$destdir"/>
1726 <xsl:with-param name=
"return" select=
"'A'"/>
1727 </xsl:call-template>
1730 <xsl:variable name=
"destdir.trimmed">
1731 <xsl:call-template name=
"trim.common.uri.paths">
1732 <xsl:with-param name=
"uriA" select=
"$srcurl"/>
1733 <xsl:with-param name=
"uriB" select=
"$destdir"/>
1734 <xsl:with-param name=
"return" select=
"'B'"/>
1735 </xsl:call-template>
1738 <xsl:variable name=
"depth">
1739 <xsl:call-template name=
"count.uri.path.depth">
1740 <xsl:with-param name=
"filename" select=
"$destdir.trimmed"/>
1741 </xsl:call-template>
1744 <xsl:call-template name=
"copy-string">
1745 <xsl:with-param name=
"string" select=
"'../'"/>
1746 <xsl:with-param name=
"count" select=
"$depth"/>
1747 </xsl:call-template>
1748 <xsl:value-of select=
"$srcurl.trimmed"/>
1752 <!-- ===================================== -->
1754 <xsl:template name=
"xml.base.dirs">
1755 <xsl:param name=
"base.elem" select=
"NONODE"/>
1757 <!-- Recursively resolve xml:base attributes, up to a
1758 full path with : in uri -->
1759 <xsl:if test=
"$base.elem/ancestor::*[@xml:base != ''] and
1760 not(contains($base.elem/@xml:base, ':'))">
1761 <xsl:call-template name=
"xml.base.dirs">
1762 <xsl:with-param name=
"base.elem"
1763 select=
"$base.elem/ancestor::*[@xml:base != ''][1]"/>
1764 </xsl:call-template>
1766 <xsl:call-template name=
"getdir">
1767 <xsl:with-param name=
"filename" select=
"$base.elem/@xml:base"/>
1768 </xsl:call-template>
1772 <!-- ===================================== -->
1774 <xsl:template name=
"strippath">
1775 <xsl:param name=
"filename" select=
"''"/>
1777 <!-- Leading .. are not eliminated -->
1778 <xsl:when test=
"starts-with($filename, '../')">
1779 <xsl:value-of select=
"'../'"/>
1780 <xsl:call-template name=
"strippath">
1781 <xsl:with-param name=
"filename" select=
"substring-after($filename, '../')"/>
1782 </xsl:call-template>
1784 <xsl:when test=
"contains($filename, '/../')">
1785 <xsl:call-template name=
"strippath">
1786 <xsl:with-param name=
"filename">
1787 <xsl:call-template name=
"getdir">
1788 <xsl:with-param name=
"filename" select=
"substring-before($filename, '/../')"/>
1789 </xsl:call-template>
1790 <xsl:value-of select=
"substring-after($filename, '/../')"/>
1792 </xsl:call-template>
1795 <xsl:value-of select=
"$filename"/>
1800 <!-- ===================================== -->
1802 <xsl:template name=
"getdir">
1803 <xsl:param name=
"filename" select=
"''"/>
1804 <xsl:if test=
"contains($filename, '/')">
1805 <xsl:value-of select=
"substring-before($filename, '/')"/>
1806 <xsl:text>/
</xsl:text>
1807 <xsl:call-template name=
"getdir">
1808 <xsl:with-param name=
"filename" select=
"substring-after($filename, '/')"/>
1809 </xsl:call-template>
1813 <!-- ===================================== -->
1815 <doc:template name=
"string.upper" xmlns=
"">
1816 <refpurpose>Converts a string to all uppercase letters
</refpurpose>
1819 <para>Given a string, this template does a language-aware conversion
1820 of that string to all uppercase letters, based on the values of the
1821 <literal>lowercase.alpha
</literal> and
1822 <literal>uppercase.alpha
</literal> gentext keys for the current
1823 locale. It affects only those characters found in the values of
1824 <literal>lowercase.alpha
</literal> and
1825 <literal>uppercase.alpha
</literal>. All other characters are left
1831 <varlistentry><term>string
</term>
1833 <para>The string to convert to uppercase.
</para>
1840 <xsl:template name=
"string.upper">
1841 <xsl:param name=
"string" select=
"''"/>
1842 <xsl:variable name=
"lowercase.alpha">
1843 <xsl:call-template name=
"gentext">
1844 <xsl:with-param name=
"key" select=
"'lowercase.alpha'"/>
1845 </xsl:call-template>
1847 <xsl:variable name=
"uppercase.alpha">
1848 <xsl:call-template name=
"gentext">
1849 <xsl:with-param name=
"key" select=
"'uppercase.alpha'"/>
1850 </xsl:call-template>
1852 <xsl:value-of select=
"translate($string,$lowercase.alpha,$uppercase.alpha)"/>
1855 <!-- ===================================== -->
1857 <doc:template name=
"string.lower" xmlns=
"">
1858 <refpurpose>Converts a string to all lowercase letters
</refpurpose>
1861 <para>Given a string, this template does a language-aware conversion
1862 of that string to all lowercase letters, based on the values of the
1863 <literal>uppercase.alpha
</literal> and
1864 <literal>lowercase.alpha
</literal> gentext keys for the current
1865 locale. It affects only those characters found in the values of
1866 <literal>uppercase.alpha
</literal> and
1867 <literal>lowercase.alpha
</literal>. All other characters are left
1873 <varlistentry><term>string
</term>
1875 <para>The string to convert to lowercase.
</para>
1882 <xsl:template name=
"string.lower">
1883 <xsl:param name=
"string" select=
"''"/>
1884 <xsl:variable name=
"uppercase.alpha">
1885 <xsl:call-template name=
"gentext">
1886 <xsl:with-param name=
"key" select=
"'uppercase.alpha'"/>
1887 </xsl:call-template>
1889 <xsl:variable name=
"lowercase.alpha">
1890 <xsl:call-template name=
"gentext">
1891 <xsl:with-param name=
"key" select=
"'lowercase.alpha'"/>
1892 </xsl:call-template>
1894 <xsl:value-of select=
"translate($string,$uppercase.alpha,$lowercase.alpha)"/>
1897 <!-- ===================================== -->
1899 <doc:template name=
"select.choice.separator" xmlns=
"">
1900 <refpurpose>Returns localized choice separator
</refpurpose>
1902 <para>This template enables auto-generation of an appropriate
1903 localized
"choice" separator (for example,
"and" or
"or") before
1904 the final item in an inline list (though it could also be useful
1905 for generating choice separators for non-inline lists).
</para>
1907 <para>It currently works by evaluating a processing instruction
1908 (PI) of the form
<?dbchoice
 choice=
"foo"?> :
1912 <simpara>if the value of the
<sgmltag>choice
</sgmltag>
1913 pseudo-attribute is
"and" or
"or", returns a localized
"and"
1917 <simpara>otherwise returns the literal value of the
1918 <sgmltag>choice
</sgmltag> pseudo-attribute
</simpara>
1922 The latter is provided only as a temporary workaround because the
1923 locale files do not currently have translations for the word
1924 <wordasword>or
</wordasword>. So if you want to generate a a
1925 logical
"or" separator in French (for example), you currently need
1928 <literallayout><?dbchoice
choice=
"ou"?></literallayout>
1932 <para>The
<sgmltag>dbchoice
</sgmltag> processing instruction is
1933 an unfortunate hack; support for it may disappear in the future
1934 (particularly if and when a more appropriate means for marking
1935 up
"choice" lists becomes available in DocBook).
</para>
1940 <xsl:template name=
"select.choice.separator">
1942 <xsl:variable name=
"choice">
1943 <xsl:call-template name=
"pi-attribute">
1944 <xsl:with-param name=
"pis" select=
"processing-instruction('dbchoice')"/>
1945 <xsl:with-param name=
"attribute">choice
</xsl:with-param>
1946 </xsl:call-template>
1950 <!-- if value of $choice is "and" or "or", translate to equivalent in -->
1951 <!-- current locale -->
1952 <xsl:when test=
"$choice = 'and' or $choice = 'or'">
1953 <xsl:call-template name=
"gentext">
1954 <xsl:with-param name=
"key" select=
"$choice"/>
1955 </xsl:call-template>
1957 <!-- otherwise, just output value of $choice, whatever it is -->
1959 <xsl:value-of select=
"$choice"/>
1964 <!-- ===================================== -->
1966 <doc:template name=
"evaluate.info.profile" xmlns=
"">
1967 <refpurpose>Evaluates an info profile
</refpurpose>
1969 <para>This function evaluates an
"info profile" matching the XPath
1970 expression given by the
<parameter>profile
</parameter>
1971 parameter. It relies on the XSLT
<function>evaluate()
</function>
1972 extension function.
</para>
1974 <para>The value of the
<parameter>profile
</parameter> parameter
1975 can include the literal string
<literal>$info
</literal>. If found
1976 in the value of the
<parameter>profile
</parameter> parameter, the
1977 literal string
<literal>$info
</literal> string is replaced with
1978 the value of the
<parameter>info
</parameter> parameter, which
1979 should be a set of
<replaceable>*info
</replaceable> nodes; the
1980 expression is then evaluated using the XSLT
1981 <function>evaluate()
</function> extension function.
</para>
1986 <term>profile
</term>
1988 <para>A string representing an XPath expression
</para>
1994 <para>A set of *info nodes
</para>
2001 <para>Returns a node (the result of evaluating the
2002 <parameter>profile
</parameter> parameter)
</para>
2006 <xsl:template name=
"evaluate.info.profile">
2007 <xsl:param name=
"profile"/>
2008 <xsl:param name=
"info"/>
2010 <!-- * xsltproc and Xalan both support dyn:evaluate() -->
2011 <xsl:when test=
"function-available('dyn:evaluate')">
2012 <xsl:apply-templates
2013 select=
"dyn:evaluate($profile)" mode=
"get.refentry.metadata"/>
2015 <!-- * Saxon has its own evaluate() & doesn't support dyn:evaluate() -->
2016 <xsl:when test=
"function-available('saxon:evaluate')">
2017 <xsl:apply-templates
2018 select=
"saxon:evaluate($profile)" mode=
"get.refentry.metadata"/>
2021 <xsl:message terminate=
"yes">
2022 Error: The
"info profiling" mechanism currently requires an XSLT
2023 engine that supports the evaluate() XSLT extension function. Your XSLT
2024 engine does not support it.
2030 <!-- ===================================== -->
2032 <doc:template name=
"log.message" xmlns=
"">
2033 <refpurpose>Logs/emits formatted notes and warnings
</refpurpose>
2036 <para>The
<function>log.message
</function> function is a utility
2037 function for logging/emitting formatted messages
 – that is,
2038 notes and warnings, along with a given log
"level" and an
2039 identifier for the
"source" that the message relates to.
</para>
2047 <para>Text to indicate the message level
2048 (
<literal>Note
</literal> or
2049 <literal>Warning
</literal>)
</para>
2055 <para>Text to identify source element the
2056 notification/warning relates to
</para>
2060 <term>message
</term>
2062 <para>Message to lot/emit
</para>
2066 <term>message-width
</term>
2068 <para>Expected maximum message width
</para>
2074 <para>Outputs a message (generally, to standard error).
</para></refreturn>
2077 <xsl:template name=
"log.message">
2078 <xsl:param name=
"level"/>
2079 <xsl:param name=
"source"/>
2080 <xsl:param name=
"message"/>
2081 <xsl:param name=
"message-width">50</xsl:param>
2082 <xsl:message><xsl:value-of
2083 select=
"$level"/><xsl:text>:
</xsl:text><xsl:value-of
2084 select=
"$message"/><xsl:call-template
2086 <xsl:with-param name=
"string" select=
"' '"/>
2089 select=
"$message-width - string-length($message)"/>
2090 </xsl:call-template><xsl:value-of
2091 select=
"$source"/></xsl:message>