<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xh="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xh" version="1.0" >

<xsl:output indent="no" encoding="iso-8859-1" method="text" />

<xsl:template match="/"><!--
-->#EXTM3U<xsl:apply-templates select="/plist/dict/key[text() = 'Playlists']/following-sibling::array/dict[1]/array/dict[key/text() = 'Track ID']/integer" mode="find-track"/>
</xsl:template>

<!-- Create an index to the tracks' keys -->
<!-- can't use following-sibling in match pattern =( -->
<xsl:key name="tracks" match="/plist/dict/dict/dict" use="key[text() = 'Track ID']/following-sibling::integer[1]"/>
<xsl:template match="integer" mode="find-track">
  <xsl:apply-templates select="key('tracks',.)" mode="create-entry"/>
</xsl:template>

<xsl:template match="dict" mode="create-entry">
<xsl:variable name="millis" select="key[text() = 'Total Time']/following-sibling::integer[1]"/>
<xsl:variable name="ituneslocation" select="key[text() = 'Location']/following-sibling::string[1]"/>
<xsl:variable name="m3ulocation">
<xsl:choose>
<!-- convert local file URLs to absolute paths -->
<xsl:when test="contains($ituneslocation,'file://localhost/')">
<xsl:call-template name="decode">
<xsl:with-param name="encoded" select="substring($ituneslocation,18,string-length($ituneslocation)-18)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="decode">
<xsl:with-param name="encoded" select="substring($ituneslocation,1,string-length($ituneslocation)-1)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
#EXTINF:<xsl:value-of select="substring($millis,1,string-length($millis)-3)"/>,<xsl:value-of select="key[text() = 'Artist']/following-sibling::string[1]"/> - <xsl:value-of select="key[text() = 'Name']/following-sibling::string[1]"/><xsl:text xml:space="preserve">
</xsl:text><xsl:value-of select="$m3ulocation"/>
</xsl:template>

<!-- Mike Brown's URL decoding template from 
     http://skew.org/xml/stylesheets/url-encode/ -->
<xsl:template name="decode">
<xsl:param name="encoded"/>
<xsl:variable name="hex" select="'0123456789ABCDEF'"/>
<xsl:variable name="ascii"> !"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~</xsl:variable>
<xsl:variable name="latin1">&#160;&#161;&#162;&#163;&#164;&#165;&#166;&#167;&#168;&#169;&#170;&#171;&#172;&#173;&#174;&#175;&#176;&#177;&#178;&#179;&#180;&#181;&#182;&#183;&#184;&#185;&#186;&#187;&#188;&#189;&#190;&#191;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#201;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#215;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#247;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;</xsl:variable>
<xsl:choose>
<xsl:when test="contains($encoded,'%')">
<xsl:value-of select="substring-before($encoded,'%')"/>
<xsl:variable name="hexpair" select="translate(substring(substring-after($encoded,'%'),1,2),'abcdef','ABCDEF')"/>
<xsl:variable name="decimal" select="(string-length(substring-before($hex,substring($hexpair,1,1))))*16 + string-length(substring-before($hex,substring($hexpair,2,1)))"/>
<xsl:choose>
<xsl:when test="$decimal &lt; 127 and $decimal &gt; 31">
<xsl:value-of select="substring($ascii,$decimal - 31,1)"/>
</xsl:when>
<xsl:when test="$decimal &gt; 159">
<xsl:value-of select="substring($latin1,$decimal - 159,1)"/>
</xsl:when>
<xsl:otherwise>?</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="decode">
<xsl:with-param name="encoded" select="substring(substring-after($encoded,'%'),3)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$encoded"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

