comparison refs.xsl @ 32:f4432c1faf7f

move to more structure mostly working but external vars are lost
author Henry S. Thompson <ht@markup.co.uk>
date Wed, 12 Apr 2017 14:33:47 +0100
parents 6270bef9b5d4
children 27bffc66ce10
comparison
equal deleted inserted replaced
31:6270bef9b5d4 32:f4432c1faf7f
18 starts-with($defn,$prefix)) 18 starts-with($defn,$prefix))
19 then substring-after($defn,$prefix) 19 then substring-after($defn,$prefix)
20 else ()"/> 20 else ()"/>
21 </xsl:function> 21 </xsl:function>
22 22
23 <xsl:function name="e:tokenise" as="array(xs:string*)*"> 23 <xsl:function name="e:tokenise" as="array(element(*)*)*">
24 <!-- Tokenise a formula, recursively wrt variables --> 24 <!-- Tokenise a formula, recursively wrt variables -->
25 <xsl:param name="formula" as="xs:string" required="yes"/> 25 <xsl:param name="formula" as="xs:string" required="yes"/>
26 <xsl:sequence select=" 26 <xsl:sequence select="
27 let $tokens := analyze-string($formula,$pat)/xf:match/xf:group 27 let $tokens := analyze-string($formula,$pat)/xf:match/xf:group
28 return if ($tokens[@nr=(7,8,9)]) 28 return if ($tokens[@nr=(7,8,9)])
38 not($r[@nr=10 and .=':'])) 38 not($r[@nr=10 and .=':']))
39 then string($t) 39 then string($t)
40 else (), 40 else (),
41 $defns := for $var in $vars return e:lookup($var), 41 $defns := for $var in $vars return e:lookup($var),
42 $recur := for $sub in $defns 42 $recur := for $sub in $defns
43 return if ($sub) then e:tokenise($defns) else (), 43 return if ($sub) then e:tokenise($sub) else (),
44 $singles := for $i in (1 to $n) return 44 $singles := for $i in (1 to $n) return
45 let $t := $tokens[$i], 45 let $t := $tokens[$i],
46 $l := $tokens[$i - 1], 46 $l := $tokens[$i - 1],
47 $r := $tokens[$i + 1] return 47 $r := $tokens[$i + 1] return
48 if ($t/@nr=8 and 48 if ($t/@nr=8 and
49 not($l[@nr=10 and 49 not($l[@nr=10 and
50 .=(':','!')]) and 50 .=(':','!')]) and
51 not($r[@nr=10 and .=':'])) 51 not($r[@nr=10 and .=':']))
52 then string($t) 52 then e:single($t)
53 else (), 53 else (),
54 $ranges := for $i in (1 to count($tokens)) return 54 $ranges := for $i in (1 to count($tokens)) return
55 let $t := $tokens[$i] return 55 let $t := $tokens[$i] return
56 if ($t[@nr=10 and .=':' and 56 if ($t[@nr=10 and .=':' and
57 not($i gt 2 and 57 not($i gt 2 and
58 $tokens[$i - 2][@nr=10 and .='!'])]) 58 $tokens[$i - 2][@nr=10 and .='!'])])
59 then let $l := $tokens[$i - 1], 59 then let $l := $tokens[$i - 1],
60 $r := $tokens[$i + 1], 60 $r := $tokens[$i + 1]
61 $l1 := if ($l/@nr=9) then e:lookup($l) 61 return e:range(e:single($l),
62 else $l, 62 e:single($r))
63 $r1 := if ($r/@nr=9) then e:lookup($r)
64 else $r
65 return concat($l1,':',$r1)
66 else (), 63 else (),
67 $externals := for $i in (1 to count($tokens)) return 64 $externals := for $i in (1 to count($tokens)) return
68 let $t := $tokens[$i] return 65 let $t := $tokens[$i] return
69 if ($t/@nr=7) 66 if ($t/@nr=7)
70 then 67 then
71 let $bit := concat($t,'!',$tokens[$i + 2]) return 68 let $ref := e:single($tokens[$i + 2]) return
72 if ((($i+3) le $n) and 69 if ((($i+3) le $n) and
73 $tokens[$i + 3][@nr=10 and .=':']) 70 $tokens[$i + 3][@nr=10 and .=':'])
74 then concat($bit,':', 71 then e:external($t,e:range($ref,
75 $tokens[$i + 4]) 72 e:single($tokens[$i+4])))
76 else $bit 73 else e:external($t,$ref)
77 else () 74 else ()
78 return [($singles,for $a in $recur return $a?1), 75 return [($singles,for $a in $recur return $a?1),
79 ($ranges,for $a in $recur return $a?2), 76 ($ranges,for $a in $recur return $a?2),
80 ($externals,for $a in $recur return $a?3)] 77 ($externals,for $a in $recur return $a?3)]
81 else ()"/> 78 else ()"/>
79 </xsl:function>
80
81 <xsl:function name="e:single" as="element(e:s)">
82 <xsl:param name="group" as="element(xf:group)" required="yes"/>
83 <xsl:variable name="val" select="if ($group/@nr=9) then e:lookup($group)
84 else string($group)"/>
85 <s><xsl:value-of select="$val"/></s>
86 </xsl:function>
87
88 <xsl:function name="e:range" as="element(e:r)">
89 <xsl:param name="l" as="element(e:s)" required="yes"/>
90 <xsl:param name="r" as="element(e:s)" required="yes"/>
91 <r><xsl:copy-of select="$l"/><xsl:copy-of select="$r"/></r>
92 </xsl:function>
93
94 <xsl:function name="e:external" as="element(e:e)">
95 <xsl:param name="source" as="element(xf:group)" required="yes"/>
96 <xsl:param name="ref" as="element(*)" required="yes"/>
97 <e s="{$source}"><xsl:sequence select="$ref"/></e>
82 </xsl:function> 98 </xsl:function>
83 99
84 <xsl:template match="/"> 100 <xsl:template match="/">
85 <refs sheetName="{$sheet-name}"><xsl:apply-templates select="//s:c"/></refs> 101 <refs sheetName="{$sheet-name}"><xsl:apply-templates select="//s:c"/></refs>
86 </xsl:template> 102 </xsl:template>
93 <xsl:variable name="singles" select="$tokens?1"/> 109 <xsl:variable name="singles" select="$tokens?1"/>
94 <!-- Note that we don't bother to treat external ranges as ranges, 110 <!-- Note that we don't bother to treat external ranges as ranges,
95 since we're not going to try to detect cross-document refs --> 111 since we're not going to try to detect cross-document refs -->
96 <xsl:variable name="ranges" select="$tokens?2"/> 112 <xsl:variable name="ranges" select="$tokens?2"/>
97 <xsl:variable name="externals" select="$tokens?3"/> 113 <xsl:variable name="externals" select="$tokens?3"/>
114 <!-- Lost distinct-values filter, not sure it's really possible... -->
98 <ref c="{@r}"> 115 <ref c="{@r}">
99 <xsl:for-each select="distinct-values($singles)"> 116 <xsl:copy-of select="$singles"/>
100 <s><xsl:value-of select="."/></s> 117 <xsl:copy-of select="$ranges"/>
101 </xsl:for-each> 118 <xsl:copy-of select="$externals"/>
102 <xsl:for-each select="distinct-values($ranges)">
103 <r><xsl:value-of select="."/></r>
104 </xsl:for-each>
105 <xsl:for-each select="distinct-values($externals)">
106 <e><xsl:value-of select="."/></e>
107 </xsl:for-each>
108 </ref></xsl:if> 119 </ref></xsl:if>
109 </xsl:template> 120 </xsl:template>
110 121
111 <xsl:template match="s:c"/> 122 <xsl:template match="s:c"/>
112 </xsl:stylesheet> 123 </xsl:stylesheet>