<?xml version="1.0" encoding="UTF-8" ?>
<!--
# Stéphane Casset, Raphaël Hertzog, Logidée 2000-2001
# See LICENSE file for copyright notice
-->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="text" encoding="UTF-8"/>

<!-- Begin Document -->
<xsl:template name="begindoc">
  <xsl:text>\documentclass[11pt,cours,</xsl:text>
  <xsl:value-of select="$mylang"/>
  <xsl:text>]{logidoc}

\begin{document}
</xsl:text>

  <!-- Definition of authors -->
  <xsl:text>\def\auteurs{</xsl:text>
  <xsl:variable name="auteurs">
  <xsl:for-each select="//author">
    <xsl:variable name="nom" select="text()"/>
    <xsl:if test="not(preceding::author[text()=$nom])">
      <xsl:value-of select="."/>
      <xsl:if test="../email">
	<xsl:text> &lt;</xsl:text>
	<xsl:value-of select="../email"/>
	<xsl:text>&gt;</xsl:text>
      </xsl:if>
      <xsl:text>, </xsl:text>
    </xsl:if>
  </xsl:for-each>
  </xsl:variable>
  <xsl:value-of select="substring($auteurs,1,string-length($auteurs)-2)"/>
  <xsl:text>}&#10;</xsl:text>
</xsl:template>

<!-- End document -->
<xsl:template name="enddoc">
  <xsl:if test="//page[@restriction='all' or contains(concat(' ',$selection,' '),concat(' ',@restriction,' ')) or not(@restriction) or $selection='all']//exercise[@restriction='all' or contains(concat(' ',$selection,' '),concat(' ',@restriction,' ')) or not(@restriction) or $selection='all']/answer">
     <xsl:text>\soluces&#10;</xsl:text>
     <xsl:apply-templates select="descendant::exercise" mode="exercice"/>
  </xsl:if>
  <xsl:if test="//page[@restriction='all' or contains(concat(' ',$selection,' '),concat(' ',@restriction,' ')) or not(@restriction) or $selection='all']//glossary[text() != '']">
     <xsl:text>\glossary&#10;</xsl:text>
     <xsl:apply-templates select="descendant::glossary" mode="glossary">
       <xsl:sort select="@name"/>
     </xsl:apply-templates>
  </xsl:if>
  <xsl:text>\noticefin&#10;\end{document}&#10;</xsl:text>
</xsl:template>

<!-- Begin and end of slide -->
<xsl:template name="begindiapo">
  <xsl:param name="titre" select="''"/>
  <xsl:text>\begin{diapo}</xsl:text>
  <xsl:choose>
    <xsl:when test="@background">
      <xsl:text>[</xsl:text>
      <xsl:call-template name="fond"/>
      <xsl:text>]</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="cycle"/>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:text>{</xsl:text>
  <xsl:choose>
    <xsl:when test="$titre">
      <xsl:value-of select="$titre"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="title"/>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:text>}&#10;</xsl:text>
</xsl:template>

<xsl:template name="enddiapo">
  <xsl:text>\end{diapo}&#10;&#10;</xsl:text>
</xsl:template>

<!-- A slide automatically generated -->
<xsl:template name="diapoauto">
  <xsl:call-template name="begindiapo"/>
  <xsl:if test="section[@restriction='all' or contains(concat(' ',$selection,' '),concat(' ',@restriction,' ')) or not(@restriction) or $selection='all']">
  <xsl:text>\begin{liste}&#10;</xsl:text>
  <xsl:for-each select="section[@restriction='all' or contains(concat(' ',$selection,' '),concat(' ',@restriction,' ')) or not(@restriction) or $selection='all']">
    <xsl:text>\item </xsl:text>
    <xsl:apply-templates select="title"/>
    <xsl:text>&#10;</xsl:text>
    <xsl:if test="section[@restriction='all' or contains(concat(' ',$selection,' '),concat(' ',@restriction,' ')) or not(@restriction) or $selection='all']">
      <xsl:text>\begin{liste}&#10;</xsl:text>
      <xsl:for-each select="section[@restriction='all' or contains(concat(' ',$selection,' '),concat(' ',@restriction,' ')) or not(@restriction) or $selection='all']">
        <xsl:text>\item </xsl:text>
        <xsl:apply-templates select="title"/>
        <xsl:text>&#10;</xsl:text>
      </xsl:for-each>
      <xsl:text>\end{liste}</xsl:text>
    </xsl:if>
  </xsl:for-each>
  <xsl:text>&#10;\end{liste}&#10;</xsl:text>
  </xsl:if>
  <xsl:call-template name="enddiapo"/>
</xsl:template>


<!-- Emphasis -->
<xsl:template match="em">
  <xsl:text>{\em </xsl:text>
  <xsl:apply-templates/>
  <xsl:text>}</xsl:text>
</xsl:template>

<!-- Menu -->
<xsl:template match="menu">
  <xsl:text>{\bfseries\large </xsl:text>
  <xsl:call-template name="convert2tex">
    <xsl:with-param name="string" select="string(.)"/>
  </xsl:call-template>
  <xsl:text>}</xsl:text>
</xsl:template>

<!-- Command ou file -->
<xsl:template match="cmd|file">
  <xsl:text>{\tt </xsl:text>
  <xsl:call-template name="convert2tex">
    <xsl:with-param name="string" select="string(.)"/>
    <xsl:with-param name="mode" select="'verbatim'"/>
  </xsl:call-template>
  <xsl:text>}</xsl:text>
</xsl:template>

<!-- URLs -->
<xsl:template match="url">
  <xsl:text>{\tt </xsl:text>
  <xsl:choose>
    <xsl:when test="string(.)=''">
      <xsl:call-template name="convert2tex">
        <xsl:with-param name="string" select="@href"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="convert2tex">
        <xsl:with-param name="string" select="@href"/>
      </xsl:call-template>
      <xsl:text> (</xsl:text>
      <xsl:value-of select="."/>
      <xsl:text>)</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:text>}</xsl:text>
</xsl:template>

<!-- A piece of code -->
<xsl:template match="code">
  <xsl:text>\begin{code}</xsl:text>
  <xsl:apply-templates/>
  <xsl:text>\end{code}&#10;</xsl:text>
</xsl:template>

<!-- A normal list -->
<xsl:template match="list">
  <xsl:text>\begin{liste}&#10;</xsl:text>
  <xsl:apply-templates/>
  <xsl:text>\end{liste}&#10;</xsl:text>
</xsl:template>

<!-- An item of list -->
<xsl:template match="item">
  <xsl:text>\item </xsl:text>
  <xsl:apply-templates/>
  <xsl:text>&#10;</xsl:text>
</xsl:template>

<!-- A list in a slide -->
<xsl:template match="list" mode="diapo">
  <xsl:text>\begin{liste}&#10;\nohyphens&#10;</xsl:text>
  <xsl:apply-templates mode="diapo"/>
  <xsl:text>\end{liste}&#10;</xsl:text>
</xsl:template>

<!-- A list item in a slide -->
<xsl:template match="item" mode="diapo">
  <xsl:choose>
    <xsl:when test="child::code">
      <xsl:text>\item[]</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>\item </xsl:text>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:apply-templates/>
  <xsl:text>&#10;&#10;</xsl:text>
</xsl:template>

<!-- A subtitle in a slide -->
<xsl:template match="subtitle" mode="diapo">
  <!-- TODO: Something better -->
  <xsl:text>{\bfseries </xsl:text>
  <xsl:apply-templates/>
  <xsl:text>}\par\vskip 3mm&#10;</xsl:text>
</xsl:template>

<!-- An image -->
<xsl:template match="image">
  <xsl:text>\image{</xsl:text>
  <xsl:value-of select="@src"/>
  <xsl:text>}</xsl:text>
  <xsl:choose>
    <xsl:when test="@scale">
      <xsl:text>{</xsl:text>
      <xsl:value-of select="@scale"/>
      <xsl:text>}</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>{0}</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:text>{</xsl:text>
    <xsl:if test="legend|caption"><xsl:apply-templates/></xsl:if>
  <xsl:text>}</xsl:text>
</xsl:template>

<!-- An image of a slide -->
<xsl:template match="image" mode="diapo">
  <xsl:text>\imagedia{</xsl:text>
  <xsl:value-of select="@src"/>
  <xsl:text>}</xsl:text>
</xsl:template>

<!-- Para within a diapo -->
<xsl:template match="para" mode="diapo">
  <xsl:if test="@restriction='all' or contains(concat(' ',$selection,' '),concat(' ',@restriction,' ')) or not(@restriction) or $selection='all'">
  <xsl:text>{</xsl:text>
  <xsl:apply-templates mode="diapo"/>
  <xsl:text>}\par&#10;</xsl:text>
  </xsl:if>
</xsl:template>

<!-- Title within a diapo -->
<xsl:template match="title" mode="diapo">
  <!-- nothing -->
</xsl:template>

<!-- Default rule for diapo mode to switch back to normal mode -->
<xsl:template match="*" mode="diapo" priority="-1.0">
  <xsl:apply-templates/>
</xsl:template>

<!-- Tables ... -->
<xsl:template match="table">
  <xsl:variable name="border" select="@border=1 or not(@border)"/>

  <xsl:text>\begin{tabular}{</xsl:text>

  <!-- Line on left if border -->
  <xsl:if test="$border">
   <xsl:text>|</xsl:text>
  </xsl:if>
  
  <!-- Each alignement of cell read from the first row -->
  <xsl:for-each select="row[1]/col">
    <xsl:choose>
      <xsl:when test="@align">
	<xsl:value-of select="@align"/>
      </xsl:when>
      <xsl:otherwise>
	<xsl:text>c</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="(@border=1 or not(@border)) and (position()!=last())">
      <xsl:text>|</xsl:text>
    </xsl:if>
  </xsl:for-each>

  <!-- Line on right if border -->
  <xsl:if test="$border">
   <xsl:text>|</xsl:text>
  </xsl:if>

  <xsl:text>}&#10;</xsl:text>

  <!-- Horizontal line on top if border -->
  <xsl:if test="$border">
   <xsl:text>\hline&#10;</xsl:text>
  </xsl:if>

  <xsl:apply-templates/>
  
  <!-- Horizontal line on bottom if border -->
  <xsl:if test="$border">
    <xsl:text>\hline&#10;</xsl:text>
  </xsl:if>
  
  <xsl:text>\end{tabular}&#10;</xsl:text>
</xsl:template>

<!-- A row -->
<xsl:template match="row">
  <xsl:apply-templates/>
  <xsl:text> \\&#10;</xsl:text>
  <xsl:if test="(@border=1 or not(@border)) and 
  		(position()!=last())">
    <xsl:text>\hline&#10;</xsl:text>
  </xsl:if>
</xsl:template>

<!-- A cell -->
<xsl:template match="col">
  <xsl:variable name="multi" select="@border or @align"/>
  <xsl:variable name="numcol" select="count(preceding-sibling::col)+1"/>

  <!-- column separator if not the first -->
  <xsl:if test="count(preceding-sibling::col)">
    <xsl:text> &amp; </xsl:text>
  </xsl:if>
  <!-- Specific alignement/border needed-->
  <xsl:if test="$multi">
  <xsl:text>\multicolumn{1}{</xsl:text>
  <!-- The left border -->
  <xsl:choose>
    <!-- First column, lookup the table -->
    <xsl:when test="$numcol=1">
      <xsl:if test="not(ancestor::table/@border=0)">
	<xsl:text>|</xsl:text>
      </xsl:if>
    </xsl:when>
    <!-- no left border for other cell, the left border if the right
         border of the previous cell -->
    <xsl:otherwise>
    </xsl:otherwise>
  </xsl:choose>
  <!-- Decide the alignment -->
  <xsl:choose>
    <xsl:when test="@align">
      <xsl:value-of select="@align"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="ancestor::table/row[1]/col[$numcol]/@align">
          <xsl:value-of select="ancestor::table/row[1]/col[$numcol]/@align"/>
	</xsl:when>
	<xsl:otherwise>
          <xsl:text>c</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
  <!-- The right border -->
  <xsl:choose>
    <!-- Last column, lookup the table -->
    <xsl:when test="$numcol=last()">
      <xsl:if test="not(ancestor::table/@border=0)">
	<xsl:text>|</xsl:text>
      </xsl:if>
    </xsl:when>
    <!-- Not the last column, lookup the first row -->
    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="@border">
	  <xsl:if test="@border=1">
	    <xsl:text>|</xsl:text>
	  </xsl:if>
	</xsl:when>
	<xsl:otherwise>
	  <xsl:if test="not(ancestor::table/row[1]/col[$numcol]/@border=0)">
	    <xsl:text>|</xsl:text>
	  </xsl:if>
	</xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
  <!-- End of the right border -->
  <xsl:text>}{</xsl:text>
  </xsl:if>
  <!-- Start head/bold -->
  <xsl:if test="@head=1">
    <xsl:text>{ \bfseries </xsl:text>
  </xsl:if>
  <!-- content -->
  <xsl:apply-templates/>
  <!-- end head/bold -->
  <xsl:if test="@head=1">
    <xsl:text>}</xsl:text>
  </xsl:if>
  <!-- End special alignment -->
  <xsl:if test="$multi">
    <xsl:text>}</xsl:text>
  </xsl:if>
</xsl:template>

<!-- Math notation -->
<xsl:template match="math">
  <xsl:if test="@notation='tex'">
    <xsl:apply-templates mode="texready"/>
  </xsl:if>
</xsl:template>


<!-- Functions to convert a normal string to a TeX ready one -->

<xsl:template match="text()">
  <xsl:call-template name="convert2tex">
    <xsl:with-param name="string" select="."/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="replace">
  <xsl:param name="before" select="''"/>
  <xsl:param name="after" select="''"/>
  <xsl:param name="string" select="''"/>

  <xsl:choose>
    <xsl:when test="contains($string, $before)">
      <xsl:value-of select="substring-before($string, $before)"/>
      <xsl:value-of select="$after"/>
      <xsl:call-template name="replace">
        <xsl:with-param name="before" select="$before"/>
        <xsl:with-param name="after" select="$after"/>
        <xsl:with-param name="string" 
			select="substring-after($string, $before)"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$string"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="convert2tex">
  <xsl:param name="string" select="''"/>
  <xsl:param name="mode" select="''"/>
  <!-- Convert "\" -> "\char92" -->
  <xsl:variable name="after_step1">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'\'"/>
      <xsl:with-param name="after" select="'\char92'"/>
      <xsl:with-param name="string" select="$string"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "_" -> "\_" -->
  <xsl:variable name="after_step2">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'_'"/>
      <xsl:with-param name="after" select="'\_'"/>
      <xsl:with-param name="string" select="$after_step1"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "{" -> "\{" -->
  <xsl:variable name="after_step3">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'{'"/>
      <xsl:with-param name="after" select="'\{'"/>
      <xsl:with-param name="string" select="$after_step2"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "}" -> "\}" -->
  <xsl:variable name="after_step4">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'}'"/>
      <xsl:with-param name="after" select="'\}'"/>
      <xsl:with-param name="string" select="$after_step3"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "%" -> "\%" -->
  <xsl:variable name="after_step5">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'%'"/>
      <xsl:with-param name="after" select="'\%'"/>
      <xsl:with-param name="string" select="$after_step4"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "~" -> "\~{}" -->
  <xsl:variable name="after_step6">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'~'"/>
      <xsl:with-param name="after" select="'\~{}'"/>
      <xsl:with-param name="string" select="$after_step5"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "#" -> "\#" -->
  <xsl:variable name="after_step7">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'#'"/>
      <xsl:with-param name="after" select="'\#'"/>
      <xsl:with-param name="string" select="$after_step6"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "^" -> "\^{}" -->
  <xsl:variable name="after_step8">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'^'"/>
      <xsl:with-param name="after" select="'\^{}'"/>
      <xsl:with-param name="string" select="$after_step7"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "&" -> "\&amp;" -->
  <xsl:variable name="after_step9">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&amp;'"/>
      <xsl:with-param name="after" select="'\&amp;'"/>
      <xsl:with-param name="string" select="$after_step8"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "&#x20AC;" -> "\euro{}" -->
  <xsl:variable name="after_step10">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&#x20AC;'"/>
      <xsl:with-param name="after" select="'\euro{}'"/>
      <xsl:with-param name="string" select="$after_step9"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "®" -> "\Pisymbol{psy}{226}" -->
  <xsl:variable name="after_step11">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&#x00A9;'"/>
      <xsl:with-param name="after" select="'\Pisymbol{psy}{226}'"/>
      <xsl:with-param name="string" select="$after_step10"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "$" -> "\$" -->
  <xsl:variable name="after_step12">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'$'"/>
      <xsl:with-param name="after" select="'\$'"/>
      <xsl:with-param name="string" select="$after_step11"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "&#160;" -> "~" -->
  <xsl:variable name="after_step13">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&#x00A0;'"/>
      <xsl:with-param name="after" select="'~'"/>
      <xsl:with-param name="string" select="$after_step12"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "&#x0152;" -> "\OE{}" -->
  <xsl:variable name="after_step14">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&#x0152;'"/>
      <xsl:with-param name="after" select="'\OE{}'"/>
      <xsl:with-param name="string" select="$after_step13"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "&#x0153;" -> "\oe{}" -->
  <xsl:variable name="after_step15">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&#x0153;'"/>
      <xsl:with-param name="after" select="'\oe{}'"/>
      <xsl:with-param name="string" select="$after_step14"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "&#x2014;" -> "-x3" -->
  <xsl:variable name="after_step16">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&#x2014;'"/>
      <xsl:with-param name="after" select="'---'"/>
      <xsl:with-param name="string" select="$after_step15"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert ">" -> "\textgreater{}" -->
  <xsl:variable name="after_step17">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&gt;'"/>
      <xsl:with-param name="after" select="'\textgreater{}'"/>
      <xsl:with-param name="string" select="$after_step16"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "<" -> "\textless{}" -->
  <xsl:variable name="after_step18">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&lt;'"/>
      <xsl:with-param name="after" select="'\textless{}'"/>
      <xsl:with-param name="string" select="$after_step17"/>
    </xsl:call-template>
  </xsl:variable>
  <!-- Convert "<" -> "\textless{}" -->
  <xsl:variable name="after_step19">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'&quot;'"/>
      <xsl:with-param name="after" select="'\dq{}'"/>
      <xsl:with-param name="string" select="$after_step18"/>
    </xsl:call-template>
  </xsl:variable>

  <!-- Convert "- -" -> "-\/-" -->
  <xsl:variable name="after_step20">
    <xsl:call-template name="replace">
      <xsl:with-param name="before" select="'--'"/>
      <xsl:with-param name="after" select="'-\/-'"/>
      <xsl:with-param name="string" select="$after_step19"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>

  <xsl:when test="contains($mode,'verbatim')">
    <xsl:value-of select="$after_step20"/>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="$after_step19"/>
  </xsl:otherwise>
  </xsl:choose>
</xsl:template>


</xsl:stylesheet>
