changeset 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
files refs.xsl
diffstat 1 files changed, 25 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/refs.xsl	Tue Apr 11 12:28:44 2017 +0100
+++ b/refs.xsl	Tue Apr 11 14:33:14 2017 +0100
@@ -9,16 +9,37 @@
  
  <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"/>
+ 
+ <xsl:function name="e:lookup" as="xs:string*">
+  <xsl:param name="name" as="xs:string" required="yes"/>
+  <xsl:variable name="defn" select="$workbook/s:definedNames/s:definedName[@name=$name]"/>
+  <xsl:sequence select="let $prefix := concat($sheet-name,'!')
+                   return if ($defn and
+                              starts-with($defn,$prefix))
+                           then substring-after($defn,$prefix)
+                           else ()"/>
+ </xsl:function>
 
  <xsl:function name="e:tokenise" as="array(xs:string*)*">
+  <!-- Tokenise a formula, recursively wrt variables -->
   <xsl:param name="formula" as="xs:string" required="yes"/>
   <xsl:sequence select="
     let $tokens := analyze-string($formula,$pat)/xf:match/xf:group
      return if ($tokens[@nr=(7,8,9)])
              then 
               let $n := count($tokens),
+                  $vars := for $i in (1 to $n)
+                     return if ($tokens[$i][@nr=9] and
+                                not($tokens[$i - 1][@nr=10 and
+                                .=(':','!')]) and
+                                not($tokens[$i + 1][@nr=10 and .=':']))
+                             then string($tokens[$i])
+                             else (),
+                  $defns := for $var in $vars return e:lookup($var),
+                  $recur := for $sub in $defns 
+                              return if ($sub) then e:tokenise($defns) else (),
                   $singles := for $i in (1 to $n)
-                     return if ($tokens[$i][@nr=(8,9)] and
+                     return if ($tokens[$i][@nr=8] and
                                 not($tokens[$i - 1][@nr=10 and
                                 .=(':','!')]) and
                                 not($tokens[$i + 1][@nr=10 and .=':']))
@@ -44,7 +65,9 @@
                                                              '$',''))
                                        else $bit
                              else ()
-                  return [$singles,$ranges,$externals]
+                  return [($singles,for $a in $recur return $a?1),
+                          ($ranges,for $a in $recur return $a?2),
+                          ($externals,for $a in $recur return $a?3)]
              else ()"/>
  </xsl:function>