comparison refs.xsl @ 29:87ed04a0fde2

recursion in place, need to check for names in ranges
author Henry S. Thompson <ht@markup.co.uk>
date Tue, 11 Apr 2017 14:33:14 +0100
parents c56a2e6990bd
children 16eff0d30d4d
comparison
equal deleted inserted replaced
28:c56a2e6990bd 29:87ed04a0fde2
7 <xsl:variable name="pat1">("[^"]*")|(\{[^}]+})|(,)|([^=\-+*/();:,.$&lt;>^!]+(?:\.[^=\-+*/();:,.$&lt;>^!]+)*\()|([)])|(^=|\()|((?:'[^']+')|(?:\[[0-9]+\][^!]*))|(\$?[A-Z]+\$?[0-9]+)|([a-zA-Z_\\][a-zA-Z0-9._]*)|(.)</xsl:variable> 7 <xsl:variable name="pat1">("[^"]*")|(\{[^}]+})|(,)|([^=\-+*/();:,.$&lt;>^!]+(?:\.[^=\-+*/();:,.$&lt;>^!]+)*\()|([)])|(^=|\()|((?:'[^']+')|(?:\[[0-9]+\][^!]*))|(\$?[A-Z]+\$?[0-9]+)|([a-zA-Z_\\][a-zA-Z0-9._]*)|(.)</xsl:variable>
8 <xsl:param name="pat" select="$pat1"/><!-- xsl:param for refinement debugging by passing in the pattern --> 8 <xsl:param name="pat" select="$pat1"/><!-- xsl:param for refinement debugging by passing in the pattern -->
9 9
10 <xsl:variable name="workbook" select="document(concat($xlDir,'/workbook.xml'))/*"/> 10 <xsl:variable name="workbook" select="document(concat($xlDir,'/workbook.xml'))/*"/>
11 <xsl:variable name="sheet-name" select="$workbook/s:sheets/s:sheet[@sheetId=$sheet-number]/@name"/> 11 <xsl:variable name="sheet-name" select="$workbook/s:sheets/s:sheet[@sheetId=$sheet-number]/@name"/>
12
13 <xsl:function name="e:lookup" as="xs:string*">
14 <xsl:param name="name" as="xs:string" required="yes"/>
15 <xsl:variable name="defn" select="$workbook/s:definedNames/s:definedName[@name=$name]"/>
16 <xsl:sequence select="let $prefix := concat($sheet-name,'!')
17 return if ($defn and
18 starts-with($defn,$prefix))
19 then substring-after($defn,$prefix)
20 else ()"/>
21 </xsl:function>
12 22
13 <xsl:function name="e:tokenise" as="array(xs:string*)*"> 23 <xsl:function name="e:tokenise" as="array(xs:string*)*">
24 <!-- Tokenise a formula, recursively wrt variables -->
14 <xsl:param name="formula" as="xs:string" required="yes"/> 25 <xsl:param name="formula" as="xs:string" required="yes"/>
15 <xsl:sequence select=" 26 <xsl:sequence select="
16 let $tokens := analyze-string($formula,$pat)/xf:match/xf:group 27 let $tokens := analyze-string($formula,$pat)/xf:match/xf:group
17 return if ($tokens[@nr=(7,8,9)]) 28 return if ($tokens[@nr=(7,8,9)])
18 then 29 then
19 let $n := count($tokens), 30 let $n := count($tokens),
31 $vars := for $i in (1 to $n)
32 return if ($tokens[$i][@nr=9] and
33 not($tokens[$i - 1][@nr=10 and
34 .=(':','!')]) and
35 not($tokens[$i + 1][@nr=10 and .=':']))
36 then string($tokens[$i])
37 else (),
38 $defns := for $var in $vars return e:lookup($var),
39 $recur := for $sub in $defns
40 return if ($sub) then e:tokenise($defns) else (),
20 $singles := for $i in (1 to $n) 41 $singles := for $i in (1 to $n)
21 return if ($tokens[$i][@nr=(8,9)] and 42 return if ($tokens[$i][@nr=8] and
22 not($tokens[$i - 1][@nr=10 and 43 not($tokens[$i - 1][@nr=10 and
23 .=(':','!')]) and 44 .=(':','!')]) and
24 not($tokens[$i + 1][@nr=10 and .=':'])) 45 not($tokens[$i + 1][@nr=10 and .=':']))
25 then translate($tokens[$i],'$','') 46 then translate($tokens[$i],'$','')
26 else (), 47 else (),
42 then concat($bit,':', 63 then concat($bit,':',
43 translate($tokens[$i + 4], 64 translate($tokens[$i + 4],
44 '$','')) 65 '$',''))
45 else $bit 66 else $bit
46 else () 67 else ()
47 return [$singles,$ranges,$externals] 68 return [($singles,for $a in $recur return $a?1),
69 ($ranges,for $a in $recur return $a?2),
70 ($externals,for $a in $recur return $a?3)]
48 else ()"/> 71 else ()"/>
49 </xsl:function> 72 </xsl:function>
50 73
51 <xsl:template match="/"> 74 <xsl:template match="/">
52 <refs sheetName="{$sheet-name}"><xsl:apply-templates select="//s:c"/></refs> 75 <refs sheetName="{$sheet-name}"><xsl:apply-templates select="//s:c"/></refs>