5.1 Outline

<..tabular hor lines..>
 <script element="tbody" >
    <set name="dirt" >
       <.open xslt script.>
       <.tbody dirt templates.>
       <.close xslt script.>
    </set>
    <set name="tbody" >
       <.open xslt script.>
       <.tbody templates.>
       <.close xslt script.>
    </set>
    <xslt name="." xml="." xsl="tbody" />
    <xslt name="." xml="." xsl="dirt" />
    <dom name="." xml="." method="cline" class="tex4ht.DbUtilities" />
 </script>
-_-_-

<..static void cline(dom)..>
 public static void cline(Node dom) {
    Node row, entry, para, nextrow;
    Node node = dom.getFirstChild();
    if( node != null ){
       <.remove empty trailing rows.>
       <.merge cline rows into non-line rows.>
    }
 }
-_-_-

<..remove empty trailing rows..>
 row = node.getLastChild();
 while(     (row != null)
         && ( (entry = row.getLastChild()) != null)
         && ( (para = entry.getFirstChild()) != null)
         && ( para.getNextSibling() == null)
         && ( para.getFirstChild() == null)
 ){
   node.removeChild(row);
   row = node.getLastChild();
 }
-_-_-

The merging of rows deal with cases similar to the following one.

<row>  
  <entry align="left">  
    <para> 1</para>  
  </entry>  
  <entry align="left" nameend="3" namest="2">  
    <para>2 to 3</para>  
  </entry>  
</row>  
<row role="cline">  
  <entry rowsep="0"/>  
  <entry rowsep="1"/>  
  <entry rowsep="1"/>  
</row>

<..merge cline rows into non-line rows..>
 row = node.getFirstChild();
 while( row != null ){
   if(    (row.getNodeType() == Node.ELEMENT_NODE)
       && ((Element) row).getAttribute("rowsep").equals("")
       && !((Element) row).getAttribute("role"  ).equals("cline")
       && ((nextrow = row.getNextSibling()) != null)
       && (nextrow.getNodeType() == Node.ELEMENT_NODE)
       && ((Element) nextrow).getAttribute("role"  ).equals("cline")
   ){
     <.boolean compatible = ....>
     if( compatible ){
        <.row += nextrow.>
        node.removeChild(nextrow);
     }
   }
   row = row.getNextSibling();
 }
-_-_-

<..boolean compatible = .....>
 boolean compatible = true;
 Node entry1 = row.getFirstChild();
 Node entry2 = nextrow.getFirstChild();
 while( true ){
   if( (entry1 == null) || (entry2 == null) ){ break; }
   int range;
   try{
     range =
           Integer.parseInt( ((Element) entry1).getAttribute("nameend") )
           -
           Integer.parseInt( ((Element) entry1).getAttribute("namest") )
           +
           1;
   } catch( Exception e){ range = 1;}
   if( range > 1 ){
     String rowsep = ((Element) entry2).getAttribute("rowsep");
     while( --range > 0 ){
        entry2 = entry2.getNextSibling();
        if( entry2 == null ){
           compatible = false;
           break;
        }
        String value = ((Element) entry2).getAttribute("rowsep");
        if( !value.equals( rowsep ) ){
           compatible = false;
           break;
        }
     }
   }
   if( !compatible ){ break; }
   entry1 = entry1.getNextSibling();
   entry2 = entry2.getNextSibling();
 }
-_-_-

<..row += nextrow..>
 entry1 = row.getFirstChild();
 entry2 = nextrow.getFirstChild();
 while( true ){
   if( (entry1 == null) || (entry2 == null) ){ break; }
   int range;
   try{
     range =
           Integer.parseInt( ((Element) entry1).getAttribute("nameend") )
           -
           Integer.parseInt( ((Element) entry1).getAttribute("namest") )
           +
           1;
   } catch( Exception e){ range = 1;}
   ((Element) entry1).setAttribute(
                        "rowsep",
                        ((Element) entry2).getAttribute("rowsep") );
   while( --range > 0 ){
      entry2 = entry2.getNextSibling();
   }
   entry1 = entry1.getNextSibling();
   entry2 = entry2.getNextSibling();
 }
-_-_-