1
Vote

Calculation of row spans does not account for horizontal spans

description

In a table where there are two rows laid out like:
+------------------------------+
|    A  |       B       |    C    |
+       |--------------|         +
|        |  D   |  E    |         |
+------------------------------+
That is, first column spans both rows, two middle cells are merged on the top row, and last column spans both rows, the converted result does not count cell "B" as two cells and thus fails to find the merged cell from row 2 under cell "C".

The logic as written, which simply counts elements, will not work--the processor must take into account any horizontal spans.

comments

drmacro wrote Dec 2, 2015 at 7:39 PM

In my code that cribs the table processing from this project, I implemented this function:
  <xsl:function name="local:cellPos" as="xs:integer">
    <xsl:param name="cell" as="element()"/>
    <xsl:variable name="cellCounts" as="xs:integer*"
      select="for $c in $cell/preceding-sibling::w:tc
                  return if ($c/w:tcPr/w:gridSpan/@w:val)
                            then xs:integer($c/w:tcPr/w:gridSpan/@w:val)
                            else 1
                    "
    />
    <xsl:message> + [DEBUG] local:cellPos: cellCounts="<xsl:sequence select="$cellCounts"/>"</xsl:message>
    <xsl:variable name="result" as="xs:integer"
       select="sum($cellCounts, 1)"
    />
    <xsl:message> + [DEBUG] local:cellPos: result="<xsl:sequence select="$result"/>"</xsl:message>

    <xsl:sequence select="$result"/>
  </xsl:function>
  
I then use this in place of the sibling counts to determine cells above and below the current cell:
    <xsl:variable name="curCellPos" as="xs:integer" select="local:cellPos(.)"/>

...
              <xsl:variable name="belowCurCell"
                select="$myRowInContext/following-sibling::*//w:tc[count(ancestor::w:tbl)=$tblCount][$curCellPos = local:cellPos(.)]"/>

              <xsl:variable name="mergesAboveMe"
                select="count($myRowInContext/preceding-sibling::*[(descendant-or-self::*[name()='w:tc'])[$curCellPos = local:cellPos(.)][descendant-or-self::*[name()='w:vMerge']]])"/>
              <xsl:variable name="mergesAboveNextRestart"
                select="count($NextRestartInContext/preceding-sibling::*[(descendant-or-self::*[name()='w:tc'])[$curCellPos = local:cellPos(.)]])"/>
Based on my initial testing, this works as expected and correctly calculates the row span of the last column