comparison refs.xsl @ 36:ae605b77d1e4

compute (but not use) master formula cells info, extend refs collection to include abs/reloc info
author Henry S. Thompson <ht@markup.co.uk>
date Tue, 25 Apr 2017 12:24:31 +0100
parents 93fd0d532754
children ac3cd8de7a10
comparison
equal deleted inserted replaced
35:e500d7c18aad 36:ae605b77d1e4
1 <?xml version='1.0'?> 1 <?xml version='1.0'?>
2 <!DOCTYPE doc SYSTEM "../../../lib/xml/xsl.dtd" > 2 <!DOCTYPE doc SYSTEM "../../../lib/xml/xsl.dtd" >
3 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:s="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:e="http://markup.co.uk/excel" exclude-result-prefixes="xs s e xf" xmlns="http://markup.co.uk/excel" xmlns:xf="http://www.w3.org/2005/xpath-functions"> 3 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:s="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:e="http://markup.co.uk/excel" exclude-result-prefixes="xs s e xf" xmlns="http://markup.co.uk/excel" xmlns:xf="http://www.w3.org/2005/xpath-functions">
4 <xsl:param name="sheet-number"/> 4 <xsl:param name="sheet-number"/>
5 <xsl:param name="xlDir"/> 5 <xsl:param name="xlDir"/>
6
7 <xsl:include href="a2n.xsl"/>
6 8
7 <xsl:variable name="pat1">("[^"]*")|(\{[^}]+})|(,)|([^=\-+*/();:,.$&lt;>^!]+(?:\.[^=\-+*/();:,.$&lt;>^!]+)*\()|([)])|(^=|\()|((?:'[^']+')|(?:\[[0-9]+\][^!]*))|(\$?[A-Z]+\$?[0-9]+)|([a-zA-Z_\\][a-zA-Z0-9._]*)|(.)</xsl:variable> 9 <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 --> 10 <xsl:param name="pat" select="$pat1"/><!-- xsl:param for refinement debugging by passing in the pattern -->
9 11
10 <xsl:variable name="workbook" select="document(concat($xlDir,'/workbook.xml'))/*"/> 12 <xsl:variable name="workbook" select="document(concat($xlDir,'/workbook.xml'))/*"/>
21 </xsl:function> 23 </xsl:function>
22 24
23 <xsl:function name="e:tokenise" as="array(element(*)*)*"> 25 <xsl:function name="e:tokenise" as="array(element(*)*)*">
24 <!-- Tokenise a formula, recursively wrt variables --> 26 <!-- Tokenise a formula, recursively wrt variables -->
25 <xsl:param name="formula" as="xs:string" required="yes"/> 27 <xsl:param name="formula" as="xs:string" required="yes"/>
28 <!-- The row and column number of the cell whence the formula came -->
29 <xsl:param name="row" required="yes" as="xs:int"/>
30 <xsl:param name="col" required="yes" as="xs:int"/>
26 <xsl:sequence select=" 31 <xsl:sequence select="
27 let $tokens := analyze-string($formula,$pat)/xf:match/xf:group 32 let $tokens := analyze-string($formula,$pat)/xf:match/xf:group
28 return if ($tokens[@nr=(7,8,9)]) 33 return if ($tokens[@nr=(7,8,9)])
29 then 34 then
30 let $n := count($tokens), 35 let $n := count($tokens),
38 not($r[@nr=10 and .=':'])) 43 not($r[@nr=10 and .=':']))
39 then string($t) 44 then string($t)
40 else (), 45 else (),
41 $defns := for $var in $vars return e:lookup($var), 46 $defns := for $var in $vars return e:lookup($var),
42 $recur := for $sub in $defns 47 $recur := for $sub in $defns
43 return if ($sub) then e:tokenise($sub) else (), 48 return if ($sub) then e:tokenise($sub,$row,$col)
49 else (),
44 $singles := for $i in (1 to $n) return 50 $singles := for $i in (1 to $n) return
45 let $t := $tokens[$i], 51 let $t := $tokens[$i],
46 $l := $tokens[$i - 1], 52 $l := $tokens[$i - 1],
47 $r := $tokens[$i + 1] return 53 $r := $tokens[$i + 1] return
48 if ($t/@nr=8 and 54 if ($t/@nr=8 and
49 not($l[@nr=10 and 55 not($l[@nr=10 and
50 .=(':','!')]) and 56 .=(':','!')]) and
51 not($r[@nr=10 and .=':'])) 57 not($r[@nr=10 and .=':']))
52 then e:single($t,false()) 58 then e:single($t,$row,$col,false())
53 else (), 59 else (),
54 $ranges := for $i in (1 to count($tokens)) return 60 $ranges := for $i in (1 to count($tokens)) return
55 let $t := $tokens[$i] return 61 let $t := $tokens[$i] return
56 if ($t[@nr=10 and .=':' and 62 if ($t[@nr=10 and .=':' and
57 not($i gt 2 and 63 not($i gt 2 and
58 $tokens[$i - 2][@nr=10 and .='!'])]) 64 $tokens[$i - 2][@nr=10 and .='!'])])
59 then let $l := $tokens[$i - 1], 65 then let $l := $tokens[$i - 1],
60 $r := $tokens[$i + 1] 66 $r := $tokens[$i + 1]
61 return e:range(e:single($l,false()), 67 return e:range(e:single($l,
62 e:single($r,false())) 68 $row,$col,false()),
69 e:single($r,
70 $row,$col,false()))
63 else (), 71 else (),
64 $externals := for $i in (1 to count($tokens)) return 72 $externals := for $i in (1 to count($tokens)) return
65 let $t := $tokens[$i] return 73 let $t := $tokens[$i] return
66 if ($t/@nr=7 and $tokens[$i+1]='!') 74 if ($t/@nr=7 and $tokens[$i+1]='!')
67 then 75 then
68 let $ext := $t!='[0]', 76 let $ext := $t!='[0]',
69 $ref := e:single($tokens[$i + 2], 77 $ref := e:single($tokens[$i + 2],
70 $ext), 78 $row,$col,$ext),
71 $res := if ((($i+3) le $n) and 79 $res := if ((($i+3) le $n) and
72 $tokens[$i + 3][@nr=10 and .=':']) 80 $tokens[$i + 3][@nr=10 and .=':'])
73 then e:range($ref, 81 then e:range($ref,
74 e:single($tokens[$i+4], 82 e:single($tokens[$i+4],
75 $ext)) 83 $row,$col,$ext))
76 else $ref return 84 else $ref return
77 if ($ext) 85 if ($ext)
78 then e:external($t,$res) 86 then e:external($t,$res)
79 else $res 87 else $res
80 else () 88 else ()
84 else ()"/> 92 else ()"/>
85 </xsl:function> 93 </xsl:function>
86 94
87 <xsl:function name="e:single" as="element(*)"> 95 <xsl:function name="e:single" as="element(*)">
88 <xsl:param name="group" as="element(xf:group)"/> 96 <xsl:param name="group" as="element(xf:group)"/>
97 <xsl:param name="row" as="xs:integer"/>
98 <xsl:param name="col" as="xs:integer"/>
89 <xsl:param name="external" as="xs:boolean"/> 99 <xsl:param name="external" as="xs:boolean"/>
90 <xsl:variable name="val" select="if ($group/@nr=9) then e:lookup($group) 100 <xsl:variable name="val" select="if ($group/@nr=9) then e:lookup($group)
91 else string($group)"/> 101 else string($group)"/>
92 <xsl:choose> 102 <xsl:choose>
93 <xsl:when test="count($val)>0 or not($external)"> 103 <xsl:when test="count($val)>0 or not($external)">
94 <s><xsl:value-of select="$val"/></s> 104 <xsl:sequence select="e:cr($val,$row,$col)"/>
95 </xsl:when> 105 </xsl:when>
96 <xsl:otherwise> 106 <xsl:otherwise>
97 <v><xsl:value-of select="$group"/></v> 107 <v><xsl:value-of select="$group"/></v>
98 </xsl:otherwise> 108 </xsl:otherwise>
99 </xsl:choose> 109 </xsl:choose>
100
101 </xsl:function> 110 </xsl:function>
102 111
103 <xsl:function name="e:range" as="element(e:r)"> 112 <xsl:function name="e:range" as="element(e:r)">
104 <xsl:param name="l" as="element(e:s)" required="yes"/> 113 <xsl:param name="l" as="element(e:s)" required="yes"/>
105 <xsl:param name="r" as="element(e:s)" required="yes"/> 114 <xsl:param name="r" as="element(e:s)" required="yes"/>
115 <xsl:template match="/"> 124 <xsl:template match="/">
116 <refs sheetName="{$sheet-name}"><xsl:apply-templates select="//s:c"/></refs> 125 <refs sheetName="{$sheet-name}"><xsl:apply-templates select="//s:c"/></refs>
117 </xsl:template> 126 </xsl:template>
118 127
119 <xsl:template match="s:c[s:f]"> 128 <xsl:template match="s:c[s:f]">
120 <xsl:variable name="tokens" select="e:tokenise(s:f/.)"/> 129 <xsl:variable name="cr" select="e:cr(@r,0,0)"/>
130 <xsl:variable name="tokens" select="e:tokenise(s:f/.,$cr/e:r[1],$cr/e:r[2])"/>
121 <xsl:if test="@r='xxx'"><xsl:message><xsl:value-of select="s:f"/>|<xsl:value-of select="(analyze-string(s:f/.,$pat)/xf:match/xf:group)[3]/@nr"/></xsl:message> 131 <xsl:if test="@r='xxx'"><xsl:message><xsl:value-of select="s:f"/>|<xsl:value-of select="(analyze-string(s:f/.,$pat)/xf:match/xf:group)[3]/@nr"/></xsl:message>
122 </xsl:if> 132 </xsl:if>
123 <xsl:if test="count($tokens)>0"> 133 <xsl:if test="count($tokens)>0">
124 <xsl:variable name="singles" select="$tokens?1"/> 134 <xsl:variable name="singles" select="$tokens?1"/>
125 <!-- Note that we don't bother to treat external ranges as ranges, 135 <!-- Note that we don't bother to treat external ranges as ranges,