<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xd="http://www.pnp-software.com/XSLTdoc" xmlns:exsl="http://exslt.org/common" xmlns:tei="http://www.tei-c.org/ns/1.0" xmlns="http://www.tei-c.org/ns/1.0" extension-element-prefixes="exsl" exclude-result-prefixes="xd exsl tei" version="1.0">
    
    <xd:doc type="stylesheet">
        
<xd:short>Stylesheet for MULTEXT-East morphosyntactic specifications. Merges language
            particular specification to common specification.
</xd:short>
        
<xd:detail>Stylesheet takes the common specifications, in particular the tables defining
            categories (PoS), their attributes and values, and modifies these tables so that they
            correspond to the (tables of a) language specific section, i.e. it merges the l.s.
            tables into the common ones. The stylesheet reports on attributes and values removed or
            added to the common specifications on STDERR.
</xd:detail>
        
<xd:author>Tomaž Erjavec tomaz.erjavec@ijs.si</xd:author>
        
<xd:date>2009-05-09</xd:date>
        
<xd:detail> This stylesheet is free software; you can redistribute it and/or modify it under
            the terms of the GNU Lesser General Public License as published by the Free Software
            Foundation; either version 2.1 of the License, or (at your option) any later version.
            This library 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 Lesser General Public License for more details. You
            should have received a copy of the GNU Lesser General Public License along with this
            library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite
            330, Boston, MA 02111-1307 USA 
</xd:detail>
    
</xd:doc>


    
<xsl:output indent="yes" encoding="utf-8" omit-xml-declaration="no" doctype-system="teiP5/teilite.dtd" />
    
<xsl:strip-space elements="*" />
    
<xsl:param name="add" />
    
<xsl:param name="debug">yes</xsl:param>
    
<xsl:variable name="lang" select="document($add)//tei:*[@select][1]/@select" />

    
<!--
    <xsl:template match="/">
      <xsl:message terminate="yes">
        <xsl:text>Language: </xsl:text>
        <xsl:value-of select="$lang"/>
      </xsl:message>
  </xsl:template>  
    
-->

    
    <xd:doc>
        
<xd:short>By default pass through</xd:short>
    
</xd:doc>

    
<xsl:template match="tei:*">
        
<xsl:element name="{local-name()}">
            
<xsl:apply-templates select="@*" />
            
<xsl:apply-templates select="*|comment()|text()" />
        
</xsl:element>
    
</xsl:template>
    
<xsl:template match="*">
        
<xsl:copy>
            
<xsl:apply-templates select="@*" />
            
<xsl:apply-templates select="*|comment()|text()" />
        
</xsl:copy>
    
</xsl:template>
    
<xsl:template match="@*|comment()">
        
<xsl:copy />
    
</xsl:template>
    
<xsl:template match="tei:cell[@role='lang']">
        
<xsl:element name="{local-name()}">
            
<xsl:apply-templates select="@*" />
            
<xsl:apply-templates select="*|comment()|text()" />
        
</xsl:element>
    
</xsl:template>

    
    <xd:doc>
        
<xd:short>Process Category table from common specifications</xd:short>
    
</xd:doc>

    
<xsl:template match="tei:table[@n='msd.cat']">
        
<xsl:variable name="cat-name" select="tei:row[@role='type']/tei:cell[@role='value']" />
        
<!-- the tree fragment from the (modified) language category table -->
        
<xsl:variable name="add-category" select="document($add)//tei:table[@n='msd.cat'][tei:row[@role='type']/tei:cell[@role='value']=$cat-name]" />
        
<xsl:element name="{local-name()}">
            
<xsl:apply-templates select="@*" />
            
<xsl:apply-templates select="tei:head" />
            
<xsl:apply-templates mode="merge" select="tei:row[@role='type']">
                
<xsl:with-param name="add-type" select="exsl:node-set($add-category)/tei:row[@role='type']" />
            
</xsl:apply-templates>
            
<xsl:apply-templates mode="merge" select="tei:row[@role='attribute']">
                
<xsl:with-param name="cat-name" select="$cat-name" />
                
<xsl:with-param name="add-category" select="exsl:node-set($add-category)" />
            
</xsl:apply-templates>
            
<xsl:apply-templates mode="new" select="exsl:node-set($add-category)/tei:row[@role='attribute'][1]">
                
<xsl:with-param name="cat-name" select="$cat-name" />
                
<xsl:with-param name="com-category" select="." />
                
<xsl:with-param name="com-position">
                  
<xsl:choose>
                    
<xsl:when test="tei:row[@role='attribute']">
                      
<xsl:value-of select="tei:row[@role='attribute'][last()]/tei:cell[@role='position'] + 1" />
                    
</xsl:when>
                    
<xsl:otherwise>
                      
<xsl:text>1</xsl:text>
                    
</xsl:otherwise>
                  
</xsl:choose>
                
</xsl:with-param>
            
</xsl:apply-templates>
        
</xsl:element>
    
</xsl:template>
    
    <xd:doc>
        
<xd:short>Process Type row</xd:short>
    
</xd:doc>

    
<xsl:template mode="merge" match="tei:row[@role='type']">
        
<xsl:param name="add-type" />
        
<xsl:variable name="cat-name" select="tei:cell[@role='value']" />
        
<xsl:variable name="message-str" select="concat('category ', $cat-name)" />
        
<xsl:element name="{local-name()}">
            
<xsl:apply-templates select="@*" />
            
<xsl:apply-templates select="tei:cell[not(@role='lang')] | comment()" />
            
<xsl:choose>
                
<xsl:when test="not(normalize-space($add-type)) and not(tei:cell[@role='lang']=$lang)">
                    
<xsl:apply-templates select="tei:cell[@role='lang']" />
                
</xsl:when>
                
<xsl:when test="not(normalize-space($add-type)) and tei:cell[@role='lang']=$lang">
                    
<xsl:call-template name="message">
                        
<xsl:with-param name="msg" select="concat('removed from ',$message-str)" />
                    
</xsl:call-template>
                    
<xsl:apply-templates select="tei:cell[@role='lang'][text() != $lang]" />
                
</xsl:when>
                
<xsl:when test="normalize-space($add-type) and not(tei:cell[@role='lang']=$lang)">
                    
<xsl:apply-templates select="tei:cell[@role='lang']" />
                    
<xsl:call-template name="message">
                        
<xsl:with-param name="msg" select="concat('added to ',$message-str)" />
                    
</xsl:call-template>
                    
<xsl:element namespace="http://www.tei-c.org/ns/1.0" name="cell">
                        
<xsl:attribute name="role">lang</xsl:attribute>
                        
<xsl:value-of select="$lang" />
                    
</xsl:element>
                
</xsl:when>
                
<xsl:when test="normalize-space($add-type) and tei:cell[@role='lang']=$lang">
                    
<xsl:apply-templates select="tei:cell[@role='lang']" />
                
</xsl:when>
                
<xsl:otherwise>
                    
<xsl:message terminate="yes">Weird Type combo</xsl:message>
                
</xsl:otherwise>
            
</xsl:choose>
        
</xsl:element>
    
</xsl:template>
    
    <xd:doc>
        
<xd:short>Process Attribute row</xd:short>
    
</xd:doc>

    
<xsl:template mode="merge" match="tei:row[@role='attribute']">
        
<xsl:param name="cat-name" />
        
<xsl:param name="add-category" />
        
<xsl:element name="{local-name()}">
            
<xsl:apply-templates select="@*" />
            
<xsl:apply-templates select="comment()" />
            
<xsl:apply-templates select="tei:cell[@role='position']" />
            
<xsl:apply-templates select="tei:cell[@role='name']" />
            
<xsl:element name="cell">
                
<xsl:element name="table">
                    
<xsl:variable name="att-name" select="tei:cell[@role='name']" />
                    
<xsl:variable name="add-attribute" select="exsl:node-set($add-category)/tei:row[@role='attribute'][tei:cell[@role='name']=$att-name]/tei:cell/tei:table" />
                    
<xsl:apply-templates mode="merge" select="tei:cell/tei:table/tei:row[@role='value']">
                        
<xsl:with-param name="cat-name" select="$cat-name" />
                        
<xsl:with-param name="att-name" select="$att-name" />
                        
<xsl:with-param name="add-attribute" select="$add-attribute" />
                    
</xsl:apply-templates>
                    
<xsl:apply-templates mode="new" select="exsl:node-set($add-attribute)/tei:row[@role='value'][1]">
                        
<xsl:with-param name="cat-name" select="$cat-name" />
                        
<xsl:with-param name="att-name" select="$att-name" />
                        
<xsl:with-param name="com-attribute" select="tei:cell/tei:table" />
                    
</xsl:apply-templates>
                
</xsl:element>
            
</xsl:element>
        
</xsl:element>
    
</xsl:template>
    
    <xd:doc>
        
<xd:short>Process Value row</xd:short>
    
</xd:doc>

    
<xsl:template mode="merge" match="tei:row[@role='value']">
        
<xsl:param name="cat-name" />
        
<xsl:param name="att-name" />
        
<xsl:param name="add-attribute" />
        
<xsl:variable name="value" select="tei:cell[@role='name']" />
        
<xsl:variable name="add-value" select="exsl:node-set($add-attribute)/tei:row[@role='value'][tei:cell[@role='name']=$value]" />
        
<xsl:variable name="message-str" select="concat('feature ', $cat-name,'/',$att-name,'=',$value)" />
        
<xsl:element name="{local-name()}">
            
<xsl:apply-templates select="@*" />
            
<xsl:apply-templates select="comment()" />
            
<xsl:apply-templates select="tei:cell[not(@role='lang')]" />
            
<xsl:choose>
                
<xsl:when test="not(normalize-space($add-value)) and not(tei:cell[@role='lang']=$lang)">
                    
<xsl:apply-templates select="tei:cell[@role='lang']" />
                
</xsl:when>
                
<xsl:when test="not(normalize-space($add-value)) and tei:cell[@role='lang']=$lang">
                    
<xsl:call-template name="message">
                        
<xsl:with-param name="msg" select="concat('removed from ',$message-str)" />
                    
</xsl:call-template>
                    
<xsl:if test="not(normalize-space(tei:cell[@role='lang'][. != $lang]))">
                        
<xsl:call-template name="message">
                            
<xsl:with-param name="level">WARN</xsl:with-param>
                            
<xsl:with-param name="msg" select="concat('NO LANGUAGES LEFT for ',$message-str)" />
                        
</xsl:call-template>
                    
</xsl:if>
                    
<xsl:apply-templates select="tei:cell[@role='lang'][. != $lang]" />
                
</xsl:when>
                
<xsl:when test="normalize-space($add-value) and not(tei:cell[@role='lang']=$lang)">
                    
<xsl:apply-templates select="tei:cell[@role='lang']" />
                    
<xsl:call-template name="message">
                        
<xsl:with-param name="msg" select="concat('added to ',$message-str)" />
                    
</xsl:call-template>
                    
<xsl:element namespace="http://www.tei-c.org/ns/1.0" name="cell">
                        
<xsl:attribute name="role">lang</xsl:attribute>
                        
<xsl:value-of select="$lang" />
                    
</xsl:element>
                
</xsl:when>
                
<xsl:when test="normalize-space($add-value) and tei:cell[@role='lang']=$lang">
                    
<xsl:apply-templates select="tei:cell[@role='lang']" />
                
</xsl:when>
                
<xsl:otherwise>
                    
<xsl:message terminate="yes">Weird value combo</xsl:message>
                
</xsl:otherwise>
            
</xsl:choose>
        
</xsl:element>
    
</xsl:template>
    
    <xd:doc>
        
<xd:short>Check if l.s. table introduces new attributes, and merge them to the common table</xd:short>
    
</xd:doc>

    
<xsl:template mode="new" match="tei:row[@role='attribute']">
        
<xsl:param name="cat-name" />
        
<xsl:param name="com-category" />
        
<xsl:param name="com-position" />
        
<xsl:variable name="att-name" select="tei:cell[@role='name'][ancestor-or-self::tei:*[@xml:lang][1][@xml:lang='en']]" />
        
<xsl:choose>
            
<xsl:when test="exsl:node-set($com-category)/tei:row[@role='attribute']/tei:cell[@role='name'] = $att-name">
                
<xsl:apply-templates mode="new" select="following-sibling::tei:row[@role='attribute'][1]">
                    
<xsl:with-param name="cat-name" select="$cat-name" />
                    
<xsl:with-param name="com-category" select="$com-category" />
                    
<xsl:with-param name="com-position" select="$com-position" />
                
</xsl:apply-templates>
            
</xsl:when>
            
<xsl:otherwise>
                
<xsl:variable name="message-str" select="concat('attribute ', $cat-name,'/',$att-name,' at position ',$com-position)" />
                
<xsl:call-template name="message">
                    
<xsl:with-param name="level">WARN</xsl:with-param>
                    
<xsl:with-param name="msg" select="concat('NEW ',$message-str)" />
                
</xsl:call-template>
                
<xsl:element name="row">
                    
<xsl:attribute name="role">attribute</xsl:attribute>
                    
<xsl:element name="cell">
                        
<xsl:attribute name="role">position</xsl:attribute>
                        
<xsl:value-of select="$com-position" />
                    
</xsl:element>
                    
<xsl:element name="cell">
                        
<xsl:attribute name="role">name</xsl:attribute>
                        
<xsl:value-of select="$att-name" />
                    
</xsl:element>
                    
<xsl:element name="cell">
                        
<xsl:element name="table">
                            
<xsl:for-each select="tei:cell/tei:table/tei:row">
                                
<xsl:element name="row">
                                    
<xsl:attribute name="role">value</xsl:attribute>
                                    
<xsl:element name="cell">
                                        
<xsl:attribute name="role">name</xsl:attribute>
                                        
<xsl:value-of select="tei:cell[@role='name'][ancestor-or-self::tei:*[@xml:lang][1][@xml:lang='en']]" />
                                    
</xsl:element>
                                    
<xsl:element name="cell">
                                        
<xsl:attribute name="role">code</xsl:attribute>
                                        
<xsl:value-of select="tei:cell[@role='code'][ancestor-or-self::tei:*[@xml:lang][1][@xml:lang='en']]" />
                                    
</xsl:element>
                                    
<xsl:element name="cell">
                                        
<xsl:attribute name="role">lang</xsl:attribute>
                                        
<xsl:value-of select="$lang" />
                                    
</xsl:element>
                                
</xsl:element>
                            
</xsl:for-each>
                        
</xsl:element>
                    
</xsl:element>
                
</xsl:element>
                
<xsl:apply-templates mode="new" select="following-sibling::tei:row[@role='attribute'][1]">
                    
<xsl:with-param name="cat-name" select="$cat-name" />
                    
<xsl:with-param name="com-category" select="$com-category" />
                    
<xsl:with-param name="com-position" select="$com-position+1" />
                
</xsl:apply-templates>
            
</xsl:otherwise>
        
</xsl:choose>
    
</xsl:template>

    
    <xd:doc>
        
<xd:short>Check if l.s. table introduces new values, and merge them to the common
            table=
</xd:short>
    
</xd:doc>

    
<xsl:template mode="new" match="tei:row[@role='value']">
        
<xsl:param name="cat-name" />
        
<xsl:param name="com-attribute" />
        
<xsl:param name="att-name" />
        
<xsl:variable name="com-value" select="exsl:node-set($com-attribute)/tei:row[@role='value']" />
        
<xsl:variable name="val-name" select="tei:cell[@role='name'][ancestor-or-self::tei:*[@xml:lang][1][@xml:lang='en']]" />
        
<xsl:variable name="code-name" select="tei:cell[@role='code'][ancestor-or-self::tei:*[@xml:lang][1][@xml:lang='en']]" />
        
<xsl:if test="not(normalize-space($val-name))">
            
<xsl:message terminate="yes">
                
<xsl:text>Not value found in </xsl:text>
                
<xsl:value-of select="." />
                
<xsl:text> for </xsl:text>
                
<xsl:value-of select="$lang" />
            
</xsl:message>
        
</xsl:if>
        
<xsl:variable name="message-str" select="concat('value ', $cat-name,'/',$att-name,'=',$val-name,' with code ',$code-name)" />
        
<xsl:choose>
            
<xsl:when test="exsl:node-set($com-value)/tei:cell[@role='name'] = $val-name" />
            
<xsl:otherwise>
                
<xsl:call-template name="message">
                    
<xsl:with-param name="level">WARN</xsl:with-param>
                    
<xsl:with-param name="msg" select="concat('NEW ',$message-str)" />
                
</xsl:call-template>
                
<xsl:if test="exsl:node-set($com-value)/tei:cell[@role='code'] = $code-name">
                    
<xsl:call-template name="message">
                        
<xsl:with-param name="level">!ERROR</xsl:with-param>
                        
<xsl:with-param name="msg" select="concat('CODE CLASH: NEW ',$message-str)" />
                    
</xsl:call-template>
                
</xsl:if>
                
<xsl:element name="row">
                    
<xsl:attribute name="role">value</xsl:attribute>
                    
<xsl:element name="cell">
                        
<xsl:attribute name="role">name</xsl:attribute>
                        
<xsl:value-of select="$val-name" />
                    
</xsl:element>
                    
<xsl:element name="cell">
                        
<xsl:attribute name="role">code</xsl:attribute>
                        
<xsl:value-of select="$code-name" />
                    
</xsl:element>
                    
<xsl:element name="cell">
                        
<xsl:attribute name="role">lang</xsl:attribute>
                        
<xsl:value-of select="$lang" />
                    
</xsl:element>
                
</xsl:element>
            
</xsl:otherwise>
        
</xsl:choose>
        
<xsl:apply-templates mode="new" select="following-sibling::tei:row[@role='value'][1]">
            
<xsl:with-param name="cat-name" select="$cat-name" />
            
<xsl:with-param name="att-name" select="$att-name" />
            
<xsl:with-param name="com-attribute" select="$com-attribute" />
        
</xsl:apply-templates>
    
</xsl:template>

    
<!--defaults-->
    
<xsl:template match="@TEIform" />
    
<xsl:template match="@default[.='false']" />
    
<xsl:template match="@full[.='yes']" />
    
<xsl:template match="@part[.='N']" />
    
<xsl:template match="@sample[.='complete']" />
    
<xsl:template match="@org[.='uniform']" />
    
<xsl:template match="@opt[.='n']" />
    
<xsl:template match="@targOrder[.='U']" />
    
<!--xsl:template match="teiHeader/@type[.='text']"/-->
    
<xsl:template match="tei:teiHeader/@status[.='new']" />
    
<xsl:template match="tei:availability/@status[.='unknown']" />
    
<xsl:template match="tei:recording/@type[.='audio']" />
    
<xsl:template match="tei:correction/@status[.='unknown']" />
    
<xsl:template match="tei:correction/@method[.='silent']" />
    
<xsl:template match="tei:normalization/@method[.='silent']" />
    
<xsl:template match="tei:quotation/@marks[.='all']" />
    
<xsl:template match="tei:quotation/@form[.='unknown']" />
    
<xsl:template match="tei:hyphenation/@eol[.='some']" />
    
<xsl:template match="tei:refsDecl/@doctype[.='TEI.2']" />
    
<xsl:template match="tei:step/@to[.='DITTO']" />
    
<xsl:template match="tei:metDecl/@type[.='met real']" />
    
<xsl:template match="tei:symbol/@terminal[.='Y']" />
    
<xsl:template match="tei:q/@direct[.='unspecified']" />
    
<xsl:template match="tei:add/@status[.='unremarkable']" />
    
<xsl:template match="tei:del/@status[.='unremarkable']" />
    
<xsl:template match="tei:list/@type[.='simple']" />
    
<xsl:template match="tei:note/@place[.='unspecified']" />
    
<xsl:template match="tei:note/@anchored[.='yes']" />
    
<xsl:template match="tei:note/@anchored[.='true']" />
    
<xsl:template match="tei:editor/@role[.='editor']" />
    
<xsl:template match="tei:castItem/@type[.='role']" />
    
<xsl:template match="tei:sound/@discrete[.='u']" />
    
<xsl:template match="tei:u/@trans[.='smooth']" />
    
<xsl:template match="tei:vocal/@iterated[.='n']" />
    
<xsl:template match="tei:kinesic/@iterated[.='n']" />
    
<xsl:template match="tei:event/@iterated[.='n']" />
    
<xsl:template match="tei:shift/@new[.='normal']" />
    
<xsl:template match="tei:superEntry/@type[.='main']" />
    
<xsl:template match="tei:entry/@type[.='main']" />
    
<xsl:template match="tei:entryFree/@type[.='main']" />
    
<xsl:template match="tei:orth/@extent[.='full']" />
    
<xsl:template match="tei:pron/@extent[.='full']" />
    
<xsl:template match="tei:titlePart/@type[.='main']" />
    
<xsl:template match="tei:xref/@from[.='ROOT']" />
    
<xsl:template match="tei:xref/@to[.='DITTO']" />
    
<xsl:template match="tei:xptr/@from[.='ROOT']" />
    
<xsl:template match="tei:xptr/@to[.='DITTO']" />
    
<xsl:template match="tei:join/@scope[.='root']" />
    
<xsl:template match="tei:altGrp/@mode[.='excl']" />
    
<xsl:template match="tei:altGrp/@wScale[.='perc']" />
    
<xsl:template match="tei:fs/@rel[.='sb']" />
    
<xsl:template match="tei:f/@rel[.='eq']" />
    
<xsl:template match="tei:sym/@rel[.='eq']" />
    
<xsl:template match="tei:nbr/@rel[.='eq']" />
    
<xsl:template match="tei:msr/@rel[.='eq']" />
    
<xsl:template match="tei:rate/@rel[.='eq']" />
    
<xsl:template match="tei:str/@rel[.='eq']" />
    
<xsl:template match="tei:delSpan/@status[.='unremarkable']" />
    
<xsl:template match="tei:witDetail/@place[.='apparatus']" />
    
<xsl:template match="tei:distance/@exact[.='U']" />
    
<xsl:template match="tei:tree/@ord[.='Y']" />
    
<xsl:template match="tei:row/@role[.='data']" />
    
<xsl:template match="tei:row/@rows[.='1']" />
    
<xsl:template match="tei:row/@cols[.='1']" />
    
<xsl:template match="tei:cell/@role[.='data']" />
    
<xsl:template match="tei:cell/@rows[.='1']" />
    
<xsl:template match="tei:cell/@cols[.='1']" />
    
<xsl:template match="tei:channel/@mode[.='x']" />
    
<xsl:template match="tei:constitution/@type[.='single']" />
    
<xsl:template match="tei:relation/@type[.='personal']" />
    
<xsl:template match="tei:relation/@mutual[.='Y']" />
    
<xsl:template match="@rows" />
    
<xsl:template match="@cols" />

    
<xsl:template name="message">
        
<xsl:param name="msg" />
        
<xsl:param name="level" />
        
<xsl:variable name="str">
            
<xsl:if test="normalize-space($level)">
                
<xsl:value-of select="$level" />
                
<xsl:text> </xsl:text>
            
</xsl:if>
            
<xsl:value-of select="$lang" />
            
<xsl:text> </xsl:text>
            
<xsl:value-of select="$msg" />
        
</xsl:variable>
        
<xsl:message>
            
<xsl:value-of select="$str" />
        
</xsl:message>
        
<xsl:if test="$debug">
            
<xsl:comment>
                
<xsl:value-of select="$str" />
            
</xsl:comment>
        
</xsl:if>
    
</xsl:template>
</xsl:stylesheet>






































v