<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  
  <!-- Script to relativize links based on a path. 
    Specifically: link in <a> elements relative to the site root of the form 
    
    <a href="/my/path/to/resource.ext">bla</a>
    
    are replaced by
    
    <a href="../../my/path/to/resource.ext">bla</a>
    
    where the number of '..' depends on the path parameter passed to the script.
    
    It also processes the 'src' attributes. 
  --> 
  
  
  <!-- The directory path of the current file which is being processed --> 
  <xsl:param name="path" select="a/b/c"/>
  
  
  <xsl:include href="dotdots.xsl"/>
  
  <!-- =====================================================
    By default, simply copy everything 
    ===================================================== -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <!-- =====================================================
    Remove the 'includedcontent' element and process it recursively
    =====================================================-->
  <xsl:template match="includedcontent">
    <!-- xsl:element name="processedincludedcontent" -->
    <xsl:apply-templates/>
    <!-- /xsl:element -->
  </xsl:template>
  
  <!-- =====================================================
    Gets the directory path for a given file path. For instance: 
    a/b/c/file.txt becomes a/b/c/
    
    Parameters:
    file:  Filename to process. 
    =====================================================-->
  <xsl:template name="getpath">
    <xsl:param name="file"/>
    <xsl:variable name="dir">
      <xsl:choose>
        <xsl:when test="contains($file, '/')">
          <xsl:value-of select="substring-before($file, '/')"/>
          <xsl:text>/</xsl:text>
          <xsl:call-template name="getpath">
            <xsl:with-param name="file">
              <xsl:value-of select="substring-after($file, '/')"/>
            </xsl:with-param>
          </xsl:call-template>
        </xsl:when>
      </xsl:choose>    
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="starts-with($dir, '/')">
        <xsl:value-of select="substring($dir,2)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$dir"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- ====================================================
    Gets the relative path to CD back from the current page to the root of the site, ends with /
    ====================================================-->
  <xsl:template name="dotdotpath">
    <xsl:call-template name="dotdots">
      <xsl:with-param name="path">
        <xsl:value-of select="$path"/>
        <xsl:text>/x</xsl:text>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  
  <!-- ====================================================
    Transform an absolute path into a relative one 
    
    Parameters:
    file:  Path to process. If the path is not absolute, it is left unaltered
    ====================================================-->
  <xsl:template name="relativize-absolute-path">
    
    <xsl:param name="file"/>
    
    <xsl:choose>
      <xsl:when test="starts-with($file, '/')">
        <!-- absolute path --> 
        <xsl:call-template name="dotdotpath"/>
        <xsl:value-of select="substring($file,2)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$file"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- ====================================================
    Process all hyperlinks within the includedcontent element that are not site or ext references
    or other references according to some other schema (e.g. http, https). 
    
    The href elements are replaced with an appropriate reference based on the path of the 
    current file and the path of the file that contains the reference. 
    ====================================================-->
  <xsl:template match="includedcontent//@href|includedcontent//@src" priority="10">
      <xsl:attribute name="{name()}">
        <xsl:variable name="link" select="."/>
        <xsl:choose>
          
          <!-- Relative links --> 
          <xsl:when test="not(starts-with($link, '/')) and not(contains($link, ':'))">
            
            <!-- move up to the root 'directory' --> 
            <xsl:call-template name="dotdotpath"/>
            
            <!-- move down the 'directory' where the file is located -->  
            <xsl:call-template name="getpath">
              <xsl:with-param name="file">
                <xsl:value-of select="ancestor::includedcontent/@file"/>
              </xsl:with-param>
            </xsl:call-template>
           
            <!-- Add the relative path of the file --> 
            <xsl:value-of select="$link"/>  
          </xsl:when>
          
          <!-- Absolute links, or some scheme --> 
          <xsl:otherwise>
            <xsl:call-template name="relativize-absolute-path">
              <xsl:with-param name="file">
                <xsl:value-of select="$link"/>
              </xsl:with-param>
            </xsl:call-template>      
          </xsl:otherwise>
        </xsl:choose> 
        <!-- Add the relative path of the file --> 
      
      </xsl:attribute>
      <xsl:apply-templates/>
  </xsl:template>
  
  <!-- =========================================================
    Process absolute paths for the href attribute of the a element
    ========================================================== --> 
  <xsl:template match="a/@href">
    <xsl:attribute name="href">
      <xsl:call-template name="relativize-absolute-path">
        <xsl:with-param name="file">
          <xsl:value-of  select="."/>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:attribute>    
  </xsl:template>
  
</xsl:stylesheet>
