This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
tabellioOOo/legi2pdf/xsl/table.xsl

495 lines
18 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!--
Tabellio - software suite for deliberative assemblies
- suite logicielle pour assemblées délibératives
- http://www.tabellio.org/
Copyright (C) 2006 Parlement de la Communauté française de Belgique
This file is part of Tabellio.
Tabellio is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Tabellio is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
<!-- FileName: table.xsl -->
<!--
Purpose: Customize Db2Latex product for table; the major differences are:
o Generate a table across the two columns or inside one column
depending on the total width of the table columns.
o Adapt the width of the table columns depending on the width of
the page column (two columns style) or the width of the entire page.
o Generate a floating element
o Generate a threeparttable
-->
<!-- Sum the width of table columns -->
<!-- Hypothesis: the width is given using 'pt' metric -->
<xsl:param name="bqr"/>
<xsl:template name="table.sum-width">
<xsl:param name="list"/>
<xsl:choose>
<xsl:when test="$list">
<xsl:variable name="width" select="substring-before($list[1], 'pt')"/>
<xsl:variable name="otherWidth">
<!-- Recursive for next column -->
<xsl:call-template name="table.sum-width">
<xsl:with-param name="list" select="$list[position() != 1]"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$otherWidth + $width"/>
</xsl:when>
<!-- Out of the recursive iteration -->
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="table.get-type">
<xsl:param name="table" value="."/>
<xsl:variable name="total-width">
<xsl:call-template name="table.sum-width">
<xsl:with-param name="list" select="$table/tgroup[1]/colspec/@colwidth"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$bqr">longwide</xsl:when>
<xsl:when test="$total-width &gt; $table-width-threshold">longwide</xsl:when>
<xsl:when test="$parchemin and $total-width &gt; $table-width-parchemin-threshold">longwide</xsl:when>
<xsl:otherwise>narrow</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Generate the latex specification of the table column p{width-specification}... -->
<xsl:template name="table.format.tabular">
<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:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="total-width">
<xsl:call-template name="table.sum-width">
<xsl:with-param name="list" select="./colspec/@colwidth"/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="table.generate.format.tabular">
<xsl:with-param name="cols" select="$cols"/>
<xsl:with-param name="colsep" select="0"/>
<xsl:with-param name="total-width" select="$total-width"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="table.generate.format.tabular">
<xsl:param name="cols" select="1"/>
<xsl:param name="i" select="1"/>
<xsl:param name="colsep" select="0"/>
<xsl:param name="total-width"/>
<xsl:choose>
<!-- Out of the recursive iteration -->
<xsl:when test="$i > $cols"></xsl:when>
<!-- There are still columns to count -->
<xsl:otherwise>
<!-- define the width of the current column:
'$currentWidth div $totalWidth'\mytablewidth
where 'mytablewidth' is a latex length taking into account
the width available for the columns
-->
<xsl:variable name="width-specification">
<xsl:choose>
<xsl:when test="./colspec">
<xsl:variable name="current-width">
<xsl:choose>
<xsl:when test="substring-before(./colspec[@colnum=$i], 'pt')">
<xsl:value-of select="./colspec[@colnum=$i]/@colwidth"/>
</xsl:when>
<xsl:otherwise test="./colspec[position()=$i]/@colwidth">
<xsl:value-of select="substring-before(./colspec[position()=$i]/@colwidth, 'pt')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="concat($current-width div $total-width,'\mytablewidth')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="1 div number(@cols)"/>\mytablewidth
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="cells" select="thead/row/entry[$i]|tbody/row/entry[$i]"/>
</xsl:variable>
<!-- Keep the @align attribute of the colspec node -->
<xsl:variable name="useralign">
<xsl:choose>
<xsl:when test="./colspec[@colnum=$i]">
<xsl:value-of select="./colspec[@colnum=$i]/@align"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="./colspec[position()=$i]/@align"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<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-specification" /><xsl:text>}</xsl:text>
<xsl:if test="$i&lt;$cols and $colsep='1'">
<xsl:text>|</xsl:text>
</xsl:if>
<!-- Recursive for next column -->
<xsl:call-template name="table.generate.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:with-param name="total-width" select="$total-width"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Template to generate the row of the table body
Remark: no \hline is generated
-->
<xsl:template match="tbody/row">
<xsl:apply-templates/>
<xsl:text> \tabularnewline&#10;</xsl:text>
</xsl:template>
<!-- Template to generate the row of the table header
Remark: \hline are generated before and after the header rows
-->
<xsl:template match="thead/row">
<xsl:apply-templates/>
<xsl:text> \tabularnewline&#10;</xsl:text>
</xsl:template>
<!-- Template to generate the row of the table footer
Remark: \hline are generated before and after the footer rows
-->
<xsl:template match="tfoot/row">
<xsl:apply-templates/>
<xsl:text> \tabularnewline&#10;</xsl:text>
</xsl:template>
<!-- Template to generate the content of the mpsupertabular table
Hypothesis: only one tgroup per table
-->
<xsl:template match="tgroup" mode="mpsupertabular">
<xsl:variable name="colspecs" select="./colspec"/>
<xsl:variable name="align" select="@align"/>
<xsl:variable name="colsep">0</xsl:variable>
<!-- APPLY TEMPLATES -->
<xsl:choose>
<xsl:when test="thead">
<xsl:text>\tablefirsthead{&#10;</xsl:text>
<xsl:text>\hline&#10;</xsl:text>
<xsl:apply-templates select="thead"/>
<xsl:text>\hline&#10;</xsl:text>
<xsl:text>}&#10;</xsl:text>
<xsl:text>\tablehead{&#10;</xsl:text>
<xsl:text>\hline&#10;</xsl:text>
<xsl:apply-templates select="thead"/>
<xsl:text>\hline&#10;</xsl:text>
<xsl:text>}&#10;</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>\tablefirsthead{}&#10;</xsl:text>
<xsl:text>\tablehead{}&#10;</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text>\begin{mpsupertabular}{</xsl:text>
<xsl:call-template name="table.format.tabular"/>
<xsl:text>}&#10;</xsl:text>
<xsl:apply-templates select="tbody"/>
<xsl:text>\end{mpsupertabular}&#10;</xsl:text>
</xsl:template>
<!-- Template to generate the content of the threeparttable table
Hypothesis: only one tgroup per table
-->
<xsl:template match="tgroup" mode="threeparttable">
<xsl:variable name="colspecs" select="./colspec"/>
<xsl:variable name="align" select="@align"/>
<xsl:variable name="colsep">0</xsl:variable>
<!-- APPLY TEMPLATES -->
<xsl:text>\begin{threeparttable}&#10;</xsl:text>
<xsl:text>\begin{tabular}{</xsl:text>
<xsl:call-template name="table.format.tabular"/>
<xsl:text>}&#10;</xsl:text>
<xsl:if test="thead">
<xsl:text>\hline &#10;</xsl:text>
<xsl:apply-templates select="thead"/>
<xsl:text>\hline &#10;</xsl:text>
</xsl:if>
<xsl:apply-templates select="tbody"/>
<xsl:text>\end{tabular}&#10;</xsl:text>
<xsl:if test=".//footnote">
<xsl:text>\rule{1.8cm}{1pt}&#10;</xsl:text>
<xsl:text>\begin{tablenotes}&#10;</xsl:text>
<xsl:call-template name="table-footnote-generation">
<xsl:with-param name="footnotes" select=".//footnote"/>
<xsl:with-param name="index" select="1"/>
</xsl:call-template>
<xsl:text>\end{tablenotes}&#10;</xsl:text>
</xsl:if>
<xsl:text>\end{threeparttable}&#10;</xsl:text>
</xsl:template>
<!-- Template to generate the content of a normal table
Hypothesis: only one tgroup per table
-->
<xsl:template match="tgroup" mode="tabular">
<xsl:variable name="colspecs" select="./colspec"/>
<xsl:variable name="align" select="@align"/>
<xsl:variable name="colsep">0</xsl:variable>
<!-- APPLY TEMPLATES -->
<xsl:text>\begin{tabular}{</xsl:text>
<xsl:call-template name="table.format.tabular"/>
<xsl:text>}&#10;</xsl:text>
<xsl:if test="thead">
<xsl:text>\hline &#10;</xsl:text>
<xsl:apply-templates select="thead"/>
<xsl:text>\hline &#10;</xsl:text>
</xsl:if>
<xsl:apply-templates select="tbody"/>
<xsl:text>\end{tabular}&#10;</xsl:text>
</xsl:template>
<!-- Template to generate the footnotes just after the table
-->
<xsl:template name="table-footnote-generation">
<xsl:param name="footnotes"/>
<xsl:param name="index" select="1"/>
<xsl:choose>
<xsl:when test="$index > count($footnotes)">
</xsl:when>
<xsl:otherwise>
<xsl:text>\item[</xsl:text>
<xsl:number value="$index" format="a" />
<xsl:text>] {</xsl:text>
<xsl:apply-templates select="$footnotes[$index]/*"/>
<xsl:text>}</xsl:text>
<xsl:call-template name="table-footnote-generation">
<xsl:with-param name="footnotes" select="$footnotes"/>
<xsl:with-param name="index" select="$index+1"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Entry rule for table generation
-->
<xsl:template match="table">
<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>
<!-- Keep the table position specification (default: htb) -->
<xsl:variable name="position">
<xsl:choose>
<xsl:when test="@condition">
<xsl:value-of select="@condition"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>htb</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="table.type">
<xsl:call-template name="table.get-type">
<xsl:with-param name="table" select="."/>
</xsl:call-template>
</xsl:variable>
<!-- Keep the caption -->
<xsl:variable name="table.caption.mpsupertabular">
<xsl:choose>
<xsl:when test="title">
<xsl:value-of select="$latex.table.caption.style"/>
<xsl:text>\tablecaption{</xsl:text>
<xsl:if test="title/@id">
<xsl:text>\label{</xsl:text>
<xsl:value-of select="title/@id"/>
<xsl:text>}</xsl:text>
</xsl:if>
<xsl:call-template name="label.id"/>
<xsl:apply-templates select="title" mode="caption.mode"/>
<xsl:text>}</xsl:text>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="table.caption.threeparttable">
<xsl:choose>
<xsl:when test="title">
<xsl:value-of select="$latex.table.caption.style"/>
<xsl:text>\caption{</xsl:text>
<xsl:if test="title/@id">
<xsl:text>\label{</xsl:text>
<xsl:value-of select="title/@id"/>
<xsl:text>}</xsl:text>
</xsl:if>
<xsl:call-template name="label.id"/>
<xsl:apply-templates select="title" mode="caption.mode"/>
<xsl:text>}</xsl:text>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Calculate the total width of the table -->
<xsl:variable name="total-width">
<xsl:call-template name="table.sum-width">
<xsl:with-param name="list" select="./tgroup[1]/colspec/@colwidth"/>
</xsl:call-template>
</xsl:variable>
<!-- Keep the number of columns -->
<xsl:variable name="nbr-cols">
<xsl:choose>
<xsl:when test="./tgroup[1]/@cols">
<xsl:value-of select="./tgroup[1]/@cols"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="count(./tgroup[1]/tbody/row[1]/entry)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Core part of the template: Code generation -->
<xsl:text>&#10;</xsl:text>
<xsl:text>% Begin table definition (table type:</xsl:text>
<xsl:value-of select="$table.type"/>
<xsl:text>)&#10;</xsl:text>
<xsl:text>% ---------------------- &#10;&#10;</xsl:text>
<xsl:text>\setlength{\mytempvalue}{</xsl:text>
<xsl:value-of select="concat($total-width,'pt')"/>
<xsl:text>}&#10;</xsl:text>
<xsl:choose>
<xsl:when test="$table.type = 'longwide'"> <!-- long and wide table -->
<xsl:text>% The table wide (and possibly long)&#10;</xsl:text>
<xsl:if test="$parchemin">
<xsl:text>\end{changemargin}&#10;</xsl:text>
<xsl:text>\begin{changemargin}{0cm}{0cm}&#10;</xsl:text>
</xsl:if>
<xsl:if test="not($parchemin or ancestor::preface)">
<xsl:text>\end{multicols}&#10;</xsl:text>
</xsl:if>
<xsl:text>\begin{changemargin}{0cm}{0cm}&#10;</xsl:text>
<xsl:text>\setlength{\mytablewidth}{\textwidth}&#10;</xsl:text>
<xsl:text>\addtolength{\mytablewidth}{-</xsl:text>
<xsl:value-of select="$nbr-cols * 2"/>
<xsl:text>\tabcolsep}&#10;</xsl:text>
<xsl:value-of select="$table.caption.mpsupertabular" />
<xsl:text>&#10;%&#10;%&#10;%&#10;</xsl:text>
<xsl:apply-templates select="tgroup[1]" mode="mpsupertabular"/>
<xsl:text>\begin{center}&#10;&#10;</xsl:text>
<xsl:text>\vskip 3ex&#10;</xsl:text>
<xsl:if test="$pdfgen.parlement != 'PFB'">
<xsl:text>* *\\[-2mm]&#10;</xsl:text>
<xsl:text>*&#10;</xsl:text>
</xsl:if>
<xsl:text>\end{center}&#10;</xsl:text>
<xsl:text>\end{changemargin}&#10;</xsl:text>
<xsl:if test="not($parchemin or ancestor::preface)">
<xsl:text>\begin{multicols}{2}&#10;</xsl:text>
</xsl:if>
<xsl:if test="$parchemin">
<xsl:text>\end{changemargin}&#10;</xsl:text>
<xsl:text>\begin{changemargin}{4.25cm}{4.25cm}&#10;</xsl:text>
</xsl:if>
</xsl:when>
<xsl:otherwise> <!-- narrow -->
<xsl:text>% The table is not floating: using straight tabular environment&#10;</xsl:text>
<xsl:text>\setlength{\mytablewidth}{\columnwidth}&#10;</xsl:text>
<xsl:if test="$parchemin">
<xsl:text>\addtolength{\mytablewidth}{-9.5cm}</xsl:text>
</xsl:if>
<xsl:text>\addtolength{\mytablewidth}{-</xsl:text>
<xsl:value-of select="$nbr-cols * 2"/>
<xsl:text>\tabcolsep}&#10;</xsl:text>
<xsl:if test='$bqr'>
<xsl:text>\addtolength{\mytablewidth}{-2cm}&#10;</xsl:text>
</xsl:if>
<xsl:text>\vskip 1ex&#10;</xsl:text>
<xsl:if test="title">
<xsl:value-of select="$table.caption.mpsupertabular" />
<xsl:text>&#10;%&#10;%&#10;%&#10;</xsl:text>
<xsl:apply-templates select="tgroup[1]" mode="mpsupertabular"/>
</xsl:if>
<xsl:if test="not(title)">
<xsl:apply-templates select="tgroup[1]" mode="tabular"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:text>% End table definition&#10;</xsl:text>
<xsl:text>% ------------------------ &#10;</xsl:text>
</xsl:template>
</xsl:stylesheet>