Imported Upstream version 1.77.1
[platform/upstream/docbook-xsl.git] / fo / htmltbl.xsl
1 <?xml version="1.0"?>
2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3                 xmlns:fo="http://www.w3.org/1999/XSL/Format"
4                 version="1.0">
5
6 <!-- ********************************************************************
7      $Id: htmltbl.xsl 9196 2012-01-18 17:51:39Z bobstayton $
8      ********************************************************************
9
10      This file is part of the XSL DocBook Stylesheet distribution.
11      See ../README or http://docbook.sf.net/release/xsl/current/ for
12      copyright and other information.
13
14      ******************************************************************** -->
15
16 <!-- ==================================================================== -->
17
18 <!-- Outputs an fo:table only, not the caption -->
19 <xsl:template match="table|informaltable" mode="htmlTable">
20
21   <xsl:variable name="numcols">
22     <xsl:call-template name="widest-html-row">
23       <xsl:with-param name="rows" select=".//tr"/>
24     </xsl:call-template>
25   </xsl:variable>
26
27   <xsl:variable name="prop-columns"
28                 select=".//col[contains(@width, '%')] |
29                         .//colgroup[contains(@width, '%')]"/>
30
31   <xsl:variable name="table.width">
32     <xsl:call-template name="table.width"/>
33   </xsl:variable>
34
35   <fo:table xsl:use-attribute-sets="table.table.properties">
36     <xsl:choose>
37       <xsl:when test="$fop.extensions != 0 or
38                       $fop1.extensions != 0 or
39                       $passivetex.extensions != 0">
40         <xsl:attribute name="table-layout">fixed</xsl:attribute>
41       </xsl:when>
42     </xsl:choose>
43
44     <xsl:attribute name="width">
45       <xsl:choose>
46         <xsl:when test="@width">
47           <xsl:value-of select="@width"/>
48         </xsl:when>
49         <xsl:when test="$table.width">
50           <xsl:value-of select="$table.width"/>
51         </xsl:when>
52         <xsl:otherwise>100%</xsl:otherwise>
53       </xsl:choose>
54     </xsl:attribute>
55
56     <xsl:call-template name="table.frame">
57       <xsl:with-param name="frame">
58         <xsl:choose>
59           <xsl:when test="@frame = 'box'">all</xsl:when>
60           <xsl:when test="@frame = 'border'">all</xsl:when>
61           <xsl:when test="@frame = 'below'">bottom</xsl:when>
62           <xsl:when test="@frame = 'above'">top</xsl:when>
63           <xsl:when test="@frame = 'hsides'">topbot</xsl:when>
64           <xsl:when test="@frame = 'vsides'">sides</xsl:when>
65           <xsl:when test="@frame = 'lhs'">lhs</xsl:when>
66           <xsl:when test="@frame = 'rhs'">rhs</xsl:when>
67           <xsl:when test="@frame = 'void'">none</xsl:when>
68           <xsl:when test="@border != '' and @border != 0">all</xsl:when>
69           <xsl:when test="@border != '' and @border = 0">none</xsl:when>
70           <xsl:when test="@frame != ''">
71             <xsl:value-of select="@frame"/>
72           </xsl:when>
73           <xsl:when test="$default.table.frame != ''">
74             <xsl:value-of select="$default.table.frame"/>
75           </xsl:when>
76           <xsl:otherwise>all</xsl:otherwise>
77         </xsl:choose>
78       </xsl:with-param>
79     </xsl:call-template>
80
81     <xsl:call-template name="make-html-table-columns">
82       <xsl:with-param name="count" select="$numcols"/>
83     </xsl:call-template>
84
85     <xsl:apply-templates select="thead" mode="htmlTable"/>
86     <xsl:apply-templates select="tfoot" mode="htmlTable"/>
87     <xsl:choose>
88       <xsl:when test="tbody">
89         <xsl:apply-templates select="tbody" mode="htmlTable"/>
90       </xsl:when>
91       <xsl:otherwise>
92         <fo:table-body start-indent="0pt" end-indent="0pt">
93           <xsl:apply-templates select="tr" mode="htmlTable"/>
94         </fo:table-body>
95       </xsl:otherwise>
96     </xsl:choose>
97   </fo:table>
98
99 </xsl:template>
100
101 <!-- This template writes rowsep or colsep equivalant for html tables -->
102 <xsl:template name="html.table.cell.rules">
103   <xsl:variable name="border" 
104                 select="(ancestor::table |
105                          ancestor::informaltable)[last()]/@border"/>
106   <xsl:variable name="table.rules"
107                 select="(ancestor::table |
108                          ancestor::informaltable)[last()]/@rules"/>
109
110   <xsl:variable name="rules">
111     <xsl:choose>
112       <xsl:when test="$table.rules != ''">
113         <xsl:value-of select="$table.rules"/>
114       </xsl:when>
115       <xsl:when test="$default.table.rules != ''">
116         <xsl:value-of select="$default.table.rules"/>
117       </xsl:when>
118     </xsl:choose>
119   </xsl:variable>
120
121   <xsl:choose>
122     <xsl:when test="$border != '' and $border != 0">
123       <xsl:attribute name="border">
124         <xsl:value-of select="$table.cell.border.thickness"/>
125         <xsl:text> </xsl:text>
126         <xsl:value-of select="$table.cell.border.style"/>
127         <xsl:text> </xsl:text>
128         <xsl:value-of select="$table.cell.border.color"/>
129       </xsl:attribute>
130     </xsl:when>
131     <xsl:when test="$rules = 'none'">
132       <xsl:attribute name="border-start-style">none</xsl:attribute>
133       <xsl:attribute name="border-end-style">none</xsl:attribute>
134       <xsl:attribute name="border-top-style">none</xsl:attribute>
135       <xsl:attribute name="border-bottom-style">none</xsl:attribute>
136     </xsl:when>
137
138     <xsl:when test="$rules = 'cols' and following-sibling::*">
139       <!-- If not the last column, add border after -->
140       <xsl:attribute name="border-start-style">none</xsl:attribute>
141       <xsl:attribute name="border-top-style">none</xsl:attribute>
142       <xsl:attribute name="border-bottom-style">none</xsl:attribute>
143       <xsl:attribute name="border-end-style">
144         <xsl:value-of select="$table.frame.border.style"/>
145       </xsl:attribute>
146       <xsl:attribute name="border-end-width">
147         <xsl:value-of select="$table.frame.border.thickness"/>
148       </xsl:attribute>
149       <xsl:attribute name="border-end-color">
150         <xsl:value-of select="$table.frame.border.color"/>
151       </xsl:attribute>
152     </xsl:when>
153     <!-- If not the last row, add border below -->
154     <xsl:when test="$rules = 'rows'">
155       <xsl:variable name="rowborder">
156         <xsl:choose>
157           <!-- If in thead and tbody has rows, add border -->
158           <xsl:when test="parent::tr/parent::thead/
159                           following-sibling::tbody/tr">1</xsl:when>
160           <!-- If in tbody and tfoot has rows, add border -->
161           <xsl:when test="parent::tr/parent::tbody/
162                           following-sibling::tfoot/tr">1</xsl:when>
163           <xsl:when test="parent::tr/parent::tbody/
164                           preceding-sibling::tfoot/tr">1</xsl:when>
165           <!-- If following rows, but not rowspan reaches last row -->
166           <xsl:when test="parent::tr/following-sibling::tr and
167              not(@rowspan = count(parent::tr/following-sibling::tr) + 1)">1</xsl:when>
168           <xsl:otherwise>0</xsl:otherwise>
169         </xsl:choose>
170       </xsl:variable>
171
172       <xsl:if test="$rowborder = 1">
173         <xsl:attribute name="border-start-style">none</xsl:attribute>
174         <xsl:attribute name="border-end-style">none</xsl:attribute>
175         <xsl:attribute name="border-top-style">none</xsl:attribute>
176         <xsl:attribute name="border-bottom-style">
177           <xsl:value-of select="$table.frame.border.style"/>
178         </xsl:attribute>
179         <xsl:attribute name="border-bottom-width">
180           <xsl:value-of select="$table.frame.border.thickness"/>
181         </xsl:attribute>
182         <xsl:attribute name="border-bottom-color">
183           <xsl:value-of select="$table.frame.border.color"/>
184         </xsl:attribute>
185       </xsl:if>
186     </xsl:when>
187     <xsl:when test="$rules = 'all'">
188       <xsl:attribute name="border-start-style">none</xsl:attribute>
189       <xsl:attribute name="border-top-style">none</xsl:attribute>
190
191       <xsl:variable name="rowborder">
192         <xsl:choose>
193           <!-- If in thead and tbody has rows, add border -->
194           <xsl:when test="parent::tr/parent::thead/
195                           following-sibling::tbody/tr">1</xsl:when>
196           <!-- If in tbody and tfoot has rows, add border -->
197           <xsl:when test="parent::tr/parent::tbody/
198                           following-sibling::tfoot/tr">1</xsl:when>
199           <xsl:when test="parent::tr/parent::tbody/
200                           preceding-sibling::tfoot/tr">1</xsl:when>
201           <!-- If following rows, but not rowspan reaches last row -->
202           <xsl:when test="parent::tr/following-sibling::tr and
203              not(@rowspan = count(parent::tr/following-sibling::tr) + 1)">1</xsl:when>
204           <xsl:otherwise>0</xsl:otherwise>
205         </xsl:choose>
206       </xsl:variable>
207
208       <xsl:if test="$rowborder = 1">
209         <xsl:attribute name="border-bottom-style">
210           <xsl:value-of select="$table.frame.border.style"/>
211         </xsl:attribute>
212         <xsl:attribute name="border-bottom-width">
213           <xsl:value-of select="$table.frame.border.thickness"/>
214         </xsl:attribute>
215         <xsl:attribute name="border-bottom-color">
216           <xsl:value-of select="$table.frame.border.color"/>
217         </xsl:attribute>
218       </xsl:if>
219
220       <xsl:if test="following-sibling::*">
221         <!-- If not the last column, add border after -->
222         <xsl:attribute name="border-end-style">
223           <xsl:value-of select="$table.frame.border.style"/>
224         </xsl:attribute>
225         <xsl:attribute name="border-end-width">
226           <xsl:value-of select="$table.frame.border.thickness"/>
227         </xsl:attribute>
228         <xsl:attribute name="border-end-color">
229           <xsl:value-of select="$table.frame.border.color"/>
230         </xsl:attribute>
231       </xsl:if>
232     </xsl:when>
233     <xsl:when test="$rules = 'groups' and ancestor::thead 
234                     and not(parent::tr/following-sibling::tr)">
235       <xsl:attribute name="border-start-style">none</xsl:attribute>
236       <xsl:attribute name="border-end-style">none</xsl:attribute>
237       <xsl:attribute name="border-top-style">none</xsl:attribute>
238       <xsl:attribute name="border-bottom-style">
239         <xsl:value-of select="$table.frame.border.style"/>
240       </xsl:attribute>
241       <xsl:attribute name="border-bottom-width">
242         <xsl:value-of select="$table.frame.border.thickness"/>
243       </xsl:attribute>
244       <xsl:attribute name="border-bottom-color">
245         <xsl:value-of select="$table.frame.border.color"/>
246       </xsl:attribute>
247     </xsl:when>
248     <xsl:when test="$rules = 'groups' and ancestor::tfoot 
249                     and not(parent::tr/preceding-sibling::tr)">
250       <xsl:attribute name="border-start-style">none</xsl:attribute>
251       <xsl:attribute name="border-end-style">none</xsl:attribute>
252       <xsl:attribute name="border-top-style">none</xsl:attribute>
253       <xsl:attribute name="border-top-style">
254         <xsl:value-of select="$table.frame.border.style"/>
255       </xsl:attribute>
256       <xsl:attribute name="border-top-width">
257         <xsl:value-of select="$table.frame.border.thickness"/>
258       </xsl:attribute>
259       <xsl:attribute name="border-top-color">
260         <xsl:value-of select="$table.frame.border.color"/>
261       </xsl:attribute>
262     </xsl:when>
263   </xsl:choose>
264 </xsl:template>
265
266 <xsl:template match="caption" mode="htmlTable">
267   <!-- Handled by formal.object.heading -->
268 </xsl:template>
269
270 <xsl:template name="widest-html-row">
271   <xsl:param name="rows" select="''"/>
272   <xsl:param name="count" select="0"/>
273   <xsl:choose>
274     <xsl:when test="count($rows) = 0">
275       <xsl:value-of select="$count"/>
276     </xsl:when>
277     <xsl:otherwise>
278       <xsl:choose>
279         <xsl:when test="$count &gt; count($rows[1]/*)">
280           <xsl:call-template name="widest-html-row">
281             <xsl:with-param name="rows" select="$rows[position() &gt; 1]"/>
282             <xsl:with-param name="count" select="$count"/>
283           </xsl:call-template>
284         </xsl:when>
285         <xsl:otherwise>
286           <xsl:call-template name="widest-html-row">
287             <xsl:with-param name="rows" select="$rows[position() &gt; 1]"/>
288             <xsl:with-param name="count" select="count($rows[1]/*)"/>
289           </xsl:call-template>
290         </xsl:otherwise>
291       </xsl:choose>
292     </xsl:otherwise>
293   </xsl:choose>
294 </xsl:template>
295
296 <xsl:template name="make-html-table-columns">
297   <xsl:param name="count" select="0"/>
298   <xsl:param name="number" select="1"/>
299
300   <xsl:choose>
301     <xsl:when test="col|colgroup/col">
302       <xsl:for-each select="col|colgroup/col">
303         <fo:table-column>
304           <xsl:attribute name="column-number">
305             <xsl:number from="table|informaltable" level="any" format="1"/>
306           </xsl:attribute>
307           <xsl:if test="@width">
308             <xsl:attribute name="column-width">
309               <xsl:choose>
310                 <xsl:when test="$fop.extensions != 0 and 
311                                 contains(@width, '%')">
312                   <xsl:value-of select="concat('proportional-column-width(',
313                                                substring-before(@width, '%'),
314                                                ')')"/>
315                 </xsl:when>
316                 <xsl:otherwise>
317                   <xsl:value-of select="@width"/>
318                 </xsl:otherwise>
319               </xsl:choose>
320             </xsl:attribute>
321           </xsl:if>
322         </fo:table-column>
323       </xsl:for-each>
324     </xsl:when>
325     <xsl:when test="$fop.extensions != 0">
326       <xsl:if test="$number &lt;= $count">
327         <fo:table-column column-number="{$number}"
328                          column-width="{6.5 div $count}in"/>
329         <xsl:call-template name="make-html-table-columns">
330           <xsl:with-param name="count" select="$count"/>
331           <xsl:with-param name="number" select="$number + 1"/>
332         </xsl:call-template>
333       </xsl:if>
334     </xsl:when>
335   </xsl:choose>
336 </xsl:template>
337
338 <xsl:template match="tbody" mode="htmlTable">
339   <fo:table-body start-indent="0pt"
340                  end-indent="0pt">
341     <xsl:apply-templates mode="htmlTable"/>
342   </fo:table-body>
343 </xsl:template>
344
345 <xsl:template match="tfoot" mode="htmlTable">
346   <fo:table-footer start-indent="0pt"
347                    end-indent="0pt">
348     <xsl:apply-templates mode="htmlTable"/>
349   </fo:table-footer>
350 </xsl:template>
351
352 <xsl:template match="th|td" mode="htmlTable">
353   <xsl:variable name="bgcolor.pi">
354     <xsl:call-template name="pi.dbfo_bgcolor"/>
355   </xsl:variable>
356
357   <xsl:variable name="bgcolor">
358     <xsl:choose>
359       <xsl:when test="$bgcolor.pi != ''">
360         <xsl:value-of select="$bgcolor.pi"/>
361       </xsl:when>
362       <xsl:when test="string-length(@bgcolor) != 0">
363         <xsl:value-of select="@bgcolor"/>
364       </xsl:when>
365     </xsl:choose>
366   </xsl:variable>
367
368   <xsl:variable name="align">
369     <xsl:call-template name="inherited.table.attribute">
370       <xsl:with-param name="entry" select="."/>
371       <xsl:with-param name="row" select="parent::tr"/>
372       <xsl:with-param name="attribute" select="'align'"/>
373     </xsl:call-template>
374   </xsl:variable>
375
376   <xsl:variable name="valign">
377     <xsl:call-template name="inherited.table.attribute">
378       <xsl:with-param name="entry" select="."/>
379       <xsl:with-param name="row" select="parent::tr"/>
380       <xsl:with-param name="attribute" select="'valign'"/>
381     </xsl:call-template>
382   </xsl:variable>
383
384   <fo:table-cell xsl:use-attribute-sets="table.cell.padding">
385     <xsl:call-template name="table.cell.properties">
386       <xsl:with-param name="bgcolor.pi" select="$bgcolor"/>
387       <xsl:with-param name="rowsep.inherit" select="0"/>
388       <xsl:with-param name="align.inherit" select="$align"/>
389       <xsl:with-param name="valign.inherit" select="$valign"/>
390       <xsl:with-param name="colsep.inherit" select="0"/>
391     </xsl:call-template>
392
393     <xsl:if test="@colspan &gt; 1">
394       <xsl:attribute name="number-columns-spanned">
395         <xsl:value-of select="@colspan"/>
396       </xsl:attribute>
397     </xsl:if>
398
399     <xsl:if test="@rowspan &gt; 1">
400       <xsl:attribute name="number-rows-spanned">
401         <xsl:value-of select="@rowspan"/>
402       </xsl:attribute>
403     </xsl:if>
404
405     <fo:block>
406       <xsl:call-template name="table.cell.block.properties"/>
407       <xsl:apply-templates/>
408     </fo:block>
409   </fo:table-cell>
410 </xsl:template>
411
412 <xsl:template match="thead" mode="htmlTable">
413   <fo:table-header start-indent="0pt"
414                    end-indent="0pt">
415     <xsl:apply-templates mode="htmlTable"/>
416   </fo:table-header>
417 </xsl:template>
418
419 <xsl:template match="tr" mode="htmlTable">
420   <fo:table-row>
421     <xsl:call-template name="table.row.properties"/>
422     <xsl:apply-templates mode="htmlTable"/>
423   </fo:table-row>
424 </xsl:template>
425
426 </xsl:stylesheet>