view n2a.xsl @ 72:0654e37583b5

appears to read kdir.js correctly
author Henry S. Thompson <ht@markup.co.uk>
date Thu, 29 Jun 2017 17:58:06 +0100
parents adeb9575b273
children
line wrap: on
line source

<?xml version='1.0'?>
<!DOCTYPE xsl:stylesheet SYSTEM "file:///C:/C64/home/ht/lib/xml/xsl.dtd" >
<xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:e="http://markup.co.uk/excel" version="3.0">
 <xsl:variable name="codeBase" select="string-to-codepoints('A')-1"/>
 
 <xsl:function name="e:n2aa" as="xs:integer*">
  <!-- Does the real work for e:n2a -->
  <xsl:param name="n" as="xs:integer"/>
  <xsl:sequence select="let $least := $codeBase+(($n - 1) mod 26)+1
                         return if ($n &lt; 27) then $least
                          else (e:n2aa(($n - 1) idiv 26),$least)"/>
 </xsl:function>

 <xsl:function name="e:n2a" as="xs:string">
  <!-- Invert the a2n computation -->
  <xsl:param name="n" as="xs:integer"/>
  <xsl:value-of select="codepoints-to-string(e:n2aa($n))"/>
 </xsl:function>
 
 <xsl:function name="e:crnf" as="xs:string">
  <!-- compute CR-normal-form of a singleton reference -->
  <xsl:param name="s" as="element(e:s)"/>
  <xsl:value-of select="concat(e:snf(($s/*)[1]),e:snf(($s/*)[2]))"/>
 </xsl:function>
 
 <xsl:function name="e:snf" as="xs:string">
  <xsl:param name="s" as="element(*)"/><!-- either a(bsolute) or r(elative)-->
  <xsl:value-of select="if (local-name($s)='a')
                         then concat('&#xAA;',$s)
                         else concat('&#xBA;',$s/@d)"/>
 </xsl:function>
 
 <xsl:function name="e:rnf" as="xs:string">
  <!-- CRNF for a range or singleton reference -->
  <xsl:param name="b" as="element(*)"/>
  <xsl:value-of select="if (local-name($b)='s') then e:crnf($b)
                           else if (local-name($b)='r')
                                 then
                                  let $l := ($b/e:s)[1],
                                      $r := ($b/e:s)[2] return
                                     concat(e:crnf($l),
                                            ':',
                                            e:crnf($r))
                                 else if (local-name($b)='v')
                                  then $b/text()
                                 else e:shouldnt('rnf',concat(local-name($b),' ',string($b)))"/>
 </xsl:function>

 <xsl:function name="e:bcrnf" as="xs:string">
  <!-- Like crnf, but backpointer -->
  <!-- compute CR-normal-form of a singleton reference -->
  <xsl:param name="s" as="element(e:s)"/>
  <xsl:value-of select="concat(e:bnf(($s/*)[1]),e:bnf(($s/*)[2]))"/>
 </xsl:function>
 
 <xsl:function name="e:bnf" as="xs:string">
  <!-- invert any relative references, neutralise any absolute ones, i.e. convert a pointer into a kind of backpointer -->
  <xsl:param name="s" as="element(*)"/><!-- either a(bsolute) or r(elative)-->
  <xsl:value-of select="if (local-name($s)='a')
                         then concat('&#xAA;',$s) (: avoid spurious concord :)
                         else concat('&#xBA;',-xs:integer($s/@d))"/>
 </xsl:function>

 
 <xsl:function name="e:fnf" as="xs:string">
  <!-- rebuild a formula from its parts, but using CRNF for all references -->
  <xsl:param name="bits" as="element(*)*"/>
  <xsl:value-of select="string-join(
                          for $b in $bits return
                           if (local-name($b)=('s','r')) then e:rnf($b)
                           else if (local-name($b)='e')
                                 then concat($b/@x,'!',e:rnf($b/*))
                          else $b/text())"/>
 </xsl:function>
 
 <xsl:template name="shift">
  <xsl:param name="row" as="xs:integer"/>  
  <xsl:param name="col" as="xs:integer"/>
  <!-- Reconstruct a shifted version of an analysed formula, relative to a new position -->
  <xsl:copy>
   <xsl:apply-templates select="@*"/>
   <xsl:apply-templates select="*" mode="shift">
    <xsl:with-param name="row" select="$row"/>
    <xsl:with-param name="col" select="$col"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
 
 <xsl:template match="e:s" mode="shift">
  <xsl:param name="row" as="xs:integer"/>  
  <xsl:param name="col" as="xs:integer"/>
  <xsl:copy>
   <xsl:attribute name="r">
    <xsl:value-of select="concat(e:n2a(e:delta(*[1],$col)),
                                 e:delta(*[2],$row))"/>
   </xsl:attribute>
   <xsl:apply-templates select="node()" mode="shift">
    <xsl:with-param name="row" select="$row"/>
    <xsl:with-param name="col" select="$col"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
 
 <xsl:function name="e:delta" as="xs:integer">
  <xsl:param name="c" as="element(*)"/>
  <xsl:param name="h" as="xs:integer"/>
  <xsl:value-of select="if (local-name($c)='a') then xs:integer($c/text())
                          else if (local-name($c)='r')
                            then xs:integer($c/@d)+$h
                          else e:shouldnt('delta',local-name($c))"/>
 </xsl:function>
 
 <xsl:template match="e:*|@*" mode="shift">
  <xsl:param name="row" as="xs:integer"/>  
  <xsl:param name="col" as="xs:integer"/>
  <xsl:copy>
   <xsl:apply-templates select="node()|@*" mode="shift">
    <xsl:with-param name="row" select="$row"/>
    <xsl:with-param name="col" select="$col"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
 
 <xsl:function name="e:shouldnt">
  <xsl:param name="where" as="xs:string"/>  
  <xsl:param name="what" as="xs:string"/>
  <xsl:message terminate="yes">shouldn't happen in <xsl:value-of select="$where"/>: <xsl:value-of select="$what"/></xsl:message>
 </xsl:function>
</xsl:stylesheet>