changeset 39:4c6a341e75da

big rework works on sample2, w/o refs processing
author Henry S. Thompson <ht@markup.co.uk>
date Wed, 26 Apr 2017 18:51:34 +0100
parents 468a6cf8bf0b
children ac6d1ca099f7
files notes.txt rect.xsl tokenise.xsl visualise.xpl
diffstat 4 files changed, 40 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/notes.txt	Tue Apr 25 22:17:12 2017 +0100
+++ b/notes.txt	Wed Apr 26 18:51:34 2017 +0100
@@ -24,7 +24,7 @@
 8 (\$?[A-Z]+\$?[0-9]+) s or r
   A cell reference
 9 ([a-zA-Z_\\][a-zA-Z0-9._]*) v
-  A name (always for a variable?)
+  A name (boolean constant or a variable -- anything else?)
 10 (.) x
   Single characters not matched by the previous patterns
 ----------
--- a/rect.xsl	Tue Apr 25 22:17:12 2017 +0100
+++ b/rect.xsl	Wed Apr 26 18:51:34 2017 +0100
@@ -7,7 +7,7 @@
  <xsl:include href="n2a.xsl"/>
  <xsl:include href="tokenise.xsl"/>
  
- <xsl:variable name="refs" select="collection()[2]/*"/>
+ <xsl:variable name="refs" select="document('sample2/empty_refs.xml')/*"/><!--collection()[2]/*-->
  
  <xsl:key name="ref" match="e:i" use="@r"/>
 
@@ -42,9 +42,9 @@
           <xsl:if test="$c/@e:class"><xsl:attribute name="c"><xsl:value-of select="substring($c/@e:class,1,1)"/></xsl:attribute></xsl:if>
           <xsl:if test="$c/@e:code"><xsl:attribute name="l"><xsl:value-of select="$c/@e:code"/></xsl:attribute></xsl:if>
           <xsl:if test="$c/s:f">
-           <s:f>
+           <f>
             <xsl:copy-of select="e:tokenise($c/s:f,$row,$col)"/>
-           </s:f></xsl:if>
+           </f></xsl:if>
           <xsl:value-of select="substring($c/@e:type,1,1)"/>
          </t>
         </xsl:if>
--- a/tokenise.xsl	Tue Apr 25 22:17:12 2017 +0100
+++ b/tokenise.xsl	Wed Apr 26 18:51:34 2017 +0100
@@ -5,7 +5,8 @@
  <xsl:param name="xlDir"/>
 
   <xsl:variable name="pat1">("[^"]*")|(\{[^}]+})|(,)|([^=\-+*/();:,.$&lt;>^!]+(?:\.[^=\-+*/();:,.$&lt;>^!]+)*\()|([)])|(^=|\()|((?:(?:'[^']+')|(?:\[[0-9]+\][^!]*)|(?:[a-zA-Z_][a-zA-Z0-9._]*)!))|(\$?[A-Z]+\$?[0-9]+)|([a-zA-Z_\\][a-zA-Z0-9._]*)|(.)</xsl:variable>
- <xsl:param name="pat" select="$pat1"/><!-- xsl:param for refinement debugging by passing in the pattern -->
+ <xsl:variable name="pat2">("[^"]*")|(\{[^}]+})|(,)|([^=\-+*/();:,.$&lt;>^!]+(?:\.[^=\-+*/();:,.$&lt;>^!]+)*\()|([)])|(^=|\()|((?:'[^']+'!)|(?:[\[0-9A-Za-z_][^=\-+*/();:,.$&lt;>^!]*!))|(\$?[A-Z]+\$?[0-9]+)|([a-zA-Z_\\][a-zA-Z0-9._]*)|(.)</xsl:variable>
+ <xsl:param name="pat" select="$pat2"/><!-- xsl:param for refinement debugging by passing in the pattern -->
  
  <xsl:variable name="workbook" select="document(concat($xlDir,'/workbook.xml'))/*"/>
  <xsl:variable name="sheet-name" select="$workbook/s:sheets/s:sheet[@sheetId=$sheet-number]/@name"/>
@@ -18,6 +19,7 @@
  <xsl:function name="e:tokenise" as="element(*)*">
   <!-- Tokenise a formula, recursively wrt variables
        Output is composed of e:* as follows:
+       b: Boolean constant
        c: A list (function parameter) separator
        e: An external (variable, cell or range) reference
        f: A function name followed by an opening parenthesis
@@ -34,6 +36,7 @@
   <!-- The row and column number of the cell whence the formula came -->
   <xsl:param name="row" required="yes" as="xs:integer"/>
   <xsl:param name="col" required="yes" as="xs:integer"/>
+  <xsl:message>tok: <xsl:value-of select="$formula"/></xsl:message>
   <xsl:sequence select="
      let $tokens := analyze-string($formula,$pat)/xf:match/xf:group
         return e:tok1($tokens,count($tokens),1,$row,$col,())"/>
@@ -45,7 +48,9 @@
   <xsl:param name="i" required="yes" as="xs:integer"/>
   <xsl:param name="row" required="yes" as="xs:integer"/>
   <xsl:param name="col" required="yes" as="xs:integer"/>
-  <xsl:param name="soFar" required="yes" as="element(*)*"/>
+  <xsl:param name="soFar" as="element(*)*"/>
+  <xsl:variable name="last" select="$soFar[count($soFar)]"></xsl:variable>
+  <xsl:message>tok1: <xsl:value-of select="$n"/>|<xsl:value-of select="$i"/>|<xsl:value-of select="if ($last instance of element()) then name($last) else 'bogus'"/>|<xsl:value-of select="string($last)"/></xsl:message>
   <xsl:sequence select="
     if ($i gt $n)
           then $soFar
@@ -62,6 +67,7 @@
   <xsl:param name="local" required="yes" as="xs:boolean"/>
   <xsl:param name="row" required="yes" as="xs:integer"/>
   <xsl:param name="col" required="yes" as="xs:integer"/>
+  <xsl:message>exp: <xsl:value-of select="$tokens[$i]/@nr"/>:<xsl:value-of select="$tokens[$i]"/>,<xsl:value-of select="$tokens[$i+1]"/></xsl:message>
   <xsl:sequence select="
     let $t := $tokens[$i],
         $r := $tokens[$i + 1] return
@@ -72,18 +78,21 @@
      else if ($t/@nr=5) then e:exp1($i,'p',')')
      else if ($t/@nr=6) then e:exp1($i,'l',string($t))
      else if ($t/@nr=7)
-       then if (substring-before($t,'!')=('[0]',$sheet-name))
+       then let $xref := substring-before($t,'!') return
+              if ($xref=('[0]',$sheet-name))
               then (: it's a local reference after all :)
                e:expand($tokens,$i+1,true(),$row,$col)
               else let $ext := e:expand($tokens,$i+1,false(),$row,$col) return
-                    [$ext?1,e:external($ext?2)]
+                    [$ext?1,e:external($xref,$ext?2)]
      else if ($t/@nr=10) then e:amalgamate($tokens,$i+1,string($t))
      else if ($r[@nr=10 and .=':'])
        then (: a range, takes priority :)
-          [$i+2,e:range($tokens,$i,$local,$row,$col)]
+          [$i+3,e:range($tokens,$i,$local,$row,$col)]
      else if ($t/@nr=8) then [$i+1,e:single(string($t),$row,$col)]
      else if ($t/@nr=9)
-       then if ($local)
+       then if (matches($t,'^(true|false)$','i'))
+            then e:exp1($i,upper-case($t),'b')
+            else (: a variable name, I think :) if ($local)
             then let $sub := e:tokenise(e:lookup(string($t)),$row,$col) return
               [$i+1,$sub]
             else (: can't expand :) e:exp1($i,'v',string($t))
@@ -94,10 +103,20 @@
   <xsl:param name="tokens" as="element(xf:group)*"/>
   <xsl:param name="i" as="xs:integer"/>
   <xsl:param name="soFar" as="xs:string"/>
-  <xsl:sequence select="if ($tokens[i]/@nr=10)
-                 then e:amalgamate($tokens,$i+1,concat($soFar,
-                                                       string($tokens[$i])))
-                 else [$i,$soFar]"/>
+  <xsl:choose>
+   <xsl:when test="$tokens[i]/@nr=10">
+    <xsl:sequence select="e:amalgamate($tokens,$i+1,concat($soFar,
+                                                       string($tokens[$i])))"/>
+   </xsl:when>
+   <xsl:otherwise>
+    <xsl:variable name="res">
+     <x><xsl:value-of select="$soFar"/></x>
+    </xsl:variable>
+    <xsl:message>amal: <xsl:value-of select="$res/."/></xsl:message>
+    <xsl:sequence select="[$i,$res/*]"/>
+   </xsl:otherwise>
+  </xsl:choose>
+  
  </xsl:function>
  
  <xsl:function name="e:exp1" as="array(*)">
@@ -109,7 +128,8 @@
     <xsl:value-of select="$val"/>
    </xsl:element>
   </xsl:variable>
-  <xsl:sequence select="[$i+1,$elt]"/>
+  <xsl:message>exp1: <xsl:value-of select="$name"/>|<xsl:value-of select="$val"/>|<xsl:value-of select="name($elt/*)"/></xsl:message>
+  <xsl:sequence select="[$i+1,$elt/*]"/>
  </xsl:function>
  
  <xsl:function name="e:single" as="element(e:s)">
@@ -167,14 +187,15 @@
   <xsl:param name="row" as="xs:integer"/>
   <xsl:param name="col" as="xs:integer"/>
   <xsl:param name="toks" as="element(*)*"/>
-  <xsl:message terminate="yes">Bad range part in <xsl:value-of select="concat(e:n2a($col),$row)"/>: <xsl:value-of select="$s"/> of type <xsl:value-of select="$t"/> (<xsl:value-of select="if ($local) then 'local' else 'external'"/>: (<xsl:value-of select="string-join($toks,',')"/>)</xsl:message>
+  <xsl:message>Bad range part in <xsl:value-of select="concat(e:n2a($col),$row)"/>: <xsl:value-of select="$s"/> of type <xsl:value-of select="$t"/> (<xsl:value-of select="if ($local) then 'local' else 'external'"/>: (<xsl:value-of select="string-join($toks,',')"/>)</xsl:message>
   <u r="{concat(e:n2a($col),$row)}" s="{$s}" t="{$t}" local="{$local}">
    <xsl:value-of select="string-join($toks,',')"/>
   </u>
  </xsl:function>
  
  <xsl:function name="e:external" as="element(e:e)">
+  <xsl:param name="xref" as="xs:string" required="yes"/>
   <xsl:param name="ref" as="element(*)" required="yes"/>
-  <e><xsl:sequence select="$ref"/></e>
+  <e x="{$xref}"><xsl:sequence select="$ref"/></e>
  </xsl:function>
 </xsl:stylesheet>
--- a/visualise.xpl	Tue Apr 25 22:17:12 2017 +0100
+++ b/visualise.xpl	Wed Apr 26 18:51:34 2017 +0100
@@ -116,6 +116,8 @@
   <p:input port="stylesheet">
    <p:pipe step="ss2" port="result"/>
   </p:input>
+  <p:with-param name="sheet-number" select="$sheet-number"/>
+  <p:with-param name="xlDir" select="$root"/>  
  </p:xslt>
  
  <p:choose>