<commit_before><?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright (C) 2009-2016 Simonsoft Nordic AB

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

            http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns:indexfn="http://www.simonsoft.se/namespace/cms-indexing-functions"
    exclude-result-prefixes="xs" 
    version="2.0">



    <xsl:param name="patharea"/>
    <xsl:param name="locale"/>
    <xsl:param name="prefix" select="''"></xsl:param>
    <xsl:param name="defaultSheet" select="'keydefmap'"></xsl:param>
    <xsl:param name="enableDescr" as="xs:boolean" select="false()"/>
    <xsl:param name="enableIDParentGroupPrefix" as="xs:boolean" select="true()"/>
    <xsl:param name="IDParentGroupSeparator" as="xs:string" select="'.'"></xsl:param>
    
    <xsl:param name="newline" select="'&#xa;'"/>
    
    <!-- Indexing will store keydefs only, no root element. -->
    <xsl:output omit-xml-declaration="yes" />
    
    <xsl:template match="/*">
        <xsl:message select="'Transforming Excel into keydefmap.'"/>
        <xsl:apply-templates select="xhtml:body"/>
    </xsl:template>

    <xsl:template match="xhtml:body">
        
        <xsl:if test="empty(//xhtml:div)">
            <xsl:message select="'No sheets detected in Excel file.'" terminate="yes"/>
        </xsl:if>
        <!-- TODO: Select sheet logic. -->
        <xsl:variable name="sheet" as="element(xhtml:div)">
            <xsl:choose>
                <xsl:when test="xhtml:div[xhtml:h1/text() = $locale]">
                    <xsl:sequence select="xhtml:div[xhtml:h1/text() = $locale][1]"/>
                </xsl:when>
                
                <xsl:when test="xhtml:div[xhtml:h1/text() = $defaultSheet]">
                    <xsl:sequence select="xhtml:div[xhtml:h1/text() = $defaultSheet][1]"/>
                </xsl:when>
                
                <xsl:otherwise>
                    <xsl:sequence select="xhtml:div[1]"/>
                </xsl:otherwise>
            </xsl:choose>
            
        </xsl:variable>
        
        
        
        <xsl:variable name="msg" select="concat('Transforming Excel sheet: &quot;', $sheet/xhtml:h1/text()[1], '&quot;')"/>
        <xsl:comment select="$msg"/>
        <xsl:message select="$msg"/>
        
        <xsl:apply-templates select="$sheet" mode="excel-simple"/>
        
    </xsl:template>

    <xsl:template match="xhtml:div" mode="excel-simple">
        
        <xsl:choose>
            <xsl:when test="indexfn:validate-column-count(., 2, 3)">
                <xsl:value-of select="$newline"/>
                <xsl:apply-templates select=".//xhtml:tr" mode="#current">
                    <xsl:with-param name="prefix" select="$prefix"/>
                </xsl:apply-templates>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$newline"/>
                <xsl:comment select="'Sheet failed column count validation.'"/>
                <xsl:value-of select="$newline"/>
                <xsl:comment select="indexfn:error-column-count(., 2, 3)"></xsl:comment>
            </xsl:otherwise>
        </xsl:choose>
        
        
    </xsl:template>

    <xsl:template match="xhtml:tr" mode="excel-simple">
        <xsl:param name="prefix"/>
        
        <xsl:variable name="key" select="xhtml:td[1]"/>
        <xsl:variable name="group-prefix">
            <!-- Not used in this transform. -->
            <xsl:value-of select="''"/>
        </xsl:variable>

        <xsl:element name="keydef">
            <xsl:attribute name="keys" select="indexfn:key-valid(concat($prefix, $group-prefix, $key))"/>
            <xsl:element name="topicmeta">
                <xsl:if test="$enableDescr">
                    <!-- Not used in this transform. -->
                    <xsl:apply-templates select="comment"/>
                </xsl:if>
                <xsl:element name="keywords">
                    <xsl:element name="keyword">
                        <xsl:apply-templates select="xhtml:td[2]|xhtml:td[3]" mode="#current"/>
                    </xsl:element>
                </xsl:element>
            </xsl:element>
        </xsl:element>
        <xsl:value-of select="$newline"/>
    </xsl:template>
    
    <xsl:template match="xhtml:tr[1][xhtml:td[1]/text() = 'Key']" mode="excel-simple">
        <!-- Suppress header row if first column header is 'Key'. -->
    </xsl:template>
    
    
    <xsl:template match="xhtml:td" mode="excel-simple">
        
        <xsl:apply-templates/>
    </xsl:template>
    
    
    <xsl:template match="text()" mode="keyword">
        <xsl:copy/>
    </xsl:template>
    
    
    <xsl:function name="indexfn:validate-column-count" as="xs:boolean">
        <xsl:param name="sheet" as="element()"/>
        <xsl:param name="mincol"/>
        <xsl:param name="maxcol"/>
        
        <xsl:variable name="rows" select="$sheet//xhtml:tr[count(xhtml:td) > $maxcol or $mincol > count(xhtml:td)]"/>
        
        <xsl:if test="$rows">
            <xsl:message select="concat('Rows failing column count: ', count($rows))"></xsl:message>
        </xsl:if>
        
        <xsl:sequence select="not(boolean($rows))"/>
    </xsl:function>
    
    <xsl:function name="indexfn:error-column-count" as="text()*">
        <xsl:param name="sheet" as="element()"/>
        <xsl:param name="mincol"/>
        <xsl:param name="maxcol"/>
        
        <xsl:variable name="rows" select="$sheet//xhtml:tr[count(xhtml:td) > $maxcol or $mincol > count(xhtml:td)]"/>
        
            <xsl:for-each select="$rows">
                <xsl:variable name="rowno" select="1 + count(preceding-sibling::xhtml:tr)"/>
                <xsl:variable name="rowcontent" select="string-join(.//xhtml:td, '|')"/>
                <xsl:variable name="msg" select="concat('Incorrect column count on row ', $rowno, ': &quot;', $rowcontent, '&quot;')"/>
                <xsl:value-of select="$msg"/>
                <xsl:message select="$msg"/>
            </xsl:for-each>
    </xsl:function>
    
    <xsl:function name="indexfn:key-valid" as="xs:string">
        <xsl:param name="key"/>
        <!-- Function copied btw keydefmap XSL files. --><commit_msg>Suppress empty rows (no cells) sometimes reported from Excel file.<commit_after><?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright (C) 2009-2016 Simonsoft Nordic AB

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

            http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns:indexfn="http://www.simonsoft.se/namespace/cms-indexing-functions"
    exclude-result-prefixes="xs" 
    version="2.0">



    <xsl:param name="patharea"/>
    <xsl:param name="locale"/>
    <xsl:param name="prefix" select="''"></xsl:param>
    <xsl:param name="defaultSheet" select="'keydefmap'"></xsl:param>
    <xsl:param name="enableDescr" as="xs:boolean" select="false()"/>
    <xsl:param name="enableIDParentGroupPrefix" as="xs:boolean" select="true()"/>
    <xsl:param name="IDParentGroupSeparator" as="xs:string" select="'.'"></xsl:param>
    
    <xsl:param name="newline" select="'&#xa;'"/>
    
    <!-- Indexing will store keydefs only, no root element. -->
    <xsl:output omit-xml-declaration="yes" />
    
    <xsl:template match="/*">
        <xsl:message select="'Transforming Excel into keydefmap.'"/>
        <xsl:apply-templates select="xhtml:body"/>
    </xsl:template>

    <xsl:template match="xhtml:body">
        
        <xsl:if test="empty(//xhtml:div)">
            <xsl:message select="'No sheets detected in Excel file.'" terminate="yes"/>
        </xsl:if>
        <!-- TODO: Select sheet logic. -->
        <xsl:variable name="sheet" as="element(xhtml:div)">
            <xsl:choose>
                <xsl:when test="xhtml:div[xhtml:h1/text() = $locale]">
                    <xsl:sequence select="xhtml:div[xhtml:h1/text() = $locale][1]"/>
                </xsl:when>
                
                <xsl:when test="xhtml:div[xhtml:h1/text() = $defaultSheet]">
                    <xsl:sequence select="xhtml:div[xhtml:h1/text() = $defaultSheet][1]"/>
                </xsl:when>
                
                <xsl:otherwise>
                    <xsl:sequence select="xhtml:div[1]"/>
                </xsl:otherwise>
            </xsl:choose>
            
        </xsl:variable>
        
        
        
        <xsl:variable name="msg" select="concat('Transforming Excel sheet: &quot;', $sheet/xhtml:h1/text()[1], '&quot;')"/>
        <xsl:comment select="$msg"/>
        <xsl:message select="$msg"/>
        
        <xsl:apply-templates select="$sheet" mode="excel-simple"/>
        
    </xsl:template>

    <xsl:template match="xhtml:div" mode="excel-simple">
        
        <xsl:choose>
            <xsl:when test="indexfn:validate-column-count(., 2, 3)">
                <xsl:value-of select="$newline"/>
                <xsl:apply-templates select=".//xhtml:tr" mode="#current">
                    <xsl:with-param name="prefix" select="$prefix"/>
                </xsl:apply-templates>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$newline"/>
                <xsl:comment select="'Sheet failed column count validation.'"/>
                <xsl:value-of select="$newline"/>
                <xsl:comment select="indexfn:error-column-count(., 2, 3)"></xsl:comment>
            </xsl:otherwise>
        </xsl:choose>
        
        
    </xsl:template>

    <xsl:template match="xhtml:tr[xhtml:td]" mode="excel-simple">
        <xsl:param name="prefix"/>
        
        <xsl:variable name="key" select="xhtml:td[1]"/>
        <xsl:variable name="group-prefix">
            <!-- Not used in this transform. -->
            <xsl:value-of select="''"/>
        </xsl:variable>

        <xsl:element name="keydef">
            <xsl:attribute name="keys" select="indexfn:key-valid(concat($prefix, $group-prefix, $key))"/>
            <xsl:element name="topicmeta">
                <xsl:if test="$enableDescr">
                    <!-- Not used in this transform. -->
                    <xsl:apply-templates select="comment"/>
                </xsl:if>
                <xsl:element name="keywords">
                    <xsl:element name="keyword">
                        <xsl:apply-templates select="xhtml:td[2]|xhtml:td[3]" mode="#current"/>
                    </xsl:element>
                </xsl:element>
            </xsl:element>
        </xsl:element>
        <xsl:value-of select="$newline"/>
    </xsl:template>
    
    <xsl:template match="xhtml:tr[1][xhtml:td[1]/text() = 'Key']" mode="excel-simple" priority="100">
        <!-- Suppress header row if first column header is 'Key'. -->
    </xsl:template>
    
    <xsl:template match="xhtml:tr" mode="excel-simple" priority="-1">
        <xsl:message select="'Empty row, suppressing.'"></xsl:message>
    </xsl:template>
    
    
    <xsl:template match="xhtml:td" mode="excel-simple">
        
        <xsl:apply-templates/>
    </xsl:template>
    
    
    <xsl:template match="text()" mode="keyword">
        <xsl:copy/>
    </xsl:template>
    
    
    <xsl:function name="indexfn:validate-column-count" as="xs:boolean">
        <xsl:param name="sheet" as="element()"/>
        <xsl:param name="mincol"/>
        <xsl:param name="maxcol"/>
        
        <xsl:variable name="rows" select="$sheet//xhtml:tr[xhtml:td][count(xhtml:td) > $maxcol or $mincol > count(xhtml:td)]"/>
        
        <xsl:if test="$rows">
            <xsl:message select="concat('Rows failing column count: ', count($rows))"></xsl:message>
        </xsl:if>
        
        <xsl:sequence select="not(boolean($rows))"/>
    </xsl:function>
    
    <xsl:function name="indexfn:error-column-count" as="text()*">
        <xsl:param name="sheet" as="element()"/>
        <xsl:param name="mincol"/>
        <xsl:param name="maxcol"/>
        
        <xsl:variable name="rows" select="$sheet//xhtml:tr[xhtml:td][count(xhtml:td) > $maxcol or $mincol > count(xhtml:td)]"/>
        
            <xsl:for-each select="$rows">
                <xsl:variable name="rowno" select="1 + count(preceding-sibling::xhtml:tr)"/>
                <xsl:variable name="rowcontent" select="string-join(.//xhtml:td, '|')"/>
                <xsl:variable name="msg" select="concat('Incorrect column count on row ', $rowno, ': &quot;', $rowcontent, '&quot;')"/>
                <xsl:value-of select="$msg"/>
                <xsl:message select="$msg"/>
            </xsl:for-each>
    </xsl:function>
    
    <xsl:function name="indexfn:key-valid" as="xs:string">
        <xsl:param name="key"/>
        <!-- Function copied btw keydefmap XSL files. -->
{'fraction_non_alphanumeric': 0.17480719794344474, 'fraction_numerical': 0.008283347614967152, 'mean_word_length': 2.2945189367207717, 'pattern_counts': {'":': 0, '<': 245, '<?xml version=': 2, '>': 253, 'https://': 0, 'lorem ipsum': 0, 'www.': 12, 'xml': 14}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6742380', 'n_tokens_mistral': 4564, 'n_tokens_neox': 4072, 'n_words': 801}