Skip to content

Instantly share code, notes, and snippets.

@johannes-riecken
Last active September 5, 2020 17:56
Show Gist options
  • Save johannes-riecken/ad96c1543098cd47c458f241a313d241 to your computer and use it in GitHub Desktop.
Save johannes-riecken/ad96c1543098cd47c458f241a313d241 to your computer and use it in GitHub Desktop.
Anagram finder written in XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template name="sort">
<xsl:param name="w"/>
<!-- position in word -->
<xsl:param name="i" select="1"/>
<!-- position in output -->
<xsl:param name="j" select="1"/>
<xsl:param name="out"/>
<xsl:variable name="alpha" select="'01a02b03c04d05e06f07g08h09i10j11k12l13m14n15o16p17q18r19s20t21u22v23w24x25y26z'"/>
<xsl:variable name="c0" select="substring($w, $i, 1)"/>
<xsl:variable name="n0_tmp" select="substring-before($alpha, $c0)"/>
<xsl:variable name="n0" select="substring($n0_tmp, string-length($n0_tmp) - 1)"/>
<xsl:variable name="c1" select="substring($out, $j, 1)"/>
<xsl:variable name="n1_tmp" select="substring-before($alpha, $c1)"/>
<xsl:variable name="n1" select="substring($n1_tmp, string-length($n1_tmp) - 1)"/>
<xsl:choose>
<xsl:when test="$i &gt; string-length($w)">
<xsl:value-of select="$out"/>
</xsl:when>
<xsl:when test="not($n0 &gt; $n1)">
<xsl:call-template name="sort">
<xsl:with-param name="w" select="$w"/>
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="j" select="1"/>
<xsl:with-param name="out" select="concat(substring($out, 1, $j - 1), $c0, substring($out, $j))"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$j = string-length($out)">
<xsl:call-template name="sort">
<xsl:with-param name="w" select="$w"/>
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="j" select="1"/>
<xsl:with-param name="out" select="concat($out, $c0)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="sort">
<xsl:with-param name="w" select="$w"/>
<xsl:with-param name="i" select="$i"/>
<xsl:with-param name="j" select="$j + 1"/>
<xsl:with-param name="out" select="$out"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="map_append">
<xsl:param name="m"/>
<xsl:param name="k"/>
<xsl:param name="v"/>
<xsl:variable name="ok" select="contains($m, $k)"/>
<xsl:choose>
<xsl:when test="$ok">
<xsl:value-of select="substring-before($m, $k)"/>
<xsl:value-of select="$k"/>
<xsl:value-of select="substring-before(substring-after($m, $k), ']')"/>
<xsl:value-of select="concat(', ', $v)"/>
<xsl:value-of select="']'"/>
<xsl:value-of select="substring-after(substring-after($m, $k), ']')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($m, $k, '[', $v, ']')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="print">
<xsl:param name="m"/>
<xsl:choose>
<xsl:when test="$m">
<xsl:variable name="v" select="substring-before(substring-after($m, '['), ']')"/>
<xsl:variable name="list">
<xsl:call-template name="print-list">
<xsl:with-param name="v" select="$v"/>
</xsl:call-template>
</xsl:variable>
<xsl:if test="contains($list, ' ')">
<xsl:value-of select="concat($list, '&#xA;')"/>
</xsl:if>
<xsl:call-template name="print">
<xsl:with-param name="m" select="substring-after($m, ']')"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="print-list">
<xsl:param name="v"/>
<xsl:variable name="w" select="substring-before(substring-after($v, '&#x22;'), '&#x22;')"/>
<xsl:value-of select="$w"/>
<xsl:variable name="new_v" select="substring-after($v, ', ')"/>
<xsl:if test="$new_v">
<xsl:text> </xsl:text>
<xsl:call-template name="print-list">
<xsl:with-param name="v" select="$new_v"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="main" match="/root">
<xsl:param name="i" select="1"/>
<xsl:param name="m"/>
<xsl:variable name="w" select="p[$i]"/>
<xsl:variable name="sorted">
<xsl:call-template name="sort">
<xsl:with-param name="w" select="$w"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="new_m">
<xsl:call-template name="map_append">
<xsl:with-param name="m" select="$m"/>
<xsl:with-param name="k" select="concat('&#x22;', $sorted, '&#x22;')"/>
<xsl:with-param name="v" select="concat('&#x22;', $w, '&#x22;')"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$i &gt;= count(p)">
<xsl:call-template name="print">
<xsl:with-param name="m" select="$new_m"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="main">
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="m" select="$new_m"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<root>
<p>act</p>
<p>cat</p>
<p>tree</p>
<p>race</p>
<p>care</p>
<p>acre</p>
<p>bee</p>
</root>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment