<xsl:stylesheet xmlns:attr="http://www.xstandoff.net/2009/functions/attr" xmlns:bool="http://www.xstandoff.net/2009/functions/bool" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:doc="http://www.xstandoff.net/2009/functions/doc" xmlns:double="http://www.xstandoff.net/2009/functions/double" xmlns:all="http://www.xstandoff.net/2009/all" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.pnp-software.com/XSLTdoc" xmlns:xsf="http://www.xstandoff.net/2009/xstandoff/1.1" xmlns:string="http://www.xstandoff.net/2009/functions/string" xmlns:undef="http://www.xstandoff.net/2009/functions/undef" xmlns:elem="http://www.xstandoff.net/2009/functions/elem" version="2.0" exclude-result-prefixes="string undef elem attr bool doc double xs all xsf xd">

    

    

    
<!-- ############ STYLESHEET DOCUMENTATION ##########-->

    
              <xd:doc type="stylesheet">

        
<xd:author>Daniel Jettka; daniel.jettka@uni-bielefeld.de; Project Sekimo (A2), DFG Research Group 437</xd:author>

        
<xd:copyright>GNU Lesser General Public License, see below for details</xd:copyright>

        
<xd:short><p><b>XSF2inline.xsl - Transformation of a standoff XSF instance into an inline XSF instance</b></p></xd:short>

        
<xd:detail>

            
<p><b>Version 17.02.2011, 15:41 (GMT)</b> for SGF 1.0/ XSF 1.1</p>

            
<p>This program is free software: you can redistribute it and/or modify it under the terms of the GNU GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</p>

            
<p>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 GNU Lesser General Public License for more details.</p>

            
<p>You should have received a copy of the GNU GNU Lesser General Public License along with this program (file 'lgpl-3.0.txt').  If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>

            
<p>In addition to the inline2XSF.xsl stylesheet there is a counterpart. XSF2inline.xsl creates an inline annotation on the 

                basis of an XStandoff instance. The approach covers the handling of overlapping markup insofar as these structures 

                are represented by milestone elements in the resulting inline annotation. Concerning this matter, the first task of the 

                stylesheet is to detect segments whose start and end position information constitute an overlap. These segments are 

                split up into segments representing milestones so that they can be used as an adequate basis to build an inline annotation. 

                The linear list of segments is processed recursively by taking the currently outermost segments (those who are not 

                included in other segments' spans which respectively are determined by their start and end positions in the character 

                range of the primary data). The elements from the XStandoff layers which are referenced by the outermost segments 

                are copied into the inline annotation. The segments which are embedded in the outermost segments are processed 

                recursively.
</p>

            
<p>However, copying the elements from the XStandoff layers has to be controlled by a mechanism regarding the possibility 

                of elements from different layers referencing the same segment. These elements share the same positions for starting 

                and ending tags and therefore a decision has to be made in which order they should be nested into one another. The 

                optional stylesheet parameter sort-by refers to this circumstance. Its default value is 'measure' which means that a statistical 

                analysis is performed by the stylesheet diagnosing the embedding relations of all occuring element types by frequency. An 

                expected result would be that elements representing sentence boundaries are embedded in those for paragraphs because 

                this embedding relation is more frequent than vice versa. The only case this approach could be inadequate for would be, if 

                there are elements from different layers for which no definite statistical result for embedding can be achieved. For instance, 

                there could be elements whose boundaries always share the same character positions, but which can clearly semantically 

                be assigned to a certain embedding. This case cannot be covered by the statistical method.
</p>

            
<p>In addition, the embedding can be based on the priority attribute of the level (in SGF version 1.0) or else layer element (in 

                XStandoff version 1.1, cf. the section called “The development of SGF to XStandoff”). This strategy can be accessed by 

                specifying the value 'priority' for the parameter sort-by. Low values of the priority attribute are nested deeper in the inline 

                annotation than higher ones. By this means the user can specify the embedding manually, but one has to be sure to set 

                the values of the attribute correctly to get the desired result. This method underlies the assumption that there can be a 

                semantically grounded, definite decision for the embedding. The most promising concept was a mixture of the both 

                approaches which has to be realized in future work.
</p>

            
<p>There is an additional optional stylesheet parameter return-segID which can be very helpful to retain a connection between 

                the XStandoff file and the resulting inline annotation. By default the value of this parameter is set to '1' which means that the 

                segment attribute is retained throughout the conversion process. The parameter has been added mainly for control issues.
</p>

            
<p><b>Input XML file:</b> XSF instance</p>

            
<p>

                
<b>Stylesheet parameter:</b>

                
<ul>

                    
<li>sort-by</li>

                    
<li>return-segID</li>

                
</ul>

            
</p>

            
<p><b>Execution via command line (XSLT processor Saxon9):</b> java -jar saxon9.jar [optional Saxon Parameters] -o [inline XSF output filename] [XSF input filename] XSF2inline.xsl [optional Stylesheet Parameters]</p>

            
<p>

                
<b>Known problems:</b>

                
<ul>

                    
<li>changing namespaces (different URIs with same prefixes) within input XSF</li>

                
</ul>

            
</p>

        
</xd:detail>

    
</xd:doc>


    

    

    
<xsl:output indent="yes" method="xml" encoding="UTF-8" />

    

    

    
<!--##### Keys #####-->

    
              <xd:doc><xd:short><p>Find elements by their segment reference @xsf:segment</p></xd:short></xd:doc>


    
<xsl:key name="elem-by-segRef" match="*" use="@xsf:segment" />

    

    
              <xd:doc><xd:short><p>Find &lt;xsf:segement&gt; by the value of their attribute @xml:id</p></xd:short></xd:doc>


    
<xsl:key name="seg-by-ID" match="xsf:segment" use="@xml:id" />

    

    
              <xd:doc><xd:short><p>Find elements by their element name → name()</p></xd:short></xd:doc>


    
<xsl:key name="elem-by-name" match="*" use="name()" />

    

    
              <xd:doc><xd:short><p>Find elements named "measure" by the concatenation of their attributes @parent and @child; applied to temporary tree created by <i>doc:inclusion-measures()</i></p></xd:short></xd:doc>


    
<xsl:key name="measure" match="measure" use="concat(@parent, @child)" />

    
<!--###############-->

    

    

    
<!--##### Stylesheet Parameters #####-->

    
              <xd:doc type="xs:string">

        
<xd:short><p>Determination of heuristics to nest elements with the same boundary position into one another.</p></xd:short>

        
<xd:detail><p>The default value for the nesting heuristics is 'measure' which calls a statistical analysis and nests elements into 

            one another by measuring the embedding relation. The value 'priority' evokes the nesting by the attribute @priority which is optional

            for every layer element. By this means the nesting can be determined manually.
</p></xd:detail>

    
</xd:doc>


    
<xsl:param name="sort-by" select="'measure'" as="xs:string" />

    

    
              <xd:doc type="xs:boolean"><xd:short><p>Whether or not segment information shall be maintained in the returned annotation. Default: true</p></xd:short></xd:doc>


    
<xsl:param name="return-segID" select="true()" as="xs:boolean" />

    
<!--#############################-->

    

    

    
<!--##### Global Variables #####-->

    

    
              <xd:doc><xd:short><p>Root node for referencing</p></xd:short></xd:doc>


    
<xsl:variable name="root" select="/" />

    

    
              <xd:doc><xd:short><p>Converting string value for primary data file path to URI</p></xd:short></xd:doc>


    
<xsl:variable name="primary-data-file" select="replace(//xsf:primaryDataRef/@uri, '\\', '/')" as="xs:string" />

    

    
              <xd:doc><xd:short><p>Textual content of inline annotation (primary data)</p></xd:short></xd:doc>


    
<xsl:variable name="primary-data" select="replace( if(//xsf:primaryDataRef/@uri) then unparsed-text(concat(string-join(tokenize(static-base-uri(), '/')[position() != last()], '/'), '/', $primary-data-file), ((//xsf:primaryDataRef/@encoding, 'UTF-8')[.!=''])[1]) else //xsf:primaryData/*:textualContent/text() , ' ' , '' )" as="xs:string" />

    

    
              <xd:doc><xd:short><p>String length of the primary data</p></xd:short></xd:doc>


    
<xsl:variable name="pd-length" select="string-length($primary-data)" as="xs:integer" />

    

    
              <xd:doc><xd:short><p>Segments sorted and overlapping hierarchies replaced by milestones</p></xd:short></xd:doc>


    
<xsl:variable name="new-segments">

        
<xsl:variable name="segm">

            
<xsl:copy-of select="elem:sort-segments(//xsf:segment)" />

        
</xsl:variable>

        
<!--sorting segments for elements and textual content-->

        
<xsl:message select="'*** Sorting segments.'" />

        
<xsl:copy-of select="elem:sort-segments((undef:overlaps2milestones($segm//*), elem:text-segments()))" />

        
<xsl:message select="'*** Sorting segments finished.'" />

    
</xsl:variable>

    

    
              <xd:doc><xd:short><p>Version of XSF</p></xd:short></xd:doc>


    
<xsl:variable name="xsfVersion" select="//xsf:corpusData/@xsfVersion" as="xs:string" />

    
<!--#########################-->

    

    

    
<!--####### Templates #######-->

    
              <xd:doc><xd:short><p>Creating the &lt;xsf:inline&gt; annotation by processing individual layers by <i>undef:inline-annotations()</i></p></xd:short></xd:doc>


    
<xsl:template match="/">

        

        
<!--returning information on stylesheet parameters-->

        
<xsl:copy-of select="undef:param-messages()" />

        

        
<!--analyzing bugs-->

        
<!--<xsl:result-document href="segments.xml">

            <segs><xsl:copy-of select="$new-segments"/></segs>

            </xsl:result-document>

        <xsl:result-document href="inclusion.xml">

            <segs><xsl:copy-of select="doc:inclusion-measures()"/></segs>

        </xsl:result-document>

        <xsl:result-document href="newSegments.xml">

            <segs><xsl:copy-of select="$new-segments"/></segs>

        </xsl:result-document>
-->

        

        

        
<!--inlining standoff XSF-->

        
<xsf:inline>

            
<xsl:for-each select="//namespace::*">

                
<xsl:if test="not(name(.) = '' and matches(tokenize(., '/')[last()], '[^\w]'))">

                    
<xsl:namespace name="{(name(.)[.!=''], tokenize(., '/')[last()])[1]}" select="." />

                
</xsl:if>

            
</xsl:for-each>

            
<xsl:message select="'***Embedding of annotations.'" />

            
<xsl:copy-of select="undef:inline-annotations( $new-segments//*, 0, $pd-length )" />

            
<xsl:message select="'***Embedding of annotations finished.'" />

        
</xsf:inline>

    
</xsl:template>

    

    

    
              <xd:doc>

        
<xd:short><p>Copy of elements into an inline annotation by reference to segments</p></xd:short>

        
<xd:param name="segments">Segments that reference elements from the annotation and serve as the basis for inlining the annotation.</xd:param>

        
<xd:param name="ancestor-start-pos">Start position of the ancestor of the current element.</xd:param>

        
<xd:param name="ancestor-end-pos">End position of the ancestor of the current element.</xd:param>

    
</xd:doc>


    
<xsl:function name="undef:inline-annotations">

        
<xsl:param name="segments" as="element()*" />

        
<xsl:param name="ancestor-start-pos" as="xs:integer" />

        
<xsl:param name="ancestor-end-pos" as="xs:integer" />

        
<!--finding segments without "ancestor" (by @start and @end information)-->

        
<!--<xsl:message select="'undef:inline-annotations() - $segments[1]: ',$segments[1]"/>-->

        
<!--$this-level-segments contains the currently "outermost" segments-->

        
<xsl:variable name="this-level-segments" as="element()*" select="$segments[ for $this-seg in . return (:### if the current segment is a text seg, then there shall be no $segment of type segment in current $segments which contains this text seg ###:) if($this-seg/local-name()='text') then empty($segments[local-name()='segment'][number(@start) &lt;= number($this-seg/@start) and number(@end) &gt;= number($this-seg/@end)]) else (:### if current seg is of type segment (for element), then there shall be no other $segment of type segment which contains the current one###:) if($this-seg/local-name()='segment') then empty(($segments except $this-seg)[local-name()='segment'][number(@start) &lt;= number($this-seg/@start) and number(@end) &gt;= number($this-seg/@end)]) else (:### if the current segment is a milestone seg, then there shall be no other seg in $segments which contains this milestone ###:) (:### milestones may not be included into other elements when at boundaries ###:) if($this-seg/local-name()='milestone') then empty( ($segments except $this-seg)[number(@start) &lt; number($this-seg/@start) and number(@end) &gt; number($this-seg/@end)] ) else (:###if none of the segment types could be identified, an error occurs:) error((), 'undef:inline-annotations() - $this-level-segments: no segment type identified!') ]" />

        
<!--<xsl:message select="'*** inlining annotation - $this-level-segments: ', for $seg in $this-level-segments return $seg/concat(@xml:id, '-', @start, '-', @end)"/>-->

        
<xsl:for-each select="$this-level-segments">

            
<xsl:message select="concat('*** Processing segment ', @xml:id)" />

            
<xsl:choose>

                
<!--if this is an element <text> containing information on textual content-->

                
<xsl:when test="local-name()='text'">

                    
<xsl:value-of select="substring($primary-data, (@start + 1), 1)" />

                
</xsl:when>

                
<!--if this is an element <segment>, i.e. no <text> containing information on textual content-->

                
<xsl:when test="local-name()='segment'">

                    
<xsl:variable name="elems-this-segment" select="key('elem-by-segRef', (substring-before(@xml:id, '~')[.!=''], @xml:id)[1], $root)" as="element()*" />

                    
<xsl:variable name="this-segment" select="." as="element()" />

                    
<xsl:choose>

                        
<xsl:when test="empty($elems-this-segment)">

                            
<!--no element found with this segment positions (maybe type 'ws')-->

                        
</xsl:when>

                        
<!--if there are more than one elements referred to by this segment-->

                        
<xsl:when test="$elems-this-segment[2]">

                            
<xsl:copy-of select="undef:multiple-inline-annotations(elem:sort-elems-by-nesting($elems-this-segment, $sort-by), $this-segment)" />

                        
</xsl:when>

                        
<!--if there is exactly one element referred to by this segment-->

                        
<xsl:otherwise>

                            
<xsl:for-each select="$elems-this-segment">

                                
<xsl:copy>

                                    
<xsl:copy-of select="@*, undef:get-nested-elems($this-segment)" />

                                
</xsl:copy>

                            
</xsl:for-each>

                        
</xsl:otherwise>

                    
</xsl:choose>

                
</xsl:when>

                
<!--if this is an element <milestone> containing information on overlapping elements replaced by milestones-->

                
<xsl:when test="local-name()='milestone'">

                    
<xsf:milestone xsf:unit="{string-join(key('elem-by-segRef', substring-before(@xml:id, '~'), $root)/name(), ' ')}" xsf:n="{index-of($new-segments//*[local-name()='milestone']/@xml:id, @xml:id)}">

                        
<xsl:if test="$return-segID">

                            
<xsl:attribute name="xsf:segment" select="@xml:id" />

                        
</xsl:if>

                        
<xsl:copy-of select="@xsf:charPos, @xsf:type" />

                    
</xsf:milestone>

                
</xsl:when>

                
<!--if this is none of the elements above-->

                
<xsl:otherwise>

                    
<xsl:value-of select="error((), 'undef:inline-annotations() - for-each($this-level-segments): no segment type identified!')" />

                
</xsl:otherwise>

            
</xsl:choose>

        
</xsl:for-each>

    
</xsl:function>

    

    

    
              <xd:doc>

        
<xd:short><p>Nesting elements with same segment reference by heuristics given by <i>func:sort-elems()</i></p></xd:short>

        
<xd:param name="elems-this-segment">Elements that are referring to the same segment.</xd:param>

        
<xd:param name="nested-elems">

            Elements which are descendants of the $elems-this-segment. They are simply copied into the 

            $elems-this-segment when the embedding relations are resolved.

        
</xd:param>

    
</xd:doc>


    
<xsl:function name="undef:multiple-inline-annotations">

        
<xsl:param name="elems-this-segment" as="element()*" />

        
<xsl:param name="this-segment" />

        
<xsl:variable name="new-elements-this-segment" select="subsequence($elems-this-segment, 2)" as="element()*" />

        
<xsl:for-each select="$elems-this-segment[1]">

            
<xsl:copy>

                
<xsl:copy-of select="@*" />

                
<xsl:choose>

                    
<xsl:when test="empty($new-elements-this-segment)">

                        
<xsl:copy-of select="undef:get-nested-elems($this-segment)" />

                    
</xsl:when>

                    
<xsl:otherwise>

                        
<xsl:copy-of select="undef:multiple-inline-annotations($new-elements-this-segment, $this-segment)" />

                    
</xsl:otherwise>

                
</xsl:choose>

            
</xsl:copy>

        
</xsl:for-each>

    
</xsl:function>

    

    

    
              <xd:doc>

        
<xd:short><p>Sorting of segments by their @start and @end</p></xd:short>

        
<xd:param name="segments">Segments which are being sorted.</xd:param>

    
</xd:doc>


    
<xsl:function name="elem:sort-segments" as="element()*">

        
<xsl:param name="segments" as="element()*" />

        
<xsl:for-each select="$segments">

            
<xsl:sort select="@start" data-type="number" order="ascending" />

            
<xsl:sort select="if(local-name()='milestone') then @x else (if(@start = @end) then @end +1 else @end)" data-type="number" order="{'descending'}" />

            
<xsl:copy-of select="." />

        
</xsl:for-each>

    
</xsl:function>

    

    

    
<xsl:function name="undef:get-nested-elems">

        
<xsl:param name="segment" as="element()?" />

        
<xsl:if test="$segment/local-name() = 'segment'">

            
<xsl:copy-of select="undef:inline-annotations( key('seg-by-ID', $segment/attr:get-ID-att(.), $new-segments)/following-sibling::*[ if(local-name()='milestone') then ( number(@start) &gt; number($segment/@start) and number(@end) &lt; number($segment/@end) ) else ( number(@start) &gt;= number($segment/@start) and number(@end) &lt;= number($segment/@end) ) ], $segment/@start, $segment/@end )" />

        
</xsl:if>

    
</xsl:function>

    

    

    
              <xd:doc>

        
<xd:short><p>

            Sorting elements which refer to the same segment

            either by priority of their xsf:level ($sort-type='priority') or 

            by measurement of their inclusion relations ($sort-type='measure').

        
</p></xd:short>

        
<xd:param name="elems-same-seg">Elements referring the same segment.</xd:param>

        
<xd:param name="sort-type">

            There are two possible sort types: 'priority' and 'measure'. The value 'priority' evokes a sorting by using the @priority of the corresponding &lt;xsf:level&gt;. 

            The value 'measure' calls a statistical analysis of the overall embedding relations of the specific elements in $elems-same-seg.

        
</xd:param>

    
</xd:doc>


    
<xsl:function name="elem:sort-elems-by-nesting" as="element()*">

        
<xsl:param name="elems-same-seg" as="element()*" />

        
<xsl:param name="sort-type" as="xs:string" />

        
<xsl:for-each select="$elems-same-seg">

            
<xsl:sort select="if($sort-type='priority') then (ancestor::xsf:level/@priority) else if($sort-type='measure') then double:multiply-int-sequence(for $child in ($elems-same-seg except .) return xs:double(key('measure', concat(name(), $child/name()), doc:inclusion-measures())/@value), 1) else error((), 'missing $sort-type at elem:sort-elems()')" data-type="number" order="descending" />

            
<xsl:copy-of select="." />

        
</xsl:for-each>

    
</xsl:function>

    

    

    
              <xd:doc>

        
<xd:short><p>Multiplication of all numbers from a sequence.</p></xd:short>

        
<xd:param name="sequence">Sequence of numbers which are multiplicated recursively.</xd:param>

        
<xd:param name="temp-result">Storation of the temporary result while numbers exist that were not already used for multiplication.</xd:param>

    
</xd:doc>


    
<xsl:function name="double:multiply-int-sequence" as="xs:double">

        
<xsl:param name="sequence" as="xs:double*" />

        
<xsl:param name="temp-result" as="xs:double" />

        
<xsl:copy-of select="if(count($sequence) = 1) then ($sequence[1] * $temp-result) else double:multiply-int-sequence(subsequence($sequence, 2), $sequence[1] * $temp-result)" />

    
</xsl:function>

    

    

    
              <xd:doc>

        
<xd:short><p>Replaces segments including overlapping position information with milestones.</p></xd:short>

        
<xd:param name="segments">Segments on the basis of which overlaps are discovered and resolved by milestones.</xd:param>

    
</xd:doc>


    
<xsl:function name="undef:overlaps2milestones">

        
<xsl:param name="segments" as="element(xsf:segment)*" />

        
<xsl:message select="'*** Checking for overlaps.'" />

        
<xsl:for-each select="$segments">

            
<xsl:choose>

                
<xsl:when test="following-sibling::xsf:segment[(number(@start) &gt;= number(current()/@start)) and (number(@start) &lt; number(current()/@end)) and (number(@end) &gt; number(current()/@end))]">

                    
<xsl:message select="concat('***ATTENTION: Overlapping hierarchies. Inserting milestones for ', @xml:id, '(', @start, ',', @end, ')', ' and ', string-join(for $seg in following-sibling::xsf:segment[(number(@start) &gt;= number(current()/@start)) and (number(@start) &lt; number(current()/@end)) and (number(@end) &gt; number(current()/@end))] return concat($seg/attr:get-ID-att(.), '(', $seg/@start, ',', $seg/@end, ')'), ' '))" />

                    
<milestone xml:id="{concat(@xml:id, '~1')}" start="{@start}" end="{@start}" x="{$pd-length + 2}" xsf:charPos="{@start}" xsf:type="start" />

                    
<milestone xml:id="{concat(@xml:id, '~2')}" start="{@end}" end="{@end}" x="{$pd-length + 2}" xsf:charPos="{@end}" xsf:type="end" />

                
</xsl:when>

                
<xsl:otherwise>

                    
<xsl:copy-of select="." />

                
</xsl:otherwise>

            
</xsl:choose>

        
</xsl:for-each>

        
<xsl:message select="'*** Checking for overlaps finished.'" />

    
</xsl:function>

    

    

    
              <xd:doc>

        
<xd:short><p>Getting the corresponding ID-attribute (intended for &lt;xsf:segment&gt; and &lt;milestone&gt;).</p></xd:short>

        
<xd:param name="node">Element whose ID is to be returned.</xd:param>

    
</xd:doc>


    
<xsl:function name="attr:get-ID-att" as="attribute()?">

        
<xsl:param name="node" as="element()?" />

        
<xsl:copy-of select="$node/(@xml:id, @segID)[1]" />

    
</xsl:function>

    

    

    
              <xd:doc><xd:short><p>Calculation of inclusion relations of elements.</p></xd:short></xd:doc>


    
<xsl:function name="doc:inclusion-measures" as="document-node()">

        
<xsl:document>

            
<xsl:for-each select="distinct-values($root//xsf:layer/descendant::*/name())">

                
<xsl:variable name="parent-name" select="." as="xs:string" />

                
<xsl:for-each select="distinct-values($root//xsf:layer/descendant::*/name())">

                    
<xsl:variable name="child-name" select="." as="xs:string" />

                    
<xsl:for-each select="$root">

                        
<measure parent="{$parent-name}" child="{$child-name}">

                            
<xsl:variable name="parent-elems" select="key('elem-by-name', $parent-name)" as="element()*" />

                            
<xsl:attribute name="value" select="if($child-name = $parent-name) then 1 else count( $parent-elems[for $parent-seg in key('seg-by-ID', @xsf:segment, $root) return exists(key('seg-by-ID', key('elem-by-name', $child-name)/@xsf:segment)[(number(@start) &gt;= number($parent-seg/@start)) and (number(@end) &lt;= number($parent-seg/@end))])] ) div count($parent-elems)" />

                        
</measure>

                    
</xsl:for-each>

                
</xsl:for-each>

            
</xsl:for-each>

        
</xsl:document>

    
</xsl:function>

    

    

    
              <xd:doc><xd:short><p>Building segments for the textual content of the input XML file.</p></xd:short></xd:doc>


    
<xsl:function name="elem:text-segments" as="element(text)*">

        
<xsl:for-each select="0 to ($pd-length - 1)">

            
<text xml:id="{concat('text', .)}" start="{.}" end="{. + 1}" />

        
</xsl:for-each>

    
</xsl:function>

    

    

    
              <xd:doc><xd:short><p>Returning information on supplied stylesheet parameters.</p></xd:short></xd:doc>


    
<xsl:function name="undef:param-messages">

        
<xsl:message select="'--------------------'" />

        
<xsl:message select="' Provided stylesheet parameters:'" />

        
<xsl:message select="concat(' sort-by=''', $sort-by, '''')" />

        
<xsl:message select="concat(' return-segID=', $return-segID)" />

        
<xsl:message select="'--------------------'" />

    
</xsl:function>

    

</xsl:stylesheet>













































































v