]> git.evergreen-ils.org Git - working/Evergreen.git/blob - stylesheets/styleguide/docbook-xsl-1.75.2/fo/table.xsl
stylesheet changes.
[working/Evergreen.git] / stylesheets / styleguide / docbook-xsl-1.75.2 / fo / table.xsl
1 <?xml version='1.0'?>
2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3                 xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
4                 xmlns:fo="http://www.w3.org/1999/XSL/Format"
5                 xmlns:rx="http://www.renderx.com/XSL/Extensions"
6                 xmlns:stbl="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.Table"
7                 xmlns:xtbl="com.nwalsh.xalan.Table"
8                 xmlns:lxslt="http://xml.apache.org/xslt"
9                 xmlns:ptbl="http://nwalsh.com/xslt/ext/xsltproc/python/Table"
10                 exclude-result-prefixes="doc stbl xtbl lxslt ptbl"
11                 version='1.0'>
12
13 <xsl:include href="../common/table.xsl"/>
14
15 <!-- ********************************************************************
16      $Id: table.xsl 8392 2009-04-01 08:47:55Z bobstayton $
17      ********************************************************************
18
19      This file is part of the XSL DocBook Stylesheet distribution.
20      See ../README or http://docbook.sf.net/release/xsl/current/ for
21      copyright and other information.
22
23      ******************************************************************** -->
24
25 <doc:reference xmlns="" xml:id="table-templates">
26   <?dbhtml dir="fo"?>
27   <info>
28     <title>Formatting Object Table Reference</title>
29     <releaseinfo role="meta">
30       $Id: table.xsl 8392 2009-04-01 08:47:55Z bobstayton $
31     </releaseinfo>
32   </info>
33   <partintro xml:id="partintro">
34     <title>Introduction</title>
35     <para>This is technical reference documentation for the FO
36       table-processing templates in the DocBook XSL Stylesheets.</para>
37     <para>This is not intended to be user documentation.  It is
38       provided for developers writing customization layers for the
39       stylesheets.</para>
40   </partintro>
41 </doc:reference>
42
43 <!-- ==================================================================== -->
44
45 <lxslt:component prefix="xtbl"
46                  functions="adjustColumnWidths"/>
47
48 <!-- ==================================================================== -->
49
50 <xsl:template name="make.table.content">
51   <xsl:choose>
52     <xsl:when test="tgroup|mediaobject|graphic">
53       <xsl:call-template name="calsTable"/>
54     </xsl:when>
55     <xsl:otherwise>
56       <xsl:apply-templates select="." mode="htmlTable"/>
57     </xsl:otherwise>
58   </xsl:choose>
59 </xsl:template>
60
61 <!-- ==================================================================== -->
62
63 <xsl:template name="calsTable">
64
65   <xsl:variable name="keep.together">
66     <xsl:call-template name="pi.dbfo_keep-together"/>
67   </xsl:variable>
68
69   <xsl:for-each select="tgroup">
70
71     <fo:table xsl:use-attribute-sets="table.table.properties">
72       <xsl:if test="$keep.together != ''">
73         <xsl:attribute name="keep-together.within-column">
74           <xsl:value-of select="$keep.together"/>
75         </xsl:attribute>
76       </xsl:if>
77       <xsl:call-template name="table.frame"/>
78       <xsl:if test="following-sibling::tgroup">
79         <xsl:attribute name="border-bottom-width">0pt</xsl:attribute>
80         <xsl:attribute name="border-bottom-style">none</xsl:attribute>
81         <xsl:attribute name="padding-bottom">0pt</xsl:attribute>
82         <xsl:attribute name="margin-bottom">0pt</xsl:attribute>
83         <xsl:attribute name="space-after">0pt</xsl:attribute>
84         <xsl:attribute name="space-after.minimum">0pt</xsl:attribute>
85         <xsl:attribute name="space-after.optimum">0pt</xsl:attribute>
86         <xsl:attribute name="space-after.maximum">0pt</xsl:attribute>
87       </xsl:if>
88       <xsl:if test="preceding-sibling::tgroup">
89         <xsl:attribute name="border-top-width">0pt</xsl:attribute>
90         <xsl:attribute name="border-top-style">none</xsl:attribute>
91         <xsl:attribute name="padding-top">0pt</xsl:attribute>
92         <xsl:attribute name="margin-top">0pt</xsl:attribute>
93         <xsl:attribute name="space-before">0pt</xsl:attribute>
94         <xsl:attribute name="space-before.minimum">0pt</xsl:attribute>
95         <xsl:attribute name="space-before.optimum">0pt</xsl:attribute>
96         <xsl:attribute name="space-before.maximum">0pt</xsl:attribute>
97       </xsl:if>
98       <xsl:apply-templates select="."/>
99     </fo:table>
100
101     <xsl:for-each select="mediaobject|graphic">
102       <xsl:apply-templates select="."/>
103     </xsl:for-each>
104
105   </xsl:for-each>
106 </xsl:template>
107
108 <!-- ==================================================================== -->
109
110 <!-- Placeholder template enables wrapping a fo:table in
111      another table for purposes of layout or applying
112      extensions such as XEP table-omit-initial-header to
113      create "continued" titles on page breaks. -->
114 <xsl:template name="table.layout">
115   <xsl:param name="table.content" select="NOTANODE"/>
116
117   <xsl:copy-of select="$table.content"/>
118 </xsl:template>
119
120 <xsl:template name="table.block">
121   <xsl:param name="table.layout" select="NOTANODE"/>
122
123   <xsl:variable name="id">
124     <xsl:call-template name="object.id"/>
125   </xsl:variable>
126
127   <xsl:variable name="param.placement"
128                 select="substring-after(normalize-space(
129                    $formal.title.placement), concat(local-name(.), ' '))"/>
130
131   <xsl:variable name="placement">
132     <xsl:choose>
133       <xsl:when test="contains($param.placement, ' ')">
134         <xsl:value-of select="substring-before($param.placement, ' ')"/>
135       </xsl:when>
136       <xsl:when test="$param.placement = ''">before</xsl:when>
137       <xsl:otherwise>
138         <xsl:value-of select="$param.placement"/>
139       </xsl:otherwise>
140     </xsl:choose>
141   </xsl:variable>
142
143   <xsl:variable name="keep.together">
144     <xsl:call-template name="pi.dbfo_keep-together"/>
145   </xsl:variable>
146
147   <xsl:choose>
148     <xsl:when test="self::table">
149       <fo:block id="{$id}"
150                 xsl:use-attribute-sets="table.properties">
151         <xsl:if test="$keep.together != ''">
152           <xsl:attribute name="keep-together.within-column">
153             <xsl:value-of select="$keep.together"/>
154           </xsl:attribute>
155         </xsl:if>
156         <xsl:if test="$placement = 'before'">
157           <xsl:call-template name="formal.object.heading">
158             <xsl:with-param name="placement" select="$placement"/>
159           </xsl:call-template>
160         </xsl:if>
161         <xsl:copy-of select="$table.layout"/>
162         <xsl:call-template name="table.footnote.block"/>
163         <xsl:if test="$placement != 'before'">
164           <xsl:call-template name="formal.object.heading">
165             <xsl:with-param name="placement" select="$placement"/>
166           </xsl:call-template>
167         </xsl:if>
168       </fo:block>
169     </xsl:when>
170     <xsl:otherwise>
171       <fo:block id="{$id}"
172                 xsl:use-attribute-sets="informaltable.properties">
173         <xsl:copy-of select="$table.layout"/>
174         <xsl:call-template name="table.footnote.block"/>
175       </fo:block>
176     </xsl:otherwise>
177   </xsl:choose>
178
179
180 </xsl:template>
181
182 <!-- Output a table's footnotes in a block -->
183 <xsl:template name="table.footnote.block">
184   <xsl:if test=".//footnote">
185     <fo:block keep-with-previous.within-column="always">
186       <xsl:apply-templates select=".//footnote" mode="table.footnote.mode"/>
187     </fo:block>
188   </xsl:if>
189 </xsl:template>
190
191 <!-- ==================================================================== -->
192
193 <xsl:template name="table.container">
194   <xsl:param name="table.block"/>
195   <xsl:choose>
196     <xsl:when test="@orient='land' and 
197                     $fop.extensions = 0 and 
198                     $passivetex.extensions = 0" >
199       <fo:block-container reference-orientation="90"
200             padding="6pt"
201             xsl:use-attribute-sets="list.block.spacing">
202         <xsl:attribute name="width">
203           <xsl:call-template name="table.width"/>
204         </xsl:attribute>
205         <fo:block start-indent="0pt" end-indent="0pt">
206           <xsl:copy-of select="$table.block"/>
207         </fo:block>
208       </fo:block-container>
209     </xsl:when>
210     <xsl:when test="@pgwide = 1">
211       <fo:block xsl:use-attribute-sets="pgwide.properties">
212         <xsl:copy-of select="$table.block"/>
213       </fo:block>
214     </xsl:when>
215     <xsl:otherwise>
216       <xsl:copy-of select="$table.block"/>
217     </xsl:otherwise>
218   </xsl:choose>
219 </xsl:template>
220
221 <!-- ==================================================================== -->
222
223 <xsl:template name="empty.table.cell">
224   <xsl:param name="colnum" select="0"/>
225
226   <xsl:variable name="rowsep">
227     <xsl:choose>
228       <!-- If this is the last row, rowsep never applies (except when 
229            the ancestor tgroup has a following sibling tgroup) -->
230       <xsl:when test="not(ancestor-or-self::row[1]/following-sibling::row
231                           or ancestor-or-self::thead/following-sibling::tbody
232                           or ancestor-or-self::tbody/preceding-sibling::tfoot)
233                           and not(ancestor::tgroup/following-sibling::tgroup)">
234         <xsl:value-of select="0"/>
235       </xsl:when>
236       <xsl:otherwise>
237         <xsl:call-template name="inherited.table.attribute">
238           <xsl:with-param name="entry" select="NOT-AN-ELEMENT-NAME"/>
239           <xsl:with-param name="row" select="ancestor-or-self::row[1]"/>
240           <xsl:with-param name="colnum" select="$colnum"/>
241           <xsl:with-param name="attribute" select="'rowsep'"/>
242         </xsl:call-template>
243       </xsl:otherwise>
244     </xsl:choose>
245   </xsl:variable>
246
247   <xsl:variable name="colsep">
248     <xsl:choose>
249       <!-- If this is the last column, colsep never applies. -->
250       <xsl:when test="number($colnum) &gt;= ancestor::tgroup/@cols">0</xsl:when>
251       <xsl:otherwise>
252         <xsl:call-template name="inherited.table.attribute">
253           <xsl:with-param name="entry" select="NOT-AN-ELEMENT-NAME"/>
254           <xsl:with-param name="row" select="ancestor-or-self::row[1]"/>
255           <xsl:with-param name="colnum" select="$colnum"/>
256           <xsl:with-param name="attribute" select="'colsep'"/>
257         </xsl:call-template>
258       </xsl:otherwise>
259     </xsl:choose>
260   </xsl:variable>
261
262   <fo:table-cell text-align="center"
263                  display-align="center"
264                  xsl:use-attribute-sets="table.cell.padding">
265     <xsl:if test="$xep.extensions != 0">
266       <!-- Suggested by RenderX to workaround a bug in their implementation -->
267       <xsl:attribute name="keep-together.within-column">always</xsl:attribute>
268     </xsl:if>
269     <xsl:if test="$rowsep &gt; 0">
270       <xsl:call-template name="border">
271         <xsl:with-param name="side" select="'bottom'"/>
272       </xsl:call-template>
273     </xsl:if>
274
275     <xsl:if test="$colsep &gt; 0 and number($colnum) &lt; ancestor::tgroup/@cols">
276       <xsl:call-template name="border">
277         <xsl:with-param name="side" select="'end'"/>
278       </xsl:call-template>
279     </xsl:if>
280
281     <!-- fo:table-cell should not be empty -->
282     <fo:block/>
283   </fo:table-cell>
284 </xsl:template>
285
286 <!-- ==================================================================== -->
287 <xsl:template name="table.frame">
288   <xsl:param name="frame">
289     <xsl:choose>
290       <xsl:when test="../@frame">
291         <xsl:value-of select="../@frame"/>
292       </xsl:when>
293       <xsl:when test="$default.table.frame != ''">
294         <xsl:value-of select="$default.table.frame"/>
295       </xsl:when>
296       <xsl:otherwise>all</xsl:otherwise>
297     </xsl:choose>
298   </xsl:param>
299
300
301   <xsl:choose>
302     <xsl:when test="$frame='all'">
303       <xsl:attribute name="border-start-style">
304         <xsl:value-of select="$table.frame.border.style"/>
305       </xsl:attribute>
306       <xsl:attribute name="border-end-style">
307         <xsl:value-of select="$table.frame.border.style"/>
308       </xsl:attribute>
309       <xsl:attribute name="border-top-style">
310         <xsl:value-of select="$table.frame.border.style"/>
311       </xsl:attribute>
312       <xsl:attribute name="border-bottom-style">
313         <xsl:value-of select="$table.frame.border.style"/>
314       </xsl:attribute>
315       <xsl:attribute name="border-start-width">
316         <xsl:value-of select="$table.frame.border.thickness"/>
317       </xsl:attribute>
318       <xsl:attribute name="border-end-width">
319         <xsl:value-of select="$table.frame.border.thickness"/>
320       </xsl:attribute>
321       <xsl:attribute name="border-top-width">
322         <xsl:value-of select="$table.frame.border.thickness"/>
323       </xsl:attribute>
324       <xsl:attribute name="border-bottom-width">
325         <xsl:value-of select="$table.frame.border.thickness"/>
326       </xsl:attribute>
327       <xsl:attribute name="border-start-color">
328         <xsl:value-of select="$table.frame.border.color"/>
329       </xsl:attribute>
330       <xsl:attribute name="border-end-color">
331         <xsl:value-of select="$table.frame.border.color"/>
332       </xsl:attribute>
333       <xsl:attribute name="border-top-color">
334         <xsl:value-of select="$table.frame.border.color"/>
335       </xsl:attribute>
336       <xsl:attribute name="border-bottom-color">
337         <xsl:value-of select="$table.frame.border.color"/>
338       </xsl:attribute>
339     </xsl:when>
340     <xsl:when test="$frame='bottom'">
341       <xsl:attribute name="border-start-style">none</xsl:attribute>
342       <xsl:attribute name="border-end-style">none</xsl:attribute>
343       <xsl:attribute name="border-top-style">none</xsl:attribute>
344       <xsl:attribute name="border-bottom-style">
345         <xsl:value-of select="$table.frame.border.style"/>
346       </xsl:attribute>
347       <xsl:attribute name="border-bottom-width">
348         <xsl:value-of select="$table.frame.border.thickness"/>
349       </xsl:attribute>
350       <xsl:attribute name="border-bottom-color">
351         <xsl:value-of select="$table.frame.border.color"/>
352       </xsl:attribute>
353     </xsl:when>
354     <xsl:when test="$frame='sides'">
355       <xsl:attribute name="border-start-style">
356         <xsl:value-of select="$table.frame.border.style"/>
357       </xsl:attribute>
358       <xsl:attribute name="border-end-style">
359         <xsl:value-of select="$table.frame.border.style"/>
360       </xsl:attribute>
361       <xsl:attribute name="border-top-style">none</xsl:attribute>
362       <xsl:attribute name="border-bottom-style">none</xsl:attribute>
363       <xsl:attribute name="border-start-width">
364         <xsl:value-of select="$table.frame.border.thickness"/>
365       </xsl:attribute>
366       <xsl:attribute name="border-end-width">
367         <xsl:value-of select="$table.frame.border.thickness"/>
368       </xsl:attribute>
369       <xsl:attribute name="border-start-color">
370         <xsl:value-of select="$table.frame.border.color"/>
371       </xsl:attribute>
372       <xsl:attribute name="border-end-color">
373         <xsl:value-of select="$table.frame.border.color"/>
374       </xsl:attribute>
375     </xsl:when>
376     <xsl:when test="$frame='lhs'">
377       <xsl:attribute name="border-start-style">
378         <xsl:value-of select="$table.frame.border.style"/>
379       </xsl:attribute>
380       <xsl:attribute name="border-end-style">none</xsl:attribute>
381       <xsl:attribute name="border-top-style">none</xsl:attribute>
382       <xsl:attribute name="border-bottom-style">none</xsl:attribute>
383       <xsl:attribute name="border-start-width">
384         <xsl:value-of select="$table.frame.border.thickness"/>
385       </xsl:attribute>
386       <xsl:attribute name="border-start-color">
387         <xsl:value-of select="$table.frame.border.color"/>
388       </xsl:attribute>
389     </xsl:when>
390     <xsl:when test="$frame='rhs'">
391       <xsl:attribute name="border-end-style">
392         <xsl:value-of select="$table.frame.border.style"/>
393       </xsl:attribute>
394       <xsl:attribute name="border-end-style">none</xsl:attribute>
395       <xsl:attribute name="border-top-style">none</xsl:attribute>
396       <xsl:attribute name="border-bottom-style">none</xsl:attribute>
397       <xsl:attribute name="border-end-width">
398         <xsl:value-of select="$table.frame.border.thickness"/>
399       </xsl:attribute>
400       <xsl:attribute name="border-end-color">
401         <xsl:value-of select="$table.frame.border.color"/>
402       </xsl:attribute>
403     </xsl:when>
404     <xsl:when test="$frame='top'">
405       <xsl:attribute name="border-start-style">none</xsl:attribute>
406       <xsl:attribute name="border-end-style">none</xsl:attribute>
407       <xsl:attribute name="border-top-style">
408         <xsl:value-of select="$table.frame.border.style"/>
409       </xsl:attribute>
410       <xsl:attribute name="border-bottom-style">none</xsl:attribute>
411       <xsl:attribute name="border-top-width">
412         <xsl:value-of select="$table.frame.border.thickness"/>
413       </xsl:attribute>
414       <xsl:attribute name="border-top-color">
415         <xsl:value-of select="$table.frame.border.color"/>
416       </xsl:attribute>
417     </xsl:when>
418     <xsl:when test="$frame='topbot'">
419       <xsl:attribute name="border-start-style">none</xsl:attribute>
420       <xsl:attribute name="border-end-style">none</xsl:attribute>
421       <xsl:attribute name="border-top-style">
422         <xsl:value-of select="$table.frame.border.style"/>
423       </xsl:attribute>
424       <xsl:attribute name="border-bottom-style">
425         <xsl:value-of select="$table.frame.border.style"/>
426       </xsl:attribute>
427       <xsl:attribute name="border-top-width">
428         <xsl:value-of select="$table.frame.border.thickness"/>
429       </xsl:attribute>
430       <xsl:attribute name="border-bottom-width">
431         <xsl:value-of select="$table.frame.border.thickness"/>
432       </xsl:attribute>
433       <xsl:attribute name="border-top-color">
434         <xsl:value-of select="$table.frame.border.color"/>
435       </xsl:attribute>
436       <xsl:attribute name="border-bottom-color">
437         <xsl:value-of select="$table.frame.border.color"/>
438       </xsl:attribute>
439     </xsl:when>
440     <xsl:when test="$frame='none'">
441       <xsl:attribute name="border-start-style">none</xsl:attribute>
442       <xsl:attribute name="border-end-style">none</xsl:attribute>
443       <xsl:attribute name="border-top-style">none</xsl:attribute>
444       <xsl:attribute name="border-bottom-style">none</xsl:attribute>
445     </xsl:when>
446     <xsl:otherwise>
447       <xsl:message>
448         <xsl:text>Impossible frame on table: </xsl:text>
449         <xsl:value-of select="$frame"/>
450       </xsl:message>
451       <xsl:attribute name="border-start-style">none</xsl:attribute>
452       <xsl:attribute name="border-end-style">none</xsl:attribute>
453       <xsl:attribute name="border-top-style">none</xsl:attribute>
454       <xsl:attribute name="border-bottom-style">none</xsl:attribute>
455     </xsl:otherwise>
456   </xsl:choose>
457 </xsl:template>
458
459 <!-- ==================================================================== -->
460
461 <xsl:template name="border">
462   <xsl:param name="side" select="'start'"/>
463
464   <xsl:attribute name="border-{$side}-width">
465     <xsl:value-of select="$table.cell.border.thickness"/>
466   </xsl:attribute>
467   <xsl:attribute name="border-{$side}-style">
468     <xsl:value-of select="$table.cell.border.style"/>
469   </xsl:attribute>
470   <xsl:attribute name="border-{$side}-color">
471     <xsl:value-of select="$table.cell.border.color"/>
472   </xsl:attribute>
473 </xsl:template>
474
475 <!-- ==================================================================== -->
476
477 <xsl:template match="tgroup" name="tgroup">
478   <xsl:if test="not(@cols) or @cols = '' or string(number(@cols)) = 'NaN'">
479     <xsl:message terminate="yes">
480       <xsl:text>Error: CALS tables must specify the number of columns.</xsl:text>
481     </xsl:message>
482   </xsl:if>
483
484   <xsl:variable name="table.width">
485     <xsl:call-template name="table.width"/>
486   </xsl:variable>
487
488   <xsl:variable name="colspecs">
489     <xsl:choose>
490       <xsl:when test="$use.extensions != 0
491                       and $tablecolumns.extension != 0">
492         <xsl:call-template name="generate.colgroup.raw">
493           <xsl:with-param name="cols" select="@cols"/>
494         </xsl:call-template>
495       </xsl:when>
496       <xsl:otherwise>
497         <xsl:call-template name="generate.colgroup">
498           <xsl:with-param name="cols" select="@cols"/>
499         </xsl:call-template>
500       </xsl:otherwise>
501     </xsl:choose>
502   </xsl:variable>
503
504   <xsl:variable name="prop-columns"
505                 select=".//colspec[contains(@colwidth, '*')]"/>
506   <xsl:if test="count($prop-columns) != 0 or
507                 $fop.extensions != 0 or
508                 $fop1.extensions != 0 or
509                 $passivetex.extensions != 0">
510     <xsl:attribute name="table-layout">fixed</xsl:attribute>
511   </xsl:if>
512  
513     <xsl:attribute name="width">
514       <xsl:value-of select="$table.width"/>
515     </xsl:attribute>
516  
517   <xsl:choose>
518     <xsl:when test="$use.extensions != 0
519                     and $tablecolumns.extension != 0">
520       <xsl:choose>
521         <xsl:when test="function-available('stbl:adjustColumnWidths')">
522           <xsl:copy-of select="stbl:adjustColumnWidths($colspecs)"/>
523         </xsl:when>
524         <xsl:when test="function-available('xtbl:adjustColumnWidths')">
525           <xsl:copy-of select="xtbl:adjustColumnWidths($colspecs)"/>
526         </xsl:when>
527         <xsl:when test="function-available('ptbl:adjustColumnWidths')">
528           <xsl:copy-of select="ptbl:adjustColumnWidths($colspecs)"/>
529         </xsl:when>
530         <xsl:otherwise>
531           <xsl:message terminate="yes">
532             <xsl:text>No adjustColumnWidths function available.</xsl:text>
533           </xsl:message>
534         </xsl:otherwise>
535       </xsl:choose>
536     </xsl:when>
537     <xsl:otherwise>
538       <xsl:copy-of select="$colspecs"/>
539     </xsl:otherwise>
540   </xsl:choose>
541
542   <xsl:apply-templates select="thead"/>
543   <xsl:apply-templates select="tfoot"/>
544   <xsl:apply-templates select="tbody"/>
545 </xsl:template>
546
547 <xsl:template match="colspec"></xsl:template>
548
549 <xsl:template name="table.width">
550
551   <xsl:variable name="numcols">
552     <xsl:call-template name="widest-html-row">
553       <xsl:with-param name="rows" select=".//tr"/>
554     </xsl:call-template>
555   </xsl:variable>
556
557   <xsl:variable name="explicit.table.width">
558     <xsl:choose>
559       <xsl:when test="self::entrytbl">
560         <xsl:call-template name="pi.dbfo_table-width"/>
561       </xsl:when>
562       <xsl:when test="self::table or self::informaltable">
563         <xsl:call-template name="pi.dbfo_table-width"/>
564       </xsl:when>
565       <xsl:otherwise>
566         <!-- * no dbfo@table-width PI as a child of this table, so check -->
567         <!-- * the parent of this table to see if the table has any -->
568         <!-- * sibling dbfo@table-width PIs (FIXME: 2007-07 MikeSmith: we -->
569         <!-- * should really instead be checking here just to see if the -->
570         <!-- * first preceding sibling of this table is a -->
571         <!-- * dbfo@table-width PI) -->
572         <xsl:call-template name="pi.dbfo_table-width">
573           <xsl:with-param name="node" select=".."/>
574         </xsl:call-template>
575       </xsl:otherwise>
576     </xsl:choose>
577   </xsl:variable>
578
579   <xsl:variable name="column.sum">
580     <xsl:choose>
581       <!-- CALS table -->
582       <xsl:when test="tgroup/@cols">
583         <!-- change context to the first tgroup -->
584         <xsl:for-each select="tgroup[1]">
585           <xsl:if test="count(colspec) = @cols">
586             <xsl:for-each select="colspec">
587               <xsl:if test="position() != 1">
588                 <xsl:text> + </xsl:text>
589               </xsl:if>
590               <xsl:choose>
591                 <xsl:when test="not(@colwidth)">NOWIDTH</xsl:when>
592                 <xsl:when test="contains(@colwidth, '*')">NOWIDTH</xsl:when>
593                 <xsl:otherwise>
594                   <xsl:value-of select="@colwidth"/>
595                 </xsl:otherwise>
596               </xsl:choose>
597             </xsl:for-each>
598           </xsl:if>
599         </xsl:for-each>
600       </xsl:when>
601       <xsl:otherwise>
602         <!-- HTML table -->
603         <xsl:if test="count(col|colgroup/col) = $numcols">
604           <xsl:for-each select="col|colgroup/col">
605             <xsl:if test="position() != 1">
606               <xsl:text> + </xsl:text>
607             </xsl:if>
608             <xsl:choose>
609               <xsl:when test="not(@width)">NOWIDTH</xsl:when>
610               <xsl:when test="contains(@width, '%')">NOWIDTH</xsl:when>
611               <xsl:otherwise>
612                 <xsl:value-of select="@width"/>
613               </xsl:otherwise>
614             </xsl:choose>
615           </xsl:for-each>
616         </xsl:if>
617       </xsl:otherwise>
618     </xsl:choose>
619   </xsl:variable>
620
621   <xsl:variable name="column.sum.width">
622     <xsl:if test="not(contains($column.sum, 'NOWIDTH'))">
623       <xsl:value-of select="$column.sum"/>
624     </xsl:if>
625   </xsl:variable>
626
627   <xsl:variable name="prop-columns"
628                 select=".//colspec[contains(@colwidth, '*')]"/>
629
630   <xsl:variable name="table.width">
631     <xsl:choose>
632       <xsl:when test="$explicit.table.width != ''">
633         <xsl:value-of select="$explicit.table.width"/>
634       </xsl:when>
635       <xsl:when test="$column.sum.width != ''">
636         <xsl:value-of select="$column.sum.width"/>
637       </xsl:when>
638       <xsl:when test="$default.table.width = ''">
639         <xsl:choose>
640           <!-- These processors don't support table-layout="auto" -->
641           <xsl:when test="$fop.extensions != 0 or
642                           $fop1.extensions != 0 or
643                           $passivetex.extensions != 0">
644             <xsl:text>100%</xsl:text>
645           </xsl:when>
646           <!-- Proportional columns imply 100% width -->
647           <xsl:when test="count($prop-columns) != 0">
648             <xsl:text>100%</xsl:text>
649           </xsl:when>
650           <xsl:otherwise>
651             <xsl:text>auto</xsl:text>
652           </xsl:otherwise>
653         </xsl:choose>
654       </xsl:when>
655       <xsl:otherwise>
656         <xsl:value-of select="$default.table.width"/>
657       </xsl:otherwise>
658     </xsl:choose>
659   </xsl:variable>
660   <xsl:value-of select="$table.width"/>
661
662 </xsl:template>
663
664 <xsl:template match="spanspec"></xsl:template>
665
666 <xsl:template match="thead">
667   <xsl:variable name="tgroup" select="parent::*"/>
668
669   <fo:table-header start-indent="0pt" end-indent="0pt">
670     <xsl:apply-templates select="row[1]">
671       <xsl:with-param name="spans">
672         <xsl:call-template name="blank.spans">
673           <xsl:with-param name="cols" select="../@cols"/>
674         </xsl:call-template>
675       </xsl:with-param>
676     </xsl:apply-templates>
677   </fo:table-header>
678 </xsl:template>
679
680 <xsl:template match="tfoot">
681   <xsl:variable name="tgroup" select="parent::*"/>
682
683   <fo:table-footer start-indent="0pt" end-indent="0pt">
684     <xsl:apply-templates select="row[1]">
685       <xsl:with-param name="spans">
686         <xsl:call-template name="blank.spans">
687           <xsl:with-param name="cols" select="../@cols"/>
688         </xsl:call-template>
689       </xsl:with-param>
690     </xsl:apply-templates>
691
692   </fo:table-footer>
693 </xsl:template>
694
695 <xsl:template match="tbody">
696   <xsl:variable name="tgroup" select="parent::*"/>
697
698   <fo:table-body start-indent="0pt" end-indent="0pt">
699     <xsl:apply-templates select="row[1]">
700       <xsl:with-param name="spans">
701         <xsl:call-template name="blank.spans">
702           <xsl:with-param name="cols" select="../@cols"/>
703         </xsl:call-template>
704       </xsl:with-param>
705     </xsl:apply-templates>
706   </fo:table-body>
707 </xsl:template>
708
709 <xsl:template match="row">
710   <xsl:param name="spans"/>
711
712   <xsl:choose>
713     <xsl:when test="contains($spans, '0')">
714       <xsl:call-template name="normal-row">
715         <xsl:with-param name="spans" select="$spans"/>
716       </xsl:call-template>
717     </xsl:when>
718     <xsl:otherwise>
719       <!--
720       <xsl:message>
721         <xsl:text>Ignoring row: </xsl:text>
722         <xsl:value-of select="$spans"/>
723         <xsl:text> = </xsl:text>
724         <xsl:call-template name="consume-row">
725           <xsl:with-param name="spans" select="$spans"/>
726         </xsl:call-template>
727       </xsl:message>
728       -->
729
730       <xsl:if test="normalize-space(.//text()) != ''">
731         <xsl:message>Warning: overlapped row contains content!</xsl:message>
732       </xsl:if>
733
734       <fo:table-row>
735         <xsl:comment> This row intentionally left blank </xsl:comment>
736         <fo:table-cell><fo:block/></fo:table-cell>
737       </fo:table-row>
738
739       <xsl:apply-templates select="following-sibling::row[1]">
740         <xsl:with-param name="spans">
741           <xsl:call-template name="consume-row">
742             <xsl:with-param name="spans" select="$spans"/>
743           </xsl:call-template>
744         </xsl:with-param>
745       </xsl:apply-templates>
746     </xsl:otherwise>
747   </xsl:choose>
748 </xsl:template>
749
750 <xsl:template name="normal-row">
751   <xsl:param name="spans"/>
752
753   <fo:table-row>
754     <xsl:call-template name="table.row.properties"/>
755     <xsl:call-template name="anchor"/>
756
757     <xsl:apply-templates select="(entry|entrytbl)[1]">
758       <xsl:with-param name="spans" select="$spans"/>
759     </xsl:apply-templates>
760   </fo:table-row>
761
762   <xsl:if test="following-sibling::row">
763     <xsl:variable name="nextspans">
764       <xsl:apply-templates select="(entry|entrytbl)[1]" mode="span">
765         <xsl:with-param name="spans" select="$spans"/>
766       </xsl:apply-templates>
767     </xsl:variable>
768
769     <xsl:apply-templates select="following-sibling::row[1]">
770       <xsl:with-param name="spans" select="$nextspans"/>
771     </xsl:apply-templates>
772   </xsl:if>
773 </xsl:template>
774
775 <!-- customize this template to add row properties -->
776 <xsl:template name="table.row.properties">
777
778   <xsl:variable name="row-height">
779     <xsl:if test="processing-instruction('dbfo')">
780       <xsl:call-template name="pi.dbfo_row-height"/>
781     </xsl:if>
782   </xsl:variable>
783
784   <xsl:if test="$row-height != ''">
785     <xsl:attribute name="block-progression-dimension">
786       <xsl:value-of select="$row-height"/>
787     </xsl:attribute>
788   </xsl:if>
789
790   <xsl:variable name="bgcolor">
791     <xsl:call-template name="pi.dbfo_bgcolor"/>
792   </xsl:variable>
793
794   <xsl:if test="$bgcolor != ''">
795     <xsl:attribute name="background-color">
796       <xsl:value-of select="$bgcolor"/>
797     </xsl:attribute>
798   </xsl:if>
799
800   <!-- Keep header row with next row -->
801   <xsl:if test="ancestor::thead">
802     <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
803   </xsl:if>
804
805 </xsl:template>
806
807 <xsl:template match="entry|entrytbl" name="entry">
808   <xsl:param name="col" select="1"/>
809   <xsl:param name="spans"/>
810
811   <xsl:variable name="row" select="parent::row"/>
812   <xsl:variable name="group" select="$row/parent::*[1]"/>
813   <xsl:variable name="frame" select="ancestor::tgroup/parent::*/@frame"/>
814
815   <xsl:variable name="empty.cell" select="count(node()) = 0"/>
816
817   <xsl:variable name="named.colnum">
818     <xsl:call-template name="entry.colnum"/>
819   </xsl:variable>
820
821   <xsl:variable name="entry.colnum">
822     <xsl:choose>
823       <xsl:when test="$named.colnum &gt; 0">
824         <xsl:value-of select="$named.colnum"/>
825       </xsl:when>
826       <xsl:otherwise>
827         <xsl:value-of select="$col"/>
828       </xsl:otherwise>
829     </xsl:choose>
830   </xsl:variable>
831
832   <xsl:variable name="entry.colspan">
833     <xsl:choose>
834       <xsl:when test="@spanname or @namest">
835         <xsl:call-template name="calculate.colspan"/>
836       </xsl:when>
837       <xsl:otherwise>1</xsl:otherwise>
838     </xsl:choose>
839   </xsl:variable>
840
841   <xsl:variable name="following.spans">
842     <xsl:call-template name="calculate.following.spans">
843       <xsl:with-param name="colspan" select="$entry.colspan"/>
844       <xsl:with-param name="spans" select="$spans"/>
845     </xsl:call-template>
846   </xsl:variable>
847
848   <xsl:variable name="rowsep">
849     <xsl:choose>
850       <!-- If this is the last row, rowsep never applies (except when 
851            the ancestor tgroup has a following sibling tgroup) -->
852       <xsl:when test="not(ancestor-or-self::row[1]/following-sibling::row
853                           or ancestor-or-self::thead/following-sibling::tbody
854                           or ancestor-or-self::tbody/preceding-sibling::tfoot)
855                           and not(ancestor::tgroup/following-sibling::tgroup)">
856         <xsl:value-of select="0"/>
857       </xsl:when>
858       <!-- Check for morerows too -->
859       <xsl:when test="(@morerows and count(ancestor-or-self::row[1]/
860                        following-sibling::row) = @morerows )
861                       and not (ancestor-or-self::thead/following-sibling::tbody
862                        or ancestor-or-self::tbody/preceding-sibling::tfoot)
863                        and not(ancestor::tgroup/following-sibling::tgroup)">
864         <xsl:value-of select="0"/>
865       </xsl:when>
866
867       <xsl:otherwise>
868         <xsl:call-template name="inherited.table.attribute">
869           <xsl:with-param name="entry" select="."/>
870           <xsl:with-param name="colnum" select="$entry.colnum"/>
871           <xsl:with-param name="attribute" select="'rowsep'"/>
872         </xsl:call-template>
873       </xsl:otherwise>
874     </xsl:choose>
875   </xsl:variable>
876
877 <!--
878   <xsl:message><xsl:value-of select="."/>: <xsl:value-of select="$rowsep"/></xsl:message>
879 -->
880
881   <xsl:variable name="colsep">
882     <xsl:choose>
883       <!-- If this is the last column, colsep never applies. -->
884       <xsl:when test="$following.spans = ''">0</xsl:when>
885       <xsl:otherwise>
886         <xsl:call-template name="inherited.table.attribute">
887           <xsl:with-param name="entry" select="."/>
888           <xsl:with-param name="colnum" select="$entry.colnum"/>
889           <xsl:with-param name="attribute" select="'colsep'"/>
890         </xsl:call-template>
891       </xsl:otherwise>
892     </xsl:choose>
893   </xsl:variable>
894
895   <xsl:variable name="valign">
896     <xsl:call-template name="inherited.table.attribute">
897       <xsl:with-param name="entry" select="."/>
898       <xsl:with-param name="colnum" select="$entry.colnum"/>
899       <xsl:with-param name="attribute" select="'valign'"/>
900     </xsl:call-template>
901   </xsl:variable>
902
903   <xsl:variable name="align">
904     <xsl:call-template name="inherited.table.attribute">
905       <xsl:with-param name="entry" select="."/>
906       <xsl:with-param name="colnum" select="$entry.colnum"/>
907       <xsl:with-param name="attribute" select="'align'"/>
908     </xsl:call-template>
909   </xsl:variable>
910
911   <xsl:variable name="char">
912     <xsl:call-template name="inherited.table.attribute">
913       <xsl:with-param name="entry" select="."/>
914       <xsl:with-param name="colnum" select="$entry.colnum"/>
915       <xsl:with-param name="attribute" select="'char'"/>
916     </xsl:call-template>
917   </xsl:variable>
918
919   <xsl:variable name="charoff">
920     <xsl:call-template name="inherited.table.attribute">
921       <xsl:with-param name="entry" select="."/>
922       <xsl:with-param name="colnum" select="$entry.colnum"/>
923       <xsl:with-param name="attribute" select="'charoff'"/>
924     </xsl:call-template>
925   </xsl:variable>
926
927   <xsl:choose>
928     <xsl:when test="$spans != '' and not(starts-with($spans,'0:'))">
929       <xsl:call-template name="entry">
930         <xsl:with-param name="col" select="$col+1"/>
931         <xsl:with-param name="spans" select="substring-after($spans,':')"/>
932       </xsl:call-template>
933     </xsl:when>
934
935     <xsl:when test="number($entry.colnum) &gt; $col">
936       <xsl:call-template name="empty.table.cell">
937         <xsl:with-param name="colnum" select="$col"/>
938       </xsl:call-template>
939       <xsl:call-template name="entry">
940         <xsl:with-param name="col" select="$col+1"/>
941         <xsl:with-param name="spans" select="substring-after($spans,':')"/>
942       </xsl:call-template>
943     </xsl:when>
944
945     <xsl:otherwise>
946       <xsl:variable name="cell.content">
947         <fo:block>
948           <xsl:call-template name="table.cell.block.properties"/>
949
950           <!-- are we missing any indexterms? -->
951           <xsl:if test="not(preceding-sibling::entry)
952                         and not(parent::row/preceding-sibling::row)">
953             <!-- this is the first entry of the first row -->
954             <xsl:if test="ancestor::thead or
955                           (ancestor::tbody
956                            and not(ancestor::tbody/preceding-sibling::thead
957                                    or ancestor::tbody/preceding-sibling::tbody))">
958               <!-- of the thead or the first tbody -->
959               <xsl:apply-templates select="ancestor::tgroup/preceding-sibling::indexterm"/>
960             </xsl:if>
961           </xsl:if>
962
963           <!--
964           <xsl:text>(</xsl:text>
965           <xsl:value-of select="$rowsep"/>
966           <xsl:text>,</xsl:text>
967           <xsl:value-of select="$colsep"/>
968           <xsl:text>)</xsl:text>
969           -->
970           <xsl:choose>
971             <xsl:when test="$empty.cell">
972               <xsl:text>&#160;</xsl:text>
973             </xsl:when>
974             <xsl:when test="self::entrytbl">
975               <xsl:variable name="prop-columns"
976                             select=".//colspec[contains(@colwidth, '*')]"/>
977               <fo:table xsl:use-attribute-sets="table.table.properties">
978                 <xsl:if test="count($prop-columns) != 0">
979                   <xsl:attribute name="table-layout">fixed</xsl:attribute>
980                 </xsl:if>
981                 <xsl:call-template name="tgroup"/>
982               </fo:table>
983             </xsl:when>
984             <xsl:otherwise>
985               <xsl:apply-templates/>
986             </xsl:otherwise>
987           </xsl:choose>
988         </fo:block>
989       </xsl:variable>
990
991       <xsl:variable name="cell-orientation">
992         <xsl:call-template name="pi.dbfo_orientation">
993           <xsl:with-param name="node" select="ancestor-or-self::entry"/>
994         </xsl:call-template>
995       </xsl:variable>
996
997       <xsl:variable name="row-orientation">
998         <xsl:call-template name="pi.dbfo_orientation">
999           <xsl:with-param name="node" select="ancestor-or-self::row"/>
1000         </xsl:call-template>
1001       </xsl:variable>
1002
1003       <xsl:variable name="cell-width">
1004         <xsl:call-template name="pi.dbfo_rotated-width">
1005           <xsl:with-param name="node" select="ancestor-or-self::entry"/>
1006         </xsl:call-template>
1007       </xsl:variable>
1008
1009       <xsl:variable name="row-width">
1010         <xsl:call-template name="pi.dbfo_rotated-width">
1011           <xsl:with-param name="node" select="ancestor-or-self::row"/>
1012         </xsl:call-template>
1013       </xsl:variable>
1014
1015       <xsl:variable name="orientation">
1016         <xsl:choose>
1017           <xsl:when test="$cell-orientation != ''">
1018             <xsl:value-of select="$cell-orientation"/>
1019           </xsl:when>
1020           <xsl:otherwise>
1021             <xsl:value-of select="$row-orientation"/>
1022           </xsl:otherwise>
1023         </xsl:choose>
1024       </xsl:variable>
1025
1026       <xsl:variable name="rotated-width">
1027         <xsl:choose>
1028           <xsl:when test="$cell-width != ''">
1029             <xsl:value-of select="$cell-width"/>
1030           </xsl:when>
1031           <xsl:otherwise>
1032             <xsl:value-of select="$row-width"/>
1033           </xsl:otherwise>
1034         </xsl:choose>
1035       </xsl:variable>
1036
1037       <xsl:variable name="bgcolor">
1038         <xsl:call-template name="pi.dbfo_bgcolor">
1039           <xsl:with-param name="node" select="ancestor-or-self::entry"/>
1040         </xsl:call-template>
1041       </xsl:variable>
1042
1043       <fo:table-cell xsl:use-attribute-sets="table.cell.padding">
1044         <xsl:call-template name="table.cell.properties">
1045           <xsl:with-param name="bgcolor.pi" select="$bgcolor"/>
1046           <xsl:with-param name="rowsep.inherit" select="$rowsep"/>
1047           <xsl:with-param name="colsep.inherit" select="$colsep"/>
1048           <xsl:with-param name="col" select="$col"/>
1049           <xsl:with-param name="valign.inherit" select="$valign"/>
1050           <xsl:with-param name="align.inherit" select="$align"/>
1051           <xsl:with-param name="char.inherit" select="$char"/>
1052         </xsl:call-template>
1053
1054         <xsl:call-template name="anchor"/>
1055
1056         <xsl:if test="@morerows">
1057           <xsl:attribute name="number-rows-spanned">
1058             <xsl:value-of select="@morerows+1"/>
1059           </xsl:attribute>
1060         </xsl:if>
1061
1062         <xsl:if test="$entry.colspan &gt; 1">
1063           <xsl:attribute name="number-columns-spanned">
1064             <xsl:value-of select="$entry.colspan"/>
1065           </xsl:attribute>
1066         </xsl:if>
1067
1068 <!--
1069         <xsl:if test="@charoff">
1070           <xsl:attribute name="charoff">
1071             <xsl:value-of select="@charoff"/>
1072           </xsl:attribute>
1073         </xsl:if>
1074 -->
1075
1076         <xsl:choose>
1077           <xsl:when test="$fop.extensions = 0 and $passivetex.extensions = 0
1078                           and $orientation != ''">
1079             <fo:block-container reference-orientation="{$orientation}">
1080               <xsl:if test="$rotated-width != ''">
1081                 <xsl:attribute name="width">
1082                   <xsl:value-of select="$rotated-width"/>
1083                 </xsl:attribute>
1084               </xsl:if>
1085               <xsl:copy-of select="$cell.content"/>
1086             </fo:block-container>
1087           </xsl:when>
1088           <xsl:otherwise>
1089             <xsl:copy-of select="$cell.content"/>
1090           </xsl:otherwise>
1091         </xsl:choose>
1092       </fo:table-cell>
1093
1094       <xsl:choose>
1095         <xsl:when test="following-sibling::entry|following-sibling::entrytbl">
1096           <xsl:apply-templates select="(following-sibling::entry
1097                                        |following-sibling::entrytbl)[1]">
1098             <xsl:with-param name="col" select="$col+$entry.colspan"/>
1099             <xsl:with-param name="spans" select="$following.spans"/>
1100           </xsl:apply-templates>
1101         </xsl:when>
1102         <xsl:otherwise>
1103           <xsl:call-template name="finaltd">
1104             <xsl:with-param name="spans" select="$following.spans"/>
1105             <xsl:with-param name="col" select="$col+$entry.colspan"/>
1106           </xsl:call-template>
1107         </xsl:otherwise>
1108       </xsl:choose>
1109     </xsl:otherwise>
1110   </xsl:choose>
1111 </xsl:template>
1112
1113 <!-- Expand this template to add properties to any fo:table-cell -->
1114 <xsl:template name="table.cell.properties">
1115   <xsl:param name="bgcolor.pi" select="''"/>
1116   <xsl:param name="rowsep.inherit" select="1"/>
1117   <xsl:param name="colsep.inherit" select="1"/>
1118   <xsl:param name="col" select="1"/>
1119   <xsl:param name="valign.inherit" select="''"/>
1120   <xsl:param name="align.inherit" select="''"/>
1121   <xsl:param name="char.inherit" select="''"/>
1122
1123   <xsl:choose>
1124     <xsl:when test="ancestor::tgroup">
1125       <xsl:if test="$bgcolor.pi != ''">
1126         <xsl:attribute name="background-color">
1127           <xsl:value-of select="$bgcolor.pi"/>
1128         </xsl:attribute>
1129       </xsl:if>
1130
1131       <xsl:if test="$rowsep.inherit &gt; 0">
1132         <xsl:call-template name="border">
1133           <xsl:with-param name="side" select="'bottom'"/>
1134         </xsl:call-template>
1135       </xsl:if>
1136
1137       <xsl:if test="$colsep.inherit &gt; 0 and 
1138                       $col &lt; (ancestor::tgroup/@cols|ancestor::entrytbl/@cols)[last()]">
1139         <xsl:call-template name="border">
1140           <xsl:with-param name="side" select="'end'"/>
1141         </xsl:call-template>
1142       </xsl:if>
1143
1144       <xsl:if test="$valign.inherit != ''">
1145         <xsl:attribute name="display-align">
1146           <xsl:choose>
1147             <xsl:when test="$valign.inherit='top'">before</xsl:when>
1148             <xsl:when test="$valign.inherit='middle'">center</xsl:when>
1149             <xsl:when test="$valign.inherit='bottom'">after</xsl:when>
1150             <xsl:otherwise>
1151               <xsl:message>
1152                 <xsl:text>Unexpected valign value: </xsl:text>
1153                 <xsl:value-of select="$valign.inherit"/>
1154                 <xsl:text>, center used.</xsl:text>
1155               </xsl:message>
1156               <xsl:text>center</xsl:text>
1157             </xsl:otherwise>
1158           </xsl:choose>
1159         </xsl:attribute>
1160       </xsl:if>
1161
1162       <xsl:choose>
1163         <xsl:when test="$align.inherit = 'char' and $char.inherit != ''">
1164           <xsl:attribute name="text-align">
1165             <xsl:value-of select="$char.inherit"/>
1166           </xsl:attribute>
1167         </xsl:when>
1168         <xsl:when test="$align.inherit != ''">
1169           <xsl:attribute name="text-align">
1170             <xsl:value-of select="$align.inherit"/>
1171           </xsl:attribute>
1172         </xsl:when>
1173       </xsl:choose>
1174
1175     </xsl:when>
1176     <xsl:otherwise>
1177       <!-- HTML table -->
1178       <xsl:if test="$bgcolor.pi != ''">
1179         <xsl:attribute name="background-color">
1180           <xsl:value-of select="$bgcolor.pi"/>
1181         </xsl:attribute>
1182       </xsl:if>
1183
1184       <xsl:if test="$align.inherit != ''">
1185         <xsl:attribute name="text-align">
1186           <xsl:value-of select="$align.inherit"/>
1187         </xsl:attribute>
1188       </xsl:if>
1189
1190       <xsl:if test="$valign.inherit != ''">
1191         <xsl:attribute name="display-align">
1192           <xsl:choose>
1193             <xsl:when test="$valign.inherit='top'">before</xsl:when>
1194             <xsl:when test="$valign.inherit='middle'">center</xsl:when>
1195             <xsl:when test="$valign.inherit='bottom'">after</xsl:when>
1196             <xsl:otherwise>
1197               <xsl:message>
1198                 <xsl:text>Unexpected valign value: </xsl:text>
1199                 <xsl:value-of select="$valign.inherit"/>
1200                 <xsl:text>, center used.</xsl:text>
1201               </xsl:message>
1202               <xsl:text>center</xsl:text>
1203             </xsl:otherwise>
1204           </xsl:choose>
1205         </xsl:attribute>
1206       </xsl:if>
1207
1208       <xsl:call-template name="html.table.cell.rules"/>
1209
1210     </xsl:otherwise>
1211   </xsl:choose>
1212
1213 </xsl:template>
1214
1215 <!-- Expand this template to add properties to any cell's block -->
1216 <xsl:template name="table.cell.block.properties">
1217   <!-- highlight this entry? -->
1218   <xsl:if test="ancestor::thead or ancestor::tfoot">
1219     <xsl:attribute name="font-weight">bold</xsl:attribute>
1220   </xsl:if>
1221 </xsl:template>
1222
1223 <xsl:template match="entry|entrytbl" name="sentry" mode="span">
1224   <xsl:param name="col" select="1"/>
1225   <xsl:param name="spans"/>
1226
1227   <xsl:variable name="entry.colnum">
1228     <xsl:call-template name="entry.colnum"/>
1229   </xsl:variable>
1230
1231   <xsl:variable name="entry.colspan">
1232     <xsl:choose>
1233       <xsl:when test="@spanname or @namest">
1234         <xsl:call-template name="calculate.colspan"/>
1235       </xsl:when>
1236       <xsl:otherwise>1</xsl:otherwise>
1237     </xsl:choose>
1238   </xsl:variable>
1239
1240   <xsl:variable name="following.spans">
1241     <xsl:call-template name="calculate.following.spans">
1242       <xsl:with-param name="colspan" select="$entry.colspan"/>
1243       <xsl:with-param name="spans" select="$spans"/>
1244     </xsl:call-template>
1245   </xsl:variable>
1246
1247   <xsl:choose>
1248     <xsl:when test="$spans != '' and not(starts-with($spans,'0:'))">
1249       <xsl:value-of select="substring-before($spans,':')-1"/>
1250       <xsl:text>:</xsl:text>
1251       <xsl:call-template name="sentry">
1252         <xsl:with-param name="col" select="$col+1"/>
1253         <xsl:with-param name="spans" select="substring-after($spans,':')"/>
1254       </xsl:call-template>
1255     </xsl:when>
1256
1257     <xsl:when test="number($entry.colnum) &gt; $col">
1258       <xsl:text>0:</xsl:text>
1259       <xsl:call-template name="sentry">
1260         <xsl:with-param name="col" select="$col + 1"/>
1261         <xsl:with-param name="spans" select="substring-after($spans,':')"/>
1262       </xsl:call-template>
1263     </xsl:when>
1264
1265     <xsl:otherwise>
1266       <xsl:call-template name="copy-string">
1267         <xsl:with-param name="count" select="$entry.colspan"/>
1268         <xsl:with-param name="string">
1269           <xsl:choose>
1270             <xsl:when test="@morerows">
1271               <xsl:value-of select="@morerows"/>
1272             </xsl:when>
1273             <xsl:otherwise>0</xsl:otherwise>
1274           </xsl:choose>
1275           <xsl:text>:</xsl:text>
1276         </xsl:with-param>
1277       </xsl:call-template>
1278
1279       <xsl:choose>
1280         <xsl:when test="following-sibling::entry|following-sibling::entrytbl">
1281           <xsl:apply-templates select="(following-sibling::entry
1282                                        |following-sibling::entrytbl)[1]"
1283                                mode="span">
1284             <xsl:with-param name="col" select="$col+$entry.colspan"/>
1285             <xsl:with-param name="spans" select="$following.spans"/>
1286           </xsl:apply-templates>
1287         </xsl:when>
1288         <xsl:otherwise>
1289           <xsl:call-template name="sfinaltd">
1290             <xsl:with-param name="spans" select="$following.spans"/>
1291           </xsl:call-template>
1292         </xsl:otherwise>
1293       </xsl:choose>
1294     </xsl:otherwise>
1295   </xsl:choose>
1296 </xsl:template>
1297
1298 <xsl:template name="generate.colgroup.raw">
1299   <xsl:param name="cols" select="1"/>
1300   <xsl:param name="count" select="1"/>
1301
1302   <xsl:choose>
1303     <xsl:when test="$count>$cols"></xsl:when>
1304     <xsl:otherwise>
1305       <xsl:call-template name="generate.col.raw">
1306         <xsl:with-param name="countcol" select="$count"/>
1307       </xsl:call-template>
1308       <xsl:call-template name="generate.colgroup.raw">
1309         <xsl:with-param name="cols" select="$cols"/>
1310         <xsl:with-param name="count" select="$count+1"/>
1311       </xsl:call-template>
1312     </xsl:otherwise>
1313   </xsl:choose>
1314 </xsl:template>
1315
1316 <xsl:template name="generate.colgroup">
1317   <xsl:param name="cols" select="1"/>
1318   <xsl:param name="count" select="1"/>
1319
1320   <xsl:choose>
1321     <xsl:when test="$count>$cols"></xsl:when>
1322     <xsl:otherwise>
1323       <xsl:call-template name="generate.col">
1324         <xsl:with-param name="countcol" select="$count"/>
1325       </xsl:call-template>
1326       <xsl:call-template name="generate.colgroup">
1327         <xsl:with-param name="cols" select="$cols"/>
1328         <xsl:with-param name="count" select="$count+1"/>
1329       </xsl:call-template>
1330     </xsl:otherwise>
1331   </xsl:choose>
1332 </xsl:template>
1333
1334 <xsl:template name="generate.col.raw">
1335   <!-- generate the table-column for column countcol -->
1336   <xsl:param name="countcol">1</xsl:param>
1337   <xsl:param name="colspecs" select="./colspec"/>
1338   <xsl:param name="count">1</xsl:param>
1339   <xsl:param name="colnum">1</xsl:param>
1340
1341   <xsl:choose>
1342     <xsl:when test="$count>count($colspecs)">
1343       <fo:table-column column-number="{$countcol}"/>
1344     </xsl:when>
1345     <xsl:otherwise>
1346       <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
1347
1348       <xsl:variable name="colspec.colnum">
1349         <xsl:choose>
1350           <xsl:when test="$colspec/@colnum">
1351             <xsl:value-of select="$colspec/@colnum"/>
1352           </xsl:when>
1353           <xsl:otherwise>
1354             <xsl:value-of select="$colnum"/>
1355           </xsl:otherwise>
1356         </xsl:choose>
1357       </xsl:variable>
1358
1359       <xsl:variable name="colspec.colwidth">
1360         <xsl:choose>
1361           <xsl:when test="$colspec/@colwidth">
1362             <xsl:value-of select="$colspec/@colwidth"/>
1363           </xsl:when>
1364           <xsl:otherwise>1*</xsl:otherwise>
1365         </xsl:choose>
1366       </xsl:variable>
1367
1368       <xsl:choose>
1369         <xsl:when test="$colspec.colnum=$countcol">
1370           <fo:table-column column-number="{$countcol}">
1371             <xsl:attribute name="column-width">
1372               <xsl:value-of select="$colspec.colwidth"/>
1373             </xsl:attribute>
1374           </fo:table-column>
1375         </xsl:when>
1376         <xsl:otherwise>
1377           <xsl:call-template name="generate.col.raw">
1378             <xsl:with-param name="countcol" select="$countcol"/>
1379             <xsl:with-param name="colspecs" select="$colspecs"/>
1380             <xsl:with-param name="count" select="$count+1"/>
1381             <xsl:with-param name="colnum">
1382               <xsl:choose>
1383                 <xsl:when test="$colspec/@colnum">
1384                   <xsl:value-of select="$colspec/@colnum + 1"/>
1385                 </xsl:when>
1386                 <xsl:otherwise>
1387                   <xsl:value-of select="$colnum + 1"/>
1388                 </xsl:otherwise>
1389               </xsl:choose>
1390             </xsl:with-param>
1391            </xsl:call-template>
1392         </xsl:otherwise>
1393       </xsl:choose>
1394     </xsl:otherwise>
1395   </xsl:choose>
1396 </xsl:template>
1397
1398 <xsl:template name="generate.col">
1399   <!-- generate the table-column for column countcol -->
1400   <xsl:param name="countcol">1</xsl:param>
1401   <xsl:param name="colspecs" select="./colspec"/>
1402   <xsl:param name="count">1</xsl:param>
1403   <xsl:param name="colnum">1</xsl:param>
1404
1405   <xsl:choose>
1406     <xsl:when test="$count>count($colspecs)">
1407       <fo:table-column column-number="{$countcol}">
1408         <xsl:variable name="colwidth">
1409           <xsl:call-template name="calc.column.width"/>
1410         </xsl:variable>
1411         <xsl:if test="$colwidth != 'proportional-column-width(1)'">
1412           <xsl:attribute name="column-width">
1413             <xsl:value-of select="$colwidth"/>
1414           </xsl:attribute>
1415         </xsl:if>
1416       </fo:table-column>
1417     </xsl:when>
1418     <xsl:otherwise>
1419       <xsl:variable name="colspec" select="$colspecs[$count=position()]"/>
1420
1421       <xsl:variable name="colspec.colnum">
1422         <xsl:choose>
1423           <xsl:when test="$colspec/@colnum">
1424             <xsl:value-of select="$colspec/@colnum"/>
1425           </xsl:when>
1426           <xsl:otherwise>
1427             <xsl:value-of select="$colnum"/>
1428           </xsl:otherwise>
1429         </xsl:choose>
1430       </xsl:variable>
1431
1432       <xsl:variable name="colspec.colwidth">
1433         <xsl:choose>
1434           <xsl:when test="$colspec/@colwidth">
1435             <xsl:value-of select="$colspec/@colwidth"/>
1436           </xsl:when>
1437           <xsl:otherwise>1*</xsl:otherwise>
1438         </xsl:choose>
1439       </xsl:variable>
1440
1441       <xsl:choose>
1442         <xsl:when test="$colspec.colnum=$countcol">
1443           <fo:table-column column-number="{$countcol}">
1444             <xsl:variable name="colwidth">
1445               <xsl:call-template name="calc.column.width">
1446                 <xsl:with-param name="colwidth">
1447                   <xsl:value-of select="$colspec.colwidth"/>
1448                 </xsl:with-param>
1449               </xsl:call-template>
1450             </xsl:variable>
1451             <xsl:if test="$colwidth != 'proportional-column-width(1)'">
1452               <xsl:attribute name="column-width">
1453                 <xsl:value-of select="$colwidth"/>
1454               </xsl:attribute>
1455             </xsl:if>
1456           </fo:table-column>
1457         </xsl:when>
1458         <xsl:otherwise>
1459           <xsl:call-template name="generate.col">
1460             <xsl:with-param name="countcol" select="$countcol"/>
1461             <xsl:with-param name="colspecs" select="$colspecs"/>
1462             <xsl:with-param name="count" select="$count+1"/>
1463             <xsl:with-param name="colnum">
1464               <xsl:choose>
1465                 <xsl:when test="$colspec/@colnum">
1466                   <xsl:value-of select="$colspec/@colnum + 1"/>
1467                 </xsl:when>
1468                 <xsl:otherwise>
1469                   <xsl:value-of select="$colnum + 1"/>
1470                 </xsl:otherwise>
1471               </xsl:choose>
1472             </xsl:with-param>
1473            </xsl:call-template>
1474         </xsl:otherwise>
1475       </xsl:choose>
1476     </xsl:otherwise>
1477   </xsl:choose>
1478 </xsl:template>
1479
1480 <doc:template name="calc.column.width" xmlns="">
1481 <refpurpose>Calculate an XSL FO table column width specification from a
1482 CALS table column width specification.</refpurpose>
1483
1484 <refdescription>
1485 <para>CALS expresses table column widths in the following basic
1486 forms:</para>
1487
1488 <itemizedlist>
1489 <listitem>
1490 <para><emphasis>99.99units</emphasis>, a fixed length specifier.</para>
1491 </listitem>
1492 <listitem>
1493 <para><emphasis>99.99</emphasis>, a fixed length specifier without any units.</para>
1494 </listitem>
1495 <listitem>
1496 <para><emphasis>99.99*</emphasis>, a relative length specifier.</para>
1497 </listitem>
1498 <listitem>
1499 <para><emphasis>99.99*+99.99units</emphasis>, a combination of both.</para>
1500 </listitem>
1501 </itemizedlist>
1502
1503 <para>The CALS units are points (pt), picas (pi), centimeters (cm),
1504 millimeters (mm), and inches (in). These are the same units as XSL,
1505 except that XSL abbreviates picas "pc" instead of "pi". If a length
1506 specifier has no units, the CALS default unit (pt) is assumed.</para>
1507
1508 <para>Relative length specifiers are represented in XSL with the
1509 proportional-column-width() function.</para>
1510
1511 <para>Here are some examples:</para>
1512
1513 <itemizedlist>
1514 <listitem>
1515 <para>"36pt" becomes "36pt"</para>
1516 </listitem>
1517 <listitem>
1518 <para>"3pi" becomes "3pc"</para>
1519 </listitem>
1520 <listitem>
1521 <para>"36" becomes "36pt"</para>
1522 </listitem>
1523 <listitem>
1524 <para>"3*" becomes "proportional-column-width(3)"</para>
1525 </listitem>
1526 <listitem>
1527 <para>"3*+2pi" becomes "proportional-column-width(3)+2pc"</para>
1528 </listitem>
1529 <listitem>
1530 <para>"1*+2" becomes "proportional-column-width(1)+2pt"</para>
1531 </listitem>
1532 </itemizedlist>
1533 </refdescription>
1534
1535 <refparameter>
1536 <variablelist>
1537 <varlistentry><term>colwidth</term>
1538 <listitem>
1539 <para>The CALS column width specification.</para>
1540 </listitem>
1541 </varlistentry>
1542 </variablelist>
1543 </refparameter>
1544
1545 <refreturn>
1546 <para>The XSL column width specification.</para>
1547 </refreturn>
1548 </doc:template>
1549
1550 <xsl:template name="calc.column.width">
1551   <xsl:param name="colwidth">1*</xsl:param>
1552
1553   <!-- Ok, the colwidth could have any one of the following forms: -->
1554   <!--        1*       = proportional width -->
1555   <!--         *       = same as 1* -->
1556   <!--     1unit       = 1.0 units wide -->
1557   <!--         1       = 1pt wide -->
1558   <!--  1*+1unit       = proportional width + some fixed width -->
1559   <!--      1*+1       = proportional width + some fixed width -->
1560
1561   <!-- If it has a proportional width, translate it to XSL -->
1562   <xsl:if test="contains($colwidth, '*')">
1563     <xsl:text>proportional-column-width(</xsl:text>
1564     <xsl:choose>
1565       <xsl:when test="substring-before($colwidth, '*') != ''"> 
1566         <xsl:value-of select="substring-before($colwidth, '*')"/>
1567       </xsl:when>
1568       <xsl:otherwise>
1569          <xsl:text>1.00</xsl:text>
1570       </xsl:otherwise>
1571     </xsl:choose>
1572     <xsl:text>)</xsl:text>
1573   </xsl:if>
1574
1575   <!-- Now grab the non-proportional part of the specification -->
1576   <xsl:variable name="width-units">
1577     <xsl:choose>
1578       <xsl:when test="contains($colwidth, '*')">
1579         <xsl:value-of
1580              select="normalize-space(substring-after($colwidth, '*'))"/>
1581       </xsl:when>
1582       <xsl:otherwise>
1583         <xsl:value-of select="normalize-space($colwidth)"/>
1584       </xsl:otherwise>
1585     </xsl:choose>
1586   </xsl:variable>
1587
1588   <!-- Ok, now the width-units could have any one of the following forms: -->
1589   <!--                 = <empty string> -->
1590   <!--     1unit       = 1.0 units wide -->
1591   <!--         1       = 1pt wide -->
1592   <!-- with an optional leading sign -->
1593
1594   <!-- Grab the width part by blanking out the units part and discarding -->
1595   <!-- whitespace. It's not pretty, but it works. -->
1596   <xsl:variable name="width"
1597        select="normalize-space(translate($width-units,
1598                                          '+-0123456789.abcdefghijklmnopqrstuvwxyz',
1599                                          '+-0123456789.'))"/>
1600
1601   <!-- Grab the units part by blanking out the width part and discarding -->
1602   <!-- whitespace. It's not pretty, but it works. -->
1603   <xsl:variable name="units"
1604        select="normalize-space(translate($width-units,
1605                                          'abcdefghijklmnopqrstuvwxyz+-0123456789.',
1606                                          'abcdefghijklmnopqrstuvwxyz'))"/>
1607
1608   <!-- Output the width -->
1609   <xsl:value-of select="$width"/>
1610
1611   <!-- Output the units, translated appropriately -->
1612   <xsl:choose>
1613     <xsl:when test="$units = 'pi'">pc</xsl:when>
1614     <xsl:when test="$units = '' and $width != ''">pt</xsl:when>
1615     <xsl:otherwise><xsl:value-of select="$units"/></xsl:otherwise>
1616   </xsl:choose>
1617 </xsl:template>
1618
1619 <!-- ==================================================================== -->
1620
1621 </xsl:stylesheet>