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 <!-- ********************************************************************
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">
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>
35 <section><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>
53 <!-- ==================================================================== -->
54 <!-- Establish strip/preserve whitespace rules -->
56 <xsl:preserve-space elements="*"/>
58 <xsl:strip-space elements="
59 abstract affiliation anchor answer appendix area areaset areaspec
60 artheader article audiodata audioobject author authorblurb authorgroup
61 beginpage bibliodiv biblioentry bibliography biblioset blockquote book
62 bookbiblio bookinfo callout calloutlist caption caution chapter
63 citerefentry cmdsynopsis co collab colophon colspec confgroup
64 copyright dedication docinfo editor entrytbl epigraph equation
65 example figure footnote footnoteref formalpara funcprototype
66 funcsynopsis glossary glossdef glossdiv glossentry glosslist graphicco
67 group highlights imagedata imageobject imageobjectco important index
68 indexdiv indexentry indexterm informalequation informalexample
69 informalfigure informaltable inlineequation inlinemediaobject
70 itemizedlist itermset keycombo keywordset legalnotice listitem lot
71 mediaobject mediaobjectco menuchoice msg msgentry msgexplan msginfo
72 msgmain msgrel msgset msgsub msgtext note objectinfo
73 orderedlist othercredit part partintro preface printhistory procedure
74 programlistingco publisher qandadiv qandaentry qandaset question
75 refentry reference refmeta refnamediv refsection refsect1 refsect1info refsect2
76 refsect2info refsect3 refsect3info refsynopsisdiv refsynopsisdivinfo
77 revhistory revision row sbr screenco screenshot sect1 sect1info sect2
78 sect2info sect3 sect3info sect4 sect4info sect5 sect5info section
79 sectioninfo seglistitem segmentedlist seriesinfo set setindex setinfo
80 shortcut sidebar simplelist simplesect spanspec step subject
81 subjectset substeps synopfragment table tbody textobject tfoot tgroup
82 thead tip toc tocchap toclevel1 toclevel2 toclevel3 toclevel4
83 toclevel5 tocpart varargs variablelist varlistentry videodata
84 videoobject void warning subjectset
99 <!-- ====================================================================== -->
101 <doc:template name="is.component" xmlns="">
102 <refpurpose>Tests if a given node is a component-level element</refpurpose>
105 <para>This template returns '1' if the specified node is a component
106 (Chapter, Appendix, etc.), and '0' otherwise.</para>
111 <varlistentry><term>node</term>
113 <para>The node which is to be tested.</para>
120 <para>This template returns '1' if the specified node is a component
121 (Chapter, Appendix, etc.), and '0' otherwise.</para>
125 <xsl:template name="is.component">
126 <xsl:param name="node" select="."/>
128 <xsl:when test="local-name($node) = 'appendix'
129 or local-name($node) = 'article'
130 or local-name($node) = 'chapter'
131 or local-name($node) = 'preface'
132 or local-name($node) = 'bibliography'
133 or local-name($node) = 'glossary'
134 or local-name($node) = 'index'">1</xsl:when>
135 <xsl:otherwise>0</xsl:otherwise>
139 <!-- ====================================================================== -->
141 <doc:template name="is.section" xmlns="">
142 <refpurpose>Tests if a given node is a section-level element</refpurpose>
145 <para>This template returns '1' if the specified node is a section
146 (Section, Sect1, Sect2, etc.), and '0' otherwise.</para>
151 <varlistentry><term>node</term>
153 <para>The node which is to be tested.</para>
160 <para>This template returns '1' if the specified node is a section
161 (Section, Sect1, Sect2, etc.), and '0' otherwise.</para>
165 <xsl:template name="is.section">
166 <xsl:param name="node" select="."/>
168 <xsl:when test="local-name($node) = 'section'
169 or local-name($node) = 'sect1'
170 or local-name($node) = 'sect2'
171 or local-name($node) = 'sect3'
172 or local-name($node) = 'sect4'
173 or local-name($node) = 'sect5'
174 or local-name($node) = 'refsect1'
175 or local-name($node) = 'refsect2'
176 or local-name($node) = 'refsect3'
177 or local-name($node) = 'simplesect'">1</xsl:when>
178 <xsl:otherwise>0</xsl:otherwise>
182 <!-- ====================================================================== -->
184 <doc:template name="section.level" xmlns="">
185 <refpurpose>Returns the hierarchical level of a section</refpurpose>
188 <para>This template calculates the hierarchical level of a section.
189 The element <sgmltag>sect1</sgmltag> is at level 1, <sgmltag>sect2</sgmltag> is
190 at level 2, etc.</para>
192 <para>Recursive sections are calculated down to the fifth level.</para>
197 <varlistentry><term>node</term>
199 <para>The section node for which the level should be calculated.
200 Defaults to the context node.</para>
207 <para>The section level, <quote>1</quote>, <quote>2</quote>, etc.
212 <xsl:template name="section.level">
213 <xsl:param name="node" select="."/>
215 <xsl:when test="name($node)='sect1'">1</xsl:when>
216 <xsl:when test="name($node)='sect2'">2</xsl:when>
217 <xsl:when test="name($node)='sect3'">3</xsl:when>
218 <xsl:when test="name($node)='sect4'">4</xsl:when>
219 <xsl:when test="name($node)='sect5'">5</xsl:when>
220 <xsl:when test="name($node)='section'">
222 <xsl:when test="$node/../../../../../../section">6</xsl:when>
223 <xsl:when test="$node/../../../../../section">5</xsl:when>
224 <xsl:when test="$node/../../../../section">4</xsl:when>
225 <xsl:when test="$node/../../../section">3</xsl:when>
226 <xsl:when test="$node/../../section">2</xsl:when>
227 <xsl:otherwise>1</xsl:otherwise>
230 <xsl:when test="name($node)='refsect1' or
231 name($node)='refsect2' or
232 name($node)='refsect3' or
233 name($node)='refsection' or
234 name($node)='refsynopsisdiv'">
235 <xsl:call-template name="refentry.section.level">
236 <xsl:with-param name="node" select="$node"/>
239 <xsl:when test="name($node)='simplesect'">
241 <xsl:when test="$node/../../sect1">2</xsl:when>
242 <xsl:when test="$node/../../sect2">3</xsl:when>
243 <xsl:when test="$node/../../sect3">4</xsl:when>
244 <xsl:when test="$node/../../sect4">5</xsl:when>
245 <xsl:when test="$node/../../sect5">5</xsl:when>
246 <xsl:when test="$node/../../section">
248 <xsl:when test="$node/../../../../../section">5</xsl:when>
249 <xsl:when test="$node/../../../../section">4</xsl:when>
250 <xsl:when test="$node/../../../section">3</xsl:when>
251 <xsl:otherwise>2</xsl:otherwise>
254 <xsl:otherwise>1</xsl:otherwise>
257 <xsl:otherwise>1</xsl:otherwise>
259 </xsl:template><!-- section.level -->
261 <doc:template name="qanda.section.level" xmlns="">
262 <refpurpose>Returns the hierarchical level of a QandASet</refpurpose>
265 <para>This template calculates the hierarchical level of a QandASet.
270 <para>The level, <quote>1</quote>, <quote>2</quote>, etc.
275 <xsl:template name="qanda.section.level">
276 <xsl:variable name="section"
277 select="(ancestor::section
278 |ancestor::simplesect
286 |ancestor::refsect1)[last()]"/>
289 <xsl:when test="count($section) = '0'">1</xsl:when>
291 <xsl:variable name="slevel">
292 <xsl:call-template name="section.level">
293 <xsl:with-param name="node" select="$section"/>
296 <xsl:value-of select="$slevel + 1"/>
301 <!-- Finds the total section depth of a section in a refentry -->
302 <xsl:template name="refentry.section.level">
303 <xsl:param name="node" select="."/>
305 <xsl:variable name="RElevel">
306 <xsl:call-template name="refentry.level">
307 <xsl:with-param name="node" select="$node/ancestor::refentry[1]"/>
311 <xsl:variable name="levelinRE">
313 <xsl:when test="name($node)='refsynopsisdiv'">1</xsl:when>
314 <xsl:when test="name($node)='refsect1'">1</xsl:when>
315 <xsl:when test="name($node)='refsect2'">2</xsl:when>
316 <xsl:when test="name($node)='refsect3'">3</xsl:when>
317 <xsl:when test="name($node)='refsection'">
319 <xsl:when test="$node/../../../../../refsection">5</xsl:when>
320 <xsl:when test="$node/../../../../refsection">4</xsl:when>
321 <xsl:when test="$node/../../../refsection">3</xsl:when>
322 <xsl:when test="$node/../../refsection">2</xsl:when>
323 <xsl:otherwise>1</xsl:otherwise>
329 <xsl:value-of select="$levelinRE + $RElevel"/>
332 <!-- Finds the section depth of a refentry -->
333 <xsl:template name="refentry.level">
334 <xsl:param name="node" select="."/>
335 <xsl:variable name="container"
336 select="($node/ancestor::section |
337 $node/ancestor::sect1 |
338 $node/ancestor::sect2 |
339 $node/ancestor::sect3 |
340 $node/ancestor::sect4 |
341 $node/ancestor::sect5)[last()]"/>
344 <xsl:when test="$container">
345 <xsl:variable name="slevel">
346 <xsl:call-template name="section.level">
347 <xsl:with-param name="node" select="$container"/>
350 <xsl:value-of select="$slevel + 1"/>
352 <xsl:otherwise>1</xsl:otherwise>
356 <xsl:template name="qandadiv.section.level">
357 <xsl:variable name="section.level">
358 <xsl:call-template name="qanda.section.level"/>
360 <xsl:variable name="anc.divs" select="ancestor::qandadiv"/>
362 <xsl:value-of select="count($anc.divs) + number($section.level)"/>
365 <xsl:template name="question.answer.label">
366 <xsl:variable name="deflabel">
368 <xsl:when test="ancestor-or-self::*[@defaultlabel]">
369 <xsl:value-of select="(ancestor-or-self::*[@defaultlabel])[last()]
373 <xsl:value-of select="$qanda.defaultlabel"/>
378 <xsl:variable name="label" select="@label"/>
381 (hnr (hierarchical-number-recursive (normalize "qandadiv") node))
383 (parsect (ancestor-member node (section-element-list)))
385 (defnum (if (and %qanda-inherit-numeration%
387 (if (node-list-empty? parsect)
388 (section-autolabel-prefix node)
389 (section-autolabel parsect))
392 (hnumber (let loop ((numlist hnr) (number defnum)
393 (sep (if (equal? defnum "") "" ".")))
397 (string-append number
399 (number->string (car numlist)))
401 (cnumber (child-number (parent node)))
402 (number (string-append hnumber
403 (if (equal? hnumber "")
406 (number->string cnumber))))
410 <xsl:when test="$deflabel = 'qanda'">
411 <xsl:call-template name="gentext">
412 <xsl:with-param name="key">
414 <xsl:when test="local-name(.) = 'question'">question</xsl:when>
415 <xsl:when test="local-name(.) = 'answer'">answer</xsl:when>
416 <xsl:when test="local-name(.) = 'qandadiv'">qandadiv</xsl:when>
417 <xsl:otherwise>qandaset</xsl:otherwise>
422 <xsl:when test="$deflabel = 'label'">
423 <xsl:value-of select="$label"/>
425 <xsl:when test="$deflabel = 'number'
426 and local-name(.) = 'question'">
427 <xsl:apply-templates select="ancestor::qandaset[1]"
430 <xsl:when test="ancestor::qandadiv">
431 <xsl:apply-templates select="ancestor::qandadiv[1]"
433 <xsl:apply-templates select="ancestor::qandaentry"
437 <xsl:apply-templates select="ancestor::qandaentry"
448 <xsl:template match="qandaset" mode="number">
452 <xsl:template match="qandadiv" mode="number">
453 <xsl:number level="multiple" from="qandaset" format="1."/>
456 <xsl:template match="qandaentry" mode="number">
458 <xsl:when test="ancestor::qandadiv">
459 <xsl:number level="single" from="qandadiv" format="1."/>
462 <xsl:number level="single" from="qandaset" format="1."/>
467 <!-- ====================================================================== -->
469 <xsl:template name="object.id">
470 <xsl:param name="object" select="."/>
472 <xsl:when test="$object/@id">
473 <xsl:value-of select="$object/@id"/>
475 <xsl:when test="$object/@xml:id">
476 <xsl:value-of select="$object/@xml:id"/>
479 <xsl:value-of select="generate-id($object)"/>
484 <xsl:template name="person.name">
485 <!-- Formats a personal name. Handles corpauthor as a special case. -->
486 <xsl:param name="node" select="."/>
488 <xsl:variable name="style">
490 <xsl:when test="$node/@role">
491 <xsl:value-of select="$node/@role"/>
494 <xsl:call-template name="gentext.template">
495 <xsl:with-param name="context" select="'styles'"/>
496 <xsl:with-param name="name" select="'person-name'"/>
503 <!-- the personname element is a specialcase -->
504 <xsl:when test="$node/personname">
505 <xsl:call-template name="person.name">
506 <xsl:with-param name="node" select="$node/personname"/>
510 <!-- handle corpauthor as a special case...-->
511 <xsl:when test="name($node)='corpauthor'">
512 <xsl:apply-templates select="$node"/>
517 <xsl:when test="$style = 'family-given'">
518 <xsl:call-template name="person.name.family-given">
519 <xsl:with-param name="node" select="$node"/>
522 <xsl:when test="$style = 'last-first'">
523 <xsl:call-template name="person.name.last-first">
524 <xsl:with-param name="node" select="$node"/>
528 <xsl:call-template name="person.name.first-last">
529 <xsl:with-param name="node" select="$node"/>
537 <xsl:template name="person.name.family-given">
538 <xsl:param name="node" select="."/>
540 <!-- The family-given style applies a convention for identifying given -->
541 <!-- and family names in locales where it may be ambiguous -->
542 <xsl:apply-templates select="$node//surname[1]"/>
544 <xsl:if test="$node//surname and $node//firstname">
545 <xsl:text> </xsl:text>
548 <xsl:apply-templates select="$node//firstname[1]"/>
550 <xsl:text> [FAMILY Given]</xsl:text>
553 <xsl:template name="person.name.last-first">
554 <xsl:param name="node" select="."/>
556 <xsl:apply-templates select="$node//surname[1]"/>
558 <xsl:if test="$node//surname and $node//firstname">
559 <xsl:text>, </xsl:text>
562 <xsl:apply-templates select="$node//firstname[1]"/>
565 <xsl:template name="person.name.first-last">
566 <xsl:param name="node" select="."/>
568 <xsl:if test="$node//honorific">
569 <xsl:apply-templates select="$node//honorific[1]"/>
570 <xsl:value-of select="$punct.honorific"/>
573 <xsl:if test="$node//firstname">
574 <xsl:if test="$node//honorific">
575 <xsl:text> </xsl:text>
577 <xsl:apply-templates select="$node//firstname[1]"/>
580 <xsl:if test="$node//othername and $author.othername.in.middle != 0">
581 <xsl:if test="$node//honorific or $node//firstname">
582 <xsl:text> </xsl:text>
584 <xsl:apply-templates select="$node//othername[1]"/>
587 <xsl:if test="$node//surname">
588 <xsl:if test="$node//honorific or $node//firstname
589 or ($node//othername and $author.othername.in.middle != 0)">
590 <xsl:text> </xsl:text>
592 <xsl:apply-templates select="$node//surname[1]"/>
595 <xsl:if test="$node//lineage">
596 <xsl:text>, </xsl:text>
597 <xsl:apply-templates select="$node//lineage[1]"/>
601 <xsl:template name="person.name.list">
602 <!-- Return a formatted string representation of the contents of
603 the current element. The current element must contain one or
604 more AUTHORs, CORPAUTHORs, OTHERCREDITs, and/or EDITORs.
608 John Doe and Jane Doe
610 John Doe, Jane Doe, and A. Nonymous
612 <xsl:param name="person.list"
613 select="author|corpauthor|othercredit|editor"/>
614 <xsl:param name="person.count" select="count($person.list)"/>
615 <xsl:param name="count" select="1"/>
618 <xsl:when test="$count > $person.count"></xsl:when>
620 <xsl:call-template name="person.name">
621 <xsl:with-param name="node" select="$person.list[position()=$count]"/>
625 <xsl:when test="$person.count = 2 and $count = 1">
626 <xsl:call-template name="gentext.template">
627 <xsl:with-param name="context" select="'authorgroup'"/>
628 <xsl:with-param name="name" select="'sep2'"/>
631 <xsl:when test="$person.count > 2 and $count+1 = $person.count">
632 <xsl:call-template name="gentext.template">
633 <xsl:with-param name="context" select="'authorgroup'"/>
634 <xsl:with-param name="name" select="'seplast'"/>
637 <xsl:when test="$count < $person.count">
638 <xsl:call-template name="gentext.template">
639 <xsl:with-param name="context" select="'authorgroup'"/>
640 <xsl:with-param name="name" select="'sep'"/>
645 <xsl:call-template name="person.name.list">
646 <xsl:with-param name="person.list" select="$person.list"/>
647 <xsl:with-param name="person.count" select="$person.count"/>
648 <xsl:with-param name="count" select="$count+1"/>
652 </xsl:template><!-- person.name.list -->
654 <!-- === synopsis ======================================================= -->
655 <!-- The following definitions match those given in the reference
656 documentation for DocBook V3.0
659 <xsl:variable name="arg.choice.opt.open.str">[</xsl:variable>
660 <xsl:variable name="arg.choice.opt.close.str">]</xsl:variable>
661 <xsl:variable name="arg.choice.req.open.str">{</xsl:variable>
662 <xsl:variable name="arg.choice.req.close.str">}</xsl:variable>
663 <xsl:variable name="arg.choice.plain.open.str"><xsl:text> </xsl:text></xsl:variable>
664 <xsl:variable name="arg.choice.plain.close.str"><xsl:text> </xsl:text></xsl:variable>
665 <xsl:variable name="arg.choice.def.open.str">[</xsl:variable>
666 <xsl:variable name="arg.choice.def.close.str">]</xsl:variable>
667 <xsl:variable name="arg.rep.repeat.str">...</xsl:variable>
668 <xsl:variable name="arg.rep.norepeat.str"></xsl:variable>
669 <xsl:variable name="arg.rep.def.str"></xsl:variable>
670 <xsl:variable name="arg.or.sep"> | </xsl:variable>
671 <xsl:variable name="cmdsynopsis.hanging.indent">4pi</xsl:variable>
673 <!-- ====================================================================== -->
676 <xsl:template name="xref.g.subst">
677 <xsl:param name="string"></xsl:param>
678 <xsl:param name="target" select="."/>
679 <xsl:variable name="subst">%g</xsl:variable>
682 <xsl:when test="contains($string, $subst)">
683 <xsl:value-of select="substring-before($string, $subst)"/>
684 <xsl:call-template name="gentext.element.name">
685 <xsl:with-param name="element.name" select="name($target)"/>
687 <xsl:call-template name="xref.g.subst">
688 <xsl:with-param name="string"
689 select="substring-after($string, $subst)"/>
690 <xsl:with-param name="target" select="$target"/>
694 <xsl:value-of select="$string"/>
699 <xsl:template name="xref.t.subst">
700 <xsl:param name="string"></xsl:param>
701 <xsl:param name="target" select="."/>
702 <xsl:variable name="subst">%t</xsl:variable>
705 <xsl:when test="contains($string, $subst)">
706 <xsl:call-template name="xref.g.subst">
707 <xsl:with-param name="string"
708 select="substring-before($string, $subst)"/>
709 <xsl:with-param name="target" select="$target"/>
711 <xsl:call-template name="title.xref">
712 <xsl:with-param name="target" select="$target"/>
714 <xsl:call-template name="xref.t.subst">
715 <xsl:with-param name="string"
716 select="substring-after($string, $subst)"/>
717 <xsl:with-param name="target" select="$target"/>
721 <xsl:call-template name="xref.g.subst">
722 <xsl:with-param name="string" select="$string"/>
723 <xsl:with-param name="target" select="$target"/>
729 <xsl:template name="xref.n.subst">
730 <xsl:param name="string"></xsl:param>
731 <xsl:param name="target" select="."/>
732 <xsl:variable name="subst">%n</xsl:variable>
735 <xsl:when test="contains($string, $subst)">
736 <xsl:call-template name="xref.t.subst">
737 <xsl:with-param name="string"
738 select="substring-before($string, $subst)"/>
739 <xsl:with-param name="target" select="$target"/>
741 <xsl:call-template name="number.xref">
742 <xsl:with-param name="target" select="$target"/>
744 <xsl:call-template name="xref.t.subst">
745 <xsl:with-param name="string"
746 select="substring-after($string, $subst)"/>
747 <xsl:with-param name="target" select="$target"/>
751 <xsl:call-template name="xref.t.subst">
752 <xsl:with-param name="string" select="$string"/>
753 <xsl:with-param name="target" select="$target"/>
759 <xsl:template name="subst.xref.text">
760 <xsl:param name="xref.text"></xsl:param>
761 <xsl:param name="target" select="."/>
763 <xsl:call-template name="xref.n.subst">
764 <xsl:with-param name="string" select="$xref.text"/>
765 <xsl:with-param name="target" select="$target"/>
770 <!-- ====================================================================== -->
772 <xsl:template name="filename-basename">
773 <!-- We assume all filenames are really URIs and use "/" -->
774 <xsl:param name="filename"></xsl:param>
775 <xsl:param name="recurse" select="false()"/>
778 <xsl:when test="substring-after($filename, '/') != ''">
779 <xsl:call-template name="filename-basename">
780 <xsl:with-param name="filename"
781 select="substring-after($filename, '/')"/>
782 <xsl:with-param name="recurse" select="true()"/>
786 <xsl:value-of select="$filename"/>
791 <xsl:template name="filename-extension">
792 <xsl:param name="filename"></xsl:param>
793 <xsl:param name="recurse" select="false()"/>
795 <!-- Make sure we only look at the base name... -->
796 <xsl:variable name="basefn">
798 <xsl:when test="$recurse">
799 <xsl:value-of select="$filename"/>
802 <xsl:call-template name="filename-basename">
803 <xsl:with-param name="filename" select="$filename"/>
810 <xsl:when test="substring-after($basefn, '.') != ''">
811 <xsl:call-template name="filename-extension">
812 <xsl:with-param name="filename"
813 select="substring-after($basefn, '.')"/>
814 <xsl:with-param name="recurse" select="true()"/>
817 <xsl:when test="$recurse">
818 <xsl:value-of select="$basefn"/>
820 <xsl:otherwise></xsl:otherwise>
824 <!-- ====================================================================== -->
826 <doc:template name="select.mediaobject" xmlns="">
827 <refpurpose>Selects and processes an appropriate media object from a list</refpurpose>
830 <para>This template takes a list of media objects (usually the
831 children of a mediaobject or inlinemediaobject) and processes
832 the "right" object.</para>
834 <para>This template relies on a template named
835 "select.mediaobject.index" to determine which object
836 in the list is appropriate.</para>
838 <para>If no acceptable object is located, nothing happens.</para>
843 <varlistentry><term>olist</term>
845 <para>The node list of potential objects to examine.</para>
852 <para>Calls <xsl:apply-templates> on the selected object.</para>
856 <xsl:template name="select.mediaobject">
857 <xsl:param name="olist"
858 select="imageobject|imageobjectco
859 |videoobject|audioobject|textobject"/>
861 <xsl:variable name="mediaobject.index">
862 <xsl:call-template name="select.mediaobject.index">
863 <xsl:with-param name="olist" select="$olist"/>
864 <xsl:with-param name="count" select="1"/>
868 <xsl:if test="$mediaobject.index != ''">
869 <xsl:apply-templates select="$olist[position() = $mediaobject.index]"/>
873 <!-- ====================================================================== -->
875 <doc:template name="select.mediaobject.index" xmlns="">
876 <refpurpose>Selects the position of the appropriate media object from a list</refpurpose>
879 <para>This template takes a list of media objects (usually the
880 children of a mediaobject or inlinemediaobject) and determines
881 the "right" object. It returns the position of that object
882 to be used by the calling template.</para>
884 <para>If the parameter <parameter>use.role.for.mediaobject</parameter>
885 is nonzero, then it first checks for an object with
886 a role attribute of the appropriate value. It takes the first
887 of those. Otherwise, it takes the first acceptable object
888 through a recursive pass through the list.</para>
890 <para>This template relies on a template named "is.acceptable.mediaobject"
891 to determine if a given object is an acceptable graphic. The semantics
892 of media objects is that the first acceptable graphic should be used.
895 <para>If no acceptable object is located, no index is returned.</para>
900 <varlistentry><term>olist</term>
902 <para>The node list of potential objects to examine.</para>
905 <varlistentry><term>count</term>
907 <para>The position in the list currently being considered by the
908 recursive process.</para>
915 <para>Returns the position in the original list of the selected object.</para>
919 <xsl:template name="select.mediaobject.index">
920 <xsl:param name="olist"
921 select="imageobject|imageobjectco
922 |videoobject|audioobject|textobject"/>
923 <xsl:param name="count">1</xsl:param>
926 <!-- Test for objects preferred by role -->
927 <xsl:when test="$use.role.for.mediaobject != 0
928 and $preferred.mediaobject.role != ''
929 and $olist[@role = $preferred.mediaobject.role]">
931 <!-- Get the first hit's position index -->
932 <xsl:for-each select="$olist">
933 <xsl:if test="@role = $preferred.mediaobject.role and
934 not(preceding-sibling::*[@role = $preferred.mediaobject.role])">
935 <xsl:value-of select="position()"/>
940 <xsl:when test="$use.role.for.mediaobject != 0
941 and $olist[@role = $stylesheet.result.type]">
942 <!-- Get the first hit's position index -->
943 <xsl:for-each select="$olist">
944 <xsl:if test="@role = $stylesheet.result.type and
945 not(preceding-sibling::*[@role = $stylesheet.result.type])">
946 <xsl:value-of select="position()"/>
950 <!-- Accept 'html' for $stylesheet.result.type = 'xhtml' -->
951 <xsl:when test="$use.role.for.mediaobject != 0
952 and $stylesheet.result.type = 'xhtml'
953 and $olist[@role = 'html']">
954 <!-- Get the first hit's position index -->
955 <xsl:for-each select="$olist">
956 <xsl:if test="@role = 'html' and
957 not(preceding-sibling::*[@role = 'html'])">
958 <xsl:value-of select="position()"/>
963 <!-- Otherwise select first acceptable object -->
964 <xsl:if test="$count <= count($olist)">
965 <xsl:variable name="object" select="$olist[position()=$count]"/>
967 <xsl:variable name="useobject">
969 <!-- The phrase is used only when contains TeX Math and output is FO -->
970 <xsl:when test="name($object)='textobject' and $object/phrase
971 and $object/@role='tex' and $stylesheet.result.type = 'fo'
972 and $tex.math.in.alt != ''">
973 <xsl:text>1</xsl:text>
975 <!-- The phrase is never used -->
976 <xsl:when test="name($object)='textobject' and $object/phrase">
977 <xsl:text>0</xsl:text>
979 <xsl:when test="name($object)='textobject'
980 and $object/ancestor::equation ">
981 <!-- The first textobject is not a reasonable fallback
982 for equation image -->
983 <xsl:text>0</xsl:text>
985 <!-- The first textobject is a reasonable fallback -->
986 <xsl:when test="name($object)='textobject'
987 and $object[not(@role) or @role!='tex']">
988 <xsl:text>1</xsl:text>
990 <!-- don't use graphic when output is FO, TeX Math is used
991 and there is math in alt element -->
992 <xsl:when test="$object/ancestor::equation and
993 $object/ancestor::equation/alt[@role='tex']
994 and $stylesheet.result.type = 'fo'
995 and $tex.math.in.alt != ''">
996 <xsl:text>0</xsl:text>
998 <!-- If there's only one object, use it -->
999 <xsl:when test="$count = 1 and count($olist) = 1">
1000 <xsl:text>1</xsl:text>
1002 <!-- Otherwise, see if this one is a useable graphic -->
1005 <!-- peek inside imageobjectco to simplify the test -->
1006 <xsl:when test="local-name($object) = 'imageobjectco'">
1007 <xsl:call-template name="is.acceptable.mediaobject">
1008 <xsl:with-param name="object" select="$object/imageobject"/>
1009 </xsl:call-template>
1012 <xsl:call-template name="is.acceptable.mediaobject">
1013 <xsl:with-param name="object" select="$object"/>
1014 </xsl:call-template>
1022 <xsl:when test="$useobject='1'">
1023 <xsl:value-of select="$count"/>
1026 <xsl:call-template name="select.mediaobject.index">
1027 <xsl:with-param name="olist" select="$olist"/>
1028 <xsl:with-param name="count" select="$count + 1"/>
1029 </xsl:call-template>
1037 <doc:template name="is.acceptable.mediaobject" xmlns="">
1038 <refpurpose>Returns '1' if the specified media object is recognized</refpurpose>
1041 <para>This template examines a media object and returns '1' if the
1042 object is recognized as a graphic.</para>
1047 <varlistentry><term>object</term>
1049 <para>The media object to consider.</para>
1060 <xsl:template name="is.acceptable.mediaobject">
1061 <xsl:param name="object"></xsl:param>
1063 <xsl:variable name="filename">
1064 <xsl:call-template name="mediaobject.filename">
1065 <xsl:with-param name="object" select="$object"/>
1066 </xsl:call-template>
1069 <xsl:variable name="ext">
1070 <xsl:call-template name="filename-extension">
1071 <xsl:with-param name="filename" select="$filename"/>
1072 </xsl:call-template>
1075 <!-- there will only be one -->
1076 <xsl:variable name="data" select="$object/videodata
1078 |$object/audiodata"/>
1080 <xsl:variable name="format" select="$data/@format"/>
1082 <xsl:variable name="graphic.format">
1083 <xsl:if test="$format">
1084 <xsl:call-template name="is.graphic.format">
1085 <xsl:with-param name="format" select="$format"/>
1086 </xsl:call-template>
1090 <xsl:variable name="graphic.ext">
1091 <xsl:if test="$ext">
1092 <xsl:call-template name="is.graphic.extension">
1093 <xsl:with-param name="ext" select="$ext"/>
1094 </xsl:call-template>
1099 <xsl:when test="$use.svg = 0 and $format = 'SVG'">0</xsl:when>
1100 <xsl:when xmlns:svg="http://www.w3.org/2000/svg"
1101 test="$use.svg != 0 and $object/svg:*">1</xsl:when>
1102 <xsl:when test="$graphic.format = '1'">1</xsl:when>
1103 <xsl:when test="$graphic.ext = '1'">1</xsl:when>
1104 <xsl:otherwise>0</xsl:otherwise>
1108 <xsl:template name="mediaobject.filename">
1109 <xsl:param name="object"></xsl:param>
1111 <xsl:variable name="data" select="$object/videodata
1116 <xsl:variable name="filename">
1118 <xsl:when test="$data[@fileref]">
1119 <xsl:apply-templates select="$data/@fileref"/>
1121 <xsl:when test="$data[@entityref]">
1122 <xsl:value-of select="unparsed-entity-uri($data/@entityref)"/>
1124 <xsl:otherwise></xsl:otherwise>
1128 <xsl:variable name="real.ext">
1129 <xsl:call-template name="filename-extension">
1130 <xsl:with-param name="filename" select="$filename"/>
1131 </xsl:call-template>
1134 <xsl:variable name="ext">
1136 <xsl:when test="$real.ext != ''">
1137 <xsl:value-of select="$real.ext"/>
1140 <xsl:value-of select="$graphic.default.extension"/>
1145 <xsl:variable name="graphic.ext">
1146 <xsl:call-template name="is.graphic.extension">
1147 <xsl:with-param name="ext" select="$ext"/>
1148 </xsl:call-template>
1152 <xsl:when test="$real.ext = ''">
1154 <xsl:when test="$ext != ''">
1155 <xsl:value-of select="$filename"/>
1156 <xsl:text>.</xsl:text>
1157 <xsl:value-of select="$ext"/>
1160 <xsl:value-of select="$filename"/>
1164 <xsl:when test="not($graphic.ext)">
1166 <xsl:when test="$graphic.default.extension != ''">
1167 <xsl:value-of select="$filename"/>
1168 <xsl:text>.</xsl:text>
1169 <xsl:value-of select="$graphic.default.extension"/>
1172 <xsl:value-of select="$filename"/>
1177 <xsl:value-of select="$filename"/>
1182 <!-- ====================================================================== -->
1184 <doc:template name="check.id.unique" xmlns="">
1185 <refpurpose>Warn users about references to non-unique IDs</refpurpose>
1187 <para>If passed an ID in <varname>linkend</varname>,
1188 <function>check.id.unique</function> prints
1189 a warning message to the user if either the ID does not exist or
1190 the ID is not unique.</para>
1194 <xsl:template name="check.id.unique">
1195 <xsl:param name="linkend"></xsl:param>
1196 <xsl:if test="$linkend != ''">
1197 <xsl:variable name="targets" select="key('id',$linkend)"/>
1198 <xsl:variable name="target" select="$targets[1]"/>
1200 <xsl:if test="count($targets)=0">
1202 <xsl:text>Error: no ID for constraint linkend: </xsl:text>
1203 <xsl:value-of select="$linkend"/>
1204 <xsl:text>.</xsl:text>
1208 <xsl:text>If the ID exists in your document, did your </xsl:text>
1209 <xsl:text>XSLT Processor load the DTD?</xsl:text>
1214 <xsl:if test="count($targets)>1">
1216 <xsl:text>Warning: multiple "IDs" for constraint linkend: </xsl:text>
1217 <xsl:value-of select="$linkend"/>
1218 <xsl:text>.</xsl:text>
1224 <doc:template name="check.idref.targets" xmlns="">
1225 <refpurpose>Warn users about incorrectly typed references</refpurpose>
1227 <para>If passed an ID in <varname>linkend</varname>,
1228 <function>check.idref.targets</function> makes sure that the element
1229 pointed to by the link is one of the elements listed in
1230 <varname>element-list</varname> and warns the user otherwise.</para>
1234 <xsl:template name="check.idref.targets">
1235 <xsl:param name="linkend"></xsl:param>
1236 <xsl:param name="element-list"></xsl:param>
1237 <xsl:if test="$linkend != ''">
1238 <xsl:variable name="targets" select="key('id',$linkend)"/>
1239 <xsl:variable name="target" select="$targets[1]"/>
1241 <xsl:if test="count($target) > 0">
1242 <xsl:if test="not(contains(concat(' ', $element-list, ' '), name($target)))">
1244 <xsl:text>Error: linkend (</xsl:text>
1245 <xsl:value-of select="$linkend"/>
1246 <xsl:text>) points to "</xsl:text>
1247 <xsl:value-of select="name($target)"/>
1248 <xsl:text>" not (one of): </xsl:text>
1249 <xsl:value-of select="$element-list"/>
1256 <!-- ====================================================================== -->
1257 <!-- Procedure Step Numeration -->
1259 <xsl:param name="procedure.step.numeration.formats" select="'1aiAI'"/>
1261 <xsl:template name="procedure.step.numeration">
1262 <xsl:param name="context" select="."/>
1263 <xsl:variable name="format.length"
1264 select="string-length($procedure.step.numeration.formats)"/>
1266 <xsl:when test="local-name($context) = 'substeps'">
1267 <xsl:variable name="ssdepth"
1268 select="count($context/ancestor::substeps)"/>
1269 <xsl:variable name="sstype" select="($ssdepth mod $format.length)+2"/>
1271 <xsl:when test="$sstype > $format.length">
1272 <xsl:value-of select="substring($procedure.step.numeration.formats,1,1)"/>
1275 <xsl:value-of select="substring($procedure.step.numeration.formats,$sstype,1)"/>
1279 <xsl:when test="local-name($context) = 'step'">
1280 <xsl:variable name="sdepth"
1281 select="count($context/ancestor::substeps)"/>
1282 <xsl:variable name="stype" select="($sdepth mod $format.length)+1"/>
1283 <xsl:value-of select="substring($procedure.step.numeration.formats,$stype,1)"/>
1287 <xsl:text>Unexpected context in procedure.step.numeration: </xsl:text>
1288 <xsl:value-of select="local-name($context)"/>
1294 <xsl:template match="step" mode="number">
1295 <xsl:param name="rest" select="''"/>
1296 <xsl:param name="recursive" select="1"/>
1297 <xsl:variable name="format">
1298 <xsl:call-template name="procedure.step.numeration"/>
1300 <xsl:variable name="num">
1301 <xsl:number count="step" format="{$format}"/>
1304 <xsl:when test="$recursive != 0 and ancestor::step">
1305 <xsl:apply-templates select="ancestor::step[1]" mode="number">
1306 <xsl:with-param name="rest" select="concat('.', $num, $rest)"/>
1307 </xsl:apply-templates>
1310 <xsl:value-of select="concat($num, $rest)"/>
1315 <!-- ====================================================================== -->
1316 <!-- OrderedList Numeration -->
1318 <xsl:template name="orderedlist-starting-number">
1319 <xsl:param name="list" select="."/>
1321 <xsl:when test="not($list/@continuation = 'continues')">1</xsl:when>
1323 <xsl:variable name="prevlist"
1324 select="$list/preceding::orderedlist[1]"/>
1326 <xsl:when test="count($prevlist) = 0">2</xsl:when>
1328 <xsl:variable name="prevlength" select="count($prevlist/listitem)"/>
1329 <xsl:variable name="prevstart">
1330 <xsl:call-template name="orderedlist-starting-number">
1331 <xsl:with-param name="list" select="$prevlist"/>
1332 </xsl:call-template>
1334 <xsl:value-of select="$prevstart + $prevlength"/>
1341 <xsl:template name="orderedlist-item-number">
1342 <!-- context node must be a listitem in an orderedlist -->
1343 <xsl:param name="node" select="."/>
1346 <xsl:when test="$node/@override">
1347 <xsl:value-of select="$node/@override"/>
1349 <xsl:when test="$node/preceding-sibling::listitem">
1350 <xsl:variable name="pnum">
1351 <xsl:call-template name="orderedlist-item-number">
1352 <xsl:with-param name="node" select="$node/preceding-sibling::listitem[1]"/>
1353 </xsl:call-template>
1355 <xsl:value-of select="$pnum + 1"/>
1358 <xsl:call-template name="orderedlist-starting-number">
1359 <xsl:with-param name="list" select="parent::*"/>
1360 </xsl:call-template>
1365 <xsl:template name="next.numeration">
1366 <xsl:param name="numeration" select="'default'"/>
1368 <!-- Change this list if you want to change the order of numerations -->
1369 <xsl:when test="$numeration = 'arabic'">loweralpha</xsl:when>
1370 <xsl:when test="$numeration = 'loweralpha'">lowerroman</xsl:when>
1371 <xsl:when test="$numeration = 'lowerroman'">upperalpha</xsl:when>
1372 <xsl:when test="$numeration = 'upperalpha'">upperroman</xsl:when>
1373 <xsl:when test="$numeration = 'upperroman'">arabic</xsl:when>
1374 <xsl:otherwise>arabic</xsl:otherwise>
1378 <xsl:template name="list.numeration">
1379 <xsl:param name="node" select="."/>
1382 <xsl:when test="$node/@numeration">
1383 <xsl:value-of select="$node/@numeration"/>
1387 <xsl:when test="$node/ancestor::orderedlist">
1388 <xsl:call-template name="next.numeration">
1389 <xsl:with-param name="numeration">
1390 <xsl:call-template name="list.numeration">
1391 <xsl:with-param name="node" select="$node/ancestor::orderedlist[1]"/>
1392 </xsl:call-template>
1394 </xsl:call-template>
1397 <xsl:call-template name="next.numeration"/>
1404 <!-- ====================================================================== -->
1405 <!-- ItemizedList "Numeration" -->
1407 <xsl:template name="next.itemsymbol">
1408 <xsl:param name="itemsymbol" select="'default'"/>
1410 <!-- Change this list if you want to change the order of symbols -->
1411 <xsl:when test="$itemsymbol = 'disc'">circle</xsl:when>
1412 <xsl:when test="$itemsymbol = 'circle'">square</xsl:when>
1413 <xsl:otherwise>disc</xsl:otherwise>
1417 <xsl:template name="list.itemsymbol">
1418 <xsl:param name="node" select="."/>
1421 <xsl:when test="@override">
1422 <xsl:value-of select="@override"/>
1424 <xsl:when test="$node/@mark">
1425 <xsl:value-of select="$node/@mark"/>
1429 <xsl:when test="$node/ancestor::itemizedlist">
1430 <xsl:call-template name="next.itemsymbol">
1431 <xsl:with-param name="itemsymbol">
1432 <xsl:call-template name="list.itemsymbol">
1433 <xsl:with-param name="node" select="$node/ancestor::itemizedlist[1]"/>
1434 </xsl:call-template>
1436 </xsl:call-template>
1439 <xsl:call-template name="next.itemsymbol"/>
1446 <!-- ====================================================================== -->
1448 <doc:template name="copyright.years" xmlns="">
1449 <refpurpose>Print a set of years with collapsed ranges</refpurpose>
1452 <para>This template prints a list of year elements with consecutive
1453 years printed as a range. In other words:</para>
1455 <screen><![CDATA[<year>1992</year>
1457 <year>1994</year>]]></screen>
1459 <para>is printed <quote>1992-1994</quote>, whereas:</para>
1461 <screen><![CDATA[<year>1992</year>
1462 <year>1994</year>]]></screen>
1464 <para>is printed <quote>1992, 1994</quote>.</para>
1466 <para>This template assumes that all the year elements contain only
1467 decimal year numbers, that the elements are sorted in increasing
1468 numerical order, that there are no duplicates, and that all the years
1469 are expressed in full <quote>century+year</quote>
1470 (<quote>1999</quote> not <quote>99</quote>) notation.</para>
1475 <varlistentry><term>years</term>
1477 <para>The initial set of year elements.</para>
1480 <varlistentry><term>print.ranges</term>
1482 <para>If non-zero, multi-year ranges are collapsed. If zero, all years
1483 are printed discretely.</para>
1486 <varlistentry><term>single.year.ranges</term>
1488 <para>If non-zero, two consecutive years will be printed as a range,
1489 otherwise, they will be printed discretely. In other words, a single
1490 year range is <quote>1991-1992</quote> but discretely it's
1491 <quote>1991, 1992</quote>.</para>
1498 <para>This template returns the formatted list of years.</para>
1502 <xsl:template name="copyright.years">
1503 <xsl:param name="years"/>
1504 <xsl:param name="print.ranges" select="1"/>
1505 <xsl:param name="single.year.ranges" select="0"/>
1506 <xsl:param name="firstyear" select="0"/>
1507 <xsl:param name="nextyear" select="0"/>
1510 <xsl:message terminate="no">
1511 <xsl:text>CY: </xsl:text>
1512 <xsl:value-of select="count($years)"/>
1513 <xsl:text>, </xsl:text>
1514 <xsl:value-of select="$firstyear"/>
1515 <xsl:text>, </xsl:text>
1516 <xsl:value-of select="$nextyear"/>
1517 <xsl:text>, </xsl:text>
1518 <xsl:value-of select="$print.ranges"/>
1519 <xsl:text>, </xsl:text>
1520 <xsl:value-of select="$single.year.ranges"/>
1521 <xsl:text> (</xsl:text>
1522 <xsl:value-of select="$years[1]"/>
1523 <xsl:text>)</xsl:text>
1528 <xsl:when test="$print.ranges = 0 and count($years) > 0">
1530 <xsl:when test="count($years) = 1">
1531 <xsl:apply-templates select="$years[1]" mode="titlepage.mode"/>
1534 <xsl:apply-templates select="$years[1]" mode="titlepage.mode"/>
1535 <xsl:text>, </xsl:text>
1536 <xsl:call-template name="copyright.years">
1537 <xsl:with-param name="years"
1538 select="$years[position() > 1]"/>
1539 <xsl:with-param name="print.ranges" select="$print.ranges"/>
1540 <xsl:with-param name="single.year.ranges"
1541 select="$single.year.ranges"/>
1542 </xsl:call-template>
1546 <xsl:when test="count($years) = 0">
1547 <xsl:variable name="lastyear" select="$nextyear - 1"/>
1549 <xsl:when test="$firstyear = 0">
1550 <!-- there weren't any years at all -->
1552 <xsl:when test="$firstyear = $lastyear">
1553 <xsl:value-of select="$firstyear"/>
1555 <xsl:when test="$single.year.ranges = 0
1556 and $lastyear = $firstyear + 1">
1557 <xsl:value-of select="$firstyear"/>
1558 <xsl:text>, </xsl:text>
1559 <xsl:value-of select="$lastyear"/>
1562 <xsl:value-of select="$firstyear"/>
1563 <xsl:text>-</xsl:text>
1564 <xsl:value-of select="$lastyear"/>
1568 <xsl:when test="$firstyear = 0">
1569 <xsl:call-template name="copyright.years">
1570 <xsl:with-param name="years"
1571 select="$years[position() > 1]"/>
1572 <xsl:with-param name="firstyear" select="$years[1]"/>
1573 <xsl:with-param name="nextyear" select="$years[1] + 1"/>
1574 <xsl:with-param name="print.ranges" select="$print.ranges"/>
1575 <xsl:with-param name="single.year.ranges"
1576 select="$single.year.ranges"/>
1577 </xsl:call-template>
1579 <xsl:when test="$nextyear = $years[1]">
1580 <xsl:call-template name="copyright.years">
1581 <xsl:with-param name="years"
1582 select="$years[position() > 1]"/>
1583 <xsl:with-param name="firstyear" select="$firstyear"/>
1584 <xsl:with-param name="nextyear" select="$nextyear + 1"/>
1585 <xsl:with-param name="print.ranges" select="$print.ranges"/>
1586 <xsl:with-param name="single.year.ranges"
1587 select="$single.year.ranges"/>
1588 </xsl:call-template>
1591 <!-- we have years left, but they aren't in the current range -->
1593 <xsl:when test="$nextyear = $firstyear + 1">
1594 <xsl:value-of select="$firstyear"/>
1595 <xsl:text>, </xsl:text>
1597 <xsl:when test="$single.year.ranges = 0
1598 and $nextyear = $firstyear + 2">
1599 <xsl:value-of select="$firstyear"/>
1600 <xsl:text>, </xsl:text>
1601 <xsl:value-of select="$nextyear - 1"/>
1602 <xsl:text>, </xsl:text>
1605 <xsl:value-of select="$firstyear"/>
1606 <xsl:text>-</xsl:text>
1607 <xsl:value-of select="$nextyear - 1"/>
1608 <xsl:text>, </xsl:text>
1611 <xsl:call-template name="copyright.years">
1612 <xsl:with-param name="years"
1613 select="$years[position() > 1]"/>
1614 <xsl:with-param name="firstyear" select="$years[1]"/>
1615 <xsl:with-param name="nextyear" select="$years[1] + 1"/>
1616 <xsl:with-param name="print.ranges" select="$print.ranges"/>
1617 <xsl:with-param name="single.year.ranges"
1618 select="$single.year.ranges"/>
1619 </xsl:call-template>
1624 <!-- ====================================================================== -->
1626 <doc:template name="find.path.params" xmlns="">
1627 <refpurpose>Search in a table for the "best" match for the node</refpurpose>
1630 <para>This template searches in a table for the value that most-closely
1631 (in the typical best-match sense of XSLT) matches the current (element)
1632 node location.</para>
1636 <xsl:template name="find.path.params">
1637 <xsl:param name="node" select="."/>
1638 <xsl:param name="table" select="''"/>
1639 <xsl:param name="location">
1640 <xsl:call-template name="xpath.location">
1641 <xsl:with-param name="node" select="$node"/>
1642 </xsl:call-template>
1645 <xsl:variable name="value">
1646 <xsl:call-template name="lookup.key">
1647 <xsl:with-param name="key" select="$location"/>
1648 <xsl:with-param name="table" select="$table"/>
1649 </xsl:call-template>
1653 <xsl:when test="$value != ''">
1654 <xsl:value-of select="$value"/>
1656 <xsl:when test="contains($location, '/')">
1657 <xsl:call-template name="find.path.params">
1658 <xsl:with-param name="node" select="$node"/>
1659 <xsl:with-param name="table" select="$table"/>
1660 <xsl:with-param name="location" select="substring-after($location, '/')"/>
1661 </xsl:call-template>
1666 <xsl:template name="relative-uri">
1667 <xsl:param name="filename" select="."/>
1668 <xsl:param name="destdir" select="''"/>
1670 <xsl:variable name="srcurl">
1671 <xsl:call-template name="strippath">
1672 <xsl:with-param name="filename">
1673 <xsl:call-template name="xml.base.dirs">
1674 <xsl:with-param name="base.elem"
1675 select="$filename/ancestor-or-self::*
1676 [@xml:base != ''][1]"/>
1677 </xsl:call-template>
1678 <xsl:value-of select="$filename"/>
1680 </xsl:call-template>
1683 <xsl:variable name="srcurl.trimmed">
1684 <xsl:call-template name="trim.common.uri.paths">
1685 <xsl:with-param name="uriA" select="$srcurl"/>
1686 <xsl:with-param name="uriB" select="$destdir"/>
1687 <xsl:with-param name="return" select="'A'"/>
1688 </xsl:call-template>
1691 <xsl:variable name="destdir.trimmed">
1692 <xsl:call-template name="trim.common.uri.paths">
1693 <xsl:with-param name="uriA" select="$srcurl"/>
1694 <xsl:with-param name="uriB" select="$destdir"/>
1695 <xsl:with-param name="return" select="'B'"/>
1696 </xsl:call-template>
1699 <xsl:variable name="depth">
1700 <xsl:call-template name="count.uri.path.depth">
1701 <xsl:with-param name="filename" select="$destdir.trimmed"/>
1702 </xsl:call-template>
1705 <xsl:call-template name="copy-string">
1706 <xsl:with-param name="string" select="'../'"/>
1707 <xsl:with-param name="count" select="$depth"/>
1708 </xsl:call-template>
1709 <xsl:value-of select="$srcurl.trimmed"/>
1713 <!-- ===================================== -->
1715 <xsl:template name="xml.base.dirs">
1716 <xsl:param name="base.elem" select="NONODE"/>
1718 <!-- Recursively resolve xml:base attributes -->
1719 <xsl:if test="$base.elem/ancestor::*[@xml:base != '']">
1720 <xsl:call-template name="xml.base.dirs">
1721 <xsl:with-param name="base.elem"
1722 select="$base.elem/ancestor::*[@xml:base != ''][1]"/>
1723 </xsl:call-template>
1725 <xsl:call-template name="getdir">
1726 <xsl:with-param name="filename" select="$base.elem/@xml:base"/>
1727 </xsl:call-template>
1731 <!-- ===================================== -->
1733 <xsl:template name="strippath">
1734 <xsl:param name="filename" select="''"/>
1736 <!-- Leading .. are not eliminated -->
1737 <xsl:when test="starts-with($filename, '../')">
1738 <xsl:value-of select="'../'"/>
1739 <xsl:call-template name="strippath">
1740 <xsl:with-param name="filename" select="substring-after($filename, '../')"/>
1741 </xsl:call-template>
1743 <xsl:when test="contains($filename, '/../')">
1744 <xsl:call-template name="strippath">
1745 <xsl:with-param name="filename">
1746 <xsl:call-template name="getdir">
1747 <xsl:with-param name="filename" select="substring-before($filename, '/../')"/>
1748 </xsl:call-template>
1749 <xsl:value-of select="substring-after($filename, '/../')"/>
1751 </xsl:call-template>
1754 <xsl:value-of select="$filename"/>
1759 <!-- ===================================== -->
1761 <xsl:template name="getdir">
1762 <xsl:param name="filename" select="''"/>
1763 <xsl:if test="contains($filename, '/')">
1764 <xsl:value-of select="substring-before($filename, '/')"/>
1765 <xsl:text>/</xsl:text>
1766 <xsl:call-template name="getdir">
1767 <xsl:with-param name="filename" select="substring-after($filename, '/')"/>
1768 </xsl:call-template>
1772 <!-- ===================================== -->
1774 <doc:template name="string.upper" xmlns="">
1775 <refpurpose>Converts a string to all uppercase letters</refpurpose>
1778 <para>Given a string, this template does a language-aware conversion
1779 of that string to all uppercase letters, based on the values of the
1780 <literal>lowercase.alpha</literal> and
1781 <literal>uppercase.alpha</literal> gentext keys for the current
1782 locale. It affects only those characters found in the values of
1783 <literal>lowercase.alpha</literal> and
1784 <literal>uppercase.alpha</literal>. All other characters are left
1790 <varlistentry><term>string</term>
1792 <para>The string to convert to uppercase.</para>
1799 <xsl:template name="string.upper">
1800 <xsl:param name="string" select="''"/>
1801 <xsl:variable name="lowercase.alpha">
1802 <xsl:call-template name="gentext">
1803 <xsl:with-param name="key" select="'lowercase.alpha'"/>
1804 </xsl:call-template>
1806 <xsl:variable name="uppercase.alpha">
1807 <xsl:call-template name="gentext">
1808 <xsl:with-param name="key" select="'uppercase.alpha'"/>
1809 </xsl:call-template>
1811 <xsl:value-of select="translate($string,$lowercase.alpha,$uppercase.alpha)"/>
1814 <!-- ===================================== -->
1816 <doc:template name="select.choice.separator" xmlns="">
1817 <refpurpose>Returns localized choice separator</refpurpose>
1819 <para>This template enables auto-generation of an appropriate
1820 localized "choice" separator (for example, "and" or "or") before
1821 the final item in an inline list (though it could also be useful
1822 for generating choice separators for non-inline lists).</para>
1824 <para>It currently works by evaluating a processing instruction
1825 (PI) of the form <?dbchoice choice="foo"?> :
1829 <simpara>if the value of the <sgmltag>choice</sgmltag>
1830 pseudo-attribute is "and" or "or", returns a localized "and"
1834 <simpara>otherwise returns the literal value of the
1835 <sgmltag>choice</sgmltag> pseudo-attribute</simpara>
1839 The latter is provided only as a temporary workaround because the
1840 locale files do not currently have translations for the word
1841 <wordasword>or</wordasword>. So if you want to generate a a
1842 logical "or" separator in French (for example), you currently need
1845 <literallayout><?dbchoice choice="ou"?></literallayout>
1849 <para>The <sgmltag>dbchoice</sgmltag> processing instruction is
1850 an unfortunate hack; support for it may disappear in the future
1851 (particularly if and when a more appropriate means for marking
1852 up "choice" lists becomes available in DocBook).</para>
1857 <xsl:template name="select.choice.separator">
1859 <xsl:variable name="choice">
1860 <xsl:call-template name="pi-attribute">
1861 <xsl:with-param name="pis" select="processing-instruction('dbchoice')"/>
1862 <xsl:with-param name="attribute">choice</xsl:with-param>
1863 </xsl:call-template>
1867 <!-- if value of $choice is "and" or "or", translate to equivalent in -->
1868 <!-- current locale -->
1869 <xsl:when test="$choice = 'and' or $choice = 'or'">
1870 <xsl:call-template name="gentext">
1871 <xsl:with-param name="key" select="$choice"/>
1872 </xsl:call-template>
1874 <!-- otherwise, just output value of $choice, whatever it is -->
1876 <xsl:value-of select="$choice"/>
1881 <!-- ===================================== -->
1883 <doc:template name="evaluate.info.profile" xmlns="">
1884 <refpurpose>Evaluates an info profile</refpurpose>
1886 <para>This function evaluates an "info profile" matching the XPath
1887 expression given by the <parameter>profile</parameter>
1888 parameter. It relies on the XSLT <function>evaluate()</function>
1889 extension function.</para>
1891 <para>The value of the <parameter>profile</parameter> parameter
1892 can include the strings <literal>$info</literal> and
1893 <literal>$parentinfo</literal>. If found in the value of the
1894 <parameter>profile</parameter> parameter, those strings are
1895 evaluated using the <parameter>info</parameter> and
1896 <parameter>parentinfo</parameter> parameters, the values of which
1897 should be DocBook <replaceable>*info</replaceable> element node
1903 <term>profile</term>
1905 <para>A string representing an XPath expression </para>
1911 <para>A DocBook info node</para>
1915 <term>parentinfo</term>
1917 <para>A DocBook info node (from a parent element)</para>
1924 <para>Returns a node (the result of evaluating the
1925 <parameter>profile</parameter> parameter)</para>
1929 <xsl:template name="evaluate.info.profile">
1930 <xsl:param name="profile"/>
1931 <xsl:param name="info"/>
1932 <xsl:param name="parentinfo"/>
1934 <!-- xsltproc and Xalan both support dyn:evaluate() -->
1935 <xsl:when test="function-available('dyn:evaluate')">
1936 <xsl:apply-templates
1937 select="dyn:evaluate($profile)"/>
1939 <!-- Saxon has its own evaluate() & doesn't support dyn:evaluate() -->
1940 <xsl:when test="function-available('saxon:evaluate')">
1941 <xsl:apply-templates
1942 select="saxon:evaluate($profile)"/>
1945 <xsl:message terminate="yes">
1946 Error: The "info profiling" mechanism currently requires an XSLT
1947 engine that supports the evaluate() XSLT extension function. Your XSLT
1948 engine does not support it.