Copy purify.fvwm2rc to /tmp - add instructions in README.
[fvwm.git] / doc / docbook-xsl / manpages / table.xsl
blobd410cfe7463f83f7379a947814c3bdc779cf08be
1 <?xml version="1.0"?>
2 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3 xmlns:exsl="http://exslt.org/common"
4 exclude-result-prefixes="exsl"
5 version='1.0'>
7 <!-- ********************************************************************
8 $Id: table.xsl,v 1.1 2007/03/10 05:15:34 scott Exp $
9 ********************************************************************
11 This file is part of the XSL DocBook Stylesheet distribution.
12 See ../README or http://docbook.sf.net/release/xsl/current/ for
13 copyright and other information.
15 ******************************************************************** -->
16 <!--
17 <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
18 <xsl:param name="tbl.font.title">B</xsl:param>
19 <xsl:param name="tbl.font.headings">B</xsl:param>
20 -->
21 <xsl:param name="tbl.running.header.from.thead" select="0"/>
22 <xsl:param name="tbl.column.separator.char">:</xsl:param>
24 <!-- ==================================================================== -->
26 <!-- * This stylesheet transforms DocBook and HTML table source into -->
27 <!-- * tbl(1) markup. -->
28 <!-- * -->
29 <!-- * For details on tbl(1) and its markup syntaxt, see M. E. Lesk,-->
30 <!-- * "Tbl - A Program to Format Tables": -->
31 <!-- * -->
32 <!-- * http://cm.bell-labs.com/7thEdMan/vol2/tbl -->
33 <!-- * http://cm.bell-labs.com/cm/cs/doc/76/tbl.ps.gz -->
34 <!-- * http://www.snake.net/software/troffcvt/tbl.html -->
36 <xsl:template match="table|informaltable" mode="to.tbl">
37 <!--* the "source" param is an optional param; it can be any -->
38 <!--* string you want to use that gives some indication of the -->
39 <!--* source context for a table; it gets passed down to the named -->
40 <!--* templates that do the actual table processing; this -->
41 <!--* stylesheet currently uses the "source" information for -->
42 <!--* logging purposes -->
43 <xsl:param name="source"/>
44 <xsl:param name="title">
45 <xsl:if test="local-name(.) = 'table'">
46 <xsl:apply-templates select="." mode="object.title.markup.textonly"/>
47 </xsl:if>
48 </xsl:param>
49 <!-- * ============================================================== -->
50 <!-- * Set global table parameters -->
51 <!-- * ============================================================== -->
52 <!-- * First, set a few parameters based on attributes specified in -->
53 <!-- * the table source. -->
54 <xsl:param name="allbox">
55 <xsl:if test="not(@frame = 'none') and not(@border = '0')">
56 <!-- * By default, put a box around table and between all cells, -->
57 <!-- * unless frame="none" or border="0" -->
58 <xsl:text>allbox </xsl:text>
59 </xsl:if>
60 </xsl:param>
61 <xsl:param name="center">
62 <!-- * If align="center", center the table. Otherwise, tbl(1) -->
63 <!-- * left-aligns it by default; note that there is no support -->
64 <!-- * in tbl(1) for specifying right alignment. -->
65 <xsl:if test="@align = 'center' or tgroup/@align = 'center'">
66 <xsl:text>center </xsl:text>
67 </xsl:if>
68 </xsl:param>
69 <xsl:param name="expand">
70 <!-- * If pgwide="1" or width="100%", then "expand" the table by -->
71 <!-- * making it "as wide as the current line length" (to quote -->
72 <!-- * the tbl(1) guide). -->
73 <xsl:if test="@pgwide = '1' or @width = '100%'">
74 <xsl:text>expand </xsl:text>
75 </xsl:if>
76 </xsl:param>
78 <!-- * ============================================================== -->
79 <!-- * Convert table to HTML -->
80 <!-- * ============================================================== -->
81 <!-- * Process the table by applying the HTML templates from the -->
82 <!-- * DocBook XSL stylesheets to the whole thing; because we don't -->
83 <!-- * override any of the <row>, <entry>, <tr>, <td>, etc. templates, -->
84 <!-- * the templates in the HTML stylesheets (which we import) are -->
85 <!-- * used to process those. -->
86 <xsl:param name="html-table-output">
87 <xsl:choose>
88 <xsl:when test=".//tr">
89 <!-- * If this table has a TR child, it means that it's an -->
90 <!-- * HTML table in the DocBook source, instead of a CALS -->
91 <!-- * table. So we just copy it as-is, while wrapping it -->
92 <!-- * in an element with same name as its original parent. -->
93 <xsl:for-each select="descendant-or-self::table|descendant-or-self::informaltable">
94 <xsl:element name="{local-name(..)}">
95 <table>
96 <xsl:copy-of select="*"/>
97 </table>
98 </xsl:element>
99 </xsl:for-each>
100 </xsl:when>
101 <xsl:otherwise>
102 <!-- * Otherwise, this is a CALS table in the DocBook source, -->
103 <!-- * so we need to apply the templates in the HTML -->
104 <!-- * stylesheets to transform it into HTML before we do -->
105 <!-- * any further processing of it. -->
106 <xsl:apply-templates/>
107 </xsl:otherwise>
108 </xsl:choose>
109 </xsl:param>
110 <xsl:param name="contents" select="exsl:node-set($html-table-output)"/>
112 <!-- ==================================================================== -->
113 <!-- * Output the table -->
114 <!-- ==================================================================== -->
115 <!-- * -->
116 <!-- * This is the "driver" part of the code; it calls a series of named
117 * templates (further below) to generate the actual tbl(1) markup, -->
118 <!-- * including the optional "options line", required "format section", -->
119 <!-- * and then the actual contents of the table. -->
120 <!-- * -->
121 <!-- ==================================================================== -->
123 <xsl:for-each select="$contents//table">
124 <!-- * ============================================================== -->
125 <!-- * Output table title -->
126 <!-- * ============================================================== -->
127 <xsl:if test="$title != '' or parent::td">
128 <xsl:text>.PP&#10;</xsl:text>
129 <xsl:text>.</xsl:text>
130 <xsl:value-of select="$tbl.font.title"/>
131 <xsl:text> </xsl:text>
132 <xsl:if test="parent::td">
133 <xsl:text>*[nested&#x2580;table]</xsl:text>
134 </xsl:if>
135 <xsl:value-of select="normalize-space($title)"/>
136 <xsl:text>&#10;</xsl:text>
137 <xsl:text>.sp -1n&#10;</xsl:text>
138 </xsl:if>
140 <!-- * mark the start of the table -->
141 <!-- * "TS" = "table start" -->
142 <xsl:text>.TS</xsl:text>
143 <xsl:if test="thead and $tbl.running.header.from.thead">
144 <!-- * H = "has header" -->
145 <xsl:text> H</xsl:text>
146 </xsl:if>
147 <xsl:text>&#10;</xsl:text>
149 <!-- * ============================================================== -->
150 <!-- * Output "options line" -->
151 <!-- * ============================================================== -->
152 <xsl:variable name="options-line">
153 <xsl:value-of select="$allbox"/>
154 <xsl:value-of select="$center"/>
155 <xsl:value-of select="$expand"/>
156 <xsl:text>tab(</xsl:text>
157 <xsl:value-of select="$tbl.column.separator.char"/>
158 <xsl:text>)</xsl:text>
159 </xsl:variable>
160 <xsl:if test="normalize-space($options-line) != ''">
161 <xsl:value-of select="normalize-space($options-line)"/>
162 <xsl:text>;&#10;</xsl:text>
163 </xsl:if>
165 <!-- * ============================================================== -->
166 <!-- * Output table header rows -->
167 <!-- * ============================================================== -->
168 <xsl:if test="thead">
169 <xsl:call-template name="output.rows">
170 <xsl:with-param name="rows" select="thead/tr"/>
171 </xsl:call-template>
172 <xsl:text>&#10;</xsl:text>
174 <!-- * mark the end of table-header rows -->
175 <xsl:choose>
176 <xsl:when test="$tbl.running.header.from.thead">
177 <!-- * "TH" = "table header end" -->
178 <xsl:text>.TH&#10;</xsl:text>
179 </xsl:when>
180 <xsl:otherwise>
181 <!-- * "T&" = "table continuation" and is meant just as a kind -->
182 <!-- * of convenience macro and is sorta equivalent to a "TE" -->
183 <!-- * (table end) followed immediately by a "TS" (table start); -->
184 <!-- * in this case, it marks the end of a table "subsection" -->
185 <!-- * with header rows, and the start of a subsection with body -->
186 <!-- * rows. It's necessary to output it here because the "TH" -->
187 <!-- * macro is not being output, so there's otherwise no way -->
188 <!-- * for tbl(1) to know we have the table "sectioned". -->
189 <xsl:text>.T&amp;&#10;</xsl:text>
190 </xsl:otherwise>
191 </xsl:choose>
192 </xsl:if>
194 <!-- * ============================================================== -->
195 <!-- * Output table body rows -->
196 <!-- * ============================================================== -->
197 <!-- * First create node set with all non-thead rows (tbody+tfoot), -->
198 <!-- * but reordered with the tfoot rows at the end of the node set -->
199 <xsl:variable name="rows-set">
200 <xsl:copy-of select="tbody/tr|tr"/>
201 <xsl:copy-of select="tfoot/tr"/>
202 </xsl:variable>
203 <xsl:call-template name="output.rows">
204 <xsl:with-param name="source" select="$source"/>
205 <xsl:with-param name="rows" select="exsl:node-set($rows-set)"/>
206 </xsl:call-template>
208 <!-- * mark the end of the table -->
209 <xsl:text>&#10;</xsl:text>
210 <!-- * .TE = "Table End" -->
211 <xsl:text>.TE&#10;</xsl:text>
212 <!-- * put a blank line of space below the table -->
213 <xsl:text>.sp&#10;</xsl:text>
214 </xsl:for-each>
215 </xsl:template>
217 <!-- ==================================================================== -->
218 <!-- * named templates -->
219 <!-- ==================================================================== -->
220 <!-- * -->
221 <!-- * All of the following are named templates that get called directly -->
222 <!-- * or indirectly by the main "driver" part of the code (above) -->
223 <!-- * -->
224 <!-- ==================================================================== -->
226 <xsl:template name="output.rows">
227 <xsl:param name="source"/>
228 <xsl:param name="rows"/>
229 <!-- * ============================================================== -->
230 <!-- * Flatten row set into simple list of cells -->
231 <!-- * ============================================================== -->
232 <!-- * Now we flatten the structure further into just a set of -->
233 <!-- * cells without the row parents. This basically creates a -->
234 <!-- * copy of the entire contents of the original table, but -->
235 <!-- * restructured in such a way that we can more easily generate -->
236 <!-- * the corresponding tbl(1) markup we need to output. -->
237 <xsl:variable name="cells-list">
238 <xsl:call-template name="build.cell.list">
239 <xsl:with-param name="source" select="$source"/>
240 <xsl:with-param name="rows" select="$rows"/>
241 </xsl:call-template>
242 </xsl:variable>
243 <xsl:variable name="cells" select="exsl:node-set($cells-list)"/>
245 <!-- * Output the table "format section", which tells tbl(1) how to -->
246 <!-- * format each row and column -->
247 <xsl:call-template name="create.table.format">
248 <xsl:with-param name="cells" select="$cells"/>
249 </xsl:call-template>
251 <!--* Output the formatted contents of each cell. -->
252 <xsl:for-each select="$cells/cell">
253 <xsl:call-template name="output.cell"/>
254 </xsl:for-each>
255 </xsl:template>
258 <!-- * ============================================================== -->
259 <!-- * Output the tbl(1)-formatted contents of each cell. -->
260 <!-- * ============================================================== -->
261 <xsl:template name="output.cell">
262 <xsl:choose>
263 <xsl:when test="preceding-sibling::cell[1]/@row != @row or
264 not(preceding-sibling::cell)">
265 <!-- * If the value of the "row" attribute on this cell is -->
266 <!-- * different from the value of that on the previous cell, it -->
267 <!-- * means we have a new row. So output a line break (as long -->
268 <!-- * as this isn't the first cell in the table) -->
269 <xsl:text>&#10;</xsl:text>
270 </xsl:when>
271 <xsl:otherwise>
272 <!-- * Otherwise we are not at the start of a new row, so we -->
273 <!-- * output a tab character to delimit the contents of this -->
274 <!-- * cell from the contents of the next one. -->
275 <xsl:value-of select="$tbl.column.separator.char"/>
276 </xsl:otherwise>
277 </xsl:choose>
278 <xsl:choose>
279 <xsl:when test="@type = '^'">
280 <!-- * If this is a dummy cell resulting from the presence of -->
281 <!-- * rowpan attribute in the source, it has no contents, so -->
282 <!-- * we need to handle it differently. -->
283 <xsl:if test="@colspan and @colspan > 1">
284 <!-- * If there is a colspan attribute on this dummy row, then -->
285 <!-- * we need to output a tab character for each column that -->
286 <!-- * it spans. -->
287 <xsl:call-template name="copy-string">
288 <xsl:with-param name="string" select="$tbl.column.separator.char"/>
289 <xsl:with-param name="count">
290 <xsl:value-of select="@colspan - 1"/>
291 </xsl:with-param>
292 </xsl:call-template>
293 </xsl:if>
294 </xsl:when>
295 <xsl:otherwise>
296 <!-- * Otherwise, we have a "real" cell (not a dummy one) with -->
297 <!-- * contents that we need to output, -->
298 <!-- * -->
299 <!-- * The "T{" and "T}" stuff are delimiters to tell tbl(1) that -->
300 <!-- * the delimited contents are "text blocks" that roff -->
301 <!-- * needs to process -->
302 <xsl:text>T{&#10;</xsl:text>
303 <xsl:copy-of select="."/>
304 <xsl:text>&#10;T}</xsl:text>
305 </xsl:otherwise>
306 </xsl:choose>
307 </xsl:template>
309 <!-- * ============================================================== -->
310 <!-- * Build a restructured "cell list" copy of the entire table -->
311 <!-- * ============================================================== -->
312 <xsl:template name="build.cell.list">
313 <xsl:param name="source"/>
314 <xsl:param name="rows"/>
315 <xsl:param name="cell-data-unsorted">
316 <!-- * This param collects all the "real" cells from the table, -->
317 <!-- * along with "dummy" rows that we generate for keeping -->
318 <!-- * track of Rowspan instances. -->
319 <xsl:apply-templates select="$rows" mode="cell.list">
320 <xsl:with-param name="source" select="$source"/>
321 </xsl:apply-templates>
322 </xsl:param>
323 <xsl:param name="cell-data-sorted">
324 <!-- * Sort the cells so that the dummy cells get put where we -->
325 <!-- * need them in the structure. -->
326 <xsl:for-each select="exsl:node-set($cell-data-unsorted)/cell">
327 <xsl:sort select="@row"/>
328 <xsl:sort select="@slot"/>
329 <xsl:copy-of select="."/>
330 </xsl:for-each>
331 </xsl:param>
332 <!-- * Return the sorted cell list -->
333 <xsl:copy-of select="$cell-data-sorted"/>
334 </xsl:template>
336 <xsl:template match="tr" mode="cell.list">
337 <xsl:param name="source"/>
338 <xsl:variable name="row">
339 <xsl:value-of select="count(preceding-sibling::tr) + 1"/>
340 </xsl:variable>
341 <xsl:for-each select="td|th">
342 <xsl:call-template name="cell">
343 <xsl:with-param name="source" select="$source"/>
344 <xsl:with-param name="row" select="$row"/>
345 <!-- * pass on the element name so we can select the appropriate -->
346 <!-- * roff font for styling the cell contents -->
347 <xsl:with-param name="class" select="name(.)"/>
348 </xsl:call-template>
349 </xsl:for-each>
350 </xsl:template>
352 <xsl:template name="cell">
353 <xsl:param name="source"/>
354 <xsl:param name="row"/>
355 <xsl:param name="class"/>
356 <xsl:param name="slot">
357 <!-- * The "slot" is the horizontal position of this cell (usually -->
358 <!-- * just the same as its column, but not so when it is preceded -->
359 <!-- * by cells that have colspans or cells in preceding rows that -->
360 <!-- * that have rowspans). -->
361 <xsl:value-of select="position()"/>
362 </xsl:param>
363 <!-- * For each real TD cell, create a Cell instance; contents will -->
364 <!-- * be the roff-formatted contents of its original table cell. -->
365 <cell type=""
366 row="{$row}"
367 slot="{$slot}"
368 class="{$class}"
369 colspan="{@colspan}"
370 align="{@align}"
371 valign="{@valign}"
373 <xsl:choose>
374 <xsl:when test=".//tr">
375 <xsl:call-template name="log.message">
376 <xsl:with-param name="level">Warn</xsl:with-param>
377 <xsl:with-param name="source" select="$source"/>
378 <xsl:with-param name="message">
379 <xsl:text
380 >tbl convert : Extracted a nested table</xsl:text>
381 </xsl:with-param>
382 </xsl:call-template>
383 <xsl:text>[\fInested&#x2580;table\fR]*&#10;</xsl:text>
384 </xsl:when>
385 <xsl:otherwise>
386 <!-- * Apply templates to the child contents of this cell, to -->
387 <!-- * transform them into marked-up roff. -->
388 <xsl:variable name="contents">
389 <xsl:apply-templates/>
390 </xsl:variable>
391 <!-- * We now have the contents in roff (plain-text) form, -->
392 <!-- * but we may also still have unnecessary whitespace at -->
393 <!-- * the beginning and/or end of it, so trim it off. -->
394 <xsl:call-template name="trim.text">
395 <xsl:with-param name="contents" select="$contents"/>
396 </xsl:call-template>
397 </xsl:otherwise>
398 </xsl:choose>
399 </cell>
401 <!-- * For each instance of a rowspan attribute found, we create N -->
402 <!-- * dummy cells, where N is equal to the value of the rowspan. -->
403 <xsl:if test="@rowspan and @rowspan > 0">
404 <!-- * If this cell is preceded in the same row by cells that -->
405 <!-- * have colspan attributes, then we need to calculate the -->
406 <!-- * "offset" caused by those colspan instances; the formula -->
407 <!-- * is to (1) check for all the preceding cells that have -->
408 <!-- * colspan attributes that are not empty and which have a -->
409 <!-- * value greater than 1, then (2) take the sum of the values -->
410 <!-- * of all those colspan attributes, and subtract from that -->
411 <!-- * the number of such colspan instances found. -->
412 <xsl:variable name="colspan-offset">
413 <xsl:value-of
414 select="sum(preceding-sibling::td[@colspan != ''
415 and @colspan > 1]/@colspan) -
416 count(preceding-sibling::td[@colspan != ''
417 and @colspan > 1]/@colspan)"/>
418 </xsl:variable>
419 <xsl:call-template name="create.dummy.cells">
420 <xsl:with-param name="row" select="$row + 1"/>
421 <!-- * The slot value on each dummy cell must be offset by the -->
422 <!-- * value of $colspan-offset to adjust for preceding colpans -->
423 <xsl:with-param name="slot" select="$slot + $colspan-offset"/>
424 <xsl:with-param name="colspan" select="@colspan"/>
425 <xsl:with-param name="rowspan" select="@rowspan"/>
426 </xsl:call-template>
427 </xsl:if>
428 </xsl:template>
430 <xsl:template name="create.dummy.cells">
431 <xsl:param name="row"/>
432 <xsl:param name="slot"/>
433 <xsl:param name="colspan"/>
434 <xsl:param name="rowspan"/>
435 <xsl:choose>
436 <xsl:when test="$rowspan > 1">
437 <!-- * Tail recurse until we have no more rowspans, creating -->
438 <!-- * an empty dummy cell each time. The type value, '^' -->
439 <!-- * is the marker that tbl(1) uses to indicate a -->
440 <!-- * "vertically spanned heading". -->
441 <cell row="{$row}" slot="{$slot}" type="^" colspan="{@colspan}"/>
442 <xsl:call-template name="create.dummy.cells">
443 <xsl:with-param name="row" select="$row + 1"/>
444 <xsl:with-param name="slot" select="$slot"/>
445 <xsl:with-param name="colspan" select="$colspan"/>
446 <xsl:with-param name="rowspan" select="$rowspan - 1"/>
447 </xsl:call-template>
448 </xsl:when>
449 </xsl:choose>
450 </xsl:template>
452 <!-- * ============================================================== -->
453 <!-- * Build the "format section" for the table -->
454 <!-- * ============================================================== -->
455 <!-- * Description from the tbl(1) guide: -->
456 <!-- * -->
457 <!-- * "The format section of the table specifies the layout of the -->
458 <!-- * columns. Each line in this section corresponds to one line of -->
459 <!-- * the table... and each line contains a key-letter for each -->
460 <!-- * column of the table." -->
461 <xsl:template name="create.table.format">
462 <xsl:param name="cells"/>
463 <xsl:apply-templates mode="table.format" select="$cells"/>
464 <!-- * last line of table format section must end with a dot -->
465 <xsl:text>.</xsl:text>
466 </xsl:template>
468 <xsl:template match="cell" mode="table.format">
469 <xsl:choose>
470 <xsl:when test="preceding-sibling::cell[1]/@row != @row">
471 <!-- * If the value of the row attribute on this cell is -->
472 <!-- * different from the value of that on the previous cell, it -->
473 <!-- * means we have a new row. So output a line break. -->
474 <xsl:text>&#xa;</xsl:text>
475 </xsl:when>
476 <xsl:otherwise>
477 <!-- * If this isn't the first cell, output a space before it to -->
478 <!-- * separate it from the preceding key letter. -->
479 <xsl:if test="position() != 1">
480 <xsl:text> </xsl:text>
481 </xsl:if>
482 </xsl:otherwise>
483 </xsl:choose>
484 <!-- * Select an appropriate "alignment" key letter based on this -->
485 <!-- * cell's attributes. -->
486 <xsl:choose>
487 <xsl:when test="@type = '^'">
488 <xsl:text>^</xsl:text>
489 </xsl:when>
490 <xsl:when test="@align = 'center'">
491 <xsl:text>c</xsl:text>
492 </xsl:when>
493 <xsl:when test="@align = 'right'">
494 <xsl:text>r</xsl:text>
495 </xsl:when>
496 <xsl:when test="@align = 'char'">
497 <xsl:text>n</xsl:text>
498 </xsl:when>
499 <xsl:otherwise>
500 <!-- * Default to left alignment. -->
501 <xsl:text>l</xsl:text>
502 </xsl:otherwise>
503 </xsl:choose>
504 <!-- * By default, tbl(1) vertically centers cell contents within -->
505 <!-- * their cells; the "t" key latter tells it to top-align the -->
506 <!-- * contents instead. Note that tbl(1) has no options for -->
507 <!-- * bottom or baseline alignment. -->
508 <xsl:if test="@valign = 'top'">
509 <xsl:text>t</xsl:text>
510 </xsl:if>
511 <xsl:if test="@class = 'th'">
512 <!-- * If this is a heading row, generate a font indicator (B or I), -->
513 <!-- * or if the value of $tbl.font.headings is empty, nothing. -->
514 <xsl:value-of select="$tbl.font.headings"/>
515 </xsl:if>
516 <!-- * We only need to deal with colspans whose value is greater -->
517 <!-- * than one (a colspan="1" is the same as having no colspan -->
518 <!-- * attribute at all). -->
519 <xsl:if test="@colspan > 1">
520 <xsl:call-template name="process.colspan">
521 <xsl:with-param name="colspan" select="@colspan - 1"/>
522 <xsl:with-param name="type" select="@type"/>
523 </xsl:call-template>
524 </xsl:if>
525 </xsl:template>
527 <xsl:template name="process.colspan">
528 <xsl:param name="colspan"/>
529 <xsl:param name="type"/>
530 <!-- * Output a space to separate this key letter from preceding one. -->
531 <xsl:text> </xsl:text>
532 <xsl:choose>
533 <xsl:when test="$type = '^'">
534 <!-- * A '^' ("vertically spanned heading" marker) indicates -->
535 <!-- * that the "parent" of this spanned cell is a dummy cell; -->
536 <!-- * in this case, we need to generate a '^' instead of the -->
537 <!-- * normal 's'. -->
538 <xsl:text>^</xsl:text>
539 </xsl:when>
540 <xsl:otherwise>
541 <!-- * s = 'spanned heading' -->
542 <xsl:text>s</xsl:text>
543 </xsl:otherwise>
544 </xsl:choose>
545 <xsl:if test="$colspan > 1">
546 <!-- * Tail recurse until we have no more colspans, outputting -->
547 <!-- * another marker each time. -->
548 <xsl:call-template name="process.colspan">
549 <xsl:with-param name="colspan" select="$colspan - 1"/>
550 <xsl:with-param name="type" select="$type"/>
551 </xsl:call-template>
552 </xsl:if>
553 </xsl:template>
555 <!-- * ============================================================== -->
556 <!-- * colgroup and col -->
557 <!-- * ============================================================== -->
558 <!-- * We currently don't do anything with colgroup. Not sure if it -->
559 <!-- * is widely used enough to bother adding support for it -->
560 <xsl:template match="colgroup"/>
561 <xsl:template match="col"/>
563 <!-- * ============================================================== -->
564 <!-- * table footnotes -->
565 <!-- * ============================================================== -->
566 <xsl:template match="footnote" mode="table.footnote.mode">
567 <xsl:variable name="footnotes" select=".//footnote"/>
568 <xsl:variable name="table.footnotes"
569 select=".//tgroup//footnote"/>
570 <xsl:value-of select="$man.table.footnotes.divider"/>
571 <xsl:text>&#10;</xsl:text>
572 <xsl:text>.br&#10;</xsl:text>
573 <xsl:apply-templates select="*[1]" mode="footnote.body.number"/>
574 <xsl:apply-templates select="*[position() &gt; 1]"/>
575 </xsl:template>
577 <!-- * The following template for footnote.body.number mode was just -->
578 <!-- * lifted from the HTML stylesheets with some minor adjustments -->
579 <xsl:template match="*" mode="footnote.body.number">
580 <xsl:variable name="name">
581 <xsl:text>ftn.</xsl:text>
582 <xsl:call-template name="object.id">
583 <xsl:with-param name="object" select="ancestor::footnote"/>
584 </xsl:call-template>
585 </xsl:variable>
586 <xsl:variable name="href">
587 <xsl:text>#</xsl:text>
588 <xsl:call-template name="object.id">
589 <xsl:with-param name="object" select="ancestor::footnote"/>
590 </xsl:call-template>
591 </xsl:variable>
592 <xsl:variable name="footnote.mark">
593 <xsl:text>[</xsl:text>
594 <xsl:apply-templates select="ancestor::footnote"
595 mode="footnote.number"/>
596 <xsl:text>]&#10;</xsl:text>
597 </xsl:variable>
598 <xsl:variable name="html">
599 <xsl:apply-templates select="."/>
600 </xsl:variable>
601 <xsl:choose>
602 <xsl:when test="function-available('exsl:node-set')">
603 <xsl:variable name="html-nodes" select="exsl:node-set($html)"/>
604 <xsl:choose>
605 <xsl:when test="$html-nodes//p">
606 <xsl:apply-templates select="$html-nodes" mode="insert.html.p">
607 <xsl:with-param name="mark" select="$footnote.mark"/>
608 </xsl:apply-templates>
609 </xsl:when>
610 <xsl:otherwise>
611 <xsl:apply-templates select="$html-nodes" mode="insert.html.text">
612 <xsl:with-param name="mark" select="$footnote.mark"/>
613 </xsl:apply-templates>
614 </xsl:otherwise>
615 </xsl:choose>
616 </xsl:when>
617 <xsl:otherwise>
618 <xsl:copy-of select="$html"/>
619 </xsl:otherwise>
620 </xsl:choose>
621 </xsl:template>
623 <!-- * The HTML stylesheets output <sup><a>...</a></sup> around -->
624 <!-- * footnote markers in tables -->
625 <xsl:template match="th/sup">
626 <xsl:apply-templates/>
627 </xsl:template>
628 <xsl:template match="a">
629 <xsl:apply-templates/>
630 </xsl:template>
632 </xsl:stylesheet>