Embed db2latex as interim solution before migration to dblatex
[import/samba-docs-svnimport.git] / xslt / db2latex-xsl / xsl / table.mod.xsl
diff --git a/xslt/db2latex-xsl/xsl/table.mod.xsl b/xslt/db2latex-xsl/xsl/table.mod.xsl
new file mode 100644 (file)
index 0000000..10a36e7
--- /dev/null
@@ -0,0 +1,1414 @@
+<?xml version='1.0'?>
+<!DOCTYPE xsl:stylesheet [ <!ENTITY % xsldoc.ent SYSTEM "./xsldoc.ent"> %xsldoc.ent; ]>
+<!--############################################################################# 
+|      $Id: table.mod.xsl,v 1.32 2004/01/28 02:08:41 j-devenish Exp $
+|- #############################################################################
+|      $Author: j-devenish $
++ ############################################################################## -->
+<xsl:stylesheet
+       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+       xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
+       exclude-result-prefixes="doc" version='1.0'>
+
+       <doc:reference id="table" xmlns="">
+               <referenceinfo>
+                       <releaseinfo role="meta">
+                               $Id: table.mod.xsl,v 1.32 2004/01/28 02:08:41 j-devenish Exp $
+                       </releaseinfo>
+                       <authorgroup>
+                               &ramon;
+                               &james;
+                       </authorgroup>
+                       <copyright>
+                               <year>2000</year><year>2001</year><year>2002</year><year>2003</year><year>2004</year>
+                               <holder>Ramon Casellas</holder>
+                       </copyright>
+                       <revhistory>
+                               <doc:revision rcasver="1.24">&rev_2003_05;</doc:revision>
+                       </revhistory>
+               </referenceinfo>
+               <title>Tables <filename>table.mod.xsl</filename></title>
+               <partintro>
+                       <para>
+                       
+                       
+                       
+                       </para>
+               </partintro>
+       </doc:reference>
+
+       <doc:template xmlns="">
+               <refpurpose>Process <doc:db>table</doc:db> elements</refpurpose>
+               <doc:description>
+                       <para>
+                       
+                       
+                       
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       <variablelist>
+                               <varlistentry>
+                                       <term><xref linkend="param.latex.table.caption.style"/></term>
+                                       <listitem><simpara>
+                                               The &LaTeX; command for formatting captions.
+                                       </simpara></listitem>
+                               </varlistentry>
+                       </variablelist>
+               </doc:variables>
+               <doc:notes>
+                       <para>
+                       
+                               Unless <xref linkend="param.latex.use.ltxtable"/> is in use,
+                               tables are typeset as <quote>floats</quote> using the <link
+                               linkend="latex.mapping">mapping system</link>. This limits the
+                               size of each table to one page. It is possible to use tables
+                               without floats, but captions and cross-referencing will not
+                               function as intended.
+                       
+                       </para>
+                       <para>
+                               
+                               If a <sgmltag class="attribute">condition</sgmltag> attribute
+                               exists and begins with <quote>db2latex:</quote>, or a <sgmltag
+                               class="pi">latex-float-placement</sgmltag> processing
+                               instruction is present, the remainder of its value will be used
+                               as the &LaTeX; <quote>float</quote> placement. Otherwise, the
+                               default placement is <quote>htb</quote>.
+                               
+                       </para>
+               </doc:notes>
+               <doc:samples>
+                       <simplelist type='inline'>
+                               &test_book;
+                               &test_ecos;
+                               &test_pinkjuice;
+                               &test_tables;
+                       </simplelist>
+               </doc:samples>
+               <doc:seealso>
+                       <itemizedlist>
+                               <listitem><simpara>&mapping;</simpara></listitem>
+                               <listitem><simpara><xref linkend="template.generate.formal.title.placement"/></simpara></listitem>
+                       </itemizedlist>
+               </doc:seealso>
+       </doc:template>
+       <xsl:template match="table">
+               <xsl:choose>
+                       <xsl:when test="caption">
+                               <xsl:message>Cannot cope with new-style tables lacking tgroup -- skipped.</xsl:message>
+                       </xsl:when>
+                       <xsl:when test="$latex.use.ltxtable='1'">
+                               <!--
+                               <xsl:message>No captions for ltxtable, yet.</xsl:message>
+                               -->
+                               <!--
+                               Can use captions with longtable, but this is handled by
+                               the thead and tfoot templates :-(
+                               -->
+                               <xsl:call-template name="content-templates"/>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:variable name="placement">
+                                       <xsl:call-template name="generate.formal.title.placement">
+                                               <xsl:with-param name="object" select="local-name(.)" />
+                                       </xsl:call-template>
+                               </xsl:variable>
+                               <xsl:variable name="position">
+                                       <xsl:call-template name="generate.latex.float.position">
+                                               <xsl:with-param name="default" select="'htb'"/>
+                                       </xsl:call-template>
+                               </xsl:variable>
+                               <xsl:variable name="caption">
+                                       <xsl:call-template name="generate.table.caption"/>
+                               </xsl:variable>
+                               <xsl:call-template name="map.begin">
+                                       <xsl:with-param name="string" select="$position"/>
+                               </xsl:call-template>
+                               <xsl:if test="$placement='before'">
+                                       <xsl:text>\captionswapskip{}</xsl:text>
+                                       <xsl:value-of select="$caption" />
+                                       <xsl:text>\captionswapskip{}</xsl:text>
+                               </xsl:if>
+                               <xsl:call-template name="content-templates"/>
+                               <xsl:if test="$placement!='before'"><xsl:value-of select="$caption" /></xsl:if>
+                               <xsl:call-template name="map.end">
+                                       <xsl:with-param name="string" select="$position"/>
+                               </xsl:call-template>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <xsl:template name="generate.table.caption.longtable">
+               <xsl:for-each select="ancestor-or-self::table">
+                       <xsl:text>\caption{</xsl:text>
+                       <xsl:value-of select="$latex.table.caption.style"/>
+                       <xsl:text>{</xsl:text>
+                       <xsl:apply-templates select="title" mode="caption.mode"/>
+                       <xsl:text>}</xsl:text>
+                       <xsl:call-template name="label.id"/>
+                       <xsl:text>}\hypertarget{</xsl:text>
+                       <xsl:call-template name="generate.label.id"/>
+                       <xsl:text>}{}&#10;</xsl:text>
+               </xsl:for-each>
+       </xsl:template>
+
+       <xsl:template name="generate.table.caption">
+               <xsl:for-each select="ancestor-or-self::table">
+                       <xsl:text>{</xsl:text>
+                       <xsl:value-of select="$latex.table.caption.style"/>
+                       <xsl:text>{\caption{</xsl:text>
+                       <xsl:apply-templates select="title" mode="caption.mode"/>
+                       <xsl:text>}</xsl:text>
+                       <xsl:call-template name="label.id"/>
+                       <xsl:text>}}&#10;</xsl:text>
+               </xsl:for-each>
+       </xsl:template>
+
+       <doc:template xmlns="">
+               <refpurpose>Process <doc:db>informaltable</doc:db> elements</refpurpose>
+               <doc:description>
+                       <para>
+                       
+                       Applies templates within a &LaTeX; mapping.
+                       
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+               <doc:samples>
+                       <simplelist type='inline'>
+                               &test_bind;
+                               &test_book;
+                               &test_chemistry;
+                               &test_tables;
+                       </simplelist>
+               </doc:samples>
+               <doc:seealso>
+                       <itemizedlist>
+                               <listitem><simpara>&mapping;</simpara></listitem>
+                       </itemizedlist>
+               </doc:seealso>
+       </doc:template>
+       <xsl:template match="informaltable">
+               <xsl:call-template name="map.begin"/>
+               <xsl:apply-templates/>
+               <xsl:call-template name="map.end"/>
+       </xsl:template>
+
+       <doc:template xmlns="">
+               <refpurpose>Process <doc:db basename="table">tables</doc:db> using <productname>tabularx</productname> </refpurpose>
+               <doc:description>
+                       <para>
+                       
+                       Similar to <xref linkend="template.table.format.tabularx"/> but
+                       calculates <quote>relative</quote> column sizes.
+                       
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+               <doc:samples>
+                       <simplelist type='inline'>
+                               &test_tables;
+                       </simplelist>
+               </doc:samples>
+               <doc:seealso>
+                       <itemizedlist>
+                               <listitem><simpara><xref linkend="template.table.format.tabular"/></simpara></listitem>
+                       </itemizedlist>
+               </doc:seealso>
+       </doc:template>
+       <xsl:template name="table.format.tabularx">
+               <xsl:param name="cols" select="1"/>
+               <xsl:param name="i" select="1"/>
+               <xsl:param name="colsep" select="1"/>
+               <!-- sum of numeric portions in 1*-like colwidths -->
+               <xsl:param name="starfactor" select="0"/>
+               <xsl:choose>
+                       <!-- Out of the recursive iteration -->
+                       <xsl:when test="$i > $cols"></xsl:when>
+                       <!-- There are still columns to count -->
+                       <xsl:otherwise>
+                       <xsl:variable name="userwidth">
+                               <xsl:choose>
+                                       <xsl:when test="./colspec[@colnum=$i]">
+                                               <xsl:value-of select="./colspec[@colnum=$i]/@colwidth"/>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <xsl:value-of select="./colspec[position()=$i]/@colwidth"/>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:variable>
+                       <xsl:variable name="useralign">
+                               <xsl:choose>
+                                       <xsl:when test="./colspec[@colnum=$i]/@align!=''">
+                                               <xsl:value-of select="./colspec[@colnum=$i]/@align"/>
+                                       </xsl:when>
+                                       <xsl:when test="./colspec[position()=$i]/@align!=''">
+                                               <xsl:value-of select="./colspec[position()=$i]/@align"/>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <xsl:value-of select="./@align"/>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:variable>
+                       <xsl:variable name="width">
+                               <xsl:variable name="cells" select="thead/row/entry[$i]|tbody/row/entry[$i]"/>
+                               <xsl:choose>
+                                       <xsl:when test="string-length($userwidth)=0 and count($cells//itemizedlist|$cells//orderedlist|$cells//variablelist)&gt;0">
+                                               <!-- In these specific circumstances, we MUST use a line-wrapped column
+                                                        and yet the user hasn't specified one. -->
+                                               <xsl:value-of select="'1*'"/>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <!-- In the general case, we just do what the user wants (may even
+                                                        have no pre-specified width). -->
+                                               <xsl:value-of select="$userwidth"/>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:variable>
+                       <!-- Try to take heed of colspecs -->
+                       <xsl:choose>
+                               <xsl:when test="$width!=''">
+                                       <xsl:text>&gt;{</xsl:text>
+                                       <xsl:if test="contains($width,'*')">
+                                               <!-- see tabularx documentation -->
+                                               <xsl:text>\hsize=</xsl:text>
+                                               <xsl:value-of select="substring-before($width,'*') * $starfactor" />
+                                               <xsl:text>\hsize</xsl:text>
+                                       </xsl:if>
+                                       <xsl:choose>
+                                               <xsl:when test="$useralign='left'"><xsl:text>\RaggedRight</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='right'"><xsl:text>\RaggedLeft</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='center'"><xsl:text>\Centering</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='char' and $latex.use.dcolumn='1'">
+                                                       <xsl:variable name="char" select="(./colspec[@colnum=$i]/@char|./colspec[position()=$i]/@char)[1]"/>
+                                                       <xsl:choose>
+                                                               <xsl:when test="$char=''"><xsl:text>d</xsl:text></xsl:when>
+                                                               <xsl:otherwise>D{<xsl:value-of select="$char"/>}{<xsl:value-of select="$char"/>}{-1}</xsl:otherwise>
+                                                       </xsl:choose>
+                                               </xsl:when>
+                                               <xsl:when test="$useralign!=''"><xsl:message>Table column '<xsl:value-of select="$useralign"/>' alignment is not supported.</xsl:message></xsl:when>
+                                       </xsl:choose>
+                                       <xsl:text>}</xsl:text>
+                                       <xsl:choose>
+                                               <xsl:when test="contains($width,'*')">
+                                                       <xsl:text>X</xsl:text>
+                                               </xsl:when>
+                                               <xsl:otherwise>
+                                                       <xsl:text>p{</xsl:text><xsl:value-of select="$width" /><xsl:text>}</xsl:text>
+                                               </xsl:otherwise>
+                                       </xsl:choose>
+                                       <xsl:if test="$i&lt;$cols and $colsep='1'">
+                                               <xsl:text>|</xsl:text>
+                                       </xsl:if>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <xsl:choose>
+                                               <xsl:when test="$useralign='left'"><xsl:text>l</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='right'"><xsl:text>r</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='center'"><xsl:text>c</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='justify'"><xsl:text>X</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='char' and $latex.use.dcolumn='1'">
+                                                       <xsl:variable name="char" select="(./colspec[@colnum=$i]/@char|./colspec[position()=$i]/@char)[1]"/>
+                                                       <xsl:choose>
+                                                               <xsl:when test="$char=''"><xsl:text>d</xsl:text></xsl:when>
+                                                               <xsl:otherwise>D{<xsl:value-of select="$char"/>}{<xsl:value-of select="$char"/>}{-1}</xsl:otherwise>
+                                                       </xsl:choose>
+                                               </xsl:when>
+                                               <xsl:otherwise>
+                                                       <xsl:text>c</xsl:text>
+                                                       <xsl:if test="$useralign!=''">
+                                                               <xsl:message>Table column '<xsl:value-of select="$useralign"/>' alignment is not supported.</xsl:message>
+                                                       </xsl:if>
+                                               </xsl:otherwise>
+                                       </xsl:choose>
+                                       <xsl:if test="$i&lt;$cols and $colsep='1'">
+                                               <xsl:text>|</xsl:text>
+                                       </xsl:if>
+                               </xsl:otherwise>
+                       </xsl:choose>
+                       <!-- Recursive for next column -->
+                       <xsl:call-template name="table.format.tabularx">
+                               <xsl:with-param name="i" select="$i+1"/>
+                               <xsl:with-param name="cols" select="$cols"/>
+                               <xsl:with-param name="colsep" select="$colsep"/>
+                               <xsl:with-param name="starfactor" select="$starfactor"/>
+                       </xsl:call-template>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <doc:template xmlns="">
+               <refpurpose>Process <doc:db basename="table">tables</doc:db> using <function condition="env">tabular</function> </refpurpose>
+               <doc:description>
+                       <para>
+                       
+                       
+                       
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+               <doc:samples>
+                       <simplelist type='inline'>
+                               &test_tables;
+                       </simplelist>
+               </doc:samples>
+               <doc:seealso>
+                       <itemizedlist>
+                               <listitem><simpara><xref linkend="template.table.format.tabularx"/></simpara></listitem>
+                       </itemizedlist>
+               </doc:seealso>
+       </doc:template>
+       <xsl:template name="table.format.tabular">
+               <xsl:param name="cols" select="1"/>
+               <xsl:param name="i" select="1"/>
+               <xsl:param name="colsep" select="1"/>
+               <xsl:choose>
+                       <!-- Out of the recursive iteration -->
+                       <xsl:when test="$i > $cols"></xsl:when>
+                       <!-- There are still columns to count -->
+                       <xsl:otherwise>
+                       <!-- Try to take heed of colspecs -->
+                       <xsl:variable name="width">
+                               <xsl:variable name="userwidth">
+                                       <xsl:choose>
+                                               <xsl:when test="./colspec[@colnum=$i]">
+                                                       <xsl:value-of select="./colspec[@colnum=$i]/@colwidth"/>
+                                               </xsl:when>
+                                               <xsl:otherwise>
+                                                       <xsl:value-of select="./colspec[position()=$i]/@colwidth"/>
+                                               </xsl:otherwise>
+                                       </xsl:choose>
+                               </xsl:variable>
+                               <xsl:variable name="cells" select="thead/row/entry[$i]|tbody/row/entry[$i]"/>
+                               <xsl:choose>
+                                       <xsl:when test="string-length($userwidth)=0 and count($cells//itemizedlist|$cells//orderedlist|$cells//variablelist)&gt;0">
+                                               <!-- In these specific circumstances, we MUST use a line-wrapped column
+                                                        and yet the user hasn't specified one. -->
+                                               <xsl:value-of select="concat(1 div $cols,'\linewidth')"/>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <!-- In the general case, we just do what the user wants (may even
+                                                        have no pre-specified width). -->
+                                               <xsl:value-of select="$userwidth"/>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:variable>
+                       <xsl:variable name="useralign">
+                               <xsl:choose>
+                                       <xsl:when test="./colspec[@colnum=$i]/@align!=''">
+                                               <xsl:value-of select="./colspec[@colnum=$i]/@align"/>
+                                       </xsl:when>
+                                       <xsl:when test="./colspec[position()=$i]/@align!=''">
+                                               <xsl:value-of select="./colspec[position()=$i]/@align"/>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <xsl:value-of select="./@align"/>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:variable>
+                       <xsl:choose>
+                               <xsl:when test="$width!='' and not(contains($width,'*'))">
+                                       <xsl:choose>
+                                               <xsl:when test="$useralign='left'"><xsl:text>&gt;{\RaggedRight}</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='right'"><xsl:text>&gt;{\RaggedLeft}</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='center'"><xsl:text>&gt;{\Centering}</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='char'"><xsl:message>Table column 'char' alignment is not supported when width specified.</xsl:message></xsl:when>
+                                               <xsl:when test="$useralign!=''"><xsl:message>Table column '<xsl:value-of select="$useralign"/>' alignment is not supported.</xsl:message></xsl:when>
+                                       </xsl:choose>
+                                       <xsl:text>p{</xsl:text><xsl:value-of select="$width" /><xsl:text>}</xsl:text>
+                                       <xsl:if test="$i&lt;$cols and $colsep='1'">
+                                               <xsl:text>|</xsl:text>
+                                       </xsl:if>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <xsl:choose>
+                                               <xsl:when test="$useralign='left'"><xsl:text>l</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='right'"><xsl:text>r</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='center'"><xsl:text>c</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='justify'"><xsl:text>l</xsl:text></xsl:when>
+                                               <xsl:when test="$useralign='char' and $latex.use.dcolumn='1'">
+                                                       <xsl:variable name="char" select="(./colspec[@colnum=$i]/@char|./colspec[position()=$i]/@char)[1]"/>
+                                                       <xsl:choose>
+                                                               <xsl:when test="$char=''"><xsl:text>d</xsl:text></xsl:when>
+                                                               <xsl:otherwise>D{<xsl:value-of select="$char"/>}{<xsl:value-of select="$char"/>}{-1}</xsl:otherwise>
+                                                       </xsl:choose>
+                                               </xsl:when>
+                                               <xsl:otherwise>
+                                                       <xsl:text>c</xsl:text>
+                                                       <xsl:if test="$useralign!=''">
+                                                               <xsl:message>Table column '<xsl:value-of select="$useralign"/>' alignment is not supported.</xsl:message>
+                                                       </xsl:if>
+                                               </xsl:otherwise>
+                                       </xsl:choose>
+                                       <xsl:if test="$i&lt;$cols and $colsep='1'">
+                                               <xsl:text>|</xsl:text>
+                                       </xsl:if>
+                               </xsl:otherwise>
+                       </xsl:choose>
+                       <!-- Recursive for next column -->
+                       <xsl:call-template name="table.format.tabular">
+                               <xsl:with-param name="i" select="$i+1"/>
+                               <xsl:with-param name="cols" select="$cols"/>
+                               <xsl:with-param name="colsep" select="$colsep"/>
+                       </xsl:call-template>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <!-- See tabularx documentation. -->
+       <!-- For example, if we have a 1* column and a 3* column, then the
+            the hsizes for each column are (1/(1+3)*2) and (3/(1+3)*2).
+                The ratio of these to the star values (star values being 1 and 3)
+                is 2/(1+3).
+                BUT it is now very complicated because it takes into account columns
+                where the user has not specified a width but LaTeX requires a
+                fixed-width column (i.e. specialcols may vary).
+                Relies on there being (a) colspecs for every column or (b) no
+                colspecs.
+        -->
+       <doc:template xmlns="">
+               <refpurpose>Calculate relative column sizes</refpurpose>
+               <doc:description>
+                       <para>
+                       
+                       Determines the width of each column in terms of <quote>relative
+                       units</quote>.
+                       
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+               <doc:samples>
+                       <simplelist type='inline'>
+                               &test_tables;
+                       </simplelist>
+               </doc:samples>
+               <doc:seealso>
+                       <itemizedlist>
+                               <listitem><simpara><xref linkend="template.table.format.tabular"/></simpara></listitem>
+                               <listitem><simpara><xref linkend="template.table.format.tabularx"/></simpara></listitem>
+                       </itemizedlist>
+               </doc:seealso>
+       </doc:template>
+       <xsl:template name="generate.starfactor">
+               <xsl:param name="i" select="1"/>
+               <xsl:param name="cols" select="count(colspec)"/>
+               <xsl:param name="sum" select="0"/>
+               <xsl:param name="specialcols" select="count(colspec[contains(@colwidth,'*')])"/>
+               <xsl:choose>
+                       <xsl:when test="$i&lt;=$cols and colspec[position()=$i and contains(@colwidth,'*')]">
+                               <!-- a * column -->
+                               <xsl:call-template name="generate.starfactor">
+                                       <xsl:with-param name="i" select="$i+1"/>
+                                       <xsl:with-param name="cols" select="$cols"/>
+                                       <xsl:with-param name="sum" select="$sum+substring-before(colspec[$i]/@colwidth,'*')"/>
+                                       <xsl:with-param name="specialcols" select="$specialcols"/>
+                               </xsl:call-template>
+                       </xsl:when>
+                       <xsl:when test="$i&lt;=$cols">
+                               <!-- not a * column, but we are going to pretend that it is -->
+                               <xsl:variable name="cells" select="thead/row/entry[$i]|tbody/row/entry[$i]"/>
+                               <xsl:variable name="problems" select="count($cells//itemizedlist|$cells//orderedlist|$cells//variablelist)"/>
+                               <xsl:choose>
+                                       <xsl:when test="$problems &gt; 0">
+                                               <xsl:call-template name="generate.starfactor">
+                                                       <xsl:with-param name="i" select="$i+1"/>
+                                                       <xsl:with-param name="cols" select="$cols"/>
+                                                       <xsl:with-param name="sum" select="$sum+1"/>
+                                                       <xsl:with-param name="specialcols" select="$specialcols+1"/>
+                                               </xsl:call-template>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <xsl:call-template name="generate.starfactor">
+                                                       <xsl:with-param name="i" select="$i+1"/>
+                                                       <xsl:with-param name="cols" select="$cols"/>
+                                                       <xsl:with-param name="sum" select="$sum"/>
+                                                       <xsl:with-param name="specialcols" select="$specialcols"/>
+                                               </xsl:call-template>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:value-of select="$specialcols div $sum"/>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <doc:template xmlns="">
+               <refpurpose>Process <doc:db>tgroup</doc:db> elements</refpurpose>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="tgroup">
+               <xsl:variable name="colsep">
+                       <xsl:choose>
+                               <xsl:when test="@colsep!=''">
+                                       <xsl:value-of select="number(@colsep)"/>
+                               </xsl:when>
+                               <xsl:when test="../@colsep!=''">
+                                       <xsl:value-of select="number(../@colsep)"/>
+                               </xsl:when>
+                               <xsl:otherwise>1</xsl:otherwise>
+                       </xsl:choose>
+               </xsl:variable>
+               <xsl:variable name="frame">
+                       <xsl:choose>
+                               <xsl:when test="string-length(../@frame)&lt;1">all</xsl:when>
+                               <xsl:otherwise>
+                                       <xsl:value-of select="../@frame"/>
+                               </xsl:otherwise>
+                       </xsl:choose>
+               </xsl:variable>
+               <xsl:variable name="colspecs" select="./colspec"/>
+               <xsl:variable name="usex">
+                       <xsl:choose>
+                               <xsl:when test="$latex.use.ltxtable='1'">
+                                       <xsl:text>0</xsl:text>
+                               </xsl:when>
+                               <!-- if there are lists within cells, we need tabularx -->
+                               <xsl:when test="$latex.use.tabularx=1 and (descendant::itemizedlist|descendant::orderedlist|descendant::variablelist)">
+                                       <xsl:text>1</xsl:text>
+                               </xsl:when>
+                               <!-- if there are instances of 1*-style colwidths, we need tabularx -->
+                               <xsl:when test="$latex.use.tabularx=1 and contains(colspec/@colwidth,'*')">
+                                       <xsl:text>1</xsl:text>
+                               </xsl:when>
+                               <!-- if there are colspecs with 'justify' alignment and no explicit width, we need tabularx -->
+                               <xsl:when test="$latex.use.tabularx=1 and count(colspec[@align='justify'])&gt;0">
+                                       <xsl:text>1</xsl:text>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <xsl:text>0</xsl:text>
+                               </xsl:otherwise>
+                       </xsl:choose>
+               </xsl:variable>
+               <xsl:variable name="useminipage">
+                       <!-- Hack to get around LaTeX issue with tabular (not necessary with tabularx).
+                       This is NOT a good solution, and has problems of its own, but at least the footnotes
+                       do not actually disappear (which is what would otherwise happen). -->
+                       <xsl:if test="count(.//footnote)!=0">1</xsl:if>
+               </xsl:variable>
+               <xsl:choose>
+                       <xsl:when test="$usex='1'">
+                               <xsl:text>\begin{tabularx}{\linewidth}{</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="$latex.use.ltxtable='1'">
+                               <xsl:if test="parent::informaltable">
+                                       <xsl:text>\addtocounter{table}{-1}</xsl:text>
+                               </xsl:if>
+                               <xsl:text>\begin{longtable}{</xsl:text>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:if test="$useminipage='1'"><xsl:text>\begin{minipage}{\linewidth}&#10;</xsl:text></xsl:if>
+                               <xsl:text>\begin{tabular}{</xsl:text>
+                       </xsl:otherwise>
+               </xsl:choose>
+               <xsl:if test="$frame='all' or $frame='sides'">
+                       <xsl:text>|</xsl:text>
+               </xsl:if>
+               <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]/entry)"/>
+                                       <xsl:message>Warning: table's tgroup lacks cols attribute. Assuming <xsl:value-of select="count(tbody/row[1]/entry)"/>.</xsl:message>
+                               </xsl:otherwise>
+                       </xsl:choose>
+               </xsl:variable>
+               <xsl:choose>
+                       <xsl:when test="$usex=1">
+                               <xsl:call-template name="table.format.tabularx">
+                                       <xsl:with-param name="cols" select="$cols"/>
+                                       <xsl:with-param name="colsep" select="$colsep"/>
+                                       <xsl:with-param name="starfactor">
+                                               <xsl:call-template name="generate.starfactor">
+                                                       <xsl:with-param name="cols" select="$cols"/>
+                                               </xsl:call-template>
+                                       </xsl:with-param>
+                               </xsl:call-template>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:call-template name="table.format.tabular">
+                                       <xsl:with-param name="cols" select="$cols"/>
+                                       <xsl:with-param name="colsep" select="$colsep"/>
+                               </xsl:call-template>
+                       </xsl:otherwise>
+               </xsl:choose>
+               <xsl:if test="$frame='all' or $frame='sides'">
+                       <xsl:text>|</xsl:text>
+               </xsl:if>
+               <xsl:text>}&#10;</xsl:text>
+               <xsl:variable name="thead.frame">
+                       <xsl:choose>
+                               <xsl:when test="$frame!='sides' and $frame!='none' and $frame!='bottom'">
+                                       <xsl:value-of select="1"/>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <xsl:value-of select="0"/>
+                               </xsl:otherwise>
+                       </xsl:choose>
+               </xsl:variable>
+               <xsl:variable name="tfoot.frame">
+                       <xsl:choose>
+                               <xsl:when test="$frame!='sides' and $frame!='none' and $frame!='top'">
+                                       <xsl:value-of select="1"/>
+                               </xsl:when>
+                               <xsl:otherwise>
+                                       <xsl:value-of select="0"/>
+                               </xsl:otherwise>
+                       </xsl:choose>
+               </xsl:variable>
+               <!-- APPLY TEMPLATES -->
+               <xsl:choose>
+                       <xsl:when test="$latex.use.ltxtable='1' and parent::table">
+                               <!-- for tables only, not informaltables -->
+                               <xsl:variable name="placement">
+                                       <xsl:call-template name="generate.formal.title.placement">
+                                               <xsl:with-param name="object" select="'table'" />
+                                       </xsl:call-template>
+                               </xsl:variable>
+                               <xsl:choose>
+                                       <xsl:when test="$placement='before'">
+                                               <xsl:choose>
+                                                       <xsl:when test="thead">
+                                                               <xsl:apply-templates select="thead" mode="longtable.caption">
+                                                                       <xsl:with-param name="frame" select="$thead.frame"/>
+                                                               </xsl:apply-templates>
+                                                               <xsl:apply-templates select="thead" mode="longtable.caption.continuation">
+                                                                       <xsl:with-param name="frame" select="$thead.frame"/>
+                                                               </xsl:apply-templates>
+                                                       </xsl:when>
+                                                       <xsl:otherwise>
+                                                               <xsl:call-template name="thead.longtable.caption">
+                                                                       <xsl:with-param name="frame" select="$thead.frame"/>
+                                                               </xsl:call-template>
+                                                               <xsl:call-template name="thead.longtable.caption.continuation">
+                                                                       <xsl:with-param name="frame" select="$thead.frame"/>
+                                                               </xsl:call-template>
+                                                       </xsl:otherwise>
+                                               </xsl:choose>
+                                               <xsl:apply-templates select="tfoot">
+                                                       <xsl:with-param name="frame" select="$tfoot.frame"/>
+                                               </xsl:apply-templates>
+                                               <xsl:if test="$tfoot.frame=1 and not(tfoot)">
+                                                       <xsl:text>\hline &#10;</xsl:text>
+                                               </xsl:if>
+                                               <xsl:apply-templates select="tbody"/>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <xsl:if test="$thead.frame=1 and not(thead)">
+                                                       <xsl:text>\hline &#10;</xsl:text>
+                                               </xsl:if>
+                                               <xsl:apply-templates select="thead">
+                                                       <xsl:with-param name="frame" select="$thead.frame"/>
+                                               </xsl:apply-templates>
+                                               <xsl:choose>
+                                                       <xsl:when test="tfoot">
+                                                               <xsl:apply-templates select="tfoot" mode="longtable.caption.continued">
+                                                                       <xsl:with-param name="frame" select="$tfoot.frame"/>
+                                                               </xsl:apply-templates>
+                                                               <xsl:apply-templates select="tfoot" mode="longtable.caption">
+                                                                       <xsl:with-param name="frame" select="$tfoot.frame"/>
+                                                               </xsl:apply-templates>
+                                                       </xsl:when>
+                                                       <xsl:otherwise>
+                                                               <xsl:call-template name="tfoot.longtable.caption.continued">
+                                                                       <xsl:with-param name="frame" select="$tfoot.frame"/>
+                                                               </xsl:call-template>
+                                                               <xsl:call-template name="tfoot.longtable.caption">
+                                                                       <xsl:with-param name="frame" select="$tfoot.frame"/>
+                                                               </xsl:call-template>
+                                                       </xsl:otherwise>
+                                               </xsl:choose>
+                                               <xsl:apply-templates select="tbody"/>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:if test="$thead.frame=1 and not(thead)">
+                                       <xsl:text>\hline &#10;</xsl:text>
+                               </xsl:if>
+                               <xsl:apply-templates select="thead">
+                                       <xsl:with-param name="frame" select="$thead.frame"/>
+                               </xsl:apply-templates>
+                               <xsl:apply-templates select="tbody"/>
+                               <xsl:apply-templates select="tfoot">
+                                       <xsl:with-param name="frame" select="$tfoot.frame"/>
+                               </xsl:apply-templates>
+                               <xsl:if test="$tfoot.frame=1 and not(tfoot)">
+                                       <xsl:text>\hline &#10;</xsl:text>
+                               </xsl:if>
+                       </xsl:otherwise>
+               </xsl:choose>
+               <!--                 -->
+               <xsl:choose>
+                       <xsl:when test="$usex=1">
+                               <xsl:text>\end{tabularx}&#10;</xsl:text>
+                       </xsl:when>
+                       <xsl:when test="$latex.use.ltxtable='1'">
+                               <xsl:text>\end{longtable}&#10;</xsl:text>
+                               <!-- catcode touchup ARGH -->
+                               <xsl:call-template name="generate.latex.cell.separator">
+                                       <xsl:with-param name="which" select="'post'"/>
+                               </xsl:call-template>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:text>\end{tabular}&#10;</xsl:text>
+                               <xsl:if test="$useminipage='1'"><xsl:text>\end{minipage}&#10;</xsl:text></xsl:if>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+       <doc:template xmlns="">
+               <refpurpose>Process <doc:db>colspec</doc:db> elements</refpurpose>
+               <doc:description>
+                       <para>
+                       
+                       Suppressed.
+                       
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+               <doc:notes>
+                       <para>
+
+                               <doc:db basename="colspec">Colspec</doc:db> are interpreted by
+                               the <doc:db>tgroup</doc:db> template.
+
+                       </para>
+               </doc:notes>
+               <doc:samples>
+                       <simplelist type='inline'>
+                               &test_book;
+                               &test_tables;
+                       </simplelist>
+               </doc:samples>
+               <doc:seealso>
+                       <itemizedlist>
+                               <listitem><simpara><xref linkend="template.tgroup"/></simpara></listitem>
+                       </itemizedlist>
+               </doc:seealso>
+       </doc:template>
+       <xsl:template match="colspec"></xsl:template>
+
+       <doc:template xmlns="">
+               <refpurpose>Process <doc:db>spanspec</doc:db> elements</refpurpose>
+               <doc:description>
+                       <para>
+                       
+                       Suppressed.
+                       
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+               <doc:notes>
+                       <para>
+
+                               <doc:db basename="spanspec">Spanspecs</doc:db> are interpreted
+                               by the <doc:db>tgroup</doc:db> template.
+
+                       </para>
+               </doc:notes>
+               <doc:samples>
+                       <simplelist type='inline'>
+                               &test_book;
+                               &test_tables;
+                       </simplelist>
+               </doc:samples>
+               <doc:seealso>
+                       <itemizedlist>
+                               <listitem><simpara><xref linkend="template.tgroup"/></simpara></listitem>
+                       </itemizedlist>
+               </doc:seealso>
+       </doc:template>
+       <xsl:template match="spanspec"></xsl:template>
+
+       <doc:template basename="thead" xmlns="">
+               <refpurpose>Process <doc:db>thead</doc:db> elements</refpurpose>
+               <doc:description>
+                       <para>
+                               Applies templates.
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="thead">
+               <xsl:param name="frame" select="0"/>
+               <xsl:if test="$frame=1">
+                       <xsl:text>\hline &#10;</xsl:text>
+               </xsl:if>
+               <xsl:apply-templates/>
+               <xsl:if test="$latex.use.ltxtable='1'">
+                       <xsl:text> \endhead&#10;</xsl:text>
+               </xsl:if>
+       </xsl:template>
+
+       <doc:template basename="thead" xmlns="">
+               <refpurpose>Process <doc:db>thead</doc:db> elements</refpurpose>
+               <doc:description>
+                       <para>
+                               Emits a caption and calls <function condition="latex">endfirsthead</function>.
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="thead" mode="longtable.caption" name="thead.longtable.caption">
+               <xsl:param name="frame" select="0"/>
+               <xsl:call-template name="generate.table.caption.longtable"/>
+               <xsl:text>\\&#10;</xsl:text><!-- or should this be \tabularnewline? -->
+               <xsl:if test="$frame=1">
+                       <xsl:text>\hline &#10;</xsl:text>
+               </xsl:if>
+               <xsl:apply-templates select="row"/>
+               <xsl:text> \endfirsthead&#10;</xsl:text>
+       </xsl:template>
+
+       <doc:template basename="thead" xmlns="">
+               <refpurpose>Process <doc:db>thead</doc:db> elements</refpurpose>
+               <doc:description>
+                       <para>
+                               Emits a continuation caption and calls <function condition="latex">endhead</function>.
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="thead" mode="longtable.caption.continuation" name="thead.longtable.caption.continuation">
+               <xsl:param name="frame" select="0"/>
+               <xsl:text>\caption[]{</xsl:text>
+               <xsl:value-of select="$latex.table.caption.style"/>
+               <xsl:text>{</xsl:text>
+               <xsl:call-template name="gentext.template">
+                       <xsl:with-param name="context" select="'table'"/>
+                       <xsl:with-param name="name" select="'thead.continuation'"/>
+               </xsl:call-template>
+               <xsl:text>}}\\&#10;</xsl:text><!-- or should this be \tabularnewline? -->
+               <xsl:if test="$frame=1">
+                       <xsl:text>\hline &#10;</xsl:text>
+               </xsl:if>
+               <xsl:apply-templates select="row"/>
+               <xsl:text> \endhead&#10;</xsl:text>
+       </xsl:template>
+
+       <doc:template basename="tfoot" xmlns="">
+               <refpurpose>Process <doc:db>tfoot</doc:db> elements</refpurpose>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="tfoot">
+               <xsl:param name="frame" select="0"/>
+               <xsl:apply-templates/>
+               <xsl:if test="$frame=1">
+                       <xsl:text>\hline &#10;</xsl:text>
+               </xsl:if>
+               <xsl:if test="$latex.use.ltxtable='1'">
+                       <xsl:text> \endfoot&#10;</xsl:text>
+               </xsl:if>
+       </xsl:template>
+
+       <doc:template basename="tfoot" xmlns="">
+               <refpurpose>Process <doc:db>tfoot</doc:db> elements</refpurpose>
+               <doc:description>
+                       <para>
+                               Emits a caption and calls <function condition="latex">endlastfoot</function>.
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="tfoot" mode="longtable.caption" name="tfoot.longtable.caption">
+               <xsl:param name="frame" select="0"/>
+               <xsl:apply-templates select="row"/>
+               <xsl:if test="$frame=1">
+                       <xsl:text>\hline &#10;</xsl:text>
+               </xsl:if>
+               <xsl:call-template name="generate.table.caption.longtable"/>
+               <xsl:text>\\&#10;</xsl:text><!-- or should this be \tabularnewline? -->
+               <xsl:text> \endlastfoot&#10;</xsl:text>
+       </xsl:template>
+
+       <doc:template basename="tfoot" xmlns="">
+               <refpurpose>Process <doc:db>tfoot</doc:db> elements</refpurpose>
+               <doc:description>
+                       <para>
+                               Emits a continuation caption and calls <function condition="latex">endfoot</function>.
+                       </para>
+               </doc:description>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="tfoot" mode="longtable.caption.continued" name="tfoot.longtable.caption.continued">
+               <xsl:param name="frame" select="0"/>
+               <xsl:apply-templates select="row"/>
+               <xsl:if test="$frame=1">
+                       <xsl:text>\hline &#10;</xsl:text>
+               </xsl:if>
+               <xsl:text>\caption[]{</xsl:text>
+               <xsl:value-of select="$latex.table.caption.style"/>
+               <xsl:text>{</xsl:text>
+               <xsl:call-template name="gentext.template">
+                       <xsl:with-param name="context" select="'table'"/>
+                       <xsl:with-param name="name" select="'tfoot.continued'"/>
+               </xsl:call-template>
+               <xsl:text>}}\\&#10;</xsl:text><!-- or should this be \tabularnewline? -->
+               <xsl:text> \endfoot&#10;</xsl:text>
+       </xsl:template>
+
+       <doc:template basename="entry" xmlns="">
+               <refpurpose>Process a <doc:db>thead</doc:db>'s <doc:db>entry</doc:db> elements</refpurpose>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="thead/row/entry">
+               <xsl:call-template name="latex.entry.prealign"/>
+               <xsl:call-template name="latex.thead.row.entry"/>
+               <xsl:call-template name="latex.entry.postalign"/>
+               <xsl:if test="position()&lt;last()">
+                       <xsl:call-template name="generate.latex.cell.separator">
+                               <xsl:with-param name="which" select="'pre'"/>
+                       </xsl:call-template>
+               </xsl:if>
+       </xsl:template>
+
+       <doc:template basename="entry" xmlns="">
+               <refpurpose>Process a <doc:db>tfoot</doc:db>'s <doc:db>entry</doc:db> elements</refpurpose>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="tfoot/row/entry">
+               <xsl:call-template name="latex.entry.prealign"/>
+               <xsl:call-template name="latex.tfoot.row.entry"/>
+               <xsl:call-template name="latex.entry.postalign"/>
+               <xsl:if test="position()&lt;last()">
+                       <xsl:call-template name="generate.latex.cell.separator">
+                               <xsl:with-param name="which" select="'pre'"/>
+                       </xsl:call-template>
+               </xsl:if> 
+       </xsl:template>
+
+       <doc:template xmlns="">
+               <refpurpose>Process <doc:db>tbody</doc:db> elements</refpurpose>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="tbody">
+               <xsl:apply-templates/>
+       </xsl:template>
+
+       <doc:template basename="row" xmlns="">
+               <refpurpose>Process a <doc:db>tbody</doc:db>'s <doc:db>row</doc:db> elements</refpurpose>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="tbody/row">
+               <xsl:apply-templates/>
+               <xsl:text> \tabularnewline&#10;</xsl:text>
+               <xsl:call-template name="generate.table.row.separator"/>
+       </xsl:template>
+
+       <doc:template basename="row" xmlns="">
+               <refpurpose>Process a <doc:db>thead</doc:db>'s <doc:db>row</doc:db> elements</refpurpose>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="thead/row">
+               <xsl:apply-templates/>
+               <xsl:text> \tabularnewline&#10;</xsl:text>
+               <xsl:call-template name="generate.table.row.separator"/>
+       </xsl:template>
+
+       <doc:template basename="row" xmlns="">
+               <refpurpose>Process a <doc:db>tfoot</doc:db>'s <doc:db>row</doc:db> elements</refpurpose>
+               <doc:variables>
+                       &no_var;
+               </doc:variables>
+       </doc:template>
+       <xsl:template match="tfoot/row">
+               <xsl:call-template name="generate.table.row.separator"/>
+               <xsl:apply-templates/>
+               <xsl:text> \tabularnewline&#10;</xsl:text>
+       </xsl:template>
+
+       <!-- The rule below the last row in the table is controlled by the 
+       Frame attribute of the enclosing Table or InformalTable and the RowSep 
+       of the last row is ignored. If unspecified, this attribute is 
+       inherited from enclosing elements, rowsep=1 by default. -->
+    <xsl:template name="generate.table.row.separator">
+               <xsl:param name="rowsep">
+                       <xsl:choose>
+                               <xsl:when test="ancestor::tgroup/@rowsep!=''">
+                                       <xsl:value-of select="number(ancestor::tgroup/@rowsep)"/>
+                               </xsl:when>
+                               <xsl:when test="ancestor::tgroup/../@rowsep!=''">
+                                       <xsl:value-of select="number(ancestor::tgroup/../@rowsep)"/>
+                               </xsl:when>
+                               <xsl:otherwise>1</xsl:otherwise>
+                       </xsl:choose>
+               </xsl:param>
+               <xsl:variable name="parent_position" select="count(../preceding-sibling::node())+1"/>
+               <xsl:variable name="grandparent_children" select="count(../../child::node())"/>
+               <xsl:if test="$rowsep=1 and (position() != last() or $parent_position &lt; $grandparent_children)">
+               <xsl:call-template name="table.row.separator"/>
+               </xsl:if>
+       </xsl:template>
+
+       <xsl:template name="table.row.separator">
+               <xsl:text> \hline &#10;</xsl:text>
+       </xsl:template>
+
+    <xsl:template match="tbody/row/entry">
+       <xsl:call-template name="latex.entry.prealign"/>
+       <xsl:apply-templates/>
+       <xsl:call-template name="latex.entry.postalign"/>
+       <xsl:if test="position()&lt;last()">
+               <xsl:call-template name="generate.latex.cell.separator">
+                       <xsl:with-param name="which" select="'pre'"/>
+               </xsl:call-template>
+       </xsl:if> 
+    </xsl:template>
+
+       <xsl:template name="latex.entry.prealign">
+       <xsl:variable name="span">
+               <xsl:choose>
+                       <xsl:when test="@spanname!=''">
+                               <xsl:call-template name="calculate.colspan">
+                                       <xsl:with-param name="namest" select="../../../spanspec[@spanname=@spanname]/@namest"/>
+                                       <xsl:with-param name="nameend" select="../../../spanspec[@spanname=@spanname]/@nameend"/>
+                               </xsl:call-template>
+                       </xsl:when>
+                       <xsl:when test="@namest!=''">
+                               <xsl:call-template name="calculate.colspan"/>
+                       </xsl:when>
+                       <xsl:otherwise>-1</xsl:otherwise>
+               </xsl:choose>
+       </xsl:variable>
+       <!-- Remember: if multicolumn is present, generate.latex.cell.separator post needs to occur within multicolumn -->
+       <xsl:if test="$span &gt; 1">
+               <xsl:text>\multicolumn{</xsl:text>
+               <xsl:value-of select="$span"/>
+               <xsl:text>}{|</xsl:text><!-- TODO take heed of @colsep on BOTH sides!! -->
+               <xsl:choose>
+                       <xsl:when test="@align='left'"><xsl:text>l</xsl:text></xsl:when>
+                       <xsl:when test="@align='right'"><xsl:text>r</xsl:text></xsl:when>
+                       <xsl:when test="@align='center'"><xsl:text>c</xsl:text></xsl:when>
+                       <xsl:when test="@align='char'">c<xsl:message>Table _entry_ 'char' alignment is not supported.</xsl:message></xsl:when>
+                       <xsl:otherwise>c</xsl:otherwise>
+               </xsl:choose>
+       <!-- use this as a hook for some general warnings -->
+               <xsl:text>|}</xsl:text>
+       </xsl:if>
+       <!-- this is used when the entry's align spec wants to override the column default -->
+       <xsl:if test="$span &lt; 1">
+               <xsl:choose>
+                       <xsl:when test="@align='left'"><xsl:text>\docbooktolatexalignll </xsl:text></xsl:when>
+                       <xsl:when test="@align='right'"><xsl:text>\docbooktolatexalignrl </xsl:text></xsl:when>
+                       <xsl:when test="@align='center'"><xsl:text>\docbooktolatexaligncl </xsl:text></xsl:when>
+                       <xsl:when test="@align='char'"><xsl:message>Table _entry_ char alignment is not supported.</xsl:message></xsl:when>
+               </xsl:choose>
+       </xsl:if>
+       <xsl:text>{</xsl:text>
+       <xsl:call-template name="generate.latex.cell.separator">
+               <xsl:with-param name="which" select="'post'"/>
+       </xsl:call-template>
+       <xsl:if test="@rotate='1'">
+               <xsl:text>\rotatebox{90}</xsl:text>
+               <xsl:if test="@align!=''"><xsl:message>entry[@rotate='1' and @align!=''] probably doesn't work.</xsl:message></xsl:if>
+       </xsl:if>
+       <xsl:text>{</xsl:text>
+       <!-- use this as a hook for some general warnings -->
+       <xsl:if test="@morerows!=''"><xsl:message>The morerows attribute is not supported.</xsl:message></xsl:if>
+       </xsl:template>
+
+       <xsl:template name="latex.entry.postalign">
+       <xsl:text>}}</xsl:text>
+       <!-- this is used when the entry's align spec wants to override the column default -->
+       <xsl:if test="@namest='' and @spanspec=''"><!-- TODO improve -->
+               <xsl:choose>
+                       <xsl:when test="@align='left'"><xsl:text>\docbooktolatexalignlr </xsl:text></xsl:when>
+                       <xsl:when test="@align='right'"><xsl:text>\docbooktolatexalignrr </xsl:text></xsl:when>
+                       <xsl:when test="@align='center'"><xsl:text>\docbooktolatexaligncr </xsl:text></xsl:when>
+               </xsl:choose>
+       </xsl:if>
+       </xsl:template>
+
+    <xsl:template name="process.cell">
+       <xsl:param name="cellgi">td</xsl:param>
+       <xsl:variable name="empty.cell" select="count(node()) = 0"/>
+
+       <xsl:element name="{$cellgi}">
+           <xsl:if test="@morerows">
+               <xsl:attribute name="rowspan">
+                   <xsl:value-of select="@morerows+1"/>
+               </xsl:attribute>
+           </xsl:if>
+           <xsl:if test="@namest">
+               <xsl:attribute name="colspan">
+                   <xsl:call-template name="calculate.colspan"/>
+               </xsl:attribute>
+           </xsl:if>
+           <xsl:if test="@align">
+               <xsl:attribute name="align">
+                   <xsl:value-of select="@align"/>
+               </xsl:attribute>
+           </xsl:if>
+           <xsl:if test="@char">
+               <xsl:attribute name="char">
+                   <xsl:value-of select="@char"/>
+               </xsl:attribute>
+           </xsl:if>
+           <xsl:if test="@charoff">
+               <xsl:attribute name="charoff">
+                   <xsl:value-of select="@charoff"/>
+               </xsl:attribute>
+           </xsl:if>
+           <xsl:if test="@valign">
+               <xsl:attribute name="valign">
+                   <xsl:value-of select="@valign"/>
+               </xsl:attribute>
+           </xsl:if>
+
+           <xsl:choose>
+               <xsl:when test="$empty.cell">
+                   <xsl:text>&#160;</xsl:text>
+               </xsl:when>
+               <xsl:otherwise>
+                   <xsl:apply-templates/>
+               </xsl:otherwise>
+           </xsl:choose>
+       </xsl:element>
+    </xsl:template>
+
+    <xsl:template name="generate.colgroup">
+       <xsl:param name="cols" select="1"/>
+       <xsl:param name="count" select="1"/>
+       <xsl:choose>
+           <xsl:when test="$count>$cols"></xsl:when>
+           <xsl:otherwise>
+               <xsl:call-template name="generate.col">
+                   <xsl:with-param name="countcol" select="$count"/>
+               </xsl:call-template>
+               <xsl:call-template name="generate.colgroup">
+                   <xsl:with-param name="cols" select="$cols"/>
+                   <xsl:with-param name="count" select="$count+1"/>
+               </xsl:call-template>
+           </xsl:otherwise>
+       </xsl:choose>
+    </xsl:template>
+
+    <xsl:template name="generate.col">
+       <xsl:param name="countcol">1</xsl:param>
+       <xsl:param name="colspecs" select="./colspec"/>
+       <xsl:param name="count">1</xsl:param>
+       <xsl:param name="colnum">1</xsl:param>
+
+       <xsl:choose>
+           <xsl:when test="$count>count($colspecs)">
+               <col/>
+           </xsl:when>
+           <xsl:otherwise>
+               <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
+               <xsl:variable name="colspec.colnum">
+                   <xsl:choose>
+                       <xsl:when test="$colspec/@colnum">
+                           <xsl:value-of select="$colspec/@colnum"/>
+                       </xsl:when>
+                       <xsl:otherwise>
+                           <xsl:value-of select="$colnum"/>
+                       </xsl:otherwise>
+                   </xsl:choose>
+               </xsl:variable>
+
+               <xsl:choose>
+                   <xsl:when test="$colspec.colnum=$countcol">
+                       <col>
+                           <xsl:if test="$colspec/@align">
+                               <xsl:attribute name="align">
+                                   <xsl:value-of select="$colspec/@align"/>
+                               </xsl:attribute>
+                           </xsl:if>
+                           <xsl:if test="$colspec/@char">
+                               <xsl:attribute name="char">
+                                   <xsl:value-of select="$colspec/@char"/>
+                               </xsl:attribute>
+                           </xsl:if>
+                           <xsl:if test="$colspec/@charoff">
+                               <xsl:attribute name="charoff">
+                                   <xsl:value-of select="$colspec/@charoff"/>
+                               </xsl:attribute>
+                           </xsl:if>
+                       </col>
+                   </xsl:when>
+                   <xsl:otherwise>
+                       <xsl:call-template name="generate.col">
+                           <xsl:with-param name="countcol" select="$countcol"/>
+                           <xsl:with-param name="colspecs" select="$colspecs"/>
+                           <xsl:with-param name="count" select="$count+1"/>
+                           <xsl:with-param name="colnum">
+                               <xsl:choose>
+                                   <xsl:when test="$colspec/@colnum">
+                                       <xsl:value-of select="$colspec/@colnum + 1"/>
+                                   </xsl:when>
+                                   <xsl:otherwise>
+                                       <xsl:value-of select="$colnum + 1"/>
+                                   </xsl:otherwise>
+                               </xsl:choose>
+                           </xsl:with-param>
+                       </xsl:call-template>
+                   </xsl:otherwise>
+               </xsl:choose>
+           </xsl:otherwise>
+       </xsl:choose>
+
+    </xsl:template>
+
+    <xsl:template name="colspec.colnum">
+       <!-- when this macro is called, the current context must be an entry -->
+       <xsl:param name="colname"></xsl:param>
+       <!-- .. = row, ../.. = thead|tbody, ../../.. = tgroup -->
+       <xsl:param name="colspecs" select="../../../../tgroup/colspec"/>
+       <xsl:param name="count">1</xsl:param>
+       <xsl:param name="colnum">1</xsl:param>
+       <xsl:choose>
+           <xsl:when test="$count>count($colspecs)"></xsl:when>
+           <xsl:otherwise>
+               <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
+               <!--
+               <xsl:value-of select="$count"/>:
+               <xsl:value-of select="$colspec/@colname"/>=
+               <xsl:value-of select="$colnum"/>
+               -->
+               <xsl:choose>
+                   <xsl:when test="$colspec/@colname=$colname">
+                       <xsl:choose>
+                           <xsl:when test="$colspec/@colnum">
+                               <xsl:value-of select="$colspec/@colnum"/>
+                           </xsl:when>
+                           <xsl:otherwise>
+                               <xsl:value-of select="$colnum"/>
+                           </xsl:otherwise>
+                       </xsl:choose>
+                   </xsl:when>
+                   <xsl:otherwise>
+                       <xsl:call-template name="colspec.colnum">
+                           <xsl:with-param name="colname" select="$colname"/>
+                           <xsl:with-param name="colspecs" select="$colspecs"/>
+                           <xsl:with-param name="count" select="$count+1"/>
+                           <xsl:with-param name="colnum">
+                               <xsl:choose>
+                                   <xsl:when test="$colspec/@colnum">
+                                       <xsl:value-of select="$colspec/@colnum + 1"/>
+                                   </xsl:when>
+                                   <xsl:otherwise>
+                                       <xsl:value-of select="$colnum + 1"/>
+                                   </xsl:otherwise>
+                               </xsl:choose>
+                           </xsl:with-param>
+                       </xsl:call-template>
+                   </xsl:otherwise>
+               </xsl:choose>
+           </xsl:otherwise>
+       </xsl:choose>
+    </xsl:template>
+
+    <xsl:template name="colspec.colwidth">
+       <!-- when this macro is called, the current context must be an entry -->
+       <xsl:param name="colname"></xsl:param>
+       <!-- .. = row, ../.. = thead|tbody, ../../.. = tgroup -->
+       <xsl:param name="colspecs" select="../../../../tgroup/colspec"/>
+       <xsl:param name="count">1</xsl:param>
+       <xsl:choose>
+           <xsl:when test="$count>count($colspecs)"></xsl:when>
+           <xsl:otherwise>
+               <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
+               <xsl:choose>
+                   <xsl:when test="$colspec/@colname=$colname">
+                       <xsl:value-of select="$colspec/@colwidth"/>
+                   </xsl:when>
+                   <xsl:otherwise>
+                       <xsl:call-template name="colspec.colwidth">
+                           <xsl:with-param name="colname" select="$colname"/>
+                           <xsl:with-param name="colspecs" select="$colspecs"/>
+                           <xsl:with-param name="count" select="$count+1"/>
+                       </xsl:call-template>
+                   </xsl:otherwise>
+               </xsl:choose>
+           </xsl:otherwise>
+       </xsl:choose>
+    </xsl:template>
+
+    <xsl:template name="calculate.colspan">
+       <xsl:param name="namest" select="@namest"/>
+       <xsl:param name="nameend" select="@nameend"/>
+       <xsl:variable name="scol">
+           <xsl:call-template name="colspec.colnum">
+               <xsl:with-param name="colname" select="$namest"/>
+           </xsl:call-template>
+       </xsl:variable>
+       <xsl:variable name="ecol">
+           <xsl:call-template name="colspec.colnum">
+               <xsl:with-param name="colname" select="$nameend"/>
+           </xsl:call-template>
+       </xsl:variable>
+       <xsl:value-of select="$ecol - $scol + 1"/>
+    </xsl:template>
+
+       <!-- write docs:
+               The pre/post mechanism is to deal with multicolumn, which
+               needs to be the first command within a cell.
+       -->
+       <xsl:template name="generate.latex.cell.separator">
+               <xsl:param name="which"/>
+               <xsl:choose>
+                       <xsl:when test="$which='pre'">
+                               <xsl:if test="$latex.entities='catcode'">
+                                       <xsl:text> \catcode`\&amp;=4</xsl:text>
+                               </xsl:if>
+                               <xsl:text> &amp; </xsl:text>
+                       </xsl:when>
+                       <xsl:when test="$which='post'">
+                               <xsl:if test="$latex.entities='catcode'">
+                                       <xsl:text>\catcode`\&amp;=\active </xsl:text>
+                               </xsl:if>
+                       </xsl:when>
+                       <xsl:otherwise>
+                               <xsl:choose>
+                                       <xsl:when test="$latex.entities='catcode'">
+                                               <xsl:text> \catcode`\&amp;=4 &amp;\catcode`\&amp;=\active </xsl:text>
+                                       </xsl:when>
+                                       <xsl:otherwise>
+                                               <xsl:text> &amp; </xsl:text>
+                                       </xsl:otherwise>
+                               </xsl:choose>
+                       </xsl:otherwise>
+               </xsl:choose>
+       </xsl:template>
+
+</xsl:stylesheet>