comparison refs.xsl @ 28:c56a2e6990bd

convert tokenisation to a function, so can make recursive
author Henry S. Thompson <ht@markup.co.uk>
date Tue, 11 Apr 2017 12:28:44 +0100
parents 8309dcfce613
children 87ed04a0fde2
comparison
equal deleted inserted replaced
27:8309dcfce613 28:c56a2e6990bd
8 <xsl:param name="pat" select="$pat1"/><!-- xsl:param for refinement debugging by passing in the pattern --> 8 <xsl:param name="pat" select="$pat1"/><!-- xsl:param for refinement debugging by passing in the pattern -->
9 9
10 <xsl:variable name="workbook" select="document(concat($xlDir,'/workbook.xml'))/*"/> 10 <xsl:variable name="workbook" select="document(concat($xlDir,'/workbook.xml'))/*"/>
11 <xsl:variable name="sheet-name" select="$workbook/s:sheets/s:sheet[@sheetId=$sheet-number]/@name"/> 11 <xsl:variable name="sheet-name" select="$workbook/s:sheets/s:sheet[@sheetId=$sheet-number]/@name"/>
12 12
13 <xsl:function name="e:tokenise" as="array(xs:string*)*">
14 <xsl:param name="formula" as="xs:string" required="yes"/>
15 <xsl:sequence select="
16 let $tokens := analyze-string($formula,$pat)/xf:match/xf:group
17 return if ($tokens[@nr=(7,8,9)])
18 then
19 let $n := count($tokens),
20 $singles := for $i in (1 to $n)
21 return if ($tokens[$i][@nr=(8,9)] and
22 not($tokens[$i - 1][@nr=10 and
23 .=(':','!')]) and
24 not($tokens[$i + 1][@nr=10 and .=':']))
25 then translate($tokens[$i],'$','')
26 else (),
27 $ranges := for $i in (1 to count($tokens))
28 return if ($tokens[$i][@nr=10 and .=':' and
29 not($i gt 2 and
30 $tokens[$i - 2][@nr=10 and .='!'])])
31 then translate(concat($tokens[$i - 1],':',
32 $tokens[$i + 1]),'$','')
33 else (),
34 $externals := for $i in (1 to count($tokens))
35 return if ($tokens[$i][@nr=7])
36 then
37 let $bit := concat($tokens[$i],'!',
38 translate($tokens[$i + 2],
39 '$',''))
40 return if ((($i+3) le $n) and
41 $tokens[$i + 3][@nr=10 and .=':'])
42 then concat($bit,':',
43 translate($tokens[$i + 4],
44 '$',''))
45 else $bit
46 else ()
47 return [$singles,$ranges,$externals]
48 else ()"/>
49 </xsl:function>
50
13 <xsl:template match="/"> 51 <xsl:template match="/">
14 <refs sheetName="{$sheet-name}"><xsl:apply-templates select="//s:c"/></refs> 52 <refs sheetName="{$sheet-name}"><xsl:apply-templates select="//s:c"/></refs>
15 </xsl:template> 53 </xsl:template>
16 54
17 <xsl:template match="s:c[s:f]"> 55 <xsl:template match="s:c[s:f]">
18 <xsl:variable name="tokens" select="analyze-string(s:f/.,$pat)/xf:match/xf:group"/> 56 <xsl:variable name="tokens" select="e:tokenise(s:f/.)"/>
19 <xsl:if test="@r='A2'"><xsl:message><xsl:value-of select="$tokens/@nr"/></xsl:message> 57 <xsl:if test="@r='xxx'"><xsl:message>|</xsl:message>
20 <xsl:message><xsl:value-of select="$tokens/."/></xsl:message>
21 </xsl:if> 58 </xsl:if>
22 <xsl:if test="$tokens[@nr=(7,8,9)]"> 59 <xsl:if test="count($tokens)>0">
23 <xsl:variable name="n" select="count($tokens)"/> 60 <xsl:variable name="singles" select="$tokens?1"/>
24 <xsl:variable name="singles" select="for $i in (1 to $n)
25 return if ($tokens[$i][@nr=(8,9)] and
26 not($tokens[$i - 1][@nr=10 and
27 .=(':','!')]) and
28 not($tokens[$i + 1][@nr=10 and .=':']))
29 then translate($tokens[$i],'$','')
30 else ()"/>
31 <!-- Note that we don't bother to treat external ranges as ranges, 61 <!-- Note that we don't bother to treat external ranges as ranges,
32 since we're not going to try to detect cross-document refs --> 62 since we're not going to try to detect cross-document refs -->
33 <xsl:variable name="ranges" select="for $i in (1 to count($tokens)) 63 <xsl:variable name="ranges" select="$tokens?2"/>
34 return if ($tokens[$i][@nr=10 and .=':' and 64 <xsl:variable name="externals" select="$tokens?3"/>
35 not($i gt 2 and
36 $tokens[$i - 2][@nr=10 and .='!'])])
37 then translate(concat($tokens[$i - 1],':',$tokens[$i + 1]),'$','')
38 else ()"/>
39 <xsl:variable name="externals" select="for $i in (1 to count($tokens))
40 return if ($tokens[$i][@nr=7])
41 then
42 let $bit := concat($tokens[$i],'!',
43 translate($tokens[$i + 2],'$',''))
44 return if ((($i+3) le $n) and
45 $tokens[$i + 3][@nr=10 and .=':'])
46 then concat($bit,':',translate($tokens[$i + 4],'$',''))
47 else $bit
48 else ()"/>
49 <ref c="{@r}"> 65 <ref c="{@r}">
50 <xsl:for-each select="distinct-values($singles)"> 66 <xsl:for-each select="distinct-values($singles)">
51 <s><xsl:value-of select="."/></s> 67 <s><xsl:value-of select="."/></s>
52 </xsl:for-each> 68 </xsl:for-each>
53 <xsl:for-each select="distinct-values($ranges)"> 69 <xsl:for-each select="distinct-values($ranges)">