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: formal.xsl,v 1.52 2006/05/04 07:11:00 bobstayton Exp $
8     ********************************************************************
9
10     This file is part of the XSL DocBook Stylesheet distribution.
11     See ../README or http://nwalsh.com/docbook/xsl/ for copyright
12     and other information.
13
14     ******************************************************************** -->
15
16<!-- formal.object creates a basic block containing the
17     result of processing the object, including its title
18     and any keep-together properties.
19     The template calling formal.object may wrap these results in a
20     float or pgwide block. -->
21
22<xsl:template name="formal.object">
23  <xsl:param name="placement" select="'before'"/>
24
25  <xsl:variable name="id">
26    <xsl:call-template name="object.id"/>
27  </xsl:variable>
28
29  <xsl:variable name="content">
30    <xsl:if test="$placement = 'before'">
31      <xsl:call-template name="formal.object.heading">
32        <xsl:with-param name="placement" select="$placement"/>
33      </xsl:call-template>
34    </xsl:if>
35    <xsl:apply-templates/>
36    <xsl:if test="$placement != 'before'">
37      <xsl:call-template name="formal.object.heading">
38        <xsl:with-param name="placement" select="$placement"/>
39      </xsl:call-template>
40    </xsl:if>
41  </xsl:variable>
42
43  <xsl:variable name="keep.together">
44    <xsl:call-template name="dbfo-attribute">
45      <xsl:with-param name="pis"
46                      select="processing-instruction('dbfo')"/>
47      <xsl:with-param name="attribute" select="'keep-together'"/>
48    </xsl:call-template>
49  </xsl:variable>
50
51  <xsl:choose>
52    <!-- tables have their own templates and 
53         are not handled by formal.object -->
54    <xsl:when test="self::figure">
55      <fo:block id="{$id}"
56                xsl:use-attribute-sets="figure.properties">
57        <xsl:if test="$keep.together != ''">
58          <xsl:attribute name="keep-together.within-column"><xsl:value-of
59                          select="$keep.together"/></xsl:attribute>
60        </xsl:if>
61        <xsl:copy-of select="$content"/>
62      </fo:block>
63    </xsl:when>
64    <xsl:when test="self::example">
65      <fo:block id="{$id}"
66                xsl:use-attribute-sets="example.properties">
67        <xsl:if test="$keep.together != ''">
68          <xsl:attribute name="keep-together.within-column"><xsl:value-of
69                          select="$keep.together"/></xsl:attribute>
70        </xsl:if>
71        <xsl:copy-of select="$content"/>
72      </fo:block>
73    </xsl:when>
74    <xsl:when test="self::equation">
75      <fo:block id="{$id}"
76                xsl:use-attribute-sets="equation.properties">
77        <xsl:if test="$keep.together != ''">
78          <xsl:attribute name="keep-together.within-column"><xsl:value-of
79                          select="$keep.together"/></xsl:attribute>
80        </xsl:if>
81        <xsl:copy-of select="$content"/>
82      </fo:block>
83    </xsl:when>
84    <xsl:when test="self::procedure">
85      <fo:block id="{$id}"
86                xsl:use-attribute-sets="procedure.properties">
87        <xsl:if test="$keep.together != ''">
88          <xsl:attribute name="keep-together.within-column"><xsl:value-of
89                          select="$keep.together"/></xsl:attribute>
90        </xsl:if>
91        <xsl:copy-of select="$content"/>
92      </fo:block>
93    </xsl:when>
94    <xsl:otherwise>
95      <fo:block id="{$id}"
96                xsl:use-attribute-sets="formal.object.properties">
97        <xsl:if test="$keep.together != ''">
98          <xsl:attribute name="keep-together.within-column"><xsl:value-of
99                          select="$keep.together"/></xsl:attribute>
100        </xsl:if>
101        <xsl:copy-of select="$content"/>
102      </fo:block>
103    </xsl:otherwise>
104  </xsl:choose>
105</xsl:template>
106
107<xsl:template name="formal.object.heading">
108  <xsl:param name="object" select="."/>
109  <xsl:param name="placement" select="'before'"/>
110
111  <fo:block xsl:use-attribute-sets="formal.title.properties">
112    <xsl:choose>
113      <xsl:when test="$placement = 'before'">
114        <xsl:attribute
115               name="keep-with-next.within-column">always</xsl:attribute>
116      </xsl:when>
117      <xsl:otherwise>
118        <xsl:attribute
119               name="keep-with-previous.within-column">always</xsl:attribute>
120      </xsl:otherwise>
121    </xsl:choose>
122    <xsl:apply-templates select="$object" mode="object.title.markup">
123      <xsl:with-param name="allow-anchors" select="1"/>
124    </xsl:apply-templates>
125  </fo:block>
126</xsl:template>
127
128<xsl:template name="informal.object">
129  <xsl:variable name="id">
130    <xsl:call-template name="object.id"/>
131  </xsl:variable>
132
133  <xsl:variable name="keep.together">
134    <xsl:call-template name="dbfo-attribute">
135      <xsl:with-param name="pis"
136                      select="processing-instruction('dbfo')"/>
137      <xsl:with-param name="attribute" select="'keep-together'"/>
138    </xsl:call-template>
139  </xsl:variable>
140
141  <xsl:choose>
142    <!-- informaltables have their own templates and 
143         are not handled by formal.object -->
144    <xsl:when test="local-name(.) = 'equation'">
145      <fo:block id="{$id}"
146                xsl:use-attribute-sets="equation.properties">
147        <xsl:if test="$keep.together != ''">
148          <xsl:attribute name="keep-together.within-column"><xsl:value-of
149                          select="$keep.together"/></xsl:attribute>
150        </xsl:if>
151        <xsl:apply-templates/>
152      </fo:block>
153    </xsl:when>
154    <xsl:when test="local-name(.) = 'procedure'">
155      <fo:block id="{$id}"
156                xsl:use-attribute-sets="procedure.properties">
157        <xsl:if test="$keep.together != ''">
158          <xsl:attribute name="keep-together.within-column"><xsl:value-of
159                          select="$keep.together"/></xsl:attribute>
160        </xsl:if>
161        <xsl:apply-templates/>
162      </fo:block>
163    </xsl:when>
164    <xsl:when test="local-name(.) = 'informalfigure'">
165      <fo:block id="{$id}"
166                xsl:use-attribute-sets="informalfigure.properties">
167        <xsl:if test="$keep.together != ''">
168          <xsl:attribute name="keep-together.within-column"><xsl:value-of
169                          select="$keep.together"/></xsl:attribute>
170        </xsl:if>
171        <xsl:apply-templates/>
172      </fo:block>
173    </xsl:when>
174    <xsl:when test="local-name(.) = 'informalexample'">
175      <fo:block id="{$id}"
176                xsl:use-attribute-sets="informalexample.properties">
177        <xsl:if test="$keep.together != ''">
178          <xsl:attribute name="keep-together.within-column"><xsl:value-of
179                          select="$keep.together"/></xsl:attribute>
180        </xsl:if>
181        <xsl:apply-templates/>
182      </fo:block>
183    </xsl:when>
184    <xsl:when test="local-name(.) = 'informalequation'">
185      <fo:block id="{$id}"
186                xsl:use-attribute-sets="informalequation.properties">
187        <xsl:apply-templates/>
188      </fo:block>
189    </xsl:when>
190    <xsl:otherwise>
191      <fo:block id="{$id}" 
192                xsl:use-attribute-sets="informal.object.properties">
193        <xsl:if test="$keep.together != ''">
194          <xsl:attribute name="keep-together.within-column"><xsl:value-of
195                          select="$keep.together"/></xsl:attribute>
196        </xsl:if>
197        <xsl:apply-templates/>
198      </fo:block>
199    </xsl:otherwise>
200  </xsl:choose>
201</xsl:template>
202
203<xsl:template name="semiformal.object">
204  <xsl:param name="placement" select="'before'"/>
205  <xsl:choose>
206    <xsl:when test="./title">
207      <xsl:call-template name="formal.object">
208        <xsl:with-param name="placement" select="$placement"/>
209      </xsl:call-template>
210    </xsl:when>
211    <xsl:otherwise>
212      <xsl:call-template name="informal.object"/>
213    </xsl:otherwise>
214  </xsl:choose>
215</xsl:template>
216
217<xsl:template match="figure">
218  <xsl:variable name="param.placement"
219              select="substring-after(normalize-space($formal.title.placement),
220                                      concat(local-name(.), ' '))"/>
221
222  <xsl:variable name="placement">
223    <xsl:choose>
224      <xsl:when test="contains($param.placement, ' ')">
225        <xsl:value-of select="substring-before($param.placement, ' ')"/>
226      </xsl:when>
227      <xsl:when test="$param.placement = ''">before</xsl:when>
228      <xsl:otherwise>
229        <xsl:value-of select="$param.placement"/>
230      </xsl:otherwise>
231    </xsl:choose>
232  </xsl:variable>
233
234  <xsl:variable name="figure">
235    <xsl:choose>
236      <xsl:when test="@pgwide = '1'">
237        <fo:block xsl:use-attribute-sets="pgwide.properties">
238          <xsl:call-template name="formal.object">
239            <xsl:with-param name="placement" select="$placement"/>
240          </xsl:call-template>
241        </fo:block>
242      </xsl:when>
243      <xsl:otherwise>
244        <xsl:call-template name="formal.object">
245          <xsl:with-param name="placement" select="$placement"/>
246        </xsl:call-template>
247      </xsl:otherwise>
248    </xsl:choose>
249  </xsl:variable>
250
251  <xsl:variable name="floatstyle">
252    <xsl:call-template name="floatstyle"/>
253  </xsl:variable>
254
255  <xsl:choose>
256    <xsl:when test="$floatstyle != ''">
257      <xsl:call-template name="floater">
258        <xsl:with-param name="position" select="$floatstyle"/>
259        <xsl:with-param name="content" select="$figure"/>
260      </xsl:call-template>
261    </xsl:when>
262    <xsl:otherwise>
263      <xsl:copy-of select="$figure"/>
264    </xsl:otherwise>
265  </xsl:choose>
266</xsl:template>
267
268<xsl:template match="example">
269  <xsl:variable name="param.placement"
270             select="substring-after(normalize-space($formal.title.placement),
271                                     concat(local-name(.), ' '))"/>
272
273  <xsl:variable name="placement">
274    <xsl:choose>
275      <xsl:when test="contains($param.placement, ' ')">
276        <xsl:value-of select="substring-before($param.placement, ' ')"/>
277      </xsl:when>
278      <xsl:when test="$param.placement = ''">before</xsl:when>
279      <xsl:otherwise>
280        <xsl:value-of select="$param.placement"/>
281      </xsl:otherwise>
282    </xsl:choose>
283  </xsl:variable>
284
285  <!-- Example doesn't have a pgwide attribute, so may use a PI -->
286  <xsl:variable name="pgwide.pi">
287    <xsl:call-template name="dbfo-attribute">
288      <xsl:with-param name="pis"
289                      select="processing-instruction('dbfo')"/>
290      <xsl:with-param name="attribute" select="'pgwide'"/>
291    </xsl:call-template>
292  </xsl:variable>
293
294  <xsl:variable name="pgwide">
295    <xsl:choose>
296      <xsl:when test="$pgwide.pi">
297        <xsl:value-of select="$pgwide.pi"/>
298      </xsl:when>
299      <!-- child element may set pgwide -->
300      <xsl:when test="*[@pgwide]">
301        <xsl:value-of select="*[@pgwide][1]/@pgwide"/>
302      </xsl:when>
303    </xsl:choose>
304  </xsl:variable>
305
306  <!-- Get align value from internal mediaobject -->
307  <xsl:variable name="align">
308    <xsl:if test="mediaobject|mediaobjectco">
309      <xsl:variable name="olist" select="mediaobject/imageobject
310                     |mediaobjectco/imageobjectco
311                     |mediaobject/videoobject
312                     |mediaobject/audioobject
313                     |mediaobject/textobject"/>
314
315      <xsl:variable name="object.index">
316        <xsl:call-template name="select.mediaobject.index">
317          <xsl:with-param name="olist" select="$olist"/>
318          <xsl:with-param name="count" select="1"/>
319        </xsl:call-template>
320      </xsl:variable>
321
322      <xsl:variable name="object" select="$olist[position() = $object.index]"/>
323
324      <xsl:value-of select="$object/descendant::imagedata[@align][1]/@align"/>
325    </xsl:if>
326  </xsl:variable>
327
328  <xsl:variable name="example">
329    <xsl:choose>
330      <xsl:when test="$pgwide = '1'">
331        <fo:block xsl:use-attribute-sets="pgwide.properties">
332          <xsl:if test="$align != ''">
333            <xsl:attribute name="text-align">
334              <xsl:value-of select="$align"/>
335            </xsl:attribute>
336          </xsl:if>
337          <xsl:call-template name="formal.object">
338            <xsl:with-param name="placement" select="$placement"/>
339          </xsl:call-template>
340        </fo:block>
341      </xsl:when>
342      <xsl:otherwise>
343        <fo:block>
344          <xsl:if test="$align != ''">
345            <xsl:attribute name="text-align">
346              <xsl:value-of select="$align"/>
347            </xsl:attribute>
348          </xsl:if>
349          <xsl:call-template name="formal.object">
350            <xsl:with-param name="placement" select="$placement"/>
351          </xsl:call-template>
352        </fo:block>
353      </xsl:otherwise>
354    </xsl:choose>
355  </xsl:variable>
356
357  <xsl:variable name="floatstyle">
358    <xsl:call-template name="floatstyle"/>
359  </xsl:variable>
360
361  <xsl:choose>
362    <xsl:when test="$floatstyle != ''">
363      <xsl:call-template name="floater">
364        <xsl:with-param name="position" select="$floatstyle"/>
365        <xsl:with-param name="content" select="$example"/>
366      </xsl:call-template>
367    </xsl:when>
368    <xsl:otherwise>
369      <xsl:copy-of select="$example"/>
370    </xsl:otherwise>
371  </xsl:choose>
372
373</xsl:template>
374
375<!-- Unified handling of CALS and HTML tables, formal and not -->
376<!-- Creates a hierarchy of nested containers:
377     - Outer container does a float.
378     - Nested container does block-container for rotation
379     - Nested block contains title, layout table and footnotes
380     - Nested layout table placeholder template supports extensions.
381     - fo:table is innermost.
382     Created from the innermost and working out.
383     Not all layers apply to every table.
384-->
385<xsl:template match="table|informaltable">
386  <xsl:if test="tgroup/tbody/tr
387                |tgroup/thead/tr
388                |tgroup/tfoot/tr">
389    <xsl:message terminate="yes">
390      <xsl:text>Broken table: tr descendent of CALS Table.</xsl:text>
391      <xsl:text>The text in the first tr is:&#10;</xsl:text>
392      <xsl:value-of 
393               select="(tgroup//tr)[1]"/>
394    </xsl:message>
395  </xsl:if>
396  <xsl:if test="not(tgroup) and .//row">
397    <xsl:message terminate="yes">
398      <xsl:text>Broken table: row descendent of HTML table.</xsl:text>
399      <xsl:text>The text in the first row is:&#10;</xsl:text>
400      <xsl:value-of 
401               select=".//row[1]"/>
402    </xsl:message>
403  </xsl:if>
404
405  <!-- Contains fo:table, not title or footnotes -->
406  <xsl:variable name="table.content">
407    <xsl:call-template name="make.table.content"/>
408  </xsl:variable>
409
410  <!-- Optional layout table template for extensions -->
411  <xsl:variable name="table.layout">
412    <xsl:call-template name="table.layout">
413      <xsl:with-param name="table.content" select="$table.content"/>
414    </xsl:call-template>
415  </xsl:variable>
416
417  <!-- fo:block contains title, layout table, and footnotes  -->
418  <xsl:variable name="table.block">
419    <xsl:call-template name="table.block">
420      <xsl:with-param name="table.layout" select="$table.layout"/>
421    </xsl:call-template>
422  </xsl:variable>
423
424  <!-- pgwide or orient container -->
425  <xsl:variable name="table.container">
426    <xsl:call-template name="table.container">
427      <xsl:with-param name="table.block" select="$table.block"/>
428    </xsl:call-template>
429  </xsl:variable>
430
431  <!-- float or not -->
432  <xsl:variable name="floatstyle">
433    <xsl:call-template name="floatstyle"/>
434  </xsl:variable>
435
436  <xsl:choose>
437    <xsl:when test="$floatstyle != ''">
438      <xsl:call-template name="floater">
439        <xsl:with-param name="position" select="$floatstyle"/>
440        <xsl:with-param name="content" select="$table.container"/>
441      </xsl:call-template>
442    </xsl:when>
443    <xsl:otherwise>
444      <xsl:copy-of select="$table.container"/>
445    </xsl:otherwise>
446  </xsl:choose>
447</xsl:template>
448
449
450<xsl:template match="equation">
451  <xsl:variable name="param.placement"
452              select="substring-after(normalize-space($formal.title.placement),
453                                      concat(local-name(.), ' '))"/>
454
455  <xsl:variable name="placement">
456    <xsl:choose>
457      <xsl:when test="contains($param.placement, ' ')">
458        <xsl:value-of select="substring-before($param.placement, ' ')"/>
459      </xsl:when>
460      <xsl:when test="$param.placement = ''">before</xsl:when>
461      <xsl:otherwise>
462        <xsl:value-of select="$param.placement"/>
463      </xsl:otherwise>
464    </xsl:choose>
465  </xsl:variable>
466
467  <!-- Equation doesn't have a pgwide attribute, so may use a PI -->
468  <xsl:variable name="pgwide">
469    <xsl:call-template name="dbfo-attribute">
470      <xsl:with-param name="pis"
471                      select="processing-instruction('dbfo')"/>
472      <xsl:with-param name="attribute" select="'pgwide'"/>
473    </xsl:call-template>
474  </xsl:variable>
475
476  <xsl:variable name="equation">
477    <xsl:choose>
478      <xsl:when test="$pgwide = '1'">
479        <fo:block xsl:use-attribute-sets="pgwide.properties">
480          <xsl:call-template name="semiformal.object">
481            <xsl:with-param name="placement" select="$placement"/>
482          </xsl:call-template>
483        </fo:block>
484      </xsl:when>
485      <xsl:otherwise>
486        <xsl:call-template name="semiformal.object">
487          <xsl:with-param name="placement" select="$placement"/>
488        </xsl:call-template>
489      </xsl:otherwise>
490    </xsl:choose>
491  </xsl:variable>
492
493  <xsl:variable name="floatstyle">
494    <xsl:call-template name="floatstyle"/>
495  </xsl:variable>
496
497  <xsl:choose>
498    <xsl:when test="$floatstyle != ''">
499      <xsl:call-template name="floater">
500        <xsl:with-param name="position" select="$floatstyle"/>
501        <xsl:with-param name="content" select="$equation"/>
502      </xsl:call-template>
503    </xsl:when>
504    <xsl:otherwise>
505      <xsl:copy-of select="$equation"/>
506    </xsl:otherwise>
507  </xsl:choose>
508</xsl:template>
509
510<xsl:template match="figure/title"></xsl:template>
511<xsl:template match="figure/titleabbrev"></xsl:template>
512<xsl:template match="table/title"></xsl:template>
513<xsl:template match="table/titleabbrev"></xsl:template>
514<xsl:template match="table/textobject"></xsl:template>
515<xsl:template match="example/title"></xsl:template>
516<xsl:template match="example/titleabbrev"></xsl:template>
517<xsl:template match="equation/title"></xsl:template>
518<xsl:template match="equation/titleabbrev"></xsl:template>
519
520<xsl:template match="informalfigure">
521  <xsl:call-template name="informal.object"/>
522</xsl:template>
523
524<xsl:template match="informalexample">
525  <xsl:call-template name="informal.object"/>
526</xsl:template>
527
528<xsl:template match="informaltable/textobject"></xsl:template>
529
530<xsl:template match="informalequation">
531  <xsl:call-template name="informal.object"/>
532</xsl:template>
533
534<xsl:template name="floatstyle">
535  <xsl:if test="(@float and @float != '0') or @floatstyle != ''">
536    <xsl:choose>
537      <xsl:when test="@floatstyle != ''">
538        <xsl:value-of select="@floatstyle"/>
539      </xsl:when>
540      <xsl:when test="@float = '1'">
541        <xsl:value-of select="$default.float.class"/>
542      </xsl:when>
543      <xsl:otherwise>
544        <xsl:value-of select="@float"/>
545      </xsl:otherwise>
546    </xsl:choose>
547  </xsl:if>
548</xsl:template>
549
550</xsl:stylesheet>
551