]> git.draconx.ca Git - homepage.git/blob - layouts/functions.xsl
cdecl99-1.3 bash-5 hotfix
[homepage.git] / layouts / functions.xsl
1 <!--
2   Nick's web site: XSLT helper functions.
3
4   Copyright © 2019-2022 Nick Bowler
5
6   This program is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <https://www.gnu.org/licenses/>
18 -->
19 <xsl:stylesheet version='1.0'
20   xmlns='http://www.w3.org/1999/xhtml'
21   xmlns:xhtml='http://www.w3.org/1999/xhtml'
22   xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
23   xmlns:func='http://exslt.org/functions'
24   xmlns:f='http://draconx.ca/my-functions'
25   extension-element-prefixes='func f'>
26
27 <xsl:output method='xml' encoding='UTF-8' indent='yes'
28   doctype-public='-//W3C//DTD XHTML 1.1//EN'
29   doctype-system='http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd' />
30
31 <!-- Returns true iff the given element is an XHTML span-level element -->
32 <func:function name='f:element-is-span'>
33   <xsl:param name='node' select='.' />
34   <func:result select='$node/self::xhtml:a
35                     or $node/self::xhtml:abbr
36                     or $node/self::xhtml:acronym
37                     or $node/self::xhtml:b
38                     or $node/self::xhtml:bdo
39                     or $node/self::xhtml:big
40                     or $node/self::xhtml:br
41                     or $node/self::xhtml:button
42                     or $node/self::xhtml:cite
43                     or $node/self::xhtml:code
44                     or $node/self::xhtml:dfn
45                     or $node/self::xhtml:em
46                     or $node/self::xhtml:i
47                     or $node/self::xhtml:img
48                     or $node/self::xhtml:input
49                     or $node/self::xhtml:kbd
50                     or $node/self::xhtml:label
51                     or $node/self::xhtml:map
52                     or $node/self::xhtml:object
53                     or $node/self::xhtml:q
54                     or $node/self::xhtml:samp
55                     or $node/self::xhtml:script
56                     or $node/self::xhtml:select
57                     or $node/self::xhtml:small
58                     or $node/self::xhtml:span
59                     or $node/self::xhtml:strong
60                     or $node/self::xhtml:sub
61                     or $node/self::xhtml:sup
62                     or $node/self::xhtml:textarea
63                     or $node/self::xhtml:time
64                     or $node/self::xhtml:tt
65                     or $node/self::xhtml:var' />
66 </func:function>
67
68 <!-- Returns true iff the node is a nonempty text node or a span element -->
69 <func:function name='f:node-is-span'>
70   <xsl:param name='node' select='.' />
71   <func:result select='( $node/self::text() and normalize-text($node) )
72                        or f:element-is-span($node)' />
73 </func:function>
74
75 <!-- f:ends-with(a, b) returns true iff a ends with b -->
76 <func:function name='f:ends-with'>
77   <xsl:param name='str' />
78   <xsl:param name='suffix' />
79   <func:result select='$suffix=substring($str,
80     string-length($str)-string-length($suffix)+1)' />
81 </func:function>
82
83 <!-- Remove leading whitespace from a string -->
84 <func:function name='f:strip-leading'>
85   <xsl:param name='str' select='.' />
86   <xsl:param name='curlen' select='string-length($str)' />
87
88   <xsl:variable name='a' select='substring($str, 1, $curlen)' />
89   <xsl:variable name='b' select='substring($str, 1+$curlen)' />
90
91   <xsl:choose>
92     <xsl:when test='2 > $curlen'>
93       <func:result select='concat(normalize-space($a), $b)' />
94     </xsl:when>
95     <xsl:when test='normalize-space($a) = ""'>
96       <func:result select='f:strip-leading($b)' />
97     </xsl:when>
98     <xsl:otherwise>
99       <func:result select='f:strip-leading($str, ceiling($curlen div 2))' />
100     </xsl:otherwise>
101   </xsl:choose>
102 </func:function>
103
104 <!-- Remove trailing whitespace from a string -->
105 <func:function name='f:strip-trailing'>
106   <xsl:param name='str' select='.' />
107   <xsl:param name='curlen' select='string-length($str)' />
108
109   <xsl:variable name='split' select='string-length($str) - $curlen' />
110   <xsl:variable name='a' select='substring($str, 1, $split)' />
111   <xsl:variable name='b' select='substring($str, 1+$split)' />
112
113   <xsl:choose>
114     <xsl:when test='2 > $curlen'>
115       <func:result select='concat($a, normalize-space($b))' />
116     </xsl:when>
117     <xsl:when test='normalize-space($b) = ""'>
118       <func:result select='f:strip-trailing($a)' />
119     </xsl:when>
120     <xsl:otherwise>
121       <func:result select='f:strip-trailing($str, ceiling($curlen div 2))' />
122     </xsl:otherwise>
123   </xsl:choose>
124 </func:function>
125
126 <!--
127   Convert the given node to a string containing an XHTML listing for that node.
128 -->
129 <func:function name='f:xhtml-listing'>
130   <xsl:param name='nodeset' select='.' />
131   <xsl:variable name='node' select='$nodeset[1]' />
132
133   <func:result>
134     <xsl:choose>
135       <xsl:when test='$node/self::text()'>
136         <!-- text node -->
137         <xsl:value-of select='$node' />
138       </xsl:when>
139       <xsl:when test='$node/self::comment()'>
140         <!-- comment node -->
141         <xsl:value-of select='concat("&lt;!--", $node, "--&gt;")' />
142       </xsl:when>
143       <xsl:when test='$node/self::*'>
144         <!-- element node -->
145         <xsl:value-of select='concat("&lt;", local-name($node))' />
146         <xsl:value-of select='f:xhtml-listing($node/@*)' />
147         <xsl:if test='not($node/node())'>/</xsl:if>
148         <xsl:value-of select='concat("&gt;", f:xhtml-listing($node/node()))' />
149         <xsl:if test='$node/node()'>
150           <xsl:value-of select='concat("&lt;/", local-name($node), "&gt;")' />
151         </xsl:if>
152       </xsl:when>
153       <xsl:when test='$node'>
154         <!-- attribute node -->
155         <xsl:value-of select='concat(" ", local-name($node), "=")' />
156         <xsl:value-of select='concat("&apos;", $node, "&apos;")' />
157       </xsl:when>
158     </xsl:choose>
159     <xsl:for-each select='$nodeset[position()>1]'>
160       <xsl:value-of select='f:xhtml-listing()' />
161     </xsl:for-each>
162   </func:result>
163 </func:function>
164
165 <!--
166   f:contains-token(list, token)
167   Returns true iff the space-separated list contains the given token
168 -->
169 <func:function name='f:contains-token'>
170   <xsl:param name='haystack' />
171   <xsl:param name='needle' />
172
173   <func:result select='contains(
174                          concat(" ", normalize-space($haystack), " "),
175                          concat(" ", normalize-space($needle), " ")
176                        )' />
177 </func:function>
178
179 </xsl:stylesheet>