Rocco Rutte:
[apps/madmutt.git] / doc / xslt / lib / lib.xsl
1 <?xml version="1.0" encoding="utf-8"?>
2 <!-- ********************************************************************
3      $Id$
4      ********************************************************************
5
6      This file is part of the XSL DocBook Stylesheet distribution.
7      See ../README or http://nwalsh.com/docbook/xsl/ for copyright
8      and other information.
9
10      This module implements DTD-independent functions
11
12      ******************************************************************** -->
13
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">
15
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"/>
20   <xsl:choose>
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"/>
25       </xsl:call-template>
26     </xsl:when>
27     <xsl:otherwise>
28       <xsl:value-of select="$count"/>
29     </xsl:otherwise>
30   </xsl:choose>
31 </xsl:template>
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"/>
37
38   <xsl:choose>
39     <xsl:when test="$count&gt;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"/>
46         </xsl:with-param>
47       </xsl:call-template>
48     </xsl:when>
49     <xsl:otherwise>
50       <xsl:value-of select="$result"/>
51     </xsl:otherwise>
52   </xsl:choose>
53 </xsl:template>
54 <xsl:template name="string.subst">
55   <xsl:param name="string"/>
56   <xsl:param name="target"/>
57   <xsl:param name="replacement"/>
58
59   <xsl:choose>
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"/>
66         </xsl:call-template>
67       </xsl:variable>
68       <xsl:value-of select="concat(substring-before($string, $target),                                    $replacement,                                    $rest)"/>
69     </xsl:when>
70     <xsl:otherwise>
71       <xsl:value-of select="$string"/>
72     </xsl:otherwise>
73   </xsl:choose>
74 </xsl:template>
75 <xsl:template name="xpointer.idref">
76   <xsl:param name="xpointer">http://...</xsl:param>
77   <xsl:choose>
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)"/>
82     </xsl:when>
83     <xsl:when test="starts-with($xpointer, '#')">
84       <xsl:value-of select="substring-after($xpointer, '#')"/>
85     </xsl:when>
86     <!-- otherwise it's a pointer to some other document -->
87   </xsl:choose>
88 </xsl:template>
89 <xsl:template name="length-magnitude">
90   <xsl:param name="length" select="'0pt'"/>
91
92   <xsl:choose>
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)"/>
98       </xsl:call-template>
99     </xsl:when>
100   </xsl:choose>
101 </xsl:template>
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"/>
108     </xsl:call-template>
109   </xsl:variable>
110
111   <xsl:variable name="units">
112     <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
113   </xsl:variable>
114
115   <xsl:choose>
116     <xsl:when test="$units = ''">
117       <xsl:value-of select="$default.units"/>
118     </xsl:when>
119     <xsl:otherwise>
120       <xsl:value-of select="$units"/>
121     </xsl:otherwise>
122   </xsl:choose>
123 </xsl:template>
124 <xsl:template name="length-spec">
125   <xsl:param name="length" select="'0pt'"/>
126   <xsl:param name="default.units" select="'px'"/>
127
128   <xsl:variable name="magnitude">
129     <xsl:call-template name="length-magnitude">
130       <xsl:with-param name="length" select="$length"/>
131     </xsl:call-template>
132   </xsl:variable>
133
134   <xsl:variable name="units">
135     <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
136   </xsl:variable>
137
138   <xsl:value-of select="$magnitude"/>
139   <xsl:choose>
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"/>
142     </xsl:when>
143     <xsl:when test="$units = ''">
144       <xsl:value-of select="$default.units"/>
145     </xsl:when>
146     <xsl:otherwise>
147       <xsl:message>
148         <xsl:text>Unrecognized unit of measure: </xsl:text>
149         <xsl:value-of select="$units"/>
150         <xsl:text>.</xsl:text>
151       </xsl:message>
152     </xsl:otherwise>
153   </xsl:choose>
154 </xsl:template>
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"/>
159
160   <xsl:variable name="magnitude">
161     <xsl:call-template name="length-magnitude">
162       <xsl:with-param name="length" select="$length"/>
163     </xsl:call-template>
164   </xsl:variable>
165
166   <xsl:variable name="units">
167     <xsl:value-of select="substring($length, string-length($magnitude)+1)"/>
168   </xsl:variable>
169
170   <xsl:choose>
171     <xsl:when test="$units = 'pt'">
172       <xsl:value-of select="$magnitude"/>
173     </xsl:when>
174     <xsl:when test="$units = 'cm'">
175       <xsl:value-of select="$magnitude div 2.54 * 72.0"/>
176     </xsl:when>
177     <xsl:when test="$units = 'mm'">
178       <xsl:value-of select="$magnitude div 25.4 * 72.0"/>
179     </xsl:when>
180     <xsl:when test="$units = 'in'">
181       <xsl:value-of select="$magnitude * 72.0"/>
182     </xsl:when>
183     <xsl:when test="$units = 'pc'">
184       <xsl:value-of select="$magnitude * 12.0"/>
185     </xsl:when>
186     <xsl:when test="$units = 'px'">
187       <xsl:value-of select="$magnitude div $pixels.per.inch * 72.0"/>
188     </xsl:when>
189     <xsl:when test="$units = 'em'">
190       <xsl:value-of select="$magnitude * $em.size"/>
191     </xsl:when>
192     <xsl:otherwise>
193       <xsl:message>
194         <xsl:text>Unrecognized unit of measure: </xsl:text>
195         <xsl:value-of select="$units"/>
196         <xsl:text>.</xsl:text>
197       </xsl:message>
198     </xsl:otherwise>
199   </xsl:choose>
200 </xsl:template>
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>
205
206   <xsl:choose>
207     <xsl:when test="$count&gt;count($pis)">
208       <!-- not found -->
209     </xsl:when>
210     <xsl:otherwise>
211       <xsl:variable name="pi">
212         <xsl:value-of select="$pis[$count]"/>
213       </xsl:variable>
214       <xsl:variable name="pivalue">
215         <xsl:value-of select="concat(' ', normalize-space($pi))"/>
216       </xsl:variable>
217       <xsl:choose>
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)"/>
222         </xsl:when>
223         <xsl:otherwise>
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"/>
228           </xsl:call-template>
229         </xsl:otherwise>
230       </xsl:choose>
231     </xsl:otherwise>
232   </xsl:choose>
233 </xsl:template>
234 <xsl:template name="lookup.key">
235   <xsl:param name="key" select="''"/>
236   <xsl:param name="table" select="''"/>
237
238   <xsl:if test="contains($table, ' ')">
239     <xsl:choose>
240       <xsl:when test="substring-before($table, ' ') = $key">
241         <xsl:variable name="rest" select="substring-after($table, ' ')"/>
242         <xsl:choose>
243           <xsl:when test="contains($rest, ' ')">
244             <xsl:value-of select="substring-before($rest, ' ')"/>
245           </xsl:when>
246           <xsl:otherwise>
247             <xsl:value-of select="$rest"/>
248           </xsl:otherwise>
249         </xsl:choose>
250       </xsl:when>
251       <xsl:otherwise>
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,' '), ' ')"/>
255         </xsl:call-template>
256       </xsl:otherwise>
257     </xsl:choose>
258   </xsl:if>
259 </xsl:template>
260 <xsl:template name="xpath.location">
261   <xsl:param name="node" select="."/>
262   <xsl:param name="path" select="''"/>
263
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"/>
268   </xsl:variable>
269
270   <xsl:choose>
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"/>
275       </xsl:call-template>
276     </xsl:when>
277     <xsl:otherwise>
278       <xsl:text>/</xsl:text>
279       <xsl:value-of select="$next.path"/>
280     </xsl:otherwise>
281   </xsl:choose>
282 </xsl:template>
283 <xsl:template name="comment-escape-string">
284   <xsl:param name="string" select="''"/>
285
286   <xsl:if test="starts-with($string, '-')">
287     <xsl:text> </xsl:text>
288   </xsl:if>
289
290   <xsl:call-template name="comment-escape-string.recursive">
291     <xsl:with-param name="string" select="$string"/>
292   </xsl:call-template>
293
294   <xsl:if test="substring($string, string-length($string), 1) = '-'">
295     <xsl:text> </xsl:text>
296   </xsl:if>
297 </xsl:template>
298 <xsl:template name="comment-escape-string.recursive">
299   <xsl:param name="string" select="''"/>
300   <xsl:choose>
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, '--')"/>
306       </xsl:call-template>
307     </xsl:when>
308     <xsl:otherwise>
309       <xsl:value-of select="$string"/>
310     </xsl:otherwise>
311   </xsl:choose>
312 </xsl:template>
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"/>
319     <xsl:choose>
320       <xsl:when test="string-length($padVar) &lt; $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"/>
325         </xsl:call-template>
326       </xsl:when>
327       <xsl:otherwise>
328         <xsl:value-of select="substring($padVar,string-length($padVar) - $length + 1)"/>
329       </xsl:otherwise>
330     </xsl:choose>
331   </xsl:template>
332
333   <xsl:template name="str.tokenize.keep.delimiters">
334     <xsl:param name="string" select="''"/>
335     <xsl:param name="delimiters" select="' '"/>
336     <xsl:choose>
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"/>
341         </xsl:call-template>
342       </xsl:when>
343       <xsl:otherwise>
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"/>
347         </xsl:call-template>
348       </xsl:otherwise>
349     </xsl:choose>
350   </xsl:template>
351   
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)"/>
358       </xsl:call-template>
359     </xsl:if>
360   </xsl:template>
361   
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)"/>
366     <xsl:choose>
367       <xsl:when test="not($delimiter)">
368         <token><xsl:value-of select="$string"/></token>
369       </xsl:when>
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)"/>
375           </xsl:call-template>
376         </xsl:if>
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"/>
382         </xsl:call-template>
383       </xsl:when>
384       <xsl:otherwise>
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)"/>
388         </xsl:call-template>
389       </xsl:otherwise>
390     </xsl:choose>
391   </xsl:template>
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"/>
400         </xsl:call-template>
401       </xsl:variable>
402       <xsl:choose>
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() &gt; 1]"/>
407           </xsl:call-template>
408         </xsl:when>
409         <xsl:otherwise>
410           <xsl:value-of select="$replaced_text"/>
411         </xsl:otherwise>
412       </xsl:choose>
413     </xsl:template>
414
415   
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"/>
424         </xsl:call-template>
425       </xsl:variable>
426       <xsl:choose>
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() &gt; 1]"/>
431           </xsl:call-template>
432         </xsl:when>
433         <xsl:otherwise>
434           <xsl:value-of select="$replaced_text"/>
435         </xsl:otherwise>
436       </xsl:choose>
437     </xsl:template>
438
439   
440   <xsl:template name="read-character-map">
441     <xsl:param name="use.subset"/>
442     <xsl:param name="subset.profile"/>
443     <xsl:param name="uri"/>
444     <xsl:choose>
445       <xsl:when test="$use.subset != 0">
446         <!-- use a subset of the character map instead of the full map -->
447         <xsl:choose>
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)]"/>
451           </xsl:when>
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)]"/>
455           </xsl:when>
456           <xsl:otherwise>
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
460 does not support it.
461 </xsl:message>
462           </xsl:otherwise>
463         </xsl:choose>
464         </xsl:when>
465         <xsl:otherwise>
466           <!-- value of $use.subet is non-zero, so use the full map -->
467         <xsl:copy-of select="document($uri)//*[local-name()='output-character']"/>
468       </xsl:otherwise>
469     </xsl:choose>
470   </xsl:template>
471 <xsl:template name="count.uri.path.depth">
472   <xsl:param name="filename" select="''"/>
473   <xsl:param name="count" select="0"/>
474
475   <xsl:choose>
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"/>
480       </xsl:call-template>
481     </xsl:when>
482     <xsl:otherwise>
483       <xsl:value-of select="$count"/>
484     </xsl:otherwise>
485   </xsl:choose>
486 </xsl:template>
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'"/>
491
492   <xsl:choose>
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"/>
498       </xsl:call-template>
499     </xsl:when>
500     <xsl:otherwise>
501       <xsl:choose>
502         <xsl:when test="$return = 'A'">
503           <xsl:value-of select="$uriA"/>
504         </xsl:when>
505         <xsl:otherwise>
506           <xsl:value-of select="$uriB"/>
507         </xsl:otherwise>
508       </xsl:choose>
509     </xsl:otherwise>
510   </xsl:choose>
511 </xsl:template>
512
513 </xsl:stylesheet>