<?xml version='1.0' encoding="utf-8" ?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="doc exsl" version='1.0'>
<!--==================== newtbl table handling ========================-->
<!--= =-->
<!--= Copyright (C) 2004-2006 Vistair Systems Ltd (www.vistair.com) =-->
<!--= =-->
<!--= Released under the GNU General Public Licence (GPL) =-->
<!--= (Commercial and other licences by arrangement) =-->
<!--= =-->
<!--= Release 23/04/2006 by DCRH =-->
<!--= =-->
<!--= Email david@vistair.com with bugs, comments etc =-->
<!--= =-->
<!--===================================================================-->
<!-- Step though each column, generating a colspec entry for it. If a -->
<!-- colspec was given in the xml, then use it, otherwise generate a -->
<!-- default one -->
<xsl:template name="tbl.defcolspec">
<xsl:param name="colnum" select="1"/>
<xsl:param name="colspec"/>
<xsl:param name="align"/>
<xsl:param name="rowsep"/>
<xsl:param name="colsep"/>
<xsl:param name="cols"/>
<xsl:param name="autowidth"/>
<xsl:if test="$colnum <= $cols">
<xsl:choose>
<xsl:when test="$colspec/colspec[@colnum = $colnum]">
<xsl:copy-of select="$colspec/colspec[@colnum = $colnum]"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="natwidth">
<xsl:call-template name="natural-width">
<xsl:with-param name="autowidth" select="$autowidth"/>
<xsl:with-param name="colnum" select="$colnum"/>
</xsl:call-template>
</xsl:variable>
<colspec colnum='{$colnum}' align='{$align}' star='1'
rowsep='{$rowsep}' colsep='{$colsep}'
colwidth='\newtblstarfactor'>
<xsl:if test="$natwidth = 1">
<xsl:attribute name="autowidth">1</xsl:attribute>
</xsl:if>
</colspec>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="tbl.defcolspec">
<xsl:with-param name="colnum" select="$colnum + 1"/>
<xsl:with-param name="align" select="$align"/>
<xsl:with-param name="rowsep" select="$rowsep"/>
<xsl:with-param name="colsep" select="$colsep"/>
<xsl:with-param name="cols" select="$cols"/>
<xsl:with-param name="autowidth" select="$autowidth"/>
<xsl:with-param name="colspec" select="$colspec"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- replace-string function as XSLT doesn't have one built in. -->
<xsl:template name="replace-string">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="with"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$with"/>
<xsl:call-template name="replace-string">
<xsl:with-param name="text"
select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="with" select="$with"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- This template extracts the fixed part of a colwidth specification.
It should be able to do this:
a+b+c+d*+e+f -> a+b+c+e+f
a+b+c+d* -> a+b+c
d*+e+f -> e+f
-->
<xsl:template name="colfixed.get">
<xsl:param name="width" select="@colwidth"/>
<xsl:param name="stared" select="'0'"/>
<xsl:choose>
<xsl:when test="contains($width, '*')">
<xsl:variable name="after"
select="substring-after(substring-after($width, '*'), '+')"/>
<xsl:if test="contains(substring-before($width, '*'), '+')">
<xsl:call-template name="colfixed.get">
<xsl:with-param name="width" select="substring-before($width, '*')"/>
<xsl:with-param name="stared" select="'1'"/>
</xsl:call-template>
<xsl:if test="$after!=''">
<xsl:text>+</xsl:text>
</xsl:if>
</xsl:if>
<xsl:value-of select="$after"/>
</xsl:when>
<xsl:when test="$stared='1'">
<xsl:value-of select="substring-before($width, '+')"/>
<xsl:if test="contains(substring-after($width, '+'), '+')">
<xsl:text>+</xsl:text>
<xsl:call-template name="colfixed.get">
<xsl:with-param name="width" select="substring-after($width, '+')"/>
<xsl:with-param name="stared" select="'1'"/>
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$width"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="colstar.get">
<xsl:param name="width"/>
<xsl:choose>
<xsl:when test="contains($width, '+')">
<xsl:call-template name="colstar.get">
<xsl:with-param name="width" select="substring-after($width, '+')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="string(number($width))='NaN'">1</xsl:when>
<xsl:otherwise>
<!-- Use number() to ensure to have something well formatted -->
<xsl:value-of select="number($width)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Evaluate from the autowidth statement if the current column width
is its natural size determined by the column cells contents -->
<xsl:template name="natural-width">
<xsl:param name="autowidth"/>
<xsl:param name="colnum" select="1"/>
<xsl:choose>
<xsl:when test="not(string(@colwidth)) and
(contains($autowidth,'default') or
contains($autowidth,'all'))">1</xsl:when>
<xsl:when test="contains(@colwidth,'*') and
contains($autowidth,'all')">1</xsl:when>
<xsl:when test="contains(concat($autowidth,' '),concat(' ',$colnum,' ')) and
contains($autowidth,'column')">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Ensure each column has a colspec and each colspec has a valid column -->
<!-- number, width, alignment, colsep, rowsep -->
<xsl:template match="colspec" mode="newtbl">
<xsl:param name="colnum" select="1"/>
<xsl:param name="align"/>
<xsl:param name="colsep"/>
<xsl:param name="rowsep"/>
<xsl:param name="autowidth"/>
<xsl:variable name="natwidth">
<xsl:call-template name="natural-width">
<xsl:with-param name="autowidth" select="$autowidth"/>
<xsl:with-param name="colnum">
<xsl:choose><xsl:when test="@colnum">
<xsl:value-of select="@colnum"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$colnum"/>
</xsl:otherwise></xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:copy>
<xsl:for-each select="@*"><xsl:copy/></xsl:for-each>
<xsl:if test="$natwidth = 1">
<xsl:attribute name="autowidth">1</xsl:attribute>
</xsl:if>
<xsl:if test="not(@colnum)">
<xsl:attribute name="colnum"><xsl:value-of select="$colnum"/>
</xsl:attribute>
</xsl:if>
<!-- Find out if the column width contains fixed width -->
<xsl:variable name="fixed">
<xsl:call-template name="colfixed.get"/>
</xsl:variable>
<xsl:if test="$fixed!=''">
<xsl:attribute name="fixedwidth">
<xsl:value-of select="$fixed"/>
</xsl:attribute>
</xsl:if>
<!-- Replace '*' with our to-be-computed factor -->
<xsl:if test="contains(@colwidth,'*')">
<xsl:attribute name="colwidth">
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="@colwidth"/>
<xsl:with-param name="replace">*</xsl:with-param>
<xsl:with-param name="with">\newtblstarfactor</xsl:with-param>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="star">
<xsl:call-template name="colstar.get">
<xsl:with-param name="width" select="substring-before(@colwidth, '*')"/>
</xsl:call-template>
</xsl:attribute>
</xsl:if>
<!-- No colwidth specified? Assume '*' -->
<xsl:if test="not(string(@colwidth))">
<xsl:attribute name="colwidth">\newtblstarfactor</xsl:attribute>
<xsl:attribute name="star">1</xsl:attribute>
</xsl:if>
<xsl:if test="not(@align)">
<xsl:attribute name="align"><xsl:value-of select="$align"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="not(@rowsep)">
<xsl:attribute name="rowsep"><xsl:value-of select="$rowsep"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="not(@colsep)">
<xsl:attribute name="colsep"><xsl:value-of select="$colsep"/>
</xsl:attribute>
</xsl:if>
<!-- bgcolor specified via a PI -->
<xsl:variable name="bgcolor">
<xsl:call-template name="pi.dblatex_bgcolor"/>
</xsl:variable>
<xsl:if test="$bgcolor != ''">
<xsl:attribute name="bgcolor"><xsl:value-of select="$bgcolor"/>
</xsl:attribute>
</xsl:if>
</xsl:copy>
<xsl:variable name="nextcolnum">
<xsl:choose>
<xsl:when test="@colnum"><xsl:value-of select="@colnum + 1"/></xsl:when>
<xsl:otherwise><xsl:value-of select="$colnum + 1"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:apply-templates mode="newtbl"
select="following-sibling::colspec[1]">
<xsl:with-param name="colnum" select="$nextcolnum"/>
<xsl:with-param name="align" select="$align"/>
<xsl:with-param name="colsep" select="$colsep"/>
<xsl:with-param name="rowsep" select="$rowsep"/>
<xsl:with-param name="autowidth" select="$autowidth"/>
</xsl:apply-templates>
</xsl:template>
<!-- Generate a complete set of colspecs for each column in the table -->
<xsl:template name="tbl.colspec">
<xsl:param name="autowidth"/>
<xsl:param name="align"/>
<xsl:param name="rowsep"/>
<xsl:param name="colsep"/>
<xsl:param name="cols"/>
<!-- First, get the colspecs that have been specified -->
<xsl:variable name="givencolspec">
<xsl:apply-templates mode="newtbl" select="colspec[1]">
<xsl:with-param name="align" select="$align"/>
<xsl:with-param name="rowsep" select="$rowsep"/>
<xsl:with-param name="colsep" select="$colsep"/>
<xsl:with-param name="autowidth" select="$autowidth"/>
</xsl:apply-templates>
</xsl:variable>
<!-- Now generate colspecs for each missing column -->
<xsl:call-template name="tbl.defcolspec">
<xsl:with-param name="colspec" select="exsl:node-set($givencolspec)"/>
<xsl:with-param name="cols" select="$cols"/>
<xsl:with-param name="align" select="$align"/>
<xsl:with-param name="rowsep" select="$rowsep"/>
<xsl:with-param name="colsep" select="$colsep"/>
<xsl:with-param name="autowidth" select="$autowidth"/>
</xsl:call-template>
</xsl:template>
<!-- Create a blank entry element. We check the 'entries' node-set -->
<!-- to see if we should copy an entry from the row above instead -->
<xsl:template name="tbl.blankentry">
<xsl:param name="colnum"/>
<xsl:param name="colend"/>
<xsl:param name="rownum"/>
<xsl:param name="colspec"/>
<xsl:param name="entries"/>
<xsl:param name="rowcolor"/>
<xsl:if test="$colnum <= $colend">
<xsl:variable name="entry"
select="$entries/*[self::entry or self::entrytbl]
[@colstart=$colnum and @rowend >= $rownum]"/>
<xsl:choose>
<xsl:when test="$entry">
<!-- Just copy this entry then -->
<xsl:copy-of select="$entry"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="bgcolor">
<xsl:choose>
<xsl:when test="$rowcolor != ''">
<xsl:value-of select="$rowcolor"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$colspec/colspec[@colnum=$colnum]/@bgcolor"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- No rowspan entry found from the row above, so create a blank -->
<entry colstart='{$colnum}' colend='{$colnum}'
rowstart='{$rownum}' rowend='{$rownum}'
colsep='{$colspec/colspec[@colnum=$colnum]/@colsep}'
defrowsep='{$colspec/colspec[@colnum=$colnum]/@rowsep}'
align='{$colspec/colspec[@colnum=$colnum]/@align}'
bgcolor='{$bgcolor}'/>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="nextcol">
<xsl:choose>
<xsl:when test="$entry">
<xsl:value-of select="$entry/@colend"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$colnum"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="tbl.blankentry">
<xsl:with-param name="colnum" select="$nextcol + 1"/>
<xsl:with-param name="colend" select="$colend"/>
<xsl:with-param name="rownum" select="$rownum"/>
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="rowcolor" select="$rowcolor"/>
<xsl:with-param name="entries" select="$entries"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- Check the entry column range is valid -->
<xsl:template name="check-colrange">
<xsl:param name="colnum"/>
<xsl:param name="rownum"/>
<xsl:param name="colend"/>
<xsl:param name="colstart"/>
<xsl:variable name="msg">
<xsl:text>Invalid table entry row=</xsl:text>
<xsl:value-of select="$rownum"/>
<xsl:text>/column=</xsl:text>
<xsl:value-of select="$colnum"/>
</xsl:variable>
<xsl:if test="string(number($colend))='NaN'">
<xsl:message terminate="yes">
<xsl:value-of select="$msg"/>
<xsl:text> (@colend)</xsl:text>
</xsl:message>
</xsl:if>
<xsl:if test="string(number($colstart))='NaN'">
<xsl:message terminate="yes">
<xsl:value-of select="$msg"/>
<xsl:text> (@colstart)</xsl:text>
</xsl:message>
</xsl:if>
</xsl:template>
<!-- Returns a RTF of entry elements. rowsep, colsep and align are all -->
<!-- extracted from spanspec/colspec as required -->
<!-- Skipped columns have blank entry elements created -->
<!-- Existing entry elements in the given entries node-set are checked to -->
<!-- see if they should extend into this row and are copied if so -->
<!-- Each element is given additional attributes: -->
<!-- rowstart = The top row number of the table this entry -->
<!-- rowend = The bottom row number of the table this entry -->
<!-- colstart = The starting column number of this entry -->
<!-- colend = The ending column number of this entry -->
<!-- defrowsep = The default rowsep value inherited from the entry's span -->
<!-- or colspec -->
<xsl:template match="entry|entrytbl" mode="newtbl.buildentries">
<xsl:param name="colnum"/>
<xsl:param name="rownum"/>
<xsl:param name="colspec"/>
<xsl:param name="spanspec"/>
<xsl:param name="frame"/>
<xsl:param name="rowcolor"/>
<xsl:param name="entries"/>
<xsl:param name="tabletype"/>
<xsl:variable name="cols" select="count($colspec/*)"/>
<xsl:if test="$colnum <= $cols">
<xsl:variable name="entry"
select="$entries/*[self::entry or self::entrytbl]
[@colstart=$colnum and @rowend >= $rownum]"/>
<!-- Do we have an existing entry element from a previous row that -->
<!-- should be copied into this row? -->
<xsl:choose><xsl:when test="$entry">
<!-- Just copy this entry then -->
<xsl:copy-of select="$entry"/>
<!-- Process the next column using this current entry -->
<xsl:apply-templates mode="newtbl.buildentries" select=".">
<xsl:with-param name="colnum"
select="$entries/entry[@colstart=$colnum]/@colend + 1"/>
<xsl:with-param name="rownum" select="$rownum"/>
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="spanspec" select="$spanspec"/>
<xsl:with-param name="frame" select="$frame"/>
<xsl:with-param name="rowcolor" select="$rowcolor"/>
<xsl:with-param name="entries" select="$entries"/>
<xsl:with-param name="tabletype" select="$tabletype"/>
</xsl:apply-templates>
</xsl:when><xsl:otherwise>
<!-- Get any span for this entry -->
<xsl:variable name="span">
<xsl:if test="@spanname and $spanspec[@spanname=current()/@spanname]">
<xsl:copy-of select="$spanspec[@spanname=current()/@spanname]"/>
</xsl:if>
</xsl:variable>
<!-- Get the starting column number for this cell -->
<xsl:variable name="colstart">
<xsl:choose>
<!-- Check colname first -->
<xsl:when test="$colspec/colspec[@colname=current()/@colname]">
<xsl:value-of
select="$colspec/colspec[@colname=current()/@colname]/@colnum"/>
</xsl:when>
<!-- Now check span -->
<xsl:when test="exsl:node-set($span)/spanspec/@namest">
<xsl:value-of select="$colspec/colspec[@colname=
exsl:node-set($span)/spanspec/@namest]/@colnum"/>
</xsl:when>
<!-- Now check namest attribute -->
<xsl:when test="@namest">
<xsl:value-of select="$colspec/colspec[@colname=
current()/@namest]/@colnum"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$colnum"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Get the ending column number for this cell -->
<xsl:variable name="colend">
<xsl:choose>
<!-- Check span -->
<xsl:when test="exsl:node-set($span)/spanspec/@nameend">
<xsl:value-of select="$colspec/colspec[@colname=
exsl:node-set($span)/spanspec/@nameend]/@colnum"/>
</xsl:when>
<!-- Check nameend attribute -->
<xsl:when test="@nameend">
<xsl:value-of select="$colspec/colspec[@colname=
current()/@nameend]/@colnum"/>
</xsl:when>
<!-- Otherwise end == start -->
<xsl:otherwise>
<xsl:value-of select="$colstart"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Check column consistency -->
<xsl:call-template name="check-colrange">
<xsl:with-param name="colnum" select="$colnum"/>
<xsl:with-param name="rownum" select="$rownum"/>
<xsl:with-param name="colstart" select="$colstart"/>
<xsl:with-param name="colend" select="$colend"/>
</xsl:call-template>
<!-- No offset between column and cell content for entrytbl -->
<xsl:variable name="coloff">
<xsl:choose>
<xsl:when test="self::entrytbl">0</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Does this entry want to start at a later column? -->
<xsl:if test="$colnum < $colstart">
<!-- If so, create some blank entries to fill in the gap -->
<xsl:call-template name="tbl.blankentry">
<xsl:with-param name="colnum" select="$colnum"/>
<xsl:with-param name="colend" select="$colstart - 1"/>
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="rownum" select="$rownum"/>
<xsl:with-param name="rowcolor" select="$rowcolor"/>
<xsl:with-param name="entries" select="$entries"/>
</xsl:call-template>
</xsl:if>
<!-- Get the colsep override from this entry or its span -->
<xsl:variable name="colsep">
<xsl:choose>
<!-- Entry element override -->
<xsl:when test="@colsep"><xsl:value-of select="@colsep"/></xsl:when>
<!-- Then any span present -->
<xsl:when test="exsl:node-set($span)/spanspec/@colsep">
<xsl:value-of select="exsl:node-set($span)/spanspec/@colsep"/>
</xsl:when>
<xsl:otherwise>
<!-- Otherwise take from colspec -->
<xsl:value-of select="$colspec/colspec[@colnum=$colstart]/@colsep"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Get the default rowsep for this entry -->
<xsl:variable name="defrowsep">
<xsl:choose>
<!-- Check any span present -->
<xsl:when test="exsl:node-set($span)/spanspec/@rowsep">
<xsl:value-of select="exsl:node-set($span)/spanspec/@rowsep"/>
</xsl:when>
<xsl:otherwise>
<!-- Otherwise take from colspec -->
<xsl:value-of select="$colspec/colspec[@colnum=$colstart]/@rowsep"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Generate cell alignment -->
<xsl:variable name="align">
<xsl:choose>
<!-- Entry element attribute first -->
<xsl:when test="string(@align)">
<xsl:value-of select="@align"/>
</xsl:when>
<!-- Then any span present -->
<xsl:when test="exsl:node-set($span)/spanspec/@align">
<xsl:value-of select="exsl:node-set($span)/spanspec/@align"/>
</xsl:when>
<xsl:otherwise>
<!-- Otherwise take from colspec -->
<xsl:value-of select="$colspec/colspec[@colnum=$colstart]/@align"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Vertical cell alignment -->
<xsl:variable name="valign">
<xsl:choose>
<!-- Entry element attribute first -->
<xsl:when test="string(@valign)">
<xsl:value-of select="@valign"/>
</xsl:when>
<!-- Then parent row -->
<xsl:when test="../@valign">
<xsl:value-of select="../@valign"/>
</xsl:when>
<!-- Then parent tbody|thead -->
<xsl:when test="../../@valign">
<xsl:value-of select="../../@valign"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="cellcolor">
<xsl:call-template name="pi.dblatex_bgcolor"/>
</xsl:variable>
<xsl:variable name="bgcolor">
<xsl:choose>
<xsl:when test="$cellcolor != ''">
<xsl:value-of select="$cellcolor"/>
</xsl:when>
<xsl:when test="$rowcolor != ''">
<xsl:value-of select="$rowcolor"/>
</xsl:when>
<xsl:when test="$colspec/colspec[@colnum=$colstart]/@bgcolor">
<xsl:value-of select="$colspec/colspec[@colnum=$colstart]/@bgcolor"/>
</xsl:when>
<xsl:when test="ancestor::*[self::table or self::informaltable]/@bgcolor">
<xsl:value-of select="ancestor::*[self::table or
self::informaltable]/@bgcolor"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:copy>
<xsl:for-each select="@*"><xsl:copy/></xsl:for-each>
<xsl:attribute name="colstart">
<xsl:value-of select="$colstart"/>
</xsl:attribute>
<xsl:attribute name="colend">
<xsl:value-of select="$colend"/>
</xsl:attribute>
<xsl:attribute name="coloff">
<xsl:value-of select="$coloff"/>
</xsl:attribute>
<xsl:attribute name="rowstart">
<xsl:value-of select="$rownum"/>
</xsl:attribute>
<xsl:attribute name="rowend">
<xsl:choose>
<xsl:when test="@morerows and @morerows > 0">
<xsl:value-of select="@morerows + $rownum"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$rownum"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="colsep">
<xsl:value-of select="$colsep"/>
</xsl:attribute>
<xsl:attribute name="defrowsep">
<xsl:value-of select="$defrowsep"/>
</xsl:attribute>
<xsl:attribute name="align">
<xsl:value-of select="$align"/>
</xsl:attribute>
<xsl:attribute name="valign">
<xsl:value-of select="$valign"/>
</xsl:attribute>
<xsl:if test="$bgcolor != ''">
<xsl:attribute name="bgcolor">
<xsl:value-of select="$bgcolor"/>
</xsl:attribute>
</xsl:if>
<xsl:attribute name="tabletype">
<xsl:value-of select="$tabletype"/>
</xsl:attribute>
<!-- Process the output here, to stay in the document context. -->
<!-- In RTF entries the document links/refs are lost -->
<xsl:element name="output">
<xsl:apply-templates select="." mode="output"/>
</xsl:element>
</xsl:copy>
<!-- See if we've run out of entries for the current row -->
<xsl:if test="$colend < $cols and
not(following-sibling::*[self::entry or self::entrytbl][1])">
<!-- Create more blank entries to pad the row -->
<xsl:call-template name="tbl.blankentry">
<xsl:with-param name="colnum" select="$colend + 1"/>
<xsl:with-param name="colend" select="$cols"/>
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="rownum" select="$rownum"/>
<xsl:with-param name="rowcolor" select="$rowcolor"/>
<xsl:with-param name="entries" select="$entries"/>
<xsl:with-param name="tabletype" select="$tabletype"/>
</xsl:call-template>
</xsl:if>
<xsl:apply-templates mode="newtbl.buildentries"
select="following-sibling::*[self::entry or self::entrytbl][1]">
<xsl:with-param name="colnum" select="$colend + 1"/>
<xsl:with-param name="rownum" select="$rownum"/>
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="spanspec" select="$spanspec"/>
<xsl:with-param name="frame" select="$frame"/>
<xsl:with-param name="rowcolor" select="$rowcolor"/>
<xsl:with-param name="entries" select="$entries"/>
<xsl:with-param name="tabletype" select="$tabletype"/>
</xsl:apply-templates>
</xsl:otherwise></xsl:choose>
</xsl:if> <!-- $colnum <= $cols -->
</xsl:template>
<!-- Output the current entry node -->
<xsl:template match="entry|entrytbl" mode="newtbl">
<xsl:param name="colspec"/>
<xsl:param name="context"/>
<xsl:param name="frame"/>
<xsl:param name="rownum"/>
<xsl:variable name="cols" select="count($colspec/*)"/>
<!--
<xsl:if test="@colstart > $cols">
<xsl:message>BANG</xsl:message>
</xsl:if>
-->
<xsl:if test="@colstart <= $cols">
<!-- Should this column be sized by latex? -->
<xsl:variable name="autowidth"
select="$colspec/colspec[@colnum=current()/@colstart]/@autowidth"/>
<xsl:variable name="moreprint"
select="not($autowidth and (@rowstart != $rownum))"/>
<!-- Generate the column spec for this column -->
<xsl:text>\multicolumn{</xsl:text>
<xsl:value-of select="@colend - @colstart + 1"/>
<xsl:text>}{</xsl:text>
<xsl:apply-templates select="." mode="tbl.colfmt">
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="frame" select="$frame"/>
<xsl:with-param name="autowidth" select="$autowidth"/>
</xsl:apply-templates>
<xsl:text>}{</xsl:text>
<!-- Put everything inside a multirow if required -->
<xsl:if test="@morerows and @morerows > 0 and $moreprint">
<!-- Multirow doesn't use setlength and hence our calc stuff doesn't -->
<!-- work. Do it manually then -->
<xsl:if test="not($autowidth)">
<xsl:text>\setlength{\newtblcolwidth}{</xsl:text>
<!-- Put the column width here for line wrapping -->
<xsl:call-template name="tbl.colwidth">
<xsl:with-param name="col" select="@colstart"/>
<xsl:with-param name="colend" select="@colend"/>
<xsl:with-param name="colspec" select="$colspec"/>
</xsl:call-template>
<xsl:text>}</xsl:text>
</xsl:if>
<xsl:text>\multirowii</xsl:text>
<!-- Vertical alignment done by custom multirow -->
<xsl:if test="@valign and @valign!=''">
<xsl:choose>
<xsl:when test="@valign = 'top'"><xsl:text>[p]</xsl:text></xsl:when>
<xsl:when test="@valign = 'bottom'"><xsl:text>[b]</xsl:text></xsl:when>
<xsl:otherwise><xsl:text>[m]</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:text>{</xsl:text>
<xsl:value-of select="@morerows + 1"/>
<xsl:choose>
<xsl:when test="not($autowidth)">
<xsl:text>}{</xsl:text>
<!-- Only output the contents of this row if it's on the correct -->
<!-- row -ve width means don't output the cell contents, but maybe -->
<!-- just output a height spacer. -->
<xsl:if test="@rowstart != $rownum">
<xsl:text>-</xsl:text>
</xsl:if>
<xsl:text>\newtblcolwidth}{</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>}{*}{</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<!-- Do rotate if required. What to do about line wrapping though?? -->
<xsl:if test="@rotate and @rotate != 0">
<xsl:text>\rotatebox{90}{</xsl:text>
</xsl:if>
<xsl:if test="not($autowidth)">
<xsl:choose>
<xsl:when test="@align = 'left'">
<xsl:text>\raggedright</xsl:text>
</xsl:when>
<xsl:when test="@align = 'right'">
<xsl:text>\raggedleft</xsl:text>
</xsl:when>
<xsl:when test="@align = 'center'">
<xsl:text>\centering</xsl:text>
</xsl:when>
<xsl:when test="@align = 'justify'"></xsl:when>
<xsl:when test="@align != ''">
<xsl:message>Word-wrapped alignment <xsl:value-of
select="@align"/> not supported</xsl:message>
</xsl:when>
</xsl:choose>
</xsl:if>
<!-- Apply some default formatting depending on context -->
<xsl:choose>
<xsl:when test="$context = 'thead'">
<xsl:value-of select="$newtbl.format.thead"/>
</xsl:when>
<xsl:when test="$context = 'tbody'">
<xsl:value-of select="$newtbl.format.tbody"/>
</xsl:when>
<xsl:when test="$context = 'tfoot'">
<xsl:value-of select="$newtbl.format.tfoot"/>
</xsl:when>
<xsl:otherwise>
<xsl:message>Unknown context <xsl:value-of select="$context"/>
</xsl:message>
</xsl:otherwise>
</xsl:choose>
<!-- Dump out the entry contents -->
<xsl:if test="$moreprint">
<xsl:text>% </xsl:text>
<xsl:choose>
<xsl:when test="output">
<xsl:value-of select="output"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="output"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text>% </xsl:text>
</xsl:if>
<!-- Close off multirow if required -->
<xsl:if test="@morerows and @morerows > 0 and $moreprint">
<xsl:text>}</xsl:text>
</xsl:if>
<!-- Close off rotate if required -->
<xsl:if test="@rotate and @rotate != 0">
<xsl:text>}</xsl:text>
</xsl:if>
<!-- End of the multicolumn -->
<xsl:text>}</xsl:text>
<!-- Put in the column separator -->
<xsl:if test="@colend != $cols">
<xsl:text>&</xsl:text>
</xsl:if>
</xsl:if> <!-- colstart > cols -->
</xsl:template>
<!-- Process the entry content, and remove spurious empty lines -->
<xsl:template match="entry" mode="output">
<xsl:call-template name="normalize-border">
<xsl:with-param name="string">
<xsl:apply-templates/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<!-- Actually build the embedded table like tgroup does -->
<xsl:template match="entrytbl" mode="output">
<xsl:call-template name="tgroup">
<xsl:with-param name="tablewidth" select="'\linewidth-2\arrayrulewidth'"/>
<xsl:with-param name="tableframe" select="'none'"/>
</xsl:call-template>
</xsl:template>
<!-- Rowsep building using \cline - done within a row -->
<xsl:template name="clines.build">
<xsl:param name="entries"/>
<xsl:param name="rownum"/>
<!-- Store any rowsep for this row -->
<xsl:variable name="thisrowsep" select="@rowsep"/>
<xsl:for-each select="$entries/*">
<!-- Only do rowsep for this col if it's not spanning this row -->
<xsl:if test="@rowend = $rownum">
<xsl:variable name="dorowsep">
<xsl:choose>
<!-- Entry rowsep override -->
<xsl:when test="@rowsep">
<xsl:value-of select="@rowsep"/>
</xsl:when>
<!-- Row rowsep override -->
<xsl:when test="$thisrowsep">
<xsl:value-of select="$thisrowsep"/>
</xsl:when>
<!-- Else use the default for this column -->
<xsl:otherwise>
<xsl:value-of select="@defrowsep"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$dorowsep = 1">
<xsl:text>\cline{</xsl:text>
<xsl:value-of select="@colstart"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="@colend"/>
<xsl:text>}</xsl:text>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- Rowsep building using \hhline - done within a row -->
<xsl:template name="hhline.build">
<xsl:param name="entries"/>
<xsl:param name="rownum"/>
<!-- Store any rowsep for this row -->
<xsl:variable name="thisrowsep" select="@rowsep"/>
<xsl:text>\hhline{</xsl:text>
<xsl:for-each select="$entries/*">
<xsl:variable name="dorowsep">
<xsl:choose>
<!-- Only do rowsep for this col if it's not spanning this row -->
<xsl:when test="@rowend != $rownum">
<xsl:value-of select="0"/>
</xsl:when>
<!-- Entry rowsep override -->
<xsl:when test="@rowsep">
<xsl:value-of select="@rowsep"/>
</xsl:when>
<!-- Row rowsep override -->
<xsl:when test="$thisrowsep">
<xsl:value-of select="$thisrowsep"/>
</xsl:when>
<!-- Else use the default for this column -->
<xsl:otherwise>
<xsl:value-of select="@defrowsep"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- hhline separator value -->
<xsl:variable name="hsep">
<xsl:choose>
<xsl:when test="$dorowsep = 1">-</xsl:when>
<xsl:otherwise>~</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="@colstart = @colend">
<xsl:value-of select="$hsep"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>*{</xsl:text>
<xsl:value-of select="@colend - @colstart + 1"/>
<xsl:text>}{</xsl:text>
<xsl:value-of select="$hsep"/>
<xsl:text>}</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:template>
<!-- Process each row in turn -->
<xsl:template match="row" mode="newtbl">
<xsl:param name="tabletype"/>
<xsl:param name="rownum"/>
<xsl:param name="rows"/>
<xsl:param name="colspec"/>
<xsl:param name="spanspec"/>
<xsl:param name="frame"/>
<xsl:param name="oldentries"><nop/></xsl:param>
<xsl:param name="rowstack"/>
<xsl:variable name="bgcolor.pi">
<xsl:call-template name="pi.dblatex_bgcolor"/>
</xsl:variable>
<xsl:variable name="rowcolor">
<xsl:choose>
<xsl:when test="$bgcolor.pi!=''">
<xsl:value-of select="$bgcolor.pi"/>
</xsl:when>
<xsl:when test="ancestor::thead">
<xsl:value-of select="$newtbl.bgcolor.thead"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<!-- Build the entry node-set -->
<xsl:variable name="entries">
<xsl:choose>
<xsl:when test="(entry|entrytbl)[1]">
<xsl:apply-templates mode="newtbl.buildentries" select="(entry|entrytbl)[1]">
<xsl:with-param name="colnum" select="1"/>
<xsl:with-param name="rownum" select="$rownum"/>
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="spanspec" select="$spanspec"/>
<xsl:with-param name="frame" select="$frame"/>
<xsl:with-param name="rowcolor" select="$rowcolor"/>
<xsl:with-param name="entries" select="exsl:node-set($oldentries)"/>
<xsl:with-param name="tabletype" select="$tabletype"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="exsl:node-set($oldentries)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Now output each entry -->
<xsl:variable name="context" select="local-name(..)"/>
<xsl:variable name="row-output">
<xsl:if test="$context = 'thead'">
<xsl:value-of select="$rowstack"/>
</xsl:if>
<xsl:if test="$rownum = 1">
<!-- Need a top line? -->
<xsl:if test="$frame = 'all' or $frame = 'top' or $frame = 'topbot'">
<xsl:text>\hline</xsl:text>
</xsl:if>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:apply-templates select="exsl:node-set($entries)/*" mode="newtbl">
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="frame" select="$frame"/>
<xsl:with-param name="context" select="$context"/>
<xsl:with-param name="rownum" select="$rownum"/>
</xsl:apply-templates>
<!-- End this row -->
<xsl:text>\tabularnewline </xsl:text>
<!-- Now process rowseps only if not the last row -->
<xsl:if test="$rownum != $rows">
<xsl:choose>
<xsl:when test="$newtbl.use.hhline='1'">
<xsl:call-template name="hhline.build">
<xsl:with-param name="entries" select="exsl:node-set($entries)"/>
<xsl:with-param name="rownum" select="$rownum"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="clines.build">
<xsl:with-param name="entries" select="exsl:node-set($entries)"/>
<xsl:with-param name="rownum" select="$rownum"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:variable>
<!-- Head rows must be buffered -->
<xsl:if test="$context != 'thead'">
<xsl:value-of select="$row-output"/>
</xsl:if>
<xsl:choose>
<xsl:when test="following-sibling::row[1]">
<xsl:apply-templates mode="newtbl" select="following-sibling::row[1]">
<xsl:with-param name="tabletype" select="$tabletype"/>
<xsl:with-param name="rownum" select="$rownum + 1"/>
<xsl:with-param name="rows" select="$rows"/>
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="spanspec" select="$spanspec"/>
<xsl:with-param name="frame" select="$frame"/>
<xsl:with-param name="oldentries" select="$entries"/>
<xsl:with-param name="rowstack" select="$row-output"/>
</xsl:apply-templates>
</xsl:when>
<xsl:when test="$context = 'tfoot'">
</xsl:when>
<xsl:otherwise>
<!-- Ask to table to end the head -->
<xsl:if test="$context = 'thead'">
<xsl:apply-templates select="(ancestor::table
|ancestor::informaltable)[last()]"
mode="newtbl.endhead">
<xsl:with-param name="tabletype" select="$tabletype"/>
<xsl:with-param name="headrows" select="$row-output"/>
</xsl:apply-templates>
</xsl:if>
<xsl:apply-templates mode="newtbl"
select="(../following-sibling::tbody/row)[1]">
<xsl:with-param name="tabletype" select="$tabletype"/>
<xsl:with-param name="rownum" select="$rownum + 1"/>
<xsl:with-param name="rows" select="$rows"/>
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="spanspec" select="$spanspec"/>
<xsl:with-param name="frame" select="$frame"/>
<xsl:with-param name="oldentries" select="$entries"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Calculate column width between two columns -->
<xsl:template name="tbl.colwidth">
<xsl:param name="col"/>
<xsl:param name="colend"/>
<xsl:param name="colspec"/>
<xsl:value-of select="$colspec/colspec[@colnum=$col]/@colwidth"/>
<xsl:if test="$col < $colend">
<xsl:text>+2\tabcolsep+\arrayrulewidth+</xsl:text>
<xsl:call-template name="tbl.colwidth">
<xsl:with-param name="col" select="$col + 1"/>
<xsl:with-param name="colend" select="$colend"/>
<xsl:with-param name="colspec" select="$colspec"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="tbl.colwidth2">
<xsl:param name="col"/>
<xsl:param name="colend"/>
<xsl:param name="colspec"/>
<xsl:value-of select="$colspec/colspec[@colnum=$col]/@fixedwidth"/>
<xsl:if test="$col < $colend">
<xsl:text>+</xsl:text>
<xsl:call-template name="tbl.colwidth2">
<xsl:with-param name="col" select="$col + 1"/>
<xsl:with-param name="colend" select="$colend"/>
<xsl:with-param name="colspec" select="$colspec"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="entry|entrytbl" mode="width.colfmt">
<xsl:param name="colspec"/>
<xsl:param name="color"/>
<xsl:param name="rsep"/>
<!-- Color in pre-command -->
<xsl:if test="$color != ''">
<xsl:value-of select="concat('>{',$color,'}')"/>
</xsl:if>
<!-- Get the column width -->
<xsl:variable name="width">
<xsl:call-template name="tbl.colwidth">
<xsl:with-param name="col" select="@colstart"/>
<xsl:with-param name="colend" select="@colend"/>
<xsl:with-param name="colspec" select="$colspec"/>
</xsl:call-template>
<xsl:if test="$rsep = ''">
<xsl:text>+\arrayrulewidth</xsl:text>
</xsl:if>
<xsl:if test="@coloff = 0">
<xsl:text>+2\tabcolsep</xsl:text>
</xsl:if>
</xsl:variable>
<xsl:choose>
<xsl:when test="@valign = 'top'">
<xsl:text>p</xsl:text>
</xsl:when>
<xsl:when test="@valign = 'bottom'">
<xsl:text>b</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>m</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text>{</xsl:text>
<xsl:value-of select="$width"/>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:template match="entry|entrytbl" mode="widthx.colfmt">
<xsl:param name="colspec"/>
<xsl:param name="color"/>
<xsl:variable name="stars"
select="sum(exsl:node-set($colspec)/colspec
[@colnum >= current()/@colstart and
@colnum <= current()/@colend]/@star)"/>
<!-- Get the column fixed width part -->
<xsl:variable name="width">
<xsl:call-template name="tbl.colwidth2">
<xsl:with-param name="col" select="@colstart"/>
<xsl:with-param name="colend" select="@colend"/>
<xsl:with-param name="colspec" select="$colspec"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$stars = 0">
<xsl:if test="$color != ''">
<xsl:value-of select="concat('>{',$color,'}')"/>
</xsl:if>
<!-- Only a fixed width -->
<xsl:choose>
<xsl:when test="@valign = 'top'">
<xsl:text>p</xsl:text>
</xsl:when>
<xsl:when test="@valign = 'bottom'">
<xsl:text>b</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>m</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text>{</xsl:text>
<xsl:value-of select="$width"/>
<xsl:text>}</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>>{</xsl:text>
<xsl:value-of select="$color"/>
<xsl:text>\setlength\hsize{</xsl:text>
<xsl:if test="$width != ''">
<xsl:value-of select="$width"/>
<xsl:text>+</xsl:text>
</xsl:if>
<xsl:value-of select="$stars"/>
<xsl:text>\hsize}}X</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Convert a frame tag to a CALS frame equivalent -->
<xsl:template name="cals.frame">
<xsl:param name="frame"/>
<xsl:choose>
<xsl:when test="$frame='void'">none</xsl:when>
<xsl:when test="$frame='above'">top</xsl:when>
<xsl:when test="$frame='below'">bottom</xsl:when>
<xsl:when test="$frame='hsides'">topbot</xsl:when>
<xsl:when test="$frame='vsides'">sides</xsl:when>
<xsl:when test="$frame='box'">all</xsl:when>
<xsl:when test="$frame='border'">all</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$frame"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Generate a latex column specifier, possibly surrounded by '|' -->
<xsl:template match="entry|entrytbl" mode="tbl.colfmt">
<xsl:param name="frame"/>
<xsl:param name="colspec"/>
<xsl:param name="autowidth"/>
<xsl:variable name="cols" select="count($colspec/*)"/>
<!-- Need a colsep to the left? - only if first column and frame says so -->
<xsl:if test="@colstart = 1 and ($frame = 'all' or $frame = 'sides')">
<xsl:text>|</xsl:text>
</xsl:if>
<!-- Need a colsep to the right? - only if last column and frame says -->
<!-- so, or we are not the last column and colsep says so -->
<xsl:variable name="rsep">
<xsl:if test="(@colend = $cols and ($frame = 'all' or $frame = 'sides')) or
(@colend != $cols and @colsep = 1)">
<xsl:text>|</xsl:text>
</xsl:if>
</xsl:variable>
<!-- Remove the offset between column and cell content? -->
<xsl:if test="@coloff = 0">
<xsl:text>@{}</xsl:text>
</xsl:if>
<!-- Column color? -->
<xsl:variable name="color">
<xsl:if test="@bgcolor != ''">
<xsl:text>\columncolor</xsl:text>
<xsl:call-template name="get-color">
<xsl:with-param name="color" select="@bgcolor"/>
</xsl:call-template>
</xsl:if>
</xsl:variable>
<xsl:choose>
<xsl:when test="not($autowidth)">
<xsl:choose>
<xsl:when test="@tabletype = 'tabularx'">
<xsl:apply-templates select="." mode="widthx.colfmt">
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="color" select="$color"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="width.colfmt">
<xsl:with-param name="colspec" select="$colspec"/>
<xsl:with-param name="color" select="$color"/>
<xsl:with-param name="rsep" select="$rsep"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:if test="$color != ''">
<xsl:value-of select="concat('>{',$color,'}')"/>
</xsl:if>
<xsl:choose>
<xsl:when test="@align = 'left'">l</xsl:when>
<xsl:when test="@align = 'right'">r</xsl:when>
<xsl:when test="@align = 'center'">c</xsl:when>
<xsl:otherwise>c</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="@coloff = 0">
<xsl:text>@{}</xsl:text>
</xsl:if>
<xsl:value-of select="$rsep"/>
</xsl:template>
<xsl:template name="table.width">
<xsl:param name="fullwidth"/>
<xsl:param name="exclude"/>
<xsl:variable name="piwidth">
<xsl:call-template name="pi.dblatex_table-width">
<xsl:with-param name="node" select=".."/>
</xsl:call-template>
</xsl:variable>
<!-- precedence between table-widths specifications -->
<xsl:variable name="width">
<xsl:choose>
<xsl:when test="$piwidth != '' and
($exclude='' or not(contains($piwidth,$exclude)))">
<xsl:value-of select="$piwidth"/>
</xsl:when>
<xsl:when test="(@width or ../@width) and
($exclude='' or not(contains(../@width,$exclude)))">
<xsl:value-of select="(@width|../@width)[last()]"/>
</xsl:when>
<xsl:when test="$default.table.width != '' and
($exclude='' or
not(contains($default.table.width,$exclude)))">
<xsl:value-of select="$default.table.width"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$fullwidth"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- convert percentage to real width -->
<xsl:choose>
<xsl:when test="contains($width, '%')">
<xsl:value-of select="number(substring-before($width, '%')) div 100"/>
<xsl:value-of select="$fullwidth"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$width"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="tbl.sizes">
<xsl:param name="colspec"/>
<xsl:param name="width"/>
<!-- Now get latex to calculate the 'spare' width of the table -->
<!-- (Table width - widths of all specified columns - gaps between columns)-->
<xsl:text>\setlength{\newtblsparewidth}{</xsl:text>
<xsl:value-of select="$width"/>
<xsl:for-each select="$colspec/*">
<xsl:if test="@fixedwidth">
<xsl:text>-</xsl:text>
<xsl:value-of select="translate(@fixedwidth,'+','-')"/>
</xsl:if>
<xsl:text>-2\tabcolsep</xsl:text>
</xsl:for-each>
<xsl:text>}% </xsl:text>
<!-- Now get latex to calculate widths of cols with starred colwidths -->
<xsl:variable name="numunknown"
select="sum($colspec/colspec/@star)"/>
<!-- If we have at least one such col, then work out how wide it should -->
<!-- be -->
<xsl:if test="$numunknown > 0">
<xsl:text>\setlength{\newtblstarfactor}{\newtblsparewidth / \real{</xsl:text>
<xsl:value-of select="$numunknown"/>
<xsl:text>}}% </xsl:text>
</xsl:if>
</xsl:template>
<!-- tabularx vertical alignment setup, global to the whole table -->
<xsl:template name="tbl.valign.x">
<xsl:param name="valign"/>
<xsl:variable name="valign.param">
<xsl:choose>
<xsl:when test="$valign = 'top'"><xsl:text>p</xsl:text></xsl:when>
<xsl:when test="$valign = 'bottom'"><xsl:text>b</xsl:text></xsl:when>
<!-- default vertical alignment -->
<xsl:otherwise><xsl:text>m</xsl:text></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:text>\def\tabularxcolumn#1{</xsl:text>
<xsl:value-of select="$valign.param"/>
<xsl:text>{#1}}</xsl:text>
</xsl:template>
<xsl:template name="tbl.begin">
<xsl:param name="colspec"/>
<xsl:param name="tabletype"/>
<xsl:param name="width"/>
<xsl:text>\begin{</xsl:text>
<xsl:value-of select="$tabletype"/>
<xsl:text>}</xsl:text>
<xsl:choose>
<xsl:when test="$tabletype = 'tabularx'">
<xsl:text>{</xsl:text>
<xsl:value-of select="$width"/>
<xsl:text>}{</xsl:text>
<xsl:for-each select="$colspec/*">
<xsl:choose>
<xsl:when test="@star">
<xsl:text>>{\hsize=</xsl:text>
<xsl:if test="@fixedwidth">
<xsl:value-of select="@fixedwidth"/>
<xsl:text>+</xsl:text>
</xsl:if>
<xsl:value-of select="@star"/>
<xsl:text>\hsize}X</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>l</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>{</xsl:text>
<!-- The initial column definition -->
<xsl:for-each select="$colspec/*">
<xsl:text>l</xsl:text>
</xsl:for-each>
<xsl:text>}</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- The main starting point of the table handling -->
<xsl:template match="tgroup" mode="newtbl" name="tgroup">
<xsl:param name="tabletype">tabular</xsl:param>
<xsl:param name="tablewidth">\linewidth-2\tabcolsep</xsl:param>
<xsl:param name="tableframe">all</xsl:param>
<!-- First, save the table verbatim data, but only at tgroup level -->
<xsl:if test="not(self::entrytbl)">
<xsl:apply-templates mode="save.verbatim"/>
</xsl:if>
<xsl:text>\begingroup% </xsl:text>
<!-- Set cellpadding -->
<xsl:if test="../@cellpadding">
<xsl:text>\setlength{\tabcolsep}{</xsl:text>
<xsl:value-of select="../@cellpadding"/>
<xsl:text>}% </xsl:text>
</xsl:if>
<!-- Get the number of columns -->
<xsl:variable name="cols">
<xsl:choose>
<xsl:when test="@cols">
<xsl:value-of select="@cols"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="count(tbody/row[1]/*[self::entry or
self::entrytbl])"/>
<xsl:message>Warning: table's tgroup lacks cols attribute.
Assuming <xsl:value-of select="count(tbody/row[1]/*)"/>.
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Get the number of rows -->
<xsl:variable name="rows" select="count(*/row)"/>
<xsl:if test="$rows = 0">
<xsl:message>Warning: 0 rows</xsl:message>
</xsl:if>
<!-- Get the specified table width -->
<xsl:variable name="table.width">
<xsl:call-template name="table.width">
<xsl:with-param name="fullwidth" select="$tablewidth"/>
</xsl:call-template>
</xsl:variable>
<!-- Find the table width -->
<xsl:variable name="width">
<xsl:choose>
<xsl:when test="not(contains($table.width,'auto'))">
<xsl:value-of select="$table.width"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="table.width">
<xsl:with-param name="fullwidth" select="$tablewidth"/>
<xsl:with-param name="exclude" select="'auto'"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Get the autowidth option -->
<xsl:variable name="autowidth">
<xsl:choose>
<xsl:when test="contains($table.width,'auto')">
<!-- Expect something like 'autowidth.all' or 'autowidth.default' -->
<xsl:value-of select="$table.width"/>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$newtbl.autowidth"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Get default align -->
<xsl:variable name="align"
select="@align|parent::node()[not(*/@align)]/@align"/>
<!-- Get default colsep -->
<xsl:variable name="colsep"
select="@colsep|parent::node()[not(*/@colsep)]/@colsep"/>
<!-- Get default rowsep -->
<xsl:variable name="rowsep"
select="@rowsep|parent::node()[not(*/@rowsep)]/@rowsep"/>
<!-- Now the frame style -->
<xsl:variable name="frame">
<xsl:choose>
<xsl:when test="../@frame">
<xsl:value-of select="../@frame"/>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$tableframe"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Build up a complete colspec for each column -->
<xsl:variable name="colspec">
<xsl:call-template name="tbl.colspec">
<xsl:with-param name="autowidth" select="$autowidth"/>
<xsl:with-param name="cols" select="$cols"/>
<xsl:with-param name="rowsep">
<xsl:choose>
<xsl:when test="$rowsep"><xsl:value-of select="$rowsep"/>
</xsl:when>
<xsl:when test="$newtbl.default.rowsep">
<xsl:value-of select="$newtbl.default.rowsep"/>
</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="colsep">
<xsl:choose>
<xsl:when test="$colsep"><xsl:value-of select="$colsep"/>
</xsl:when>
<xsl:when test="$newtbl.default.colsep">
<xsl:value-of select="$newtbl.default.colsep"/>
</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="align">
<xsl:choose>
<xsl:when test="$align"><xsl:value-of select="$align"/>
</xsl:when>
<xsl:otherwise>left</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<!-- Get all the spanspecs as an RTF -->
<xsl:variable name="spanspec" select="spanspec"/>
<xsl:if test="$tabletype != 'tabularx'">
<xsl:call-template name="tbl.sizes">
<xsl:with-param name="colspec" select="exsl:node-set($colspec)"/>
<xsl:with-param name="width" select="$width"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="$tabletype = 'tabularx'">
<xsl:call-template name="tbl.valign.x">
<xsl:with-param name="valign" select="tbody/@valign"/>
</xsl:call-template>
</xsl:if>
<!-- Start the next table on a new line -->
<xsl:if test="preceding::tgroup">
<xsl:text> </xsl:text>
</xsl:if>
<!-- Start the table declaration -->
<xsl:call-template name="tbl.begin">
<xsl:with-param name="colspec" select="exsl:node-set($colspec)"/>
<xsl:with-param name="tabletype" select="$tabletype"/>
<xsl:with-param name="width" select="$width"/>
</xsl:call-template>
<xsl:if test="not(thead)">
<xsl:apply-templates select="(ancestor::table
|ancestor::informaltable)[last()]"
mode="newtbl.endhead">
<xsl:with-param name="tabletype" select="$tabletype"/>
</xsl:apply-templates>
</xsl:if>
<!-- Go through each row, starting with the header -->
<xsl:apply-templates mode="newtbl" select="((thead|tbody)/row)[1]">
<xsl:with-param name="tabletype" select="$tabletype"/>
<xsl:with-param name="rownum" select="1"/>
<xsl:with-param name="rows" select="$rows"/>
<xsl:with-param name="frame" select="$frame"/>
<xsl:with-param name="colspec" select="exsl:node-set($colspec)"/>
<xsl:with-param name="spanspec" select="exsl:node-set($spanspec)"/>
</xsl:apply-templates>
<!-- Go through each footer row -->
<xsl:apply-templates mode="newtbl" select="tfoot/row[1]">
<xsl:with-param name="tabletype" select="$tabletype"/>
<xsl:with-param name="rownum" select="count(thead/row|tbody/row)+1"/>
<xsl:with-param name="rows" select="$rows"/>
<xsl:with-param name="frame" select="$frame"/>
<xsl:with-param name="colspec" select="exsl:node-set($colspec)"/>
<xsl:with-param name="spanspec" select="exsl:node-set($spanspec)"/>
</xsl:apply-templates>
<!-- Need a bottom line? -->
<xsl:if test="$frame = 'all' or $frame = 'bottom' or $frame = 'topbot'">
<xsl:text>\hline</xsl:text>
</xsl:if>
<xsl:text> </xsl:text>
<xsl:text>\end{</xsl:text>
<xsl:value-of select="$tabletype"/>
<xsl:text>}\endgroup% </xsl:text>
</xsl:template>
</xsl:stylesheet>