Mercurial > hg > ooxml
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">("[^"]*")|(\{[^}]+})|(,)|([^=\-+*/();:,.$<>^!]+(?:\.[^=\-+*/();:,.$<>^!]+)*\()|([)])|(^=|\()|((?:'[^']+')|(?:\[[0-9]+\][^!]*))|(\$?[A-Z]+\$?[0-9]+)|([a-zA-Z_\\][a-zA-Z0-9._]*)|(.)</xsl:variable> | 9 <xsl:variable name="pat1">("[^"]*")|(\{[^}]+})|(,)|([^=\-+*/();:,.$<>^!]+(?:\.[^=\-+*/();:,.$<>^!]+)*\()|([)])|(^=|\()|((?:'[^']+')|(?:\[[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, |