<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" version="2.0" exclude-result-prefixes="#all">
<xsl:output indent="yes" include-content-type="no"/>
<xsl:template match="/*">
<nav epub:type="toc" id="toc">
<xsl:apply-templates select="*"/>
</nav>
</xsl:template>
<xsl:template match="*[local-name()='head']"/>
<xsl:template match="*[local-name()='body']">
<ol>
<xsl:call-template name="make-toc-level">
<xsl:with-param name="level" select="'h1'"/>
<xsl:with-param name="group" select="child::*"/>
</xsl:call-template>
</ol>
</xsl:template>
<xsl:template name="make-toc-level">
<xsl:param name="level" required="yes"/>
<xsl:param name="skipFirst" select="false()"/>
<xsl:param name="group" required="yes"/>
<xsl:if test="$level">
<xsl:for-each-group select="$group" group-starting-with="*[local-name()=$level]">
<xsl:choose>
<xsl:when test="current-group()[1]/local-name()=$level">
<li>
<xsl:apply-templates select="current-group()[1]"/>
<xsl:if test="current-group()[position()>1]">
<ol>
<xsl:call-template name="make-toc-level">
<xsl:with-param name="skipFirst" select="true()"/>
<xsl:with-param name="level" select="if ($level='h1') then 'h2' else if ($level='h2') then 'h3' else if ($level='h3') then 'h4' else if ($level='h4') then 'h5' else 'h6'"/>
<xsl:with-param name="group" select="current-group()[position()>1]"/>
</xsl:call-template>
</ol>
</xsl:if>
</li>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="make-toc-level">
<xsl:with-param name="level" select="if ($level='h1') then 'h2' else if ($level='h2') then 'h3' else if ($level='h3') then 'h4' else if ($level='h4') then 'h5' else if ($level='h5') then 'h6' else false()"/>
<xsl:with-param name="group" select="current-group()"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:if>
</xsl:template>
<xsl:template match="*[local-name()='h1' or local-name()='h2' or local-name()='h3' or local-name()='h4' or local-name()='h5' or local-name()='h6']">
<xsl:variable name="link-href" select="tokenize(child::*[local-name()='a'][1]/@href,'#')[1]"/>
<xsl:variable name="link-id" select="if (contains(child::*[local-name()='a'][1]/@href,'#')) then tokenize(child::*[local-name()='a'][1]/@href,'#')[last()] else ''"/>
<xsl:variable name="self-id" select="ancestor-or-self::*/@id"/>
<a href="{child::*[local-name()='a'][1]/@href}">
<xsl:copy-of select="@id"/>
<xsl:value-of select="child::*[local-name()='a'][1]"/>
</a>
</xsl:template>
</xsl:stylesheet>