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