source: trunk/Distribution/XSL/lib/lib.xweb@ 2

Last change on this file since 2 was 2, checked in by jkacer, 18 years ago

Added all DocBook Framework stuff:

  • DocBook DTD
  • Transformation software FOP 0.20.5 and Saxon 6
  • XSL styles
  • Rexx scripts

Also added some WarpIN-related stuff for creation of WarpIN installation packages.
This state corresponds to version 1.0.0 from November 2005, just slightly modified to carry versioning information (Rexx scripts).

File size: 40.0 KB
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<book xmlns:src="http://nwalsh.com/xmlns/litprog/fragment"
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4 xmlns:dyn="http://exslt.org/dynamic"
5 xmlns:saxon="http://icl.com/saxon">
6<bookinfo>
7<title>XSL Library Template Reference</title>
8<releaseinfo role="cvs">$Id: lib.xweb,v 1.13 2005/07/08 10:35:55 xmldoc Exp $
9</releaseinfo>
10<corpauthor>DocBook Open Repository Team</corpauthor>
11<copyright>
12 <year>1999</year>
13 <year>2000</year>
14 <year>2001</year>
15 <year>2002</year>
16 <year>2005</year>
17 <holder>Norman Walsh</holder>
18</copyright>
19</bookinfo>
20
21<preface><title>Introduction</title>
22
23<para>This is technical reference documentation for the DocBook XSL
24Stylesheets; it documents (some of) the parameters, templates, and
25other elements of the stylesheets.</para>
26
27<para>This is not intended to be <quote>user</quote> documentation.
28It is provided for developers writing customization layers for the
29stylesheets, and for anyone who's interested in <quote>how it
30works</quote>.</para>
31
32<para>Although I am trying to be thorough, this documentation is known
33to be incomplete. Don't forget to read the source, too :-)</para>
34
35</preface>
36
37<reference>
38<title>General Library Templates</title>
39
40<refentry id="dot.count">
41<refnamediv>
42<refname>dot.count</refname>
43<refpurpose>Returns the number of <quote>.</quote> characters in a string</refpurpose>
44</refnamediv>
45
46<refsect1><title>Description</title>
47
48<programlisting><src:fragment id='dot.count.frag'>
49<xsl:template name="dot.count">
50 <!-- Returns the number of "." characters in a string -->
51 <xsl:param name="string"></xsl:param>
52 <xsl:param name="count" select="0"/>
53 <xsl:choose>
54 <xsl:when test="contains($string, '.')">
55 <xsl:call-template name="dot.count">
56 <xsl:with-param name="string" select="substring-after($string, '.')"/>
57 <xsl:with-param name="count" select="$count+1"/>
58 </xsl:call-template>
59 </xsl:when>
60 <xsl:otherwise>
61 <xsl:value-of select="$count"/>
62 </xsl:otherwise>
63 </xsl:choose>
64</xsl:template>
65</src:fragment></programlisting>
66
67</refsect1>
68</refentry>
69
70<!-- ================================================================== -->
71
72<refentry id="copy-string">
73<refnamediv>
74<refname>copy-string</refname>
75<refpurpose>Returns <quote>count</quote> copies of a string</refpurpose>
76</refnamediv>
77
78<refsect1><title>Description</title>
79
80<programlisting><src:fragment id='copy-string.frag'>
81<xsl:template name="copy-string">
82 <!-- returns 'count' copies of 'string' -->
83 <xsl:param name="string"></xsl:param>
84 <xsl:param name="count" select="0"/>
85 <xsl:param name="result"></xsl:param>
86
87 <xsl:choose>
88 <xsl:when test="$count>0">
89 <xsl:call-template name="copy-string">
90 <xsl:with-param name="string" select="$string"/>
91 <xsl:with-param name="count" select="$count - 1"/>
92 <xsl:with-param name="result">
93 <xsl:value-of select="$result"/>
94 <xsl:value-of select="$string"/>
95 </xsl:with-param>
96 </xsl:call-template>
97 </xsl:when>
98 <xsl:otherwise>
99 <xsl:value-of select="$result"/>
100 </xsl:otherwise>
101 </xsl:choose>
102</xsl:template>
103</src:fragment></programlisting>
104
105</refsect1>
106</refentry>
107
108<!-- ====================================================================== -->
109
110<refentry id="string.subst">
111<refnamediv>
112<refname>string.subst</refname>
113<refpurpose>Substitute one text string for another in a string</refpurpose>
114</refnamediv>
115
116<refsect1><title>Description</title>
117
118<para>The <function>string.subst</function> template replaces all
119occurances of <parameter>target</parameter> in <parameter>string</parameter>
120with <parameter>replacement</parameter> and returns the result.
121</para>
122
123<programlisting><src:fragment id='string.subst.frag'>
124<xsl:template name="string.subst">
125 <xsl:param name="string"></xsl:param>
126 <xsl:param name="target"></xsl:param>
127 <xsl:param name="replacement"></xsl:param>
128
129 <xsl:choose>
130 <xsl:when test="contains($string, $target)">
131 <xsl:variable name="rest">
132 <xsl:call-template name="string.subst">
133 <xsl:with-param name="string"
134 select="substring-after($string, $target)"/>
135 <xsl:with-param name="target" select="$target"/>
136 <xsl:with-param name="replacement" select="$replacement"/>
137 </xsl:call-template>
138 </xsl:variable>
139 <xsl:value-of select="concat(substring-before($string, $target),
140 $replacement,
141 $rest)"/>
142 </xsl:when>
143 <xsl:otherwise>
144 <xsl:value-of select="$string"/>
145 </xsl:otherwise>
146 </xsl:choose>
147</xsl:template>
148</src:fragment></programlisting>
149
150</refsect1>
151</refentry>
152
153<!-- ================================================================== -->
154
155<refentry id="xpointer.idref">
156<refnamediv>
157<refname>xpointer.idref</refname>
158<refpurpose>Extract IDREF from an XPointer</refpurpose>
159</refnamediv>
160
161<refsect1><title>Description</title>
162
163<para>The <function>xpointer.idref</function> template returns the
164ID portion of an XPointer which is a pointer to an ID within the current
165document, or the empty string if it is not.</para>
166<para>In other words, <function>xpointer.idref</function> returns
167<quote>foo</quote> when passed either <literal>#foo</literal>
168or <literal>#xpointer(id('foo'))</literal>, otherwise it returns
169the empty string.</para>
170
171<programlisting><src:fragment id='xpointer.idref.frag'>
172<xsl:template name="xpointer.idref">
173 <xsl:param name="xpointer">http://...</xsl:param>
174 <xsl:choose>
175 <xsl:when test="starts-with($xpointer, '#xpointer(id(')">
176 <xsl:variable name="rest" select="substring-after($xpointer, '#xpointer(id(')"/>
177 <xsl:variable name="quote" select="substring($rest, 1, 1)"/>
178 <xsl:value-of select="substring-before(substring-after($xpointer, $quote), $quote)"/>
179 </xsl:when>
180 <xsl:when test="starts-with($xpointer, '#')">
181 <xsl:value-of select="substring-after($xpointer, '#')"/>
182 </xsl:when>
183 <!-- otherwise it's a pointer to some other document -->
184 </xsl:choose>
185</xsl:template>
186</src:fragment></programlisting>
187
188</refsect1>
189</refentry>
190
191
192<!-- ================================================================== -->
193
194<refentry id="length-magnitude">
195<refnamediv>
196<refname>length-magnitude</refname>
197<refpurpose>Return the unqualified dimension from a length specification</refpurpose>
198</refnamediv>
199
200<refsect1><title>Description</title>
201
202<para>The <function>length-magnitude</function> template returns the
203unqualified length ("20" for "20pt") from a dimension.
204</para>
205
206<programlisting><src:fragment id='length-magnitude.frag'>
207<xsl:template name="length-magnitude">
208 <xsl:param name="length" select="'0pt'"/>
209
210 <xsl:choose>
211 <xsl:when test="string-length($length) = 0"/>
212 <xsl:when test="substring($length,1,1) = '0'
213 or substring($length,1,1) = '1'
214 or substring($length,1,1) = '2'
215 or substring($length,1,1) = '3'
216 or substring($length,1,1) = '4'
217 or substring($length,1,1) = '5'
218 or substring($length,1,1) = '6'
219 or substring($length,1,1) = '7'
220 or substring($length,1,1) = '8'
221 or substring($length,1,1) = '9'
222 or substring($length,1,1) = '.'">
223 <xsl:value-of select="substring($length,1,1)"/>
224 <xsl:call-template name="length-magnitude">
225 <xsl:with-param name="length" select="substring($length,2)"/>
226 </xsl:call-template>
227 </xsl:when>
228 </xsl:choose>
229</xsl:template>
230</src:fragment></programlisting>
231
232</refsect1>
233</refentry>
234
235<!-- ================================================================== -->
236
237<refentry id="length-units">
238<refnamediv>
239<refname>length-units</refname>
240<refpurpose>Return the units from a length specification</refpurpose>
241</refnamediv>
242
243<refsect1><title>Description</title>
244
245<para>The <function>length-units</function> template returns the
246units ("pt" for "20pt") from a length. If no units are supplied on the
247length, the <parameter>defauilt.units</parameter> are returned.</para>
248
249<programlisting><src:fragment id='length-units.frag'>
250<xsl:template name="length-units">
251 <xsl:param name="length" select="'0pt'"/>
252 <xsl:param name="default.units" select="'px'"/>
253 <xsl:variable name="magnitude">
254 <xsl:call-template name="length-magnitude">
255 <xsl:with-param name="length" select="$length"/>
256 </xsl:call-template>
257 </xsl:variable>
258
259 <xsl:variable name="units">
260 <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
261 </xsl:variable>
262
263 <xsl:choose>
264 <xsl:when test="$units = ''">
265 <xsl:value-of select="$default.units"/>
266 </xsl:when>
267 <xsl:otherwise>
268 <xsl:value-of select="$units"/>
269 </xsl:otherwise>
270 </xsl:choose>
271</xsl:template>
272</src:fragment></programlisting>
273
274</refsect1>
275</refentry>
276
277<!-- ================================================================== -->
278
279<refentry id="length-spec">
280<refnamediv>
281<refname>length-spec</refname>
282<refpurpose>Return a fully qualified length specification</refpurpose>
283</refnamediv>
284
285<refsect1><title>Description</title>
286
287<para>The <function>length-spec</function> template returns the
288qualified length from a dimension. If an unqualified length is given,
289the <parameter>default.units</parameter> will be added to it.
290</para>
291
292<programlisting><src:fragment id='length-spec.frag'>
293<xsl:template name="length-spec">
294 <xsl:param name="length" select="'0pt'"/>
295 <xsl:param name="default.units" select="'px'"/>
296
297 <xsl:variable name="magnitude">
298 <xsl:call-template name="length-magnitude">
299 <xsl:with-param name="length" select="$length"/>
300 </xsl:call-template>
301 </xsl:variable>
302
303 <xsl:variable name="units">
304 <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
305 </xsl:variable>
306
307 <xsl:value-of select="$magnitude"/>
308 <xsl:choose>
309 <xsl:when test="$units='cm'
310 or $units='mm'
311 or $units='in'
312 or $units='pt'
313 or $units='pc'
314 or $units='px'
315 or $units='em'">
316 <xsl:value-of select="$units"/>
317 </xsl:when>
318 <xsl:when test="$units = ''">
319 <xsl:value-of select="$default.units"/>
320 </xsl:when>
321 <xsl:otherwise>
322 <xsl:message>
323 <xsl:text>Unrecognized unit of measure: </xsl:text>
324 <xsl:value-of select="$units"/>
325 <xsl:text>.</xsl:text>
326 </xsl:message>
327 </xsl:otherwise>
328 </xsl:choose>
329</xsl:template>
330</src:fragment></programlisting>
331
332</refsect1>
333</refentry>
334
335<!-- ================================================================== -->
336
337<refentry id="length-in-points">
338<refnamediv>
339<refname>length-in-points</refname>
340<refpurpose>Returns the size, in points, of a specified length</refpurpose>
341</refnamediv>
342
343<refsect1><title>Description</title>
344
345<para>The <function>length-in-points</function> template converts a length
346specification to points and returns that value as an unqualified
347number.
348</para>
349
350<caution>
351<para>There is no way for the template to infer the size of an
352<literal>em</literal>. It relies on the default <parameter>em.size</parameter>
353which is initially <literal>10</literal> (for 10pt).</para>
354
355<para>Similarly, converting pixels to points relies on the
356<parameter>pixels.per.inch</parameter> parameter which is initially
357<literal>90</literal>.
358</para>
359</caution>
360
361<programlisting><src:fragment id='length-in-points.frag'>
362<xsl:template name="length-in-points">
363 <xsl:param name="length" select="'0pt'"/>
364 <xsl:param name="em.size" select="10"/>
365 <xsl:param name="pixels.per.inch" select="90"/>
366
367 <xsl:variable name="magnitude">
368 <xsl:call-template name="length-magnitude">
369 <xsl:with-param name="length" select="$length"/>
370 </xsl:call-template>
371 </xsl:variable>
372
373 <xsl:variable name="units">
374 <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
375 </xsl:variable>
376
377 <xsl:choose>
378 <xsl:when test="$units = 'pt'">
379 <xsl:value-of select="$magnitude"/>
380 </xsl:when>
381 <xsl:when test="$units = 'cm'">
382 <xsl:value-of select="$magnitude div 2.54 * 72.0"/>
383 </xsl:when>
384 <xsl:when test="$units = 'mm'">
385 <xsl:value-of select="$magnitude div 25.4 * 72.0"/>
386 </xsl:when>
387 <xsl:when test="$units = 'in'">
388 <xsl:value-of select="$magnitude * 72.0"/>
389 </xsl:when>
390 <xsl:when test="$units = 'pc'">
391 <xsl:value-of select="$magnitude * 12.0"/>
392 </xsl:when>
393 <xsl:when test="$units = 'px'">
394 <xsl:value-of select="$magnitude div $pixels.per.inch * 72.0"/>
395 </xsl:when>
396 <xsl:when test="$units = 'em'">
397 <xsl:value-of select="$magnitude * $em.size"/>
398 </xsl:when>
399 <xsl:otherwise>
400 <xsl:message>
401 <xsl:text>Unrecognized unit of measure: </xsl:text>
402 <xsl:value-of select="$units"/>
403 <xsl:text>.</xsl:text>
404 </xsl:message>
405 </xsl:otherwise>
406 </xsl:choose>
407</xsl:template>
408</src:fragment></programlisting>
409
410</refsect1>
411</refentry>
412
413<!-- ================================================================== -->
414
415<refentry id="pi-attribute">
416<refnamediv>
417<refname>pi-attribute</refname>
418<refpurpose>Extract a pseudo-attribute from a PI</refpurpose>
419</refnamediv>
420
421<refsect1><title>Description</title>
422
423<para>The <function>pi-attribute</function> template extracts a pseudo-attribute
424from a processing instruction. For example, given the PI
425<quote><literal>&lt;?foo bar="1" baz='red'?&gt;</literal></quote>,</para>
426<programlisting><![CDATA[<xsl:call-template name="pi-attribute">
427 <xsl:with-param name="pis" select="processing-instruction('foo')"/>
428 <xsl:with-param name="attribute" select="'baz'"/>
429</xsl:call-template>]]></programlisting>
430<para>will return <quote>red</quote>. This template returns the first matching
431attribute that it finds. Presented with processing instructions that
432contain badly formed pseudo-attributes (missing or unbalanced quotes,
433for example), the template may silently return erroneous results.</para>
434
435<programlisting><src:fragment id='pi-attribute.frag'>
436<xsl:template name="pi-attribute">
437 <xsl:param name="pis" select="processing-instruction('BOGUS_PI')"/>
438 <xsl:param name="attribute">filename</xsl:param>
439 <xsl:param name="count">1</xsl:param>
440
441 <xsl:choose>
442 <xsl:when test="$count>count($pis)">
443 <!-- not found -->
444 </xsl:when>
445 <xsl:otherwise>
446 <xsl:variable name="pi">
447 <xsl:value-of select="$pis[$count]"/>
448 </xsl:variable>
449 <xsl:variable name="pivalue">
450 <xsl:value-of select="concat(' ', normalize-space($pi))"/>
451 </xsl:variable>
452 <xsl:choose>
453 <xsl:when test="contains($pivalue,concat(' ', $attribute, '='))">
454 <xsl:variable name="rest" select="substring-after($pivalue,concat(' ', $attribute,'='))"/>
455 <xsl:variable name="quote" select="substring($rest,1,1)"/>
456 <xsl:value-of select="substring-before(substring($rest,2),$quote)"/>
457 </xsl:when>
458 <xsl:otherwise>
459 <xsl:call-template name="pi-attribute">
460 <xsl:with-param name="pis" select="$pis"/>
461 <xsl:with-param name="attribute" select="$attribute"/>
462 <xsl:with-param name="count" select="$count + 1"/>
463 </xsl:call-template>
464 </xsl:otherwise>
465 </xsl:choose>
466 </xsl:otherwise>
467 </xsl:choose>
468</xsl:template>
469</src:fragment></programlisting>
470
471</refsect1>
472</refentry>
473
474<!-- ================================================================== -->
475
476<refentry id="lookup.key">
477<refnamediv>
478<refname>lookup.key</refname>
479<refpurpose>Retrieve the value associated with a particular key in a table</refpurpose>
480</refnamediv>
481
482<refsect1><title>Description</title>
483
484<para>Given a table of space-delimited key/value pairs,
485the <function>lookup.key</function> template extracts the value associated
486with a particular key.</para>
487
488<programlisting><src:fragment id='lookup.key.frag'>
489<xsl:template name="lookup.key">
490 <xsl:param name="key" select="''"/>
491 <xsl:param name="table" select="''"/>
492
493 <xsl:if test="contains($table, ' ')">
494 <xsl:choose>
495 <xsl:when test="substring-before($table, ' ') = $key">
496 <xsl:variable name="rest" select="substring-after($table, ' ')"/>
497 <xsl:choose>
498 <xsl:when test="contains($rest, ' ')">
499 <xsl:value-of select="substring-before($rest, ' ')"/>
500 </xsl:when>
501 <xsl:otherwise>
502 <xsl:value-of select="$rest"/>
503 </xsl:otherwise>
504 </xsl:choose>
505 </xsl:when>
506 <xsl:otherwise>
507 <xsl:call-template name="lookup.key">
508 <xsl:with-param name="key" select="$key"/>
509 <xsl:with-param name="table"
510 select="substring-after(substring-after($table,' '), ' ')"/>
511 </xsl:call-template>
512 </xsl:otherwise>
513 </xsl:choose>
514 </xsl:if>
515</xsl:template>
516</src:fragment></programlisting>
517
518</refsect1>
519</refentry>
520
521<!-- ================================================================== -->
522
523<refentry id="xpath.location">
524<refnamediv>
525<refname>xpath.location</refname>
526<refpurpose>Calculate the XPath child-sequence to the current node</refpurpose>
527</refnamediv>
528
529<refsect1><title>Description</title>
530
531<para>The <function>xpath.location</function> template calculates the
532absolute path from the root of the tree to the current element node.
533</para>
534
535<programlisting><src:fragment id='xpath.location.frag'>
536<xsl:template name="xpath.location">
537 <xsl:param name="node" select="."/>
538 <xsl:param name="path" select="''"/>
539
540 <xsl:variable name="next.path">
541 <xsl:value-of select="local-name($node)"/>
542 <xsl:if test="$path != ''">/</xsl:if>
543 <xsl:value-of select="$path"/>
544 </xsl:variable>
545
546 <xsl:choose>
547 <xsl:when test="$node/parent::*">
548 <xsl:call-template name="xpath.location">
549 <xsl:with-param name="node" select="$node/parent::*"/>
550 <xsl:with-param name="path" select="$next.path"/>
551 </xsl:call-template>
552 </xsl:when>
553 <xsl:otherwise>
554 <xsl:text>/</xsl:text>
555 <xsl:value-of select="$next.path"/>
556 </xsl:otherwise>
557 </xsl:choose>
558</xsl:template>
559</src:fragment></programlisting>
560
561</refsect1>
562</refentry>
563
564<!-- ================================================================== -->
565
566<refentry id="comment-escape-string">
567<refnamediv>
568<refname>comment-escape-string</refname>
569<refpurpose>Prepare a string for inclusion in an XML comment</refpurpose>
570</refnamediv>
571
572<refsect1><title>Description</title>
573
574<para>The <function>comment-escape-string</function> template returns a string
575that has been transformed so that it can safely be output as an XML comment.
576Internal occurrences of "--" will be replaced with "- -" and a leading and/or
577trailing space will be added to the string, if necessary.</para>
578
579<programlisting><src:fragment id='comment-escape-string'>
580<xsl:template name="comment-escape-string">
581 <xsl:param name="string" select="''"/>
582
583 <xsl:if test="starts-with($string, '-')">
584 <xsl:text> </xsl:text>
585 </xsl:if>
586
587 <xsl:call-template name="comment-escape-string.recursive">
588 <xsl:with-param name="string" select="$string"/>
589 </xsl:call-template>
590
591 <xsl:if test="substring($string, string-length($string), 1) = '-'">
592 <xsl:text> </xsl:text>
593 </xsl:if>
594</xsl:template>
595</src:fragment></programlisting>
596
597</refsect1>
598</refentry>
599
600<!-- ================================================================== -->
601
602<refentry id="comment-escape-string.recursive">
603<refnamediv>
604<refname>comment-escape-string.recursive</refname>
605<refpurpose>Internal function used by comment-escape-string</refpurpose>
606</refnamediv>
607
608<refsect1><title>Description</title>
609
610<para>The <function>comment-escape-string.recursive</function> template is used
611by <function>comment-escape-string</function>.</para>
612
613<programlisting><src:fragment id="comment-escape-string.recursive">
614<xsl:template name="comment-escape-string.recursive">
615 <xsl:param name="string" select="''"/>
616 <xsl:choose>
617 <xsl:when test="contains($string, '--')">
618 <xsl:value-of select="substring-before($string, '--')"/>
619 <xsl:value-of select="'- -'"/>
620 <xsl:call-template name="comment-escape-string.recursive">
621 <xsl:with-param name="string" select="substring-after($string, '--')"/>
622 </xsl:call-template>
623 </xsl:when>
624 <xsl:otherwise>
625 <xsl:value-of select="$string"/>
626 </xsl:otherwise>
627 </xsl:choose>
628</xsl:template>
629</src:fragment></programlisting>
630</refsect1>
631</refentry>
632
633<!-- ================================================================== -->
634
635<refentry id="prepend-pad">
636<refnamediv>
637<refname>prepend-pad</refname>
638<refpurpose>Right-pad a string out to a certain length</refpurpose>
639</refnamediv>
640
641<refsect1><title>Description</title>
642
643<para>This function takes string <parameter>padVar</parameter> and
644pads it out to the string-length <parameter>length</parameter>, using
645string <parameter>padChar</parameter> (a space character by default)
646as the padding string (note that <parameter>padChar</parameter> can be
647a string; it is not limited to just being a single character).</para>
648
649 <note>
650 <para>This function is a copy of Nate Austin's
651 <function>prepend-pad</function> function in the <ulink
652 url="http://www.dpawson.co.uk/xsl/sect2/padding.html" >Padding
653 Content</ulink> section of Dave Pawson's <ulink
654 url="http://www.dpawson.co.uk/xsl/index.html" >XSLT
655 FAQ</ulink>.</para>
656 </note>
657
658<programlisting><src:fragment id='prepend-pad.frag'>
659 <xsl:template name="prepend-pad">
660 <!-- recursive template to right justify and prepend-->
661 <!-- the value with whatever padChar is passed in -->
662 <xsl:param name="padChar" select="' '"/>
663 <xsl:param name="padVar"/>
664 <xsl:param name="length"/>
665 <xsl:choose>
666 <xsl:when test="string-length($padVar) &lt; $length">
667 <xsl:call-template name="prepend-pad">
668 <xsl:with-param name="padChar" select="$padChar"/>
669 <xsl:with-param name="padVar" select="concat($padChar,$padVar)"/>
670 <xsl:with-param name="length" select="$length"/>
671 </xsl:call-template>
672 </xsl:when>
673 <xsl:otherwise>
674 <xsl:value-of
675 select="substring($padVar,string-length($padVar) - $length + 1)"/>
676 </xsl:otherwise>
677 </xsl:choose>
678 </xsl:template>
679</src:fragment></programlisting>
680
681</refsect1>
682</refentry>
683
684<!-- ================================================================== -->
685
686<refentry id="str.tokenize.keep.delimiters">
687<refnamediv>
688<refname>str.tokenize.keep.delimiters</refname>
689<refpurpose>Tokenize a string while preserving any delimiters</refpurpose>
690</refnamediv>
691
692<refsect1><title>Description</title>
693
694<para>Based on the occurrence of one or more delimiter characters,
695this function breaks a string into a list of tokens and delimiters,
696marking up each of the tokens with a <sgmltag>token</sgmltag> element
697and preserving the delimiters as text nodes between the tokens.</para>
698
699<note>
700 <para>This function is a very slightly modified version of a
701 function from the <ulink url="http://www.exslt.org/">EXSLT
702 site</ulink>. The original is available at:
703
704 <blockquote><para><ulink url="http://www.exslt.org/str/functions/tokenize/str.tokenize.template.xsl"/></para></blockquote>
705
706 The <function>str.tokenize.keep.delimiters</function> function
707 differs only in that it preserves the delimiters instead of
708 discarding them.</para>
709</note>
710
711<programlisting><src:fragment id='str.tokenize.keep.delimiters.frag'>
712
713 <xsl:template name="str.tokenize.keep.delimiters">
714 <xsl:param name="string" select="''" />
715 <xsl:param name="delimiters" select="' '" />
716 <xsl:choose>
717 <xsl:when test="not($string)" />
718 <xsl:when test="not($delimiters)">
719 <xsl:call-template name="str.tokenize.keep.delimiters-characters">
720 <xsl:with-param name="string" select="$string" />
721 </xsl:call-template>
722 </xsl:when>
723 <xsl:otherwise>
724 <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
725 <xsl:with-param name="string" select="$string" />
726 <xsl:with-param name="delimiters" select="$delimiters" />
727 </xsl:call-template>
728 </xsl:otherwise>
729 </xsl:choose>
730 </xsl:template>
731
732 <xsl:template name="str.tokenize.keep.delimiters-characters">
733 <xsl:param name="string" />
734 <xsl:if test="$string">
735 <token><xsl:value-of select="substring($string, 1, 1)" /></token>
736 <xsl:call-template name="str.tokenize.keep.delimiters-characters">
737 <xsl:with-param name="string" select="substring($string, 2)" />
738 </xsl:call-template>
739 </xsl:if>
740 </xsl:template>
741
742 <xsl:template name="str.tokenize.keep.delimiters-delimiters">
743 <xsl:param name="string" />
744 <xsl:param name="delimiters" />
745 <xsl:variable name="delimiter" select="substring($delimiters, 1, 1)" />
746 <xsl:choose>
747 <xsl:when test="not($delimiter)">
748 <token><xsl:value-of select="$string" /></token>
749 </xsl:when>
750 <xsl:when test="contains($string, $delimiter)">
751 <xsl:if test="not(starts-with($string, $delimiter))">
752 <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
753 <xsl:with-param name="string" select="substring-before($string, $delimiter)" />
754 <xsl:with-param name="delimiters" select="substring($delimiters, 2)" />
755 </xsl:call-template>
756 </xsl:if>
757 <!-- output each delimiter -->
758 <xsl:value-of select="$delimiter"/>
759 <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
760 <xsl:with-param name="string" select="substring-after($string, $delimiter)" />
761 <xsl:with-param name="delimiters" select="$delimiters" />
762 </xsl:call-template>
763 </xsl:when>
764 <xsl:otherwise>
765 <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
766 <xsl:with-param name="string" select="$string" />
767 <xsl:with-param name="delimiters" select="substring($delimiters, 2)" />
768 </xsl:call-template>
769 </xsl:otherwise>
770 </xsl:choose>
771 </xsl:template>
772</src:fragment></programlisting>
773
774</refsect1>
775</refentry>
776
777<!-- ================================================================== -->
778
779<refentry id="apply-string-subst-map">
780 <refnamediv>
781 <refname>apply-string-subst-map</refname>
782 <refpurpose>Apply a string-substitution map</refpurpose>
783 </refnamediv>
784
785 <refsect1><title>Description</title>
786
787 <para>This function applies a "string substitution" map. Use it when
788 you want to do multiple string substitutions on the same target
789 content. It reads in two things: <parameter>content</parameter>, the
790 content on which to perform the substitution, and
791 <parameter>map.contents</parameter>, a node set of
792 elements (the names of the elements don't matter), with each element
793 having the following attributes:
794 <itemizedlist>
795 <listitem>
796 <simpara><tag class="attribute">oldstring</tag>, a string to
797 be replaced</simpara>
798 </listitem>
799 <listitem>
800 <simpara><tag class="attribute">newstring</tag>, a string with
801 which to replace <tag class="attribute">oldstring</tag></simpara>
802 </listitem>
803 </itemizedlist>
804 The function uses <parameter>map.contents</parameter> to
805 do substitution on <parameter>content</parameter>, and then
806 returns the modified contents.</para>
807
808 <note>
809 <para>This function is a very slightly modified version of Jeni
810 Tennison's <function>replace_strings</function> function in the
811 <ulink
812 url="http://www.dpawson.co.uk/xsl/sect2/StringReplace.html#d9351e13"
813 >multiple string replacements</ulink> section of Dave Pawson's
814 <ulink url="http://www.dpawson.co.uk/xsl/index.html" >XSLT
815 FAQ</ulink>.</para>
816
817 <para>The <function>apply-string-subst-map</function> function is
818 essentially the same function as the
819 <function>apply-character-map</function> function; the only
820 difference is that in the map that
821 <function>apply-string-subst-map</function> expects, <tag
822 class="attribute">oldstring</tag> and <tag
823 class="attribute">newstring</tag> attributes are used instead of
824 <tag class="attribute">character</tag> and <tag
825 class="attribute">string</tag> attributes.</para>
826 </note>
827
828 <programlisting><src:fragment id='apply-string-subst-map.frag'>
829 <xsl:template name="apply-string-subst-map">
830 <xsl:param name="content"/>
831 <xsl:param name="map.contents"/>
832 <xsl:variable name="replaced_text">
833 <xsl:call-template name="string.subst">
834 <xsl:with-param name="string" select="$content" />
835 <xsl:with-param name="target"
836 select="$map.contents[1]/@oldstring" />
837 <xsl:with-param name="replacement"
838 select="$map.contents[1]/@newstring" />
839 </xsl:call-template>
840 </xsl:variable>
841 <xsl:choose>
842 <xsl:when test="$map.contents[2]">
843 <xsl:call-template name="apply-string-subst-map">
844 <xsl:with-param name="content" select="$replaced_text" />
845 <xsl:with-param name="map.contents"
846 select="$map.contents[position() > 1]" />
847 </xsl:call-template>
848 </xsl:when>
849 <xsl:otherwise>
850 <xsl:value-of select="$replaced_text" />
851 </xsl:otherwise>
852 </xsl:choose>
853 </xsl:template>
854
855 </src:fragment></programlisting>
856 </refsect1>
857</refentry>
858
859<!-- ================================================================== -->
860
861<refentry id="apply-character-map">
862 <refnamediv>
863 <refname>apply-character-map</refname>
864 <refpurpose>Apply an XSLT character map</refpurpose>
865 </refnamediv>
866
867 <refsect1><title>Description</title>
868
869 <para>This function applies an <ulink
870 url="http://www.w3.org/TR/xslt20/#character-maps">XSLT character
871 map</ulink>; that is, it cause certain individual characters to be
872 substituted with strings of one or more characters. It is useful
873 mainly for replacing multiple "special" chararacters or symbols in
874 the same target content. It reads in two things:
875 <parameter>content</parameter>, the content on which to perform the
876 substitution, and <parameter>map.contents</parameter>, a
877 node set of elements (the names of the elements don't matter), with
878 each element having the following attributes:
879 <itemizedlist>
880 <listitem>
881 <simpara><tag class="attribute">character</tag>, a character to
882 be replaced</simpara>
883 </listitem>
884 <listitem>
885 <simpara><tag class="attribute">string</tag>, a string with
886 which to replace <tag class="attribute">character</tag></simpara>
887 </listitem>
888 </itemizedlist>
889 This function uses <parameter>map.contents</parameter> to
890 do substitution on <parameter>content</parameter>, and then returns
891 the modified contents.</para>
892
893 <note>
894 <para>This function is a very slightly modified version of Jeni
895 Tennison's <function>replace_strings</function> function in the
896 <ulink
897 url="http://www.dpawson.co.uk/xsl/sect2/StringReplace.html#d9351e13"
898 >multiple string replacements</ulink> section of Dave Pawson's
899 <ulink url="http://www.dpawson.co.uk/xsl/index.html" >XSLT
900 FAQ</ulink>.</para>
901
902 <para>The <function>apply-string-subst-map</function> function is
903 essentially the same function as the
904 <function>apply-character-map</function> function; the only
905 difference is that in the map that
906 <function>apply-string-subst-map</function> expects, <tag
907 class="attribute">oldstring</tag> and <tag
908 class="attribute">newstring</tag> attributes are used instead of
909 <tag class="attribute">character</tag> and <tag
910 class="attribute">string</tag> attributes.</para>
911 </note>
912
913 <programlisting><src:fragment id='apply-character-map.frag'>
914 <xsl:template name="apply-character-map">
915 <xsl:param name="content"/>
916 <xsl:param name="map.contents"/>
917 <xsl:variable name="replaced_text">
918 <xsl:call-template name="string.subst">
919 <xsl:with-param name="string" select="$content" />
920 <xsl:with-param name="target"
921 select="$map.contents[1]/@character" />
922 <xsl:with-param name="replacement"
923 select="$map.contents[1]/@string" />
924 </xsl:call-template>
925 </xsl:variable>
926 <xsl:choose>
927 <xsl:when test="$map.contents[2]">
928 <xsl:call-template name="apply-character-map">
929 <xsl:with-param name="content" select="$replaced_text" />
930 <xsl:with-param name="map.contents"
931 select="$map.contents[position() > 1]" />
932 </xsl:call-template>
933 </xsl:when>
934 <xsl:otherwise>
935 <xsl:value-of select="$replaced_text" />
936 </xsl:otherwise>
937 </xsl:choose>
938 </xsl:template>
939
940 </src:fragment></programlisting>
941 </refsect1>
942</refentry>
943
944<!-- ================================================================== -->
945
946<refentry id="read-character-map">
947<refnamediv>
948<refname>read-character-map</refname>
949<refpurpose>Read in all or part of an XSLT character map</refpurpose>
950</refnamediv>
951
952<refsect1><title>Description</title>
953
954<para>The XSLT 2.0 specification describes <ulink
955url="http://www.w3.org/TR/xslt20/#character-maps">character
956maps</ulink> and explains how they may be used to allow a specific
957character appearing in a text or attribute node in a final results
958tree to be substituted by a specified string of characters during
959serialization. The <function>read-character-map</function> function
960provides a means for reading and using character maps with XSLT
9611.0-based tools.</para>
962
963<para>It reads the character-map contents from
964<parameter>uri</parameter> (in full or in part, depending on the value
965of the <parameter>use.subset</parameter> parameter), then passes those
966contents to the <function>apply-character-map</function> function,
967along with <parameter>content</parameter>, the data on which to
968perform the character substition.</para>
969
970<para>Using the character map "in part" means that it uses only those
971<tag>output-character</tag> elements that match the XPATH expression
972given in the value of the <parameter>subset.profile</parameter>
973parameter. The current implementation of that capability here relies
974on the <function>evaluate</function> extension XSLT function.</para>
975
976<programlisting><src:fragment id='read-character-map.frag'>
977 <xsl:template name="read-character-map">
978 <xsl:param name="use.subset"/>
979 <xsl:param name="subset.profile"/>
980 <xsl:param name="uri"/>
981 <xsl:choose>
982 <xsl:when test="$use.subset != 0">
983 <!-- use a subset of the character map instead of the full map -->
984 <xsl:choose>
985 <!-- xsltproc and Xalan both support dyn:evaluate() -->
986 <xsl:when test="function-available('dyn:evaluate')">
987 <xsl:copy-of select="document($uri)//*[local-name()='output-character']
988 [dyn:evaluate($subset.profile)]"/>
989 </xsl:when>
990 <!-- Saxon has its own evaluate() & doesn't support dyn:evaluate() -->
991 <xsl:when test="function-available('saxon:evaluate')">
992 <xsl:copy-of select="document($uri)//*[local-name()='output-character']
993 [saxon:evaluate($subset.profile)]"/>
994 </xsl:when>
995 <xsl:otherwise>
996 <xsl:message terminate="yes"
997>
998Error: To process character-map subsets, you must use an XSLT engine
999that supports the evaluate() XSLT extension function. Your XSLT engine
1000does not support it.
1001</xsl:message>
1002 </xsl:otherwise>
1003 </xsl:choose>
1004 </xsl:when>
1005 <xsl:otherwise>
1006 <!-- value of $use.subet is non-zero, so use the full map -->
1007 <xsl:copy-of select="document($uri)//*[local-name()='output-character']"/>
1008 </xsl:otherwise>
1009 </xsl:choose>
1010 </xsl:template>
1011</src:fragment></programlisting>
1012</refsect1>
1013</refentry>
1014
1015</reference>
1016
1017<!-- ================================================================== -->
1018
1019<reference>
1020<title>Relative URI Functions</title>
1021
1022<partintro><title>Introduction</title>
1023
1024<para>These functions manipulate relative URI references.</para>
1025
1026<para>The following assumptions must hold true:</para>
1027
1028<orderedlist>
1029<listitem>
1030<para>All URIs are relative.</para>
1031</listitem>
1032<listitem>
1033<para>No URI contains the <quote><literal>../</literal></quote> sequence
1034which would effectively move <quote>up</quote> the hierarchy.</para>
1035</listitem>
1036</orderedlist>
1037
1038<para>If these assumptions do not hold, the results are unpredictable.</para>
1039
1040</partintro>
1041
1042<!-- ================================================================== -->
1043
1044<refentry id="count.uri.path.depth">
1045<refnamediv>
1046<refname>count.uri.path.depth</refname>
1047<refpurpose>Count the number of path components in a relative URI</refpurpose>
1048</refnamediv>
1049
1050<refsect1><title>Description</title>
1051
1052<para>This function counts the number of path components in a relative URI.</para>
1053
1054<programlisting><src:fragment id='count.uri.path.depth.frag'>
1055<xsl:template name="count.uri.path.depth">
1056 <xsl:param name="filename" select="''"/>
1057 <xsl:param name="count" select="0"/>
1058
1059 <xsl:choose>
1060 <xsl:when test="contains($filename, '/')">
1061 <xsl:call-template name="count.uri.path.depth">
1062 <xsl:with-param name="filename" select="substring-after($filename, '/')"/>
1063 <xsl:with-param name="count" select="$count + 1"/>
1064 </xsl:call-template>
1065 </xsl:when>
1066 <xsl:otherwise>
1067 <xsl:value-of select="$count"/>
1068 </xsl:otherwise>
1069 </xsl:choose>
1070</xsl:template>
1071</src:fragment></programlisting>
1072
1073</refsect1>
1074</refentry>
1075
1076<!-- ================================================================== -->
1077
1078<refentry id="trim.common.uri.paths">
1079<refnamediv>
1080<refname>trim.common.uri.paths</refname>
1081<refpurpose>Trim common leading path components from a relative URI</refpurpose>
1082</refnamediv>
1083
1084<refsect1><title>Description</title>
1085
1086<para>This function trims common leading path components from a relative URI.</para>
1087
1088<programlisting><src:fragment id='trim.common.uri.paths.frag'>
1089<xsl:template name="trim.common.uri.paths">
1090 <xsl:param name="uriA" select="''"/>
1091 <xsl:param name="uriB" select="''"/>
1092 <xsl:param name="return" select="'A'"/>
1093
1094 <xsl:choose>
1095 <xsl:when test="contains($uriA, '/') and contains($uriB, '/')
1096 and substring-before($uriA, '/') = substring-before($uriB, '/')">
1097 <xsl:call-template name="trim.common.uri.paths">
1098 <xsl:with-param name="uriA" select="substring-after($uriA, '/')"/>
1099 <xsl:with-param name="uriB" select="substring-after($uriB, '/')"/>
1100 <xsl:with-param name="return" select="$return"/>
1101 </xsl:call-template>
1102 </xsl:when>
1103 <xsl:otherwise>
1104 <xsl:choose>
1105 <xsl:when test="$return = 'A'">
1106 <xsl:value-of select="$uriA"/>
1107 </xsl:when>
1108 <xsl:otherwise>
1109 <xsl:value-of select="$uriB"/>
1110 </xsl:otherwise>
1111 </xsl:choose>
1112 </xsl:otherwise>
1113 </xsl:choose>
1114</xsl:template>
1115</src:fragment></programlisting>
1116
1117</refsect1>
1118</refentry>
1119
1120</reference>
1121
1122<!-- ================================================================== -->
1123
1124<appendix><title>The Stylesheet</title>
1125
1126<para>The <filename>lib.xsl</filename> stylesheet is just a wrapper
1127around these functions.</para>
1128
1129<src:fragment id="top" mundane-result-prefixes="xsl">
1130
1131<!-- ********************************************************************
1132 $Id: lib.xweb,v 1.13 2005/07/08 10:35:55 xmldoc Exp $
1133 ********************************************************************
1134
1135 This file is part of the XSL DocBook Stylesheet distribution.
1136 See ../README or http://nwalsh.com/docbook/xsl/ for copyright
1137 and other information.
1138
1139 This module implements DTD-independent functions
1140
1141 ******************************************************************** -->
1142
1143<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
1144 xmlns:src="http://nwalsh.com/xmlns/litprog/fragment"
1145 exclude-result-prefixes="src"
1146 version='1.0'>
1147
1148<src:fragref linkend="dot.count.frag"/>
1149<src:fragref linkend="copy-string.frag"/>
1150<src:fragref linkend="string.subst.frag"/>
1151<src:fragref linkend="xpointer.idref.frag"/>
1152<src:fragref linkend="length-magnitude.frag"/>
1153<src:fragref linkend="length-units.frag"/>
1154<src:fragref linkend="length-spec.frag"/>
1155<src:fragref linkend="length-in-points.frag"/>
1156<src:fragref linkend="pi-attribute.frag"/>
1157<src:fragref linkend="lookup.key.frag"/>
1158<src:fragref linkend="xpath.location.frag"/>
1159<src:fragref linkend="comment-escape-string"/>
1160<src:fragref linkend="comment-escape-string.recursive"/>
1161<src:fragref linkend="prepend-pad.frag"/>
1162<src:fragref linkend="str.tokenize.keep.delimiters.frag"/>
1163<src:fragref linkend="apply-string-subst-map.frag"/>
1164<src:fragref linkend="apply-character-map.frag"/>
1165<src:fragref linkend="read-character-map.frag"/>
1166<src:fragref linkend="count.uri.path.depth.frag"/>
1167<src:fragref linkend="trim.common.uri.paths.frag"/>
1168
1169</xsl:stylesheet>
1170</src:fragment>
1171
1172</appendix>
1173</book>
Note: See TracBrowser for help on using the repository browser.