1 <?xml version="1.0" encoding="utf-8"?>
2 <!-- ********************************************************************
4 ********************************************************************
6 This file is part of the XSL DocBook Stylesheet distribution.
7 See ../README or http://nwalsh.com/docbook/xsl/ for copyright
10 This module implements DTD-independent functions
12 ******************************************************************** -->
14 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:src="http://nwalsh.com/xmlns/litprog/fragment" xmlns:dyn="http://exslt.org/dynamic" xmlns:saxon="http://icl.com/saxon" exclude-result-prefixes="src" version="1.0">
16 <xsl:template name="dot.count">
17 <!-- Returns the number of "." characters in a string -->
18 <xsl:param name="string"/>
19 <xsl:param name="count" select="0"/>
21 <xsl:when test="contains($string, '.')">
22 <xsl:call-template name="dot.count">
23 <xsl:with-param name="string" select="substring-after($string, '.')"/>
24 <xsl:with-param name="count" select="$count+1"/>
28 <xsl:value-of select="$count"/>
32 <xsl:template name="copy-string">
33 <!-- returns 'count' copies of 'string' -->
34 <xsl:param name="string"/>
35 <xsl:param name="count" select="0"/>
36 <xsl:param name="result"/>
39 <xsl:when test="$count>0">
40 <xsl:call-template name="copy-string">
41 <xsl:with-param name="string" select="$string"/>
42 <xsl:with-param name="count" select="$count - 1"/>
43 <xsl:with-param name="result">
44 <xsl:value-of select="$result"/>
45 <xsl:value-of select="$string"/>
50 <xsl:value-of select="$result"/>
54 <xsl:template name="string.subst">
55 <xsl:param name="string"/>
56 <xsl:param name="target"/>
57 <xsl:param name="replacement"/>
60 <xsl:when test="contains($string, $target)">
61 <xsl:variable name="rest">
62 <xsl:call-template name="string.subst">
63 <xsl:with-param name="string" select="substring-after($string, $target)"/>
64 <xsl:with-param name="target" select="$target"/>
65 <xsl:with-param name="replacement" select="$replacement"/>
68 <xsl:value-of select="concat(substring-before($string, $target), $replacement, $rest)"/>
71 <xsl:value-of select="$string"/>
75 <xsl:template name="xpointer.idref">
76 <xsl:param name="xpointer">http://...</xsl:param>
78 <xsl:when test="starts-with($xpointer, '#xpointer(id(')">
79 <xsl:variable name="rest" select="substring-after($xpointer, '#xpointer(id(')"/>
80 <xsl:variable name="quote" select="substring($rest, 1, 1)"/>
81 <xsl:value-of select="substring-before(substring-after($xpointer, $quote), $quote)"/>
83 <xsl:when test="starts-with($xpointer, '#')">
84 <xsl:value-of select="substring-after($xpointer, '#')"/>
86 <!-- otherwise it's a pointer to some other document -->
89 <xsl:template name="length-magnitude">
90 <xsl:param name="length" select="'0pt'"/>
93 <xsl:when test="string-length($length) = 0"/>
94 <xsl:when test="substring($length,1,1) = '0' or substring($length,1,1) = '1' or substring($length,1,1) = '2' or substring($length,1,1) = '3' or substring($length,1,1) = '4' or substring($length,1,1) = '5' or substring($length,1,1) = '6' or substring($length,1,1) = '7' or substring($length,1,1) = '8' or substring($length,1,1) = '9' or substring($length,1,1) = '.'">
95 <xsl:value-of select="substring($length,1,1)"/>
96 <xsl:call-template name="length-magnitude">
97 <xsl:with-param name="length" select="substring($length,2)"/>
102 <xsl:template name="length-units">
103 <xsl:param name="length" select="'0pt'"/>
104 <xsl:param name="default.units" select="'px'"/>
105 <xsl:variable name="magnitude">
106 <xsl:call-template name="length-magnitude">
107 <xsl:with-param name="length" select="$length"/>
111 <xsl:variable name="units">
112 <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
116 <xsl:when test="$units = ''">
117 <xsl:value-of select="$default.units"/>
120 <xsl:value-of select="$units"/>
124 <xsl:template name="length-spec">
125 <xsl:param name="length" select="'0pt'"/>
126 <xsl:param name="default.units" select="'px'"/>
128 <xsl:variable name="magnitude">
129 <xsl:call-template name="length-magnitude">
130 <xsl:with-param name="length" select="$length"/>
134 <xsl:variable name="units">
135 <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
138 <xsl:value-of select="$magnitude"/>
140 <xsl:when test="$units='cm' or $units='mm' or $units='in' or $units='pt' or $units='pc' or $units='px' or $units='em'">
141 <xsl:value-of select="$units"/>
143 <xsl:when test="$units = ''">
144 <xsl:value-of select="$default.units"/>
148 <xsl:text>Unrecognized unit of measure: </xsl:text>
149 <xsl:value-of select="$units"/>
150 <xsl:text>.</xsl:text>
155 <xsl:template name="length-in-points">
156 <xsl:param name="length" select="'0pt'"/>
157 <xsl:param name="em.size" select="10"/>
158 <xsl:param name="pixels.per.inch" select="90"/>
160 <xsl:variable name="magnitude">
161 <xsl:call-template name="length-magnitude">
162 <xsl:with-param name="length" select="$length"/>
166 <xsl:variable name="units">
167 <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
171 <xsl:when test="$units = 'pt'">
172 <xsl:value-of select="$magnitude"/>
174 <xsl:when test="$units = 'cm'">
175 <xsl:value-of select="$magnitude div 2.54 * 72.0"/>
177 <xsl:when test="$units = 'mm'">
178 <xsl:value-of select="$magnitude div 25.4 * 72.0"/>
180 <xsl:when test="$units = 'in'">
181 <xsl:value-of select="$magnitude * 72.0"/>
183 <xsl:when test="$units = 'pc'">
184 <xsl:value-of select="$magnitude * 12.0"/>
186 <xsl:when test="$units = 'px'">
187 <xsl:value-of select="$magnitude div $pixels.per.inch * 72.0"/>
189 <xsl:when test="$units = 'em'">
190 <xsl:value-of select="$magnitude * $em.size"/>
194 <xsl:text>Unrecognized unit of measure: </xsl:text>
195 <xsl:value-of select="$units"/>
196 <xsl:text>.</xsl:text>
201 <xsl:template name="pi-attribute">
202 <xsl:param name="pis" select="processing-instruction('BOGUS_PI')"/>
203 <xsl:param name="attribute">filename</xsl:param>
204 <xsl:param name="count">1</xsl:param>
207 <xsl:when test="$count>count($pis)">
211 <xsl:variable name="pi">
212 <xsl:value-of select="$pis[$count]"/>
214 <xsl:variable name="pivalue">
215 <xsl:value-of select="concat(' ', normalize-space($pi))"/>
218 <xsl:when test="contains($pivalue,concat(' ', $attribute, '='))">
219 <xsl:variable name="rest" select="substring-after($pivalue,concat(' ', $attribute,'='))"/>
220 <xsl:variable name="quote" select="substring($rest,1,1)"/>
221 <xsl:value-of select="substring-before(substring($rest,2),$quote)"/>
224 <xsl:call-template name="pi-attribute">
225 <xsl:with-param name="pis" select="$pis"/>
226 <xsl:with-param name="attribute" select="$attribute"/>
227 <xsl:with-param name="count" select="$count + 1"/>
234 <xsl:template name="lookup.key">
235 <xsl:param name="key" select="''"/>
236 <xsl:param name="table" select="''"/>
238 <xsl:if test="contains($table, ' ')">
240 <xsl:when test="substring-before($table, ' ') = $key">
241 <xsl:variable name="rest" select="substring-after($table, ' ')"/>
243 <xsl:when test="contains($rest, ' ')">
244 <xsl:value-of select="substring-before($rest, ' ')"/>
247 <xsl:value-of select="$rest"/>
252 <xsl:call-template name="lookup.key">
253 <xsl:with-param name="key" select="$key"/>
254 <xsl:with-param name="table" select="substring-after(substring-after($table,' '), ' ')"/>
260 <xsl:template name="xpath.location">
261 <xsl:param name="node" select="."/>
262 <xsl:param name="path" select="''"/>
264 <xsl:variable name="next.path">
265 <xsl:value-of select="local-name($node)"/>
266 <xsl:if test="$path != ''">/</xsl:if>
267 <xsl:value-of select="$path"/>
271 <xsl:when test="$node/parent::*">
272 <xsl:call-template name="xpath.location">
273 <xsl:with-param name="node" select="$node/parent::*"/>
274 <xsl:with-param name="path" select="$next.path"/>
278 <xsl:text>/</xsl:text>
279 <xsl:value-of select="$next.path"/>
283 <xsl:template name="comment-escape-string">
284 <xsl:param name="string" select="''"/>
286 <xsl:if test="starts-with($string, '-')">
287 <xsl:text> </xsl:text>
290 <xsl:call-template name="comment-escape-string.recursive">
291 <xsl:with-param name="string" select="$string"/>
294 <xsl:if test="substring($string, string-length($string), 1) = '-'">
295 <xsl:text> </xsl:text>
298 <xsl:template name="comment-escape-string.recursive">
299 <xsl:param name="string" select="''"/>
301 <xsl:when test="contains($string, '--')">
302 <xsl:value-of select="substring-before($string, '--')"/>
303 <xsl:value-of select="'- -'"/>
304 <xsl:call-template name="comment-escape-string.recursive">
305 <xsl:with-param name="string" select="substring-after($string, '--')"/>
309 <xsl:value-of select="$string"/>
313 <xsl:template name="prepend-pad">
314 <!-- recursive template to right justify and prepend-->
315 <!-- the value with whatever padChar is passed in -->
316 <xsl:param name="padChar" select="' '"/>
317 <xsl:param name="padVar"/>
318 <xsl:param name="length"/>
320 <xsl:when test="string-length($padVar) < $length">
321 <xsl:call-template name="prepend-pad">
322 <xsl:with-param name="padChar" select="$padChar"/>
323 <xsl:with-param name="padVar" select="concat($padChar,$padVar)"/>
324 <xsl:with-param name="length" select="$length"/>
328 <xsl:value-of select="substring($padVar,string-length($padVar) - $length + 1)"/>
333 <xsl:template name="str.tokenize.keep.delimiters">
334 <xsl:param name="string" select="''"/>
335 <xsl:param name="delimiters" select="' '"/>
337 <xsl:when test="not($string)"/>
338 <xsl:when test="not($delimiters)">
339 <xsl:call-template name="str.tokenize.keep.delimiters-characters">
340 <xsl:with-param name="string" select="$string"/>
344 <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
345 <xsl:with-param name="string" select="$string"/>
346 <xsl:with-param name="delimiters" select="$delimiters"/>
352 <xsl:template name="str.tokenize.keep.delimiters-characters">
353 <xsl:param name="string"/>
354 <xsl:if test="$string">
355 <token><xsl:value-of select="substring($string, 1, 1)"/></token>
356 <xsl:call-template name="str.tokenize.keep.delimiters-characters">
357 <xsl:with-param name="string" select="substring($string, 2)"/>
362 <xsl:template name="str.tokenize.keep.delimiters-delimiters">
363 <xsl:param name="string"/>
364 <xsl:param name="delimiters"/>
365 <xsl:variable name="delimiter" select="substring($delimiters, 1, 1)"/>
367 <xsl:when test="not($delimiter)">
368 <token><xsl:value-of select="$string"/></token>
370 <xsl:when test="contains($string, $delimiter)">
371 <xsl:if test="not(starts-with($string, $delimiter))">
372 <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
373 <xsl:with-param name="string" select="substring-before($string, $delimiter)"/>
374 <xsl:with-param name="delimiters" select="substring($delimiters, 2)"/>
377 <!-- output each delimiter -->
378 <xsl:value-of select="$delimiter"/>
379 <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
380 <xsl:with-param name="string" select="substring-after($string, $delimiter)"/>
381 <xsl:with-param name="delimiters" select="$delimiters"/>
385 <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
386 <xsl:with-param name="string" select="$string"/>
387 <xsl:with-param name="delimiters" select="substring($delimiters, 2)"/>
392 <xsl:template name="apply-string-subst-map">
393 <xsl:param name="content"/>
394 <xsl:param name="map.contents"/>
395 <xsl:variable name="replaced_text">
396 <xsl:call-template name="string.subst">
397 <xsl:with-param name="string" select="$content"/>
398 <xsl:with-param name="target" select="$map.contents[1]/@oldstring"/>
399 <xsl:with-param name="replacement" select="$map.contents[1]/@newstring"/>
403 <xsl:when test="$map.contents[2]">
404 <xsl:call-template name="apply-string-subst-map">
405 <xsl:with-param name="content" select="$replaced_text"/>
406 <xsl:with-param name="map.contents" select="$map.contents[position() > 1]"/>
410 <xsl:value-of select="$replaced_text"/>
416 <xsl:template name="apply-character-map">
417 <xsl:param name="content"/>
418 <xsl:param name="map.contents"/>
419 <xsl:variable name="replaced_text">
420 <xsl:call-template name="string.subst">
421 <xsl:with-param name="string" select="$content"/>
422 <xsl:with-param name="target" select="$map.contents[1]/@character"/>
423 <xsl:with-param name="replacement" select="$map.contents[1]/@string"/>
427 <xsl:when test="$map.contents[2]">
428 <xsl:call-template name="apply-character-map">
429 <xsl:with-param name="content" select="$replaced_text"/>
430 <xsl:with-param name="map.contents" select="$map.contents[position() > 1]"/>
434 <xsl:value-of select="$replaced_text"/>
440 <xsl:template name="read-character-map">
441 <xsl:param name="use.subset"/>
442 <xsl:param name="subset.profile"/>
443 <xsl:param name="uri"/>
445 <xsl:when test="$use.subset != 0">
446 <!-- use a subset of the character map instead of the full map -->
448 <!-- xsltproc and Xalan both support dyn:evaluate() -->
449 <xsl:when test="function-available('dyn:evaluate')">
450 <xsl:copy-of select="document($uri)//*[local-name()='output-character'] [dyn:evaluate($subset.profile)]"/>
452 <!-- Saxon has its own evaluate() & doesn't support dyn:evaluate() -->
453 <xsl:when test="function-available('saxon:evaluate')">
454 <xsl:copy-of select="document($uri)//*[local-name()='output-character'] [saxon:evaluate($subset.profile)]"/>
457 <xsl:message terminate="yes">
458 Error: To process character-map subsets, you must use an XSLT engine
459 that supports the evaluate() XSLT extension function. Your XSLT engine
466 <!-- value of $use.subet is non-zero, so use the full map -->
467 <xsl:copy-of select="document($uri)//*[local-name()='output-character']"/>
471 <xsl:template name="count.uri.path.depth">
472 <xsl:param name="filename" select="''"/>
473 <xsl:param name="count" select="0"/>
476 <xsl:when test="contains($filename, '/')">
477 <xsl:call-template name="count.uri.path.depth">
478 <xsl:with-param name="filename" select="substring-after($filename, '/')"/>
479 <xsl:with-param name="count" select="$count + 1"/>
483 <xsl:value-of select="$count"/>
487 <xsl:template name="trim.common.uri.paths">
488 <xsl:param name="uriA" select="''"/>
489 <xsl:param name="uriB" select="''"/>
490 <xsl:param name="return" select="'A'"/>
493 <xsl:when test="contains($uriA, '/') and contains($uriB, '/') and substring-before($uriA, '/') = substring-before($uriB, '/')">
494 <xsl:call-template name="trim.common.uri.paths">
495 <xsl:with-param name="uriA" select="substring-after($uriA, '/')"/>
496 <xsl:with-param name="uriB" select="substring-after($uriB, '/')"/>
497 <xsl:with-param name="return" select="$return"/>
502 <xsl:when test="$return = 'A'">
503 <xsl:value-of select="$uriA"/>
506 <xsl:value-of select="$uriB"/>