]> git.stg.codes - stg.git/blob - doc/xslt/lib/lib.xsl
Fixed parsers.
[stg.git] / doc / xslt / lib / lib.xsl
1 <?xml version="1.0" encoding="ASCII"?>
2 <!-- ********************************************************************
3      $Id: lib.xweb 7102 2007-07-20 15:35:24Z xmldoc $
4      ********************************************************************
5
6      This file is part of the XSL DocBook Stylesheet distribution.
7      See ../README or http://docbook.sf.net/release/xsl/current/ for
8      copyright and other information.
9
10      This module implements DTD-independent functions
11
12      ******************************************************************** -->
13 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
14
15 <xsl:template name="dot.count">
16   <!-- Returns the number of "." characters in a string -->
17   <xsl:param name="string"/>
18   <xsl:param name="count" select="0"/>
19   <xsl:choose>
20     <xsl:when test="contains($string, '.')">
21       <xsl:call-template name="dot.count">
22         <xsl:with-param name="string" select="substring-after($string, '.')"/>
23         <xsl:with-param name="count" select="$count+1"/>
24       </xsl:call-template>
25     </xsl:when>
26     <xsl:otherwise>
27       <xsl:value-of select="$count"/>
28     </xsl:otherwise>
29   </xsl:choose>
30 </xsl:template>
31 <xsl:template name="copy-string">
32   <!-- returns 'count' copies of 'string' -->
33   <xsl:param name="string"/>
34   <xsl:param name="count" select="0"/>
35   <xsl:param name="result"/>
36
37   <xsl:choose>
38     <xsl:when test="$count&gt;0">
39       <xsl:call-template name="copy-string">
40         <xsl:with-param name="string" select="$string"/>
41         <xsl:with-param name="count" select="$count - 1"/>
42         <xsl:with-param name="result">
43           <xsl:value-of select="$result"/>
44           <xsl:value-of select="$string"/>
45         </xsl:with-param>
46       </xsl:call-template>
47     </xsl:when>
48     <xsl:otherwise>
49       <xsl:value-of select="$result"/>
50     </xsl:otherwise>
51   </xsl:choose>
52 </xsl:template>
53 <xsl:template name="string.subst">
54   <xsl:param name="string"/>
55   <xsl:param name="target"/>
56   <xsl:param name="replacement"/>
57
58   <xsl:choose>
59     <xsl:when test="contains($string, $target)">
60       <xsl:variable name="rest">
61         <xsl:call-template name="string.subst">
62           <xsl:with-param name="string" select="substring-after($string, $target)"/>
63           <xsl:with-param name="target" select="$target"/>
64           <xsl:with-param name="replacement" select="$replacement"/>
65         </xsl:call-template>
66       </xsl:variable>
67       <xsl:value-of select="concat(substring-before($string, $target),                                    $replacement,                                    $rest)"/>
68     </xsl:when>
69     <xsl:otherwise>
70       <xsl:value-of select="$string"/>
71     </xsl:otherwise>
72   </xsl:choose>
73 </xsl:template>
74 <xsl:template name="xpointer.idref">
75   <xsl:param name="xpointer">http://...</xsl:param>
76   <xsl:choose>
77     <xsl:when test="starts-with($xpointer, '#xpointer(id(')">
78       <xsl:variable name="rest" select="substring-after($xpointer, '#xpointer(id(')"/>
79       <xsl:variable name="quote" select="substring($rest, 1, 1)"/>
80       <xsl:value-of select="substring-before(substring-after($xpointer, $quote), $quote)"/>
81     </xsl:when>
82     <xsl:when test="starts-with($xpointer, '#')">
83       <xsl:value-of select="substring-after($xpointer, '#')"/>
84     </xsl:when>
85     <!-- otherwise it's a pointer to some other document -->
86   </xsl:choose>
87 </xsl:template>
88 <xsl:template name="length-magnitude">
89   <xsl:param name="length" select="'0pt'"/>
90
91   <xsl:choose>
92     <xsl:when test="string-length($length) = 0"/>
93     <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) = '.'">
94       <xsl:value-of select="substring($length,1,1)"/>
95       <xsl:call-template name="length-magnitude">
96         <xsl:with-param name="length" select="substring($length,2)"/>
97       </xsl:call-template>
98     </xsl:when>
99   </xsl:choose>
100 </xsl:template>
101 <xsl:template name="length-units">
102   <xsl:param name="length" select="'0pt'"/>
103   <xsl:param name="default.units" select="'px'"/>
104   <xsl:variable name="magnitude">
105     <xsl:call-template name="length-magnitude">
106       <xsl:with-param name="length" select="$length"/>
107     </xsl:call-template>
108   </xsl:variable>
109
110   <xsl:variable name="units">
111     <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
112   </xsl:variable>
113
114   <xsl:choose>
115     <xsl:when test="$units = ''">
116       <xsl:value-of select="$default.units"/>
117     </xsl:when>
118     <xsl:otherwise>
119       <xsl:value-of select="$units"/>
120     </xsl:otherwise>
121   </xsl:choose>
122 </xsl:template>
123 <xsl:template name="length-spec">
124   <xsl:param name="length" select="'0pt'"/>
125   <xsl:param name="default.units" select="'px'"/>
126
127   <xsl:variable name="magnitude">
128     <xsl:call-template name="length-magnitude">
129       <xsl:with-param name="length" select="$length"/>
130     </xsl:call-template>
131   </xsl:variable>
132
133   <xsl:variable name="units">
134     <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
135   </xsl:variable>
136
137   <xsl:value-of select="$magnitude"/>
138   <xsl:choose>
139     <xsl:when test="$units='cm'                     or $units='mm'                     or $units='in'                     or $units='pt'                     or $units='pc'                     or $units='px'                     or $units='em'">
140       <xsl:value-of select="$units"/>
141     </xsl:when>
142     <xsl:when test="$units = ''">
143       <xsl:value-of select="$default.units"/>
144     </xsl:when>
145     <xsl:otherwise>
146       <xsl:message>
147         <xsl:text>Unrecognized unit of measure: </xsl:text>
148         <xsl:value-of select="$units"/>
149         <xsl:text>.</xsl:text>
150       </xsl:message>
151     </xsl:otherwise>
152   </xsl:choose>
153 </xsl:template>
154 <xsl:template name="length-in-points">
155   <xsl:param name="length" select="'0pt'"/>
156   <xsl:param name="em.size" select="10"/>
157   <xsl:param name="pixels.per.inch" select="90"/>
158
159   <xsl:variable name="magnitude">
160     <xsl:call-template name="length-magnitude">
161       <xsl:with-param name="length" select="$length"/>
162     </xsl:call-template>
163   </xsl:variable>
164
165   <xsl:variable name="units">
166     <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
167   </xsl:variable>
168
169   <xsl:choose>
170     <xsl:when test="$units = 'pt'">
171       <xsl:value-of select="$magnitude"/>
172     </xsl:when>
173     <xsl:when test="$units = 'cm'">
174       <xsl:value-of select="$magnitude div 2.54 * 72.0"/>
175     </xsl:when>
176     <xsl:when test="$units = 'mm'">
177       <xsl:value-of select="$magnitude div 25.4 * 72.0"/>
178     </xsl:when>
179     <xsl:when test="$units = 'in'">
180       <xsl:value-of select="$magnitude * 72.0"/>
181     </xsl:when>
182     <xsl:when test="$units = 'pc'">
183       <xsl:value-of select="$magnitude * 12.0"/>
184     </xsl:when>
185     <xsl:when test="$units = 'px'">
186       <xsl:value-of select="$magnitude div $pixels.per.inch * 72.0"/>
187     </xsl:when>
188     <xsl:when test="$units = 'em'">
189       <xsl:value-of select="$magnitude * $em.size"/>
190     </xsl:when>
191     <xsl:otherwise>
192       <xsl:message>
193         <xsl:text>Unrecognized unit of measure: </xsl:text>
194         <xsl:value-of select="$units"/>
195         <xsl:text>.</xsl:text>
196       </xsl:message>
197     </xsl:otherwise>
198   </xsl:choose>
199 </xsl:template>
200 <xsl:template name="pi-attribute">
201   <xsl:param name="pis" select="processing-instruction('BOGUS_PI')"/>
202   <xsl:param name="attribute">filename</xsl:param>
203   <xsl:param name="count">1</xsl:param>
204
205   <xsl:choose>
206     <xsl:when test="$count&gt;count($pis)">
207       <!-- not found -->
208     </xsl:when>
209     <xsl:otherwise>
210       <xsl:variable name="pi">
211         <xsl:value-of select="$pis[$count]"/>
212       </xsl:variable>
213       <xsl:variable name="pivalue">
214         <xsl:value-of select="concat(' ', normalize-space($pi))"/>
215       </xsl:variable>
216       <xsl:choose>
217         <xsl:when test="contains($pivalue,concat(' ', $attribute, '='))">
218           <xsl:variable name="rest" select="substring-after($pivalue,concat(' ', $attribute,'='))"/>
219           <xsl:variable name="quote" select="substring($rest,1,1)"/>
220           <xsl:value-of select="substring-before(substring($rest,2),$quote)"/>
221         </xsl:when>
222         <xsl:otherwise>
223           <xsl:call-template name="pi-attribute">
224             <xsl:with-param name="pis" select="$pis"/>
225             <xsl:with-param name="attribute" select="$attribute"/>
226             <xsl:with-param name="count" select="$count + 1"/>
227           </xsl:call-template>
228         </xsl:otherwise>
229       </xsl:choose>
230     </xsl:otherwise>
231   </xsl:choose>
232 </xsl:template>
233 <xsl:template name="lookup.key">
234   <xsl:param name="key" select="''"/>
235   <xsl:param name="table" select="''"/>
236
237   <xsl:if test="contains($table, ' ')">
238     <xsl:choose>
239       <xsl:when test="substring-before($table, ' ') = $key">
240         <xsl:variable name="rest" select="substring-after($table, ' ')"/>
241         <xsl:choose>
242           <xsl:when test="contains($rest, ' ')">
243             <xsl:value-of select="substring-before($rest, ' ')"/>
244           </xsl:when>
245           <xsl:otherwise>
246             <xsl:value-of select="$rest"/>
247           </xsl:otherwise>
248         </xsl:choose>
249       </xsl:when>
250       <xsl:otherwise>
251         <xsl:call-template name="lookup.key">
252           <xsl:with-param name="key" select="$key"/>
253           <xsl:with-param name="table" select="substring-after(substring-after($table,' '), ' ')"/>
254         </xsl:call-template>
255       </xsl:otherwise>
256     </xsl:choose>
257   </xsl:if>
258 </xsl:template>
259 <xsl:template name="xpath.location">
260   <xsl:param name="node" select="."/>
261   <xsl:param name="path" select="''"/>
262
263   <xsl:variable name="next.path">
264     <xsl:value-of select="local-name($node)"/>
265     <xsl:if test="$path != ''">/</xsl:if>
266     <xsl:value-of select="$path"/>
267   </xsl:variable>
268
269   <xsl:choose>
270     <xsl:when test="$node/parent::*">
271       <xsl:call-template name="xpath.location">
272         <xsl:with-param name="node" select="$node/parent::*"/>
273         <xsl:with-param name="path" select="$next.path"/>
274       </xsl:call-template>
275     </xsl:when>
276     <xsl:otherwise>
277       <xsl:text>/</xsl:text>
278       <xsl:value-of select="$next.path"/>
279     </xsl:otherwise>
280   </xsl:choose>
281 </xsl:template>
282 <xsl:template name="comment-escape-string">
283   <xsl:param name="string" select="''"/>
284
285   <xsl:if test="starts-with($string, '-')">
286     <xsl:text> </xsl:text>
287   </xsl:if>
288
289   <xsl:call-template name="comment-escape-string.recursive">
290     <xsl:with-param name="string" select="$string"/>
291   </xsl:call-template>
292
293   <xsl:if test="substring($string, string-length($string), 1) = '-'">
294     <xsl:text> </xsl:text>
295   </xsl:if>
296 </xsl:template>
297 <xsl:template name="comment-escape-string.recursive">
298   <xsl:param name="string" select="''"/>
299   <xsl:choose>
300     <xsl:when test="contains($string, '--')">
301       <xsl:value-of select="substring-before($string, '--')"/>
302       <xsl:value-of select="'- -'"/>
303       <xsl:call-template name="comment-escape-string.recursive">
304         <xsl:with-param name="string" select="substring-after($string, '--')"/>
305       </xsl:call-template>
306     </xsl:when>
307     <xsl:otherwise>
308       <xsl:value-of select="$string"/>
309     </xsl:otherwise>
310   </xsl:choose>
311 </xsl:template>
312   <xsl:template name="str.tokenize.keep.delimiters">
313     <xsl:param name="string" select="''"/>
314     <xsl:param name="delimiters" select="' '"/>
315     <xsl:choose>
316       <xsl:when test="not($string)"/>
317       <xsl:when test="not($delimiters)">
318         <xsl:call-template name="str.tokenize.keep.delimiters-characters">
319           <xsl:with-param name="string" select="$string"/>
320         </xsl:call-template>
321       </xsl:when>
322       <xsl:otherwise>
323         <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
324           <xsl:with-param name="string" select="$string"/>
325           <xsl:with-param name="delimiters" select="$delimiters"/>
326         </xsl:call-template>
327       </xsl:otherwise>
328     </xsl:choose>
329   </xsl:template>
330   <xsl:template name="str.tokenize.keep.delimiters-characters">
331     <xsl:param name="string"/>
332     <xsl:if test="$string">
333       <ssb:token xmlns:ssb="http://sideshowbarker.net/ns"><xsl:value-of select="substring($string, 1, 1)"/></ssb:token>
334       <xsl:call-template name="str.tokenize.keep.delimiters-characters">
335         <xsl:with-param name="string" select="substring($string, 2)"/>
336       </xsl:call-template>
337     </xsl:if>
338   </xsl:template>
339   <xsl:template name="str.tokenize.keep.delimiters-delimiters">
340     <xsl:param name="string"/>
341     <xsl:param name="delimiters"/>
342     <xsl:variable name="delimiter" select="substring($delimiters, 1, 1)"/>
343     <xsl:choose>
344       <xsl:when test="not($delimiter)">
345         <ssb:token xmlns:ssb="http://sideshowbarker.net/ns"><xsl:value-of select="$string"/></ssb:token>
346       </xsl:when>
347       <xsl:when test="contains($string, $delimiter)">
348         <xsl:if test="not(starts-with($string, $delimiter))">
349           <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
350             <xsl:with-param name="string" select="substring-before($string, $delimiter)"/>
351             <xsl:with-param name="delimiters" select="substring($delimiters, 2)"/>
352           </xsl:call-template>
353         </xsl:if>
354         <!-- output each delimiter -->
355         <xsl:value-of select="$delimiter"/>
356         <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
357           <xsl:with-param name="string" select="substring-after($string, $delimiter)"/>
358           <xsl:with-param name="delimiters" select="$delimiters"/>
359         </xsl:call-template>
360       </xsl:when>
361       <xsl:otherwise>
362         <xsl:call-template name="str.tokenize.keep.delimiters-delimiters">
363           <xsl:with-param name="string" select="$string"/>
364           <xsl:with-param name="delimiters" select="substring($delimiters, 2)"/>
365         </xsl:call-template>
366       </xsl:otherwise>
367     </xsl:choose>
368   </xsl:template>
369     <xsl:template name="apply-string-subst-map">
370       <xsl:param name="content"/>
371       <xsl:param name="map.contents"/>
372       <xsl:variable name="replaced_text">
373         <xsl:call-template name="string.subst">
374           <xsl:with-param name="string" select="$content"/>
375           <xsl:with-param name="target" select="$map.contents[1]/@oldstring"/>
376           <xsl:with-param name="replacement" select="$map.contents[1]/@newstring"/>
377         </xsl:call-template>
378       </xsl:variable>
379       <xsl:choose>
380         <xsl:when test="$map.contents[2]">
381           <xsl:call-template name="apply-string-subst-map">
382             <xsl:with-param name="content" select="$replaced_text"/>
383             <xsl:with-param name="map.contents" select="$map.contents[position() &gt; 1]"/>
384           </xsl:call-template>
385         </xsl:when>
386         <xsl:otherwise>
387           <xsl:value-of select="$replaced_text"/>
388         </xsl:otherwise>
389       </xsl:choose>
390     </xsl:template>
391   
392 <xsl:template name="count.uri.path.depth">
393   <xsl:param name="filename" select="''"/>
394   <xsl:param name="count" select="0"/>
395
396   <xsl:choose>
397     <xsl:when test="contains($filename, '/')">
398       <xsl:call-template name="count.uri.path.depth">
399         <xsl:with-param name="filename" select="substring-after($filename, '/')"/>
400         <xsl:with-param name="count" select="$count + 1"/>
401       </xsl:call-template>
402     </xsl:when>
403     <xsl:otherwise>
404       <xsl:value-of select="$count"/>
405     </xsl:otherwise>
406   </xsl:choose>
407 </xsl:template>
408 <xsl:template name="trim.common.uri.paths">
409   <xsl:param name="uriA" select="''"/>
410   <xsl:param name="uriB" select="''"/>
411   <xsl:param name="return" select="'A'"/>
412
413   <xsl:choose>
414     <xsl:when test="contains($uriA, '/') and contains($uriB, '/')                     and substring-before($uriA, '/') = substring-before($uriB, '/')">
415       <xsl:call-template name="trim.common.uri.paths">
416         <xsl:with-param name="uriA" select="substring-after($uriA, '/')"/>
417         <xsl:with-param name="uriB" select="substring-after($uriB, '/')"/>
418         <xsl:with-param name="return" select="$return"/>
419       </xsl:call-template>
420     </xsl:when>
421     <xsl:otherwise>
422       <xsl:choose>
423         <xsl:when test="$return = 'A'">
424           <xsl:value-of select="$uriA"/>
425         </xsl:when>
426         <xsl:otherwise>
427           <xsl:value-of select="$uriB"/>
428         </xsl:otherwise>
429       </xsl:choose>
430     </xsl:otherwise>
431   </xsl:choose>
432 </xsl:template>
433
434   <xsl:template name="trim.text">
435     <xsl:param name="contents" select="."/>
436     <xsl:variable name="contents-left-trimmed">
437       <xsl:call-template name="trim-left">
438         <xsl:with-param name="contents" select="$contents"/>
439       </xsl:call-template>
440     </xsl:variable>
441     <xsl:variable name="contents-trimmed">
442       <xsl:call-template name="trim-right">
443         <xsl:with-param name="contents" select="$contents-left-trimmed"/>
444       </xsl:call-template>
445     </xsl:variable>
446     <xsl:value-of select="$contents-trimmed"/>
447   </xsl:template>
448
449   <xsl:template name="trim-left">
450     <xsl:param name="contents"/>
451     <xsl:choose>
452       <xsl:when test="starts-with($contents,'&#10;') or                       starts-with($contents,'&#13;') or                       starts-with($contents,' ') or                       starts-with($contents,'&#9;')">
453         <xsl:call-template name="trim-left">
454           <xsl:with-param name="contents" select="substring($contents, 2)"/>
455         </xsl:call-template>
456       </xsl:when>
457       <xsl:otherwise>
458         <xsl:value-of select="$contents"/>
459       </xsl:otherwise>
460     </xsl:choose>
461   </xsl:template>
462
463   <xsl:template name="trim-right">
464     <xsl:param name="contents"/>
465     <xsl:variable name="last-char">
466       <xsl:value-of select="substring($contents, string-length($contents), 1)"/>
467     </xsl:variable>
468     <xsl:choose>
469       <xsl:when test="($last-char = '&#10;') or                       ($last-char = '&#13;') or                       ($last-char = ' ') or                       ($last-char = '&#9;')">
470         <xsl:call-template name="trim-right">
471           <xsl:with-param name="contents" select="substring($contents, 1, string-length($contents) - 1)"/>
472         </xsl:call-template>
473       </xsl:when>
474       <xsl:otherwise>
475         <xsl:value-of select="$contents"/>
476       </xsl:otherwise>
477     </xsl:choose>
478   </xsl:template>
479
480 </xsl:stylesheet>