view refs.xsl @ 25:a5125a2e77ea

towards inverted map of refs
author Henry S. Thompson <ht@markup.co.uk>
date Thu, 06 Apr 2017 18:31:46 +0100
parents 87e0d620deea
children 8309dcfce613
line wrap: on
line source

<?xml version='1.0'?>
<!DOCTYPE doc SYSTEM "../../../lib/xml/xsl.dtd" >
<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">
  <xsl:variable name="pat1">("[^"]*")|(\{[^}]+})|(,)|([^=\-+*/();:,.$&lt;>^!]+(?:\.[^=\-+*/();:,.$&lt;>^!]+)*\()|([)])|(^=|\()|((?:'[^']+')|(?:\[[0-9]+\][^!]*))|(\$?[A-Z]+\$?[0-9]+)|([a-zA-Z_\\][a-zA-Z0-9._]*)|(.)</xsl:variable>
 <xsl:param name="pat" select="$pat1"/>

 <xsl:template match="/">
  <refs><xsl:apply-templates select="//s:c"/></refs>
 </xsl:template>
 
 <xsl:template match="s:c[s:f]">
  <xsl:variable name="tokens" select="analyze-string(s:f/.,$pat)/xf:match/xf:group"/>
  <xsl:if test="@r='xxx'"><xsl:message><xsl:value-of select="$tokens/@nr"/></xsl:message>
<xsl:message><xsl:value-of select="$tokens/."/></xsl:message>
  </xsl:if>
  <xsl:if test="$tokens[@nr=(7,8,9)]">
   <xsl:variable name="n" select="count($tokens)"/>
   <xsl:variable name="singles" select="for $i in (1 to $n)
       return if ($tokens[$i][@nr=(8,9)] and
                  not($tokens[$i - 1][@nr=10 and
                      .=(':','!')]) and
                  not($tokens[$i + 1][@nr=10 and .=':']))
            then translate($tokens[$i],'$','')
            else ()"/>
   <!-- Note that we don't bother to treat external ranges as ranges,
          since we're not going to try to detect cross-document refs -->
   <xsl:variable name="ranges" select="for $i in (1 to count($tokens))
          return if ($tokens[$i][@nr=10 and .=':' and
                                not($i gt 2 and
                                    $tokens[$i - 2][@nr=10 and .='!'])])
            then translate(concat($tokens[$i - 1],':',$tokens[$i + 1]),'$','')
            else ()"/>
   <xsl:variable name="externals" select="for $i in (1 to count($tokens))
          return if ($tokens[$i][@nr=7])
            then 
              let $bit := concat($tokens[$i],'!',
                                 translate($tokens[$i + 2],'$',''))
              return if ((($i+3) le $n) and
                         $tokens[$i + 3][@nr=10 and .=':'])
                then concat($bit,':',translate($tokens[$i + 4],'$',''))
                else $bit
            else ()"/>
   <ref c="{@r}">
    <xsl:for-each select="distinct-values($singles)">
     <s><xsl:value-of select="."/></s>
    </xsl:for-each>
    <xsl:for-each select="distinct-values($ranges)">
     <r><xsl:value-of select="."/></r>
    </xsl:for-each>
    <xsl:for-each select="distinct-values($externals)">
     <e><xsl:value-of select="."/></e>
    </xsl:for-each>
   </ref></xsl:if>
 </xsl:template>
 
 <xsl:template match="s:c"/>
</xsl:stylesheet>