From: Michael Smith <xmldoc@users.sourceforge.net> Date: Tue, 21 Mar 2006 06:24:03 +0000 (+0000) Subject: Checkpointing. Now works correctly with the standard test table X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a1be6ef3b718bae5683e609be28a9af27032e0a9;p=docbook-dsssl Checkpointing. Now works correctly with the standard test table (which contains rowspan and colspan instances. Need to test further to make sure it will work with other rowspan/colspan tables. --- diff --git a/xsl/manpages/table.xsl b/xsl/manpages/table.xsl index d5c1dff22..0113b28cc 100644 --- a/xsl/manpages/table.xsl +++ b/xsl/manpages/table.xsl @@ -25,8 +25,6 @@ <!-- * http://cm.bell-labs.com/cm/cs/doc/76/tbl.ps.gz --> <!-- * http://www.snake.net/software/troffcvt/tbl.html --> - <!-- ==================================================================== --> - <xsl:template match="table|informaltable"> <!-- * We first process the table by applying templates to the whole --> <!-- * thing; because we donât override any of the <row>, <entry>, --> @@ -39,42 +37,56 @@ <xsl:param name="contents"> <xsl:apply-templates/> </xsl:param> - <!-- * put first-pass transformed output into a node-set so that --> + + <!-- * ============================================================== --> + <!-- * Get all the table contents and restructure them --> + <!-- * ============================================================== --> + + <!-- * Put first-pass transformed output into a node-set so that --> <!-- * we can walk through it again and do further transformation --> <!-- * to generate correct markup for tbl(1) --> <xsl:param name="table" select="exsl:node-set($contents)/table"/> - <xsl:param name="total-rows" select="count($table//tr)"/> + <!-- * Flatten the structure into just a set of rows without any --> + <!-- * thead, tbody, or tfoot parents. And reorder the rows in --> + <!-- * such a way that the tfoot rows are at the end, --> <xsl:variable name="rows-set"> <xsl:copy-of select="$table/thead/tr"/> <xsl:copy-of select="$table/tbody/tr|$table/tr"/> <xsl:copy-of select="$table/tfoot/tr"/> </xsl:variable> - <xsl:variable name="rows" select="exsl:node-set($rows-set)"/> - <xsl:variable name="cells"> + <!-- * Now we flatten the structure further into just a set of --> + <!-- * cells without the row parents. This basically creates a --> + <!-- * copy of the entire contents of the original table, but --> + <!-- * restructured in such a way that we can more easily generate --> + <!-- * the corresponding roff markup we need to output. --> + <xsl:variable name="cells-set"> <xsl:call-template name="build.cell.list"> <xsl:with-param name="rows" select="$rows"/> </xsl:call-template> </xsl:variable> + <xsl:variable name="cells" select="exsl:node-set($cells-set)"/> + + <!-- * ============================================================== --> + <!-- * Output the table. --> + <!-- * ============================================================== --> <!-- * .TS = "Table Start" --> <xsl:text>.TS </xsl:text> <!-- * put box around table and between all cells --> <xsl:text>allbox; </xsl:text> - <!-- * create the table "format" spec, which tells tbl(1) how to --> + <!-- * Output the table "format" spec, which tells tbl(1) how to --> <!-- * format each row and column --> <xsl:call-template name="create.table.format"> - <xsl:with-param name="cells" select="exsl:node-set($cells)"/> + <xsl:with-param name="cells" select="$cells"/> </xsl:call-template> - <xsl:for-each select="$rows/tr"> - <xsl:call-template name="output.row"> - <xsl:with-param name="cells" select="exsl:node-set($cells)"/> - <xsl:with-param name="row" select="position()"/> - </xsl:call-template> + <!--* Output the formatted contents of each cell. --> + <xsl:for-each select="$cells/cell"> + <xsl:call-template name="output.cell"/> </xsl:for-each> <xsl:text> </xsl:text> @@ -84,90 +96,77 @@ <xsl:text>.sp </xsl:text> </xsl:template> - <!-- ==================================================================== --> - - <xsl:template name="output.row"> - <xsl:param name="cells"/> - <xsl:param name="row"/> - <xsl:param name="total-columns" select="count(td|th)"/> - <xsl:text> </xsl:text> - <!-- * embed a comment to show where each row starts --> - <xsl:text>.\" ============================================== </xsl:text> - <xsl:text>.\" ROW </xsl:text> - <xsl:value-of select="$row"/> - <xsl:text> </xsl:text> - <xsl:for-each select="td|th"> - <xsl:call-template name="output.cell"> - <xsl:with-param name="cells" select="exsl:node-set($cells)"/> - <xsl:with-param name="row" select="$row"/> - <xsl:with-param name="slot" select="position()"/> - <xsl:with-param name="total-columns" select="$total-columns"/> - </xsl:call-template> - </xsl:for-each> - <xsl:text> </xsl:text> - </xsl:template> - + <!-- * ============================================================== --> + <!-- * Output the actual cell contents and roff row/cell markup --> + <!-- * ============================================================== --> <xsl:template name="output.cell"> - <xsl:param name="cells"/> - <xsl:param name="row"/> - <xsl:param name="slot"/> - <xsl:param name="total-columns"/> - <xsl:param name="format-letter"> - <xsl:value-of - select="$cells//cell[@row = $row and @slot = $slot]/@type"/> - </xsl:param> <xsl:choose> - <xsl:when test="contains($format-letter,'^')"> - <xsl:text>	</xsl:text> - <xsl:call-template name="output.cell"> - <xsl:with-param name="cells" select="exsl:node-set($cells)"/> - <xsl:with-param name="row" select="$row"/> - <xsl:with-param name="slot" select="$slot + 1"/> - <xsl:with-param name="total-columns" select="$total-columns"/> - </xsl:call-template> + <xsl:when test="preceding-sibling::cell[1]/@row != @row or + not(preceding-sibling::cell)"> + <!-- * If the value of the row attribute on this cell is --> + <!-- * different from the value of that on the previous cell, it --> + <!-- * means we have a new row. So output a line break (as long --> + <!-- * as this isnât the first cell in the table --> + <xsl:text> </xsl:text> </xsl:when> <xsl:otherwise> - <!-- * the "T{" and "T}" stuff are delimiters to tell tbl(1) that --> - <!-- * the delimited contents are "text blocks" that groff(1) --> - <!-- * needs to process --> - <xsl:text>T{ </xsl:text> - <xsl:apply-templates/> - <xsl:text> T}</xsl:text> + <!-- * Otherwise we are not at the start of a new row, so we --> + <!-- * output a tab character to delmit the contents of this --> + <!-- * cell from the contents of the next one. --> + <xsl:text>⌂</xsl:text> + </xsl:otherwise> + </xsl:choose> + <xsl:choose> + <xsl:when test="@type = '^'"> + <!-- * If this is a dummy cell resulting from the presence of --> + <!-- * rowpan attribute in the source, it has no contents, so --> + <!-- * we need to handle it differently. --> <xsl:if test="@colspan and @colspan > 1"> + <!-- * If there is a colspan attribute on this dummy row, then --> + <!-- * we need to output a tab character for each column that --> + <!-- * it spans. --> <xsl:call-template name="copy-string"> - <xsl:with-param name="string">	</xsl:with-param> + <xsl:with-param name="string">⌂</xsl:with-param> <xsl:with-param name="count"> - <xsl:value-of select="@colspan"/> + <xsl:value-of select="@colspan - 1"/> </xsl:with-param> </xsl:call-template> </xsl:if> - <xsl:choose> - <xsl:when test="$slot = $total-columns"/> <!-- do nothing --> - <xsl:otherwise> - <!-- * tbl(1) treats tab characters as delimiters between --> - <!-- * cells; so we need to output a tab after each <td> except --> - <!-- * the last one in the row --> - <xsl:text>	</xsl:text> - </xsl:otherwise> - </xsl:choose> + </xsl:when> + <xsl:otherwise> + <!-- * Otherwise, we have a "real" cell (not a dummy one) with --> + <!-- * contents that we need to output, --> + <!-- * --> + <!-- * The "T{" and "T}" stuff are delimiters to tell tbl(1) that --> + <!-- * the delimited contents are "text blocks" that groff(1) --> + <!-- * needs to process --> + <xsl:text>T{ </xsl:text> + <xsl:copy-of select="."/> + <xsl:text> T}</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> - <!-- ==================================================================== --> - + <!-- * ============================================================== --> + <!-- * Build a restructured "cell list" copy of the table --> + <!-- * ============================================================== --> <xsl:template name="build.cell.list"> <xsl:param name="rows"/> - <xsl:variable name="cell-data-unsorted"> + <xsl:param name="cell-data-unsorted"> + <!-- * This gets all the "real" cells from the table along with --> + <!-- * "dummy" rows that we generate for keeping track of Rowspan --> + <!-- * instances. --> <xsl:apply-templates select="$rows" mode="cell.list"/> - </xsl:variable> - <xsl:variable name="cell-data-sorted"> + </xsl:param> + <xsl:param name="cell-data-sorted"> + <!-- * Sort the cells so that the dummy cells get put where we --> + <!-- * need them in the structure. --> <xsl:for-each select="exsl:node-set($cell-data-unsorted)/cell"> <xsl:sort select="@row"/> <xsl:sort select="@slot"/> <xsl:copy-of select="."/> </xsl:for-each> - </xsl:variable> + </xsl:param> <xsl:copy-of select="$cell-data-sorted"/> </xsl:template> @@ -187,11 +186,16 @@ <xsl:param name="slot"> <xsl:value-of select="position()"/> </xsl:param> + <!-- * For each real cell, create a Cell instance; its contents are --> + <!-- * the roff-formatted contents of the corresponding original table --> + <!-- * cell. --> <cell row="{$row}" slot="{$slot}" type="l" colspan="{@colspan}"> <xsl:apply-templates/> </cell> <xsl:if test="@rowspan and @rowspan > 0"> - <xsl:call-template name="process.rowspan"> + <!-- * For each instance of a rowspan attribute found, we create N --> + <!-- * dummy cells, where N is equal to the value of the rowspan. --> + <xsl:call-template name="create.dummy.cells"> <xsl:with-param name="row" select="$row + 1"/> <xsl:with-param name="slot" select="$slot"/> <xsl:with-param name="colspan" select="@colspan"/> @@ -200,15 +204,17 @@ </xsl:if> </xsl:template> - <xsl:template name="process.rowspan"> + <xsl:template name="create.dummy.cells"> <xsl:param name="row"/> <xsl:param name="slot"/> <xsl:param name="colspan"/> <xsl:param name="rowspan"/> <xsl:choose> <xsl:when test="$rowspan > 1"> + <!-- * Tail recurse until we have no more rowspans, creating an --> + <!-- * empty dummy cell each time --> <cell row="{$row}" slot="{$slot}" type="^" colspan="{@colspan}"/> - <xsl:call-template name="process.rowspan"> + <xsl:call-template name="create.dummy.cells"> <xsl:with-param name="row" select="$row + 1"/> <xsl:with-param name="slot" select="$slot"/> <xsl:with-param name="colspan" select="$colspan"/> @@ -218,7 +224,9 @@ </xsl:choose> </xsl:template> - <!-- ==================================================================== --> + <!-- * ============================================================== --> + <!-- * Build the "format section" for the table --> + <!-- * ============================================================== --> <xsl:template name="create.table.format"> <xsl:param name="cells"/> @@ -227,9 +235,16 @@ </xsl:template> <xsl:template match="cell" mode="table.format"> - <xsl:if test="preceding-sibling::cell[1]/@row != @row"> - <xsl:text>
</xsl:text> - </xsl:if> + <xsl:choose> + <xsl:when test="preceding-sibling::cell[1]/@row != @row"> + <xsl:text>
</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:if test="position() != 1"> + <xsl:text> </xsl:text> + </xsl:if> + </xsl:otherwise> + </xsl:choose> <xsl:choose> <xsl:when test="@type = '^'"> <xsl:text>^</xsl:text> @@ -249,6 +264,7 @@ <xsl:template name="process.colspan"> <xsl:param name="colspan"/> <xsl:param name="type"/> + <xsl:text> </xsl:text> <xsl:choose> <xsl:when test="$type = '^'"> <xsl:text>^</xsl:text>