one step further and I just want to save it
Change-Id: I781063c13218832dec52770005280fba01418cd2
diff --git a/nkjp2korap.xsl b/nkjp2korap.xsl
index 77e070a..03f66f3 100644
--- a/nkjp2korap.xsl
+++ b/nkjp2korap.xsl
@@ -52,7 +52,11 @@
   
 <!-- these two 'flags' are meant to increase the readability of the code
      they are used for the output of the calc_offsets() function, where the 
-     returned value is a sequence, (start, end) -->
+     returned value is a sequence, (start, end) 
+  
+  remove together with the function!
+  
+  --> 
   <xsl:variable name="OFFSET_START" as="xs:integer" static="yes" select="1"/>
   <xsl:variable name="OFFSET_END" as="xs:integer" static="yes" select="2"/>
 
@@ -78,7 +82,11 @@
     <xsl:param name="node" as="element()"/>
   <xsl:choose>
     <xsl:when test="local-name($node) eq 'seg'">
-        <xsl:sequence select="not(exists($node/@nkjp:nps))"/>
+        <xsl:sequence
+          select="not(exists($node/@nkjp:nps)) and not($node[count(preceding-sibling::tei:seg) eq 0]/ancestor::tei:s[count(preceding-sibling::tei:s) eq 0]/ancestor::tei:p[count(preceding-sibling::tei:p) eq 0])"
+        />
+      <!--and not($node/ancestor::tei:s[count(preceding-sibling::tei:s) eq 0]/ancestor::tei:p[count(preceding-sibling::tei:p) eq 0])-->
+    
     </xsl:when>
     <xsl:when test="local-name($node) eq 's'">
         <xsl:message select="'s - prec s:  ' || $node/preceding-sibling::tei:s"/>
@@ -96,222 +104,9 @@
   </xsl:choose>
 </xsl:function>
 
-  <xsl:function name="f:calc_offsets" as="xs:integer+">
-    <xsl:param name="node" as="element()"/>
-    <xsl:param name="skip_start" as="xs:boolean" />
-    
-    <xsl:variable name="start" as="xs:integer">
-      <xsl:choose>
+  
 
-        <xsl:when test="$skip_start or $node/self::tei:text or $node/self::tei:body">
-          <xsl:sequence select="0"/>
-        </xsl:when>
-        
-            <!--        handle p -->
-        
-        <xsl:when test="$node/self::tei:p">
-          <xsl:variable name="my_pos" as="xs:integer" select="count($node/preceding-sibling::tei:p) + 1"/>
-          <xsl:variable name="preceding" as="node()*"
-            select="$node/ancestor::tei:body/tei:p[position() lt $my_pos]"/>
-
-          <xsl:choose>
-            <xsl:when test="count($preceding) eq 0">
-              <xsl:sequence select="0"/>
-            </xsl:when>
-            <xsl:otherwise>
-              <xsl:sequence select="sum(f:calc_offsets($preceding[last()],true())[$OFFSET_END],1)"/>
-              
-<!--  BUG danger: I am not sure if a "1" should rather be added after each p; let me try to handle that in the return value of the $length variable,
-              and make it sensitive to the skip_start parameter 
-              
-              I will then have to remove the ",1" from here!
-              
-              -->
-
-<!--              <xsl:variable name="last_corresps"
-                select="$preceding/descendant::tei:s[last()]/(descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'])[last()]/@corresp"
-                as="attribute(corresp)+"/>
-              <xsl:variable name="end_offsets" as="xs:integer+">
-                <xsl:for-each select="$last_corresps">
-                  <xsl:variable name="numbers"
-                    select="substring-after(substring-before(., ')'), ',')"/>
-                  <xsl:sequence
-                    select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
-                  />
-                </xsl:for-each>
-              </xsl:variable>
-              <xsl:sequence select="sum($end_offsets, 1)"/>
-              
-              this is a non-recursive variant that may turn out to be much less cpu-intensive, not sure
-              - but if it's plugged in, it will have to be adjusted to the current form of the recursive variant,
-                because it hasn't been maintained since it got commented out
-              -->
-            </xsl:otherwise>
-          </xsl:choose>
-        </xsl:when>
-
-        <!--        handle s -->
-
-<!-- the value for s gets counted since the start of the current p 
-        - so we look at the preceding s's
-                      + the preceding p's
-        -->
-        <xsl:when test="$node/self::tei:s">
-          <!--<xsl:variable name="last_corresp"
-            select="$node/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
-            as="attribute(corresp)"/>
-          <xsl:variable name="numbers"
-            select="substring-after(substring-before($last_corresp, ')'), ',')"/>
-          <xsl:sequence
-            select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
-          />
-          -->
-          
-          <xsl:variable name="internal_start" as="xs:integer">
-            <xsl:variable name="my_pos" as="xs:integer" select="count($node/preceding-sibling::tei:s) + 1"/>
-            <xsl:variable name="preceding" as="node()*"
-              select="$node/ancestor::tei:p[1]/tei:s[position() lt $my_pos]"/>
-
-            <xsl:choose>
-              <xsl:when test="count($preceding) eq 0">
-                <xsl:sequence select="0"/>
-              </xsl:when>
-              <xsl:otherwise>
-                <xsl:sequence select="f:calc_offsets($preceding[last()],true())[$OFFSET_END]"/>
-                <!--<xsl:sequence select="sum(f:calc_offsets($preceding[last()],true())[$OFFSET_END],1)"/>-->
-                                                    <!--   again, CAREFUL ABOUT THE +1, it might need to vanish         -->
-              </xsl:otherwise>
-            </xsl:choose>
-          </xsl:variable>
-          
-          <xsl:variable name="external_start" as="xs:integer" select="f:calc_offsets($node/ancestor::tei:p[1],false())[$OFFSET_START]"/>
-          
-          <xsl:sequence select="$internal_start + $external_start"/>
-        </xsl:when>
- 
-        <!--        handle seg -->        
-
-        <xsl:when test="$node/self::tei:seg">
-          <!--   for segs, the s elements are irrelevant, and the local offset is immediately available on the @corresp       -->
-
-          <xsl:variable name="numbers"
-            select="substring-after(substring-before($node/@corresp, ')'), ',')"/>
-
-          <xsl:variable name="internal_start" select="xs:integer(substring-before($numbers, ','))"
-            as="xs:integer"/>
-          <xsl:variable name="external_start" as="xs:integer"
-            select="f:calc_offsets($node/ancestor::tei:p[1], false())[$OFFSET_START]"/>
-
-          <xsl:if test="$node/self::tei:seg and count($node/@nkjp:rejected)">
-
-            <xsl:message select="'numbers: ' || $numbers"/>
-          </xsl:if>
-          <xsl:sequence select="$internal_start + $external_start"/>
-        </xsl:when>
-      </xsl:choose>
-    </xsl:variable>
-    
-    <xsl:variable name="length" as="xs:integer">
-    <xsl:choose>
-
-      <xsl:when test="$node/self::tei:text or $node/self::tei:body">
-        <xsl:variable name="last_corresps"
-          select="$node/descendant::tei:p/descendant::tei:s[last()]/(descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'])[last()]/@corresp"
-          as="attribute(corresp)+"/>
-
-        <xsl:variable name="end_offsets" as="xs:integer+">
-          <xsl:for-each select="$last_corresps">
-            <xsl:variable name="numbers" select="substring-after(substring-before(., ')'), ',')"/>
-            <xsl:sequence
-              select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
-            />
-          </xsl:for-each>
-        </xsl:variable>
-
-        <xsl:sequence select="sum($end_offsets)"/>
-        
-      </xsl:when>
-      <xsl:when test="$node/self::tei:p">
-        <xsl:variable name="last_corresps"
-          select="$node/descendant::tei:s[last()]/(descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'])[last()]/@corresp"
-          as="attribute(corresp)+"/>
-        <xsl:variable name="end_offsets" as="xs:integer+">
-          <xsl:for-each select="$last_corresps">
-            <xsl:variable name="numbers" select="substring-after(substring-before(., ')'), ',')"/>
-            <xsl:sequence
-              select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
-            />
-          </xsl:for-each>
-        </xsl:variable>
-        <xsl:sequence select="sum($end_offsets)"/>
-      </xsl:when>
-      
-      
-      
-      
-      <xsl:when test="$node/self::tei:s">
-        <xsl:variable name="last_corresp"
-          select="$node/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
-          as="attribute(corresp)"/>
-        <xsl:variable name="numbers"
-          select="substring-after(substring-before($last_corresp, ')'), ',')"/>
-        <xsl:sequence
-          select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
-        />
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:variable name="numbers"
-          select="substring-after(substring-before($node/@corresp, ')'), ',')"/>
-        <xsl:if test="$node/self::tei:seg and count($node/@nkjp:rejected)">
-          <!--     REMOVE THIS     -->
-          <xsl:message select="'rejected: ' || $numbers"/>
-        </xsl:if>
-        <xsl:sequence
-          select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
-        />
-      </xsl:otherwise>
-    </xsl:choose>
-    </xsl:variable>
-
-    <xsl:message select="local-name($node) || '[' || count($node/preceding-sibling::*[local-name() eq local-name($node)])+1 || '] length: ' || $length || '    skip_start: ' || $skip_start"/>
-    
-    <xsl:sequence select="$start, $start + $length -1 + xs:integer($skip_start)"/>
-  </xsl:function>
-
-  <xsl:function name="f:calc_content_length" as="xs:integer">
-    <xsl:param name="node" as="node()"/>
-    <xsl:choose>
-      <xsl:when test="$node/self::tei:text or $node/self::tei:body">
-        <xsl:variable name="last_corresp"
-          select="$node/descendant::tei:p[last()]/descendant::tei:s[last()]/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
-          as="attribute(corresp)"/>
-        <xsl:variable name="numbers" select="substring-after(substring-before($last_corresp,')'),',')"/>
-        <xsl:sequence select="xs:integer(substring-before($numbers,',')) + xs:integer(substring-after($numbers,','))"/>
-      </xsl:when>
-      <xsl:when test="$node/self::tei:p">
-        <xsl:variable name="last_corresp"
-          select="$node/descendant::tei:s[last()]/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
-          as="attribute(corresp)"/>
-        <xsl:variable name="numbers" select="substring-after(substring-before($last_corresp,')'),',')"/>
-        <xsl:sequence select="xs:integer(substring-before($numbers,',')) + xs:integer(substring-after($numbers,','))"/>
-      </xsl:when>
-      <xsl:when test="$node/self::tei:s">
-        <xsl:variable name="last_corresp"
-          select="$node/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
-          as="attribute(corresp)"/>
-        <xsl:variable name="numbers" select="substring-after(substring-before($last_corresp,')'),',')"/>
-        <xsl:sequence select="xs:integer(substring-before($numbers,',')) + xs:integer(substring-after($numbers,','))"/>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:variable name="numbers" select="substring-after(substring-before($node/@corresp,')'),',')"/>
-        <xsl:if test="$node/self::tei:seg and count($node/@nkjp:rejected)">
-                                                                                                                      <!--     REMOVE THIS     -->
-          <xsl:message select="$numbers"/>
-        </xsl:if>
-        <xsl:sequence select="xs:integer(substring-before($numbers,',')) + xs:integer(substring-after($numbers,','))"/>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:function>
+  
 
 
 <!--             UTILITY TEMPLATES              -->
@@ -397,15 +192,14 @@
       <xsl:with-param name="target" select="$targetBaseDir ||  '/data.xml'" as="xs:string"/>
     </xsl:call-template>
 
-<!--    <xsl:call-template name="create_struct">
-      <xsl:with-param name="text.xml" select="$text.xml" as="document-node()"/>
+    <xsl:call-template name="create_struct">
       <xsl:with-param name="compoundID" select="$compoundID" as="xs:string"/>
       <xsl:with-param name="ann_segmentation.xml" select="$ann_segmentation.xml"
         as="document-node()"/>
       <xsl:with-param name="target" select="$targetBaseDir ||  '/struct/structure.xml'" as="xs:string"
       />
     </xsl:call-template>
--->
+
 <!--    <xsl:call-template name="create_morpho">
       <xsl:with-param name="text.xml" select="$text.xml" as="document-node()"/>
       <xsl:with-param name="compoundID" select="$compoundID" as="xs:string"/>
@@ -443,12 +237,8 @@
         </xsl:element>
 
         <xsl:element name="text" namespace="{$KorAP_namespace}">
-          <!--<xsl:value-of select="$text.xml//*[local-name() = 'ab']"/>    preserves more whitespace -->
-          <!--<xsl:apply-templates select="$text.xml//*[local-name() = 'ab']"/>-->
           <xsl:variable name="content" as="xs:string+">
-            <xsl:variable name="segs" select="$ann_segmentation.xml/tei:teiCorpus/tei:TEI/tei:text/tei:body/tei:p/tei:s//tei:seg[count(@nkjp:rejected) eq 0]" as="element()+"/>
-            <xsl:sequence select="head($segs)/tei:w"/>
-            <xsl:for-each select="tail($segs)">
+            <xsl:for-each select="$ann_segmentation.xml/tei:teiCorpus/tei:TEI/tei:text/tei:body/tei:p/tei:s//tei:seg[count(@nkjp:rejected) eq 0]">
               <xsl:sequence select="
                   if (f:is_preceded_by_ws(.)) then
                     ' '
@@ -465,11 +255,29 @@
   <!--   **************************        struct      *******************                -->
 
   <xsl:template name="create_struct">
-    <xsl:param name="text.xml" as="document-node()"/>
     <xsl:param name="compoundID" as="xs:string"/>
     <xsl:param name="ann_segmentation.xml" as="document-node()"/>
     <xsl:param name="target" as="xs:string"/>
-
+    
+    
+<!-- map the entire document, so that the processing only takes place once, and for fast lookups   -->
+    <xsl:variable name="map_w" as="map(xs:untypedAtomic,item()+)">
+      <xsl:variable name="segs" select="$ann_segmentation.xml/tei:teiCorpus/tei:TEI/tei:text/tei:body/tei:p/tei:s//tei:seg[count(@nkjp:rejected) eq 0]" as="element()+"/>
+      <xsl:map>
+        <xsl:for-each-group select="$segs" group-by="ancestor::tei:p[1]/@xml:id">
+          <xsl:variable name="current-p" select="current-grouping-key()"/>
+          <xsl:for-each-group select="current-group()" group-by="ancestor::tei:s[1]/@xml:id">
+            <xsl:variable name="current-s" select="current-grouping-key()"/>
+            <xsl:for-each select="current-group()">
+              <xsl:map-entry key="@xml:id" select="$current-p, $current-s, position(), f:is_preceded_by_ws(.), normalize-space(tei:w)"/>  
+            </xsl:for-each>
+          </xsl:for-each-group>
+        </xsl:for-each-group>
+      </xsl:map>
+    </xsl:variable>
+    
+    <xsl:message select="'size: ' || map:size($map_w)"/>
+    
     <xsl:result-document encoding="UTF-8" method="xml" indent="yes"
       xpath-default-namespace="http://ids-mannheim.de/ns/KorAP" href="{$target}">
       <xsl:processing-instruction name="xml-model">href=&quot;span.rng&quot; type=&quot;application/xml&quot; schematypens=&quot;http://relaxng.org/ns/structure/1.0&quot;</xsl:processing-instruction>
@@ -478,7 +286,7 @@
         <xsl:attribute name="version" select="$KorAP-XML_version"/>
 
         <xsl:element name="spanList" namespace="{$KorAP_namespace}">
-          <xsl:apply-templates select="$ann_segmentation.xml//tei:text" mode="struct"/>          
+          <!--<xsl:apply-templates select="$ann_segmentation.xml//tei:text" mode="struct"/>      -->    
         </xsl:element>
       </xsl:element>
     </xsl:result-document>
@@ -488,6 +296,7 @@
     <xsl:param name="ini" as="xs:integer" required="no" select="0"/>
     <xsl:param name="fin" as="xs:integer" required="no" select="999999999"/>
     <xsl:param name="index" as="xs:integer" required="no" select="1"/>
+
     <!-- It's so spread out because I want to make sure to be able to look up the individual 
       constituent values, should anything go wrong; optimization will come when it's worked against a larger dataset   -->
     <xsl:variable name="my_name" select="local-name()" as="xs:string"/>
@@ -502,7 +311,7 @@
               <xsl:sequence select="
                   sum(for $p in $preceding
                   return
-                    count($p/descendant::*))"/>
+                    count($p/descendant::*))"/>       <!--mind @nkjp:rejected -->
             </xsl:when>
             <xsl:otherwise>
               <xsl:sequence select="0"/>
@@ -546,6 +355,7 @@
         </xsl:when>
       </xsl:choose>
     </xsl:variable>
+    
     <xsl:variable name="end" as="xs:integer" select="f:calc_content_length(.)">
     </xsl:variable>
     
@@ -956,4 +766,222 @@
     <xsl:call-template name="xsl:initial-template"/>
   </xsl:template>-->
 
+  <xsl:function name="f:calc_content_length" as="xs:integer">
+    <xsl:param name="node" as="node()"/>
+    <xsl:choose>
+      <xsl:when test="$node/self::tei:text or $node/self::tei:body">
+        <xsl:variable name="last_corresp"
+          select="$node/descendant::tei:p[last()]/descendant::tei:s[last()]/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
+          as="attribute(corresp)"/>
+        <xsl:variable name="numbers" select="substring-after(substring-before($last_corresp,')'),',')"/>
+        <xsl:sequence select="xs:integer(substring-before($numbers,',')) + xs:integer(substring-after($numbers,','))"/>
+      </xsl:when>
+      <xsl:when test="$node/self::tei:p">
+        <xsl:variable name="last_corresp"
+          select="$node/descendant::tei:s[last()]/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
+          as="attribute(corresp)"/>
+        <xsl:variable name="numbers" select="substring-after(substring-before($last_corresp,')'),',')"/>
+        <xsl:sequence select="xs:integer(substring-before($numbers,',')) + xs:integer(substring-after($numbers,','))"/>
+      </xsl:when>
+      <xsl:when test="$node/self::tei:s">
+        <xsl:variable name="last_corresp"
+          select="$node/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
+          as="attribute(corresp)"/>
+        <xsl:variable name="numbers" select="substring-after(substring-before($last_corresp,')'),',')"/>
+        <xsl:sequence select="xs:integer(substring-before($numbers,',')) + xs:integer(substring-after($numbers,','))"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:variable name="numbers" select="substring-after(substring-before($node/@corresp,')'),',')"/>
+        <xsl:if test="$node/self::tei:seg and count($node/@nkjp:rejected)">
+          <!--     REMOVE THIS     -->
+          <xsl:message select="$numbers"/>
+        </xsl:if>
+        <xsl:sequence select="xs:integer(substring-before($numbers,',')) + xs:integer(substring-after($numbers,','))"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:function>
+
+  <xsl:function name="f:calc_offsets" as="xs:integer+">
+    <xsl:param name="node" as="element()"/>
+    <xsl:param name="skip_start" as="xs:boolean" />
+    
+    <xsl:variable name="start" as="xs:integer">
+      <xsl:choose>
+        
+        <xsl:when test="$skip_start or $node/self::tei:text or $node/self::tei:body">
+          <xsl:sequence select="0"/>
+        </xsl:when>
+        
+        <!--        handle p -->
+        
+        <xsl:when test="$node/self::tei:p">
+          <xsl:variable name="my_pos" as="xs:integer" select="count($node/preceding-sibling::tei:p) + 1"/>
+          <xsl:variable name="preceding" as="node()*"
+            select="$node/ancestor::tei:body/tei:p[position() lt $my_pos]"/>
+          
+          <xsl:choose>
+            <xsl:when test="count($preceding) eq 0">
+              <xsl:sequence select="0"/>
+            </xsl:when>
+            <xsl:otherwise>
+              <xsl:sequence select="sum(f:calc_offsets($preceding[last()],true())[$OFFSET_END],1)"/>
+              
+              <!--  BUG danger: I am not sure if a "1" should rather be added after each p; let me try to handle that in the return value of the $length variable,
+              and make it sensitive to the skip_start parameter 
+              
+              I will then have to remove the ",1" from here!
+              
+              -->
+              
+              <!--              <xsl:variable name="last_corresps"
+                select="$preceding/descendant::tei:s[last()]/(descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'])[last()]/@corresp"
+                as="attribute(corresp)+"/>
+              <xsl:variable name="end_offsets" as="xs:integer+">
+                <xsl:for-each select="$last_corresps">
+                  <xsl:variable name="numbers"
+                    select="substring-after(substring-before(., ')'), ',')"/>
+                  <xsl:sequence
+                    select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
+                  />
+                </xsl:for-each>
+              </xsl:variable>
+              <xsl:sequence select="sum($end_offsets, 1)"/>
+              
+              this is a non-recursive variant that may turn out to be much less cpu-intensive, not sure
+              - but if it's plugged in, it will have to be adjusted to the current form of the recursive variant,
+                because it hasn't been maintained since it got commented out
+              -->
+            </xsl:otherwise>
+          </xsl:choose>
+        </xsl:when>
+        
+        <!--        handle s -->
+        
+        <!-- the value for s gets counted since the start of the current p 
+        - so we look at the preceding s's
+                      + the preceding p's
+        -->
+        <xsl:when test="$node/self::tei:s">
+          <!--<xsl:variable name="last_corresp"
+            select="$node/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
+            as="attribute(corresp)"/>
+          <xsl:variable name="numbers"
+            select="substring-after(substring-before($last_corresp, ')'), ',')"/>
+          <xsl:sequence
+            select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
+          />
+          -->
+          
+          <xsl:variable name="internal_start" as="xs:integer">
+            <xsl:variable name="my_pos" as="xs:integer" select="count($node/preceding-sibling::tei:s) + 1"/>
+            <xsl:variable name="preceding" as="node()*"
+              select="$node/ancestor::tei:p[1]/tei:s[position() lt $my_pos]"/>
+            
+            <xsl:choose>
+              <xsl:when test="count($preceding) eq 0">
+                <xsl:sequence select="0"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:sequence select="f:calc_offsets($preceding[last()],true())[$OFFSET_END]"/>
+                <!--<xsl:sequence select="sum(f:calc_offsets($preceding[last()],true())[$OFFSET_END],1)"/>-->
+                <!--   again, CAREFUL ABOUT THE +1, it might need to vanish         -->
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:variable>
+          
+          <xsl:variable name="external_start" as="xs:integer" select="f:calc_offsets($node/ancestor::tei:p[1],false())[$OFFSET_START]"/>
+          
+          <xsl:sequence select="$internal_start + $external_start"/>
+        </xsl:when>
+        
+        <!--        handle seg -->        
+        
+        <xsl:when test="$node/self::tei:seg">
+          <!--   for segs, the s elements are irrelevant, and the local offset is immediately available on the @corresp       -->
+          
+          <xsl:variable name="numbers"
+            select="substring-after(substring-before($node/@corresp, ')'), ',')"/>
+          
+          <xsl:variable name="internal_start" select="xs:integer(substring-before($numbers, ','))"
+            as="xs:integer"/>
+          <xsl:variable name="external_start" as="xs:integer"
+            select="f:calc_offsets($node/ancestor::tei:p[1], false())[$OFFSET_START]"/>
+          
+          <xsl:if test="$node/self::tei:seg and count($node/@nkjp:rejected)">
+            
+            <xsl:message select="'numbers: ' || $numbers"/>
+          </xsl:if>
+          <xsl:sequence select="$internal_start + $external_start"/>
+        </xsl:when>
+      </xsl:choose>
+    </xsl:variable>
+    
+    <xsl:variable name="length" as="xs:integer">
+      <xsl:choose>
+        
+        <xsl:when test="$node/self::tei:text or $node/self::tei:body">
+          <xsl:variable name="last_corresps"
+            select="$node/descendant::tei:p/descendant::tei:s[last()]/(descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'])[last()]/@corresp"
+            as="attribute(corresp)+"/>
+          
+          <xsl:variable name="end_offsets" as="xs:integer+">
+            <xsl:for-each select="$last_corresps">
+              <xsl:variable name="numbers" select="substring-after(substring-before(., ')'), ',')"/>
+              <xsl:sequence
+                select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
+              />
+            </xsl:for-each>
+          </xsl:variable>
+          
+          <xsl:sequence select="sum($end_offsets)"/>
+          
+        </xsl:when>
+        <xsl:when test="$node/self::tei:p">
+          <xsl:variable name="last_corresps"
+            select="$node/descendant::tei:s[last()]/(descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'])[last()]/@corresp"
+            as="attribute(corresp)+"/>
+          <xsl:variable name="end_offsets" as="xs:integer+">
+            <xsl:for-each select="$last_corresps">
+              <xsl:variable name="numbers" select="substring-after(substring-before(., ')'), ',')"/>
+              <xsl:sequence
+                select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
+              />
+            </xsl:for-each>
+          </xsl:variable>
+          <xsl:sequence select="sum($end_offsets)"/>
+        </xsl:when>
+        
+        
+        
+        
+        <xsl:when test="$node/self::tei:s">
+          <xsl:variable name="last_corresp"
+            select="$node/descendant::tei:seg[count(@nkjp:rejected) eq 0 or @nkjp:rejected ne 'true'][last()]/attribute::corresp"
+            as="attribute(corresp)"/>
+          <xsl:variable name="numbers"
+            select="substring-after(substring-before($last_corresp, ')'), ',')"/>
+          <xsl:sequence
+            select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
+          />
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:variable name="numbers"
+            select="substring-after(substring-before($node/@corresp, ')'), ',')"/>
+          <xsl:if test="$node/self::tei:seg and count($node/@nkjp:rejected)">
+            <!--     REMOVE THIS     -->
+            <xsl:message select="'rejected: ' || $numbers"/>
+          </xsl:if>
+          <xsl:sequence
+            select="xs:integer(substring-before($numbers, ',')) + xs:integer(substring-after($numbers, ','))"
+          />
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    
+    <xsl:message select="local-name($node) || '[' || count($node/preceding-sibling::*[local-name() eq local-name($node)])+1 || '] length: ' || $length || '    skip_start: ' || $skip_start"/>
+    
+    <xsl:sequence select="$start, $start + $length -1 + xs:integer($skip_start)"/>
+  </xsl:function>
+
+
 </xsl:stylesheet>