Implemented global cross-reference generation
[senf.git] / senfscons / functions.xsl
1 <?xml version="1.0"?>\r
2 <xsl:stylesheet \r
3   version="1.0"\r
4   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"\r
5   xmlns:str="http://exslt.org/strings"\r
6   xmlns:func="http://exslt.org/functions"\r
7   xmlns:exsl="http://exslt.org/common"\r
8   extension-element-prefixes="str exsl func">\r
9   \r
10   <!-- ==================================================================== -->\r
11   <!-- node-set str:replace(string,object,object)                           -->\r
12   <!--                                                                      -->\r
13   <!-- This implements the EXSLT str:replace function                       -->\r
14   <!--                                                                      -->\r
15   <!-- Copyright Jeni Tenison                                               -->\r
16   <!-- ==================================================================== -->\r
17 \r
18   <func:function name="str:replace">\r
19      <xsl:param name="string" select="''" />\r
20      <xsl:param name="search" select="/.." />\r
21      <xsl:param name="replace" select="/.." />\r
22      <xsl:choose>\r
23         <xsl:when test="not($string)">\r
24           <func:result select="/.." />\r
25         </xsl:when>\r
26         <xsl:when test="function-available('exsl:node-set')">\r
27            <!-- this converts the search and replace arguments to node sets\r
28                 if they are one of the other XPath types -->\r
29            <xsl:variable name="search-nodes-rtf">\r
30              <xsl:copy-of select="$search" />\r
31            </xsl:variable>\r
32            <xsl:variable name="replace-nodes-rtf">\r
33              <xsl:copy-of select="$replace" />\r
34            </xsl:variable>\r
35            <xsl:variable name="replacements-rtf">\r
36               <xsl:for-each select="exsl:node-set($search-nodes-rtf)/node()">\r
37                  <xsl:variable name="pos" select="position()" />\r
38                  <replace search="{.}">\r
39                     <xsl:copy-of select="exsl:node-set($replace-nodes-rtf)/node()[$pos]" />\r
40                  </replace>\r
41               </xsl:for-each>\r
42            </xsl:variable>\r
43            <xsl:variable name="sorted-replacements-rtf">\r
44               <xsl:for-each select="exsl:node-set($replacements-rtf)/replace">\r
45                  <xsl:sort select="string-length(@search)" data-type="number" order="descending" />\r
46                  <xsl:copy-of select="." />\r
47               </xsl:for-each>\r
48            </xsl:variable>\r
49            <xsl:variable name="result">\r
50              <xsl:choose>\r
51                 <xsl:when test="not($search)">\r
52                   <xsl:value-of select="$string" />\r
53                 </xsl:when>\r
54                <xsl:otherwise>\r
55                  <xsl:call-template name="str:_replace">\r
56                     <xsl:with-param name="string" select="$string" />\r
57                     <xsl:with-param name="replacements" select="exsl:node-set($sorted-replacements-rtf)/replace" />\r
58                  </xsl:call-template>\r
59                </xsl:otherwise>\r
60              </xsl:choose>\r
61            </xsl:variable>\r
62            <func:result select="exsl:node-set($result)/node()" />\r
63         </xsl:when>\r
64         <xsl:otherwise>\r
65            <xsl:message terminate="yes">\r
66               ERROR: function implementation of str:replace() relies on exsl:node-set().\r
67            </xsl:message>\r
68         </xsl:otherwise>\r
69      </xsl:choose>\r
70   </func:function>\r
71 \r
72   <xsl:template name="str:_replace">\r
73     <xsl:param name="string" select="''" />\r
74     <xsl:param name="replacements" select="/.." />\r
75     <xsl:choose>\r
76       <xsl:when test="not($string)" />\r
77       <xsl:when test="not($replacements)">\r
78         <xsl:value-of select="$string" />\r
79       </xsl:when>\r
80       <xsl:otherwise>\r
81         <xsl:variable name="replacement" select="$replacements[1]" />\r
82         <xsl:variable name="search" select="$replacement/@search" />\r
83         <xsl:choose>\r
84           <xsl:when test="not(string($search))">\r
85             <xsl:value-of select="substring($string, 1, 1)" />\r
86             <xsl:copy-of select="$replacement/node()" />\r
87             <xsl:call-template name="str:_replace">\r
88               <xsl:with-param name="string" select="substring($string, 2)" />\r
89               <xsl:with-param name="replacements" select="$replacements" />\r
90             </xsl:call-template>\r
91           </xsl:when>\r
92           <xsl:when test="contains($string, $search)">\r
93             <xsl:call-template name="str:_replace">\r
94               <xsl:with-param name="string" select="substring-before($string, $search)" />\r
95               <xsl:with-param name="replacements" select="$replacements[position() > 1]" />\r
96             </xsl:call-template>      \r
97             <xsl:copy-of select="$replacement/node()" />\r
98             <xsl:call-template name="str:_replace">\r
99               <xsl:with-param name="string" select="substring-after($string, $search)" />\r
100               <xsl:with-param name="replacements" select="$replacements" />\r
101             </xsl:call-template>\r
102           </xsl:when>\r
103           <xsl:otherwise>\r
104             <xsl:call-template name="str:_replace">\r
105               <xsl:with-param name="string" select="$string" />\r
106               <xsl:with-param name="replacements" select="$replacements[position() > 1]" />\r
107             </xsl:call-template>\r
108           </xsl:otherwise>\r
109         </xsl:choose>\r
110       </xsl:otherwise>\r
111     </xsl:choose>\r
112   </xsl:template>\r
113 \r
114 </xsl:stylesheet>