<?xml version='1.0' encoding="UTF-8" ?>
<!--
* NAT - An universal Translator
* Copyright (C) 2005 Bruno Mascret
* Contact: bmascret@free.fr

* former authors: Frédéric Schwebel, Bruno Mascret, Ouarda Yassa
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-->

<!-- TODO : virer les mrow qui ont un seul child et simplifier fr-maths
MAIS PAS AVANT UN JEU DE TESTS DE NON-REGRESSION  -->

<!DOCTYPE xsl:stylesheet SYSTEM "mmlents/windob.dtd">

<xsl:stylesheet version="2.0"
xmlns:xsl='http://www.w3.org/1999/XSL/Transform' 
xmlns:saxon='http://icl.com/saxon'
xmlns:m='http://www.w3.org/1998/Math/MathML'
xmlns:xs='http://www.w3.org/2001/XMLSchema'
xmlns:fn='http://www.w3.org/2005/xpath-functions'
xmlns:doc='espaceDoc'
xmlns:set="http://exslt.org/sets"
extension-element-prefixes="set">

	<xsl:import href="set.xsl" />
	<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
	
<!-- ******************** Phase de preprocessing ****************** -->

<xsl:variable name="functionList" as="xs:string">
	<xsl:value-of select="'|sin|cos|tan|cot|cotan|arcsin|arccos|arctan|arccotan|arccot|sec|csc|sinh|cosh|tanh|coth|arcsinh|arccosh|arctanh|arccoth|sech|csch|ln|log|sh|ch|exp|Card|'" />
</xsl:variable>

<xsl:variable name="trigoList" as="xs:string">
	<xsl:value-of select="'|sin|cos|tan|cot|cotan|arcsin|arccos|arctan|arccotan|arccot|'" />
</xsl:variable>

<xsl:variable name="noBlocList" as="xs:string">
	<!-- les mfrac mettent leur bloc elles-mêmes et les mover (angles) pas besoin -->
	<xsl:value-of select="'|mfrac|mover|'" />
</xsl:variable>

<xsl:variable name="blocList" as="xs:string">
	<xsl:value-of select="'|msub|msup|msqrt|mroot|mover|munder|munderover|msubsup|'" />
</xsl:variable>
	
<!-- transfo identité par défaut avec controle pour fctions -->
<xsl:template match="@*|*|text()|processing-instruction()" priority="-1" mode="phase1">
	<xsl:copy>
		<xsl:apply-templates select="@*|*|text()|processing-instruction()" mode="phase1" />
	</xsl:copy>
</xsl:template>

<!-- on vire les mrow inutiles (dont le parent est mrow)  de openoffice et de mathtype(un peu)-->
<xsl:template match="m:mrow[parent::*[self::m:mrow]]" priority="0" mode="phase1">
		<xsl:apply-templates select="@*|*|text()|processing-instruction()" mode="phase1" />
</xsl:template>

<!-- traitements des mo, mi, mn membres de fonctions en pas following-sibling à cause des mrow de con -->
<xsl:template match="m:mn[parent::*[self::m:mrow and not(fn:contains($blocList,concat('|',local-name(parent::*),'|')))]]" mode="phase1">
	<xsl:call-template name="traitementMembreFonction" />
</xsl:template>

<xsl:template match="m:mi[parent::*[self::m:mrow and not(fn:contains($blocList,concat('|',local-name(parent::*),'|')))]]" mode="phase1">
	<xsl:call-template name="traitementMembreFonction" />
</xsl:template>

<xsl:template match="m:mo[parent::*[self::m:mrow and not(fn:contains($blocList,concat('|',local-name(parent::*),'|')))]]" mode="phase1">
	<xsl:call-template name="traitementMembreFonction" />
</xsl:template>

<!-- pour virer les &amp; des noms d'entites 
<xsl:template match="text()" mode="phase1">
	<xsl:choose>
		<xsl:when test="(string-length(.) > 1) and not (.='&lt;')">
			<xsl:value-of select="." disable-output-escaping="yes" />
		</xsl:when>
		<xsl:otherwise>
			<xsl:value-of select="." />
		</xsl:otherwise>
	</xsl:choose>
</xsl:template> -->

<!-- pour virer les , et . enfants de mn et les mettre dedans (conar de MathType) -->
<xsl:template match="m:mo[parent::*[self::m:mn]]" mode="phase1">
	<xsl:value-of select="string(.)" />
</xsl:template>

<!-- *********** 1er test pour les fonctions simples ************ -->
<xsl:template match="m:*[*[(self::m:mo|self::m:mi)[fn:contains($functionList,concat('|',string(.),'|'))]]]" mode="phase1">
<!-- <xsl:template match="m:*[*[self::m:mo[fn:matches(string(.),$functionList)]]]"> ce serait mieux -->
	
	<xsl:variable name="listeFonctions" select="*[(self::m:mo|self::m:mi)[fn:contains($functionList,concat('|',string(.),'|'))]]" />	
	
	<xsl:copy>
		<xsl:apply-templates select="@*" mode="phase1"/>

		<xsl:for-each select="*">
			<xsl:call-template name="traitementFonctions">
				<xsl:with-param name="listeFonctions" select="$listeFonctions" />
			</xsl:call-template>
		</xsl:for-each>
	</xsl:copy>
</xsl:template>

<!-- *********** 2eme test pour les fonctions exp genre cos² ************ -->
<!-- dans ce cas c'est le msup qui a l'attribut fonction et pas le mi -->
<!-- EBAUCHE, NE SERT PAS 
<xsl:template match="m:msup[1][*[(self::m:mo|self::m:mi)[fn:contains($functionList,concat('|',string(.),'|'))]]]" priority="-11" mode="phase1">
	<xsl:copy>
		<xsl:choose>
			<xsl:when test="fn:contains($trigoList,concat('|',string(*[1]),'|'))">
				<xsl:attribute name="fonc" select="'trigo'" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:attribute name="fonc" select="'autre'" />
			</xsl:otherwise>
		</xsl:choose>
		
		<xsl:element name="mi" namespace="http://www.w3.org/1998/Math/MathML"> pour que les mo fonctions deviennent mi 
			<xsl:apply-templates select="@*[1]|*[1]" mode="phase1" />
		</xsl:element>
		
		<xsl:apply-templates select="*[2]" mode="phase1"/>
		
	</xsl:copy>
</xsl:template>-->


<!-- *********** template de traitement d'une série d'enfants avec au moins 1 fct ******* -->
<xsl:template name="traitementFonctions">
	<xsl:param name="listeFonctions" />	
	
	<xsl:variable name="ps1" select="preceding-sibling::*[1]" />
	<xsl:variable name="ps2" select="preceding-sibling::*[2]" />
	
	<xsl:choose>
		<xsl:when test="set:has-same-node(.,$listeFonctions)"> <!-- on est sur une fonction -->
			<xsl:element name="mi" namespace="http://www.w3.org/1998/Math/MathML"> <!-- pour que les mo fonctions deviennent mi -->
				<xsl:choose>
					<xsl:when test="fn:contains($trigoList,concat('|',string(.),'|'))">
						<xsl:attribute name="fonc" select="'trigo'" />
					</xsl:when>
					<xsl:otherwise>
						<xsl:attribute name="fonc" select="'autre'" />
					</xsl:otherwise>
				</xsl:choose>
				<xsl:apply-templates select="@*|*|text()" mode="phase1"/>
			</xsl:element>
		</xsl:when>
		<xsl:otherwise> <!-- tests pour les membres -->
			<xsl:copy>
				<!-- le not(string(.)='d') c'est pour éviter les cas genre sin xdx ou ln xdx avec des blocs comprenant le d -->
				<xsl:if test="not(local-name(parent::*)='msup' or fn:contains($noBlocList,concat('|',local-name(.),'|'))) and (
				(set:has-same-node($ps1,$listeFonctions) and fn:translate(string(.),$l_alphanumgrec,'')='') or
				(set:has-same-node($ps1,$listeFonctions) and fn:contains($blocList,concat('|',local-name(.),'|'))) or
				(set:has-same-node($ps2,$listeFonctions) and fn:translate(concat(string($ps1),string(.)),$l_alphanumgrec,'')=''
					and string-length(concat(string($ps1),string(.))) &lt; 3 and not(string(.)='d')) or
				(set:has-same-node($ps2,$listeFonctions) and (string(.)='&circ;' or string(.)='&amp;circ;') and local-name($ps1)='mn')
				)">
					<xsl:attribute name="membreFonc" select="'yes'" />
				</xsl:if>

				<xsl:choose>
					<xsl:when test="local-name(.)='mrow' and
						(*[(self::m:mo|self::m:mi)[fn:contains($functionList,concat('|',string(.),'|'))]])">
						<!-- il faut vérifier si ses enfants sont fonctions et si en plus y'a pas de fct
						dans un preceding d'avant (cas rare mais arrive dans openoffice de merde) -->
						
						<xsl:variable name="liste2" select="*[(self::m:mo|self::m:mi)[fn:contains($functionList,concat('|',string(.),'|'))]]" />
						<xsl:variable name="avantFirstFunc" select="count(*[following-sibling::*[$liste2[1]]])" />
						
						<xsl:apply-templates select="*[position() &lt; ($avantFirstFunc+1)]" mode="phase1"/>
						
						<xsl:for-each select="*[position() > $avantFirstFunc]">
							<xsl:call-template name="traitementFonctions">
								<xsl:with-param name="listeFonctions" select="$liste2" />
							</xsl:call-template>
						</xsl:for-each>
						
					</xsl:when>
					<xsl:otherwise>
						<xsl:apply-templates select="@*|*|text()" mode="phase1"/>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:copy>
		</xsl:otherwise>
	</xsl:choose>

</xsl:template>

<!-- controle complementaire basé sur les preceding -->

<xsl:template name="traitementMembreFonction">
	<xsl:copy>
		<xsl:apply-templates select="@*" mode="phase1"/>
		<xsl:if test="fn:translate(string(.),$l_alphanumgrec,'')='' and (
		(preceding::text()[1][fn:contains($functionList,concat('|',string(.),'|'))])
		 or (preceding::text()[2][fn:contains($functionList,concat('|',string(.),'|')) 
				and (ancestor::*[2][self::m:msup or self::m:mrow[parent::m:msup and count(*)=1]])]))">
			<!-- le dernier test est pour les membres des cos² dont le cos est dans un msup ou un msup/mrow -->
			<xsl:attribute name="membreFonc" select="'yes'" />
		</xsl:if>
		<xsl:apply-templates select="*|text()|processing-instruction()" mode="phase1"/>
	</xsl:copy>
</xsl:template>

</xsl:stylesheet>
