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