]> git.stg.codes - stg.git/blob - doc/xslt/fo/formal.xsl
Help book chapter 3 complete
[stg.git] / doc / xslt / fo / formal.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: formal.xsl 8544 2009-12-02 06:06:53Z 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 <!-- 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="pi.dbfo_keep-together"/>
45   </xsl:variable>
46
47   <xsl:choose>
48     <!-- tables have their own templates and 
49          are not handled by formal.object -->
50     <xsl:when test="self::figure">
51       <fo:block id="{$id}"
52                 xsl:use-attribute-sets="figure.properties">
53         <xsl:if test="$keep.together != ''">
54           <xsl:attribute name="keep-together.within-column"><xsl:value-of
55                           select="$keep.together"/></xsl:attribute>
56         </xsl:if>
57         <xsl:copy-of select="$content"/>
58       </fo:block>
59     </xsl:when>
60     <xsl:when test="self::example">
61       <fo:block id="{$id}"
62                 xsl:use-attribute-sets="example.properties">
63         <xsl:if test="$keep.together != ''">
64           <xsl:attribute name="keep-together.within-column"><xsl:value-of
65                           select="$keep.together"/></xsl:attribute>
66         </xsl:if>
67         <xsl:copy-of select="$content"/>
68       </fo:block>
69     </xsl:when>
70     <xsl:when test="self::equation">
71       <fo:block id="{$id}"
72                 xsl:use-attribute-sets="equation.properties">
73         <xsl:if test="$keep.together != ''">
74           <xsl:attribute name="keep-together.within-column"><xsl:value-of
75                           select="$keep.together"/></xsl:attribute>
76         </xsl:if>
77         <xsl:copy-of select="$content"/>
78       </fo:block>
79     </xsl:when>
80     <xsl:when test="self::procedure">
81       <fo:block id="{$id}"
82                 xsl:use-attribute-sets="procedure.properties">
83         <xsl:if test="$keep.together != ''">
84           <xsl:attribute name="keep-together.within-column"><xsl:value-of
85                           select="$keep.together"/></xsl:attribute>
86         </xsl:if>
87         <xsl:copy-of select="$content"/>
88       </fo:block>
89     </xsl:when>
90     <xsl:otherwise>
91       <fo:block id="{$id}"
92                 xsl:use-attribute-sets="formal.object.properties">
93         <xsl:if test="$keep.together != ''">
94           <xsl:attribute name="keep-together.within-column"><xsl:value-of
95                           select="$keep.together"/></xsl:attribute>
96         </xsl:if>
97         <xsl:copy-of select="$content"/>
98       </fo:block>
99     </xsl:otherwise>
100   </xsl:choose>
101 </xsl:template>
102
103 <xsl:template name="formal.object.heading">
104   <xsl:param name="object" select="."/>
105   <xsl:param name="placement" select="'before'"/>
106
107   <fo:block xsl:use-attribute-sets="formal.title.properties">
108     <xsl:choose>
109       <xsl:when test="$placement = 'before'">
110         <xsl:attribute
111                name="keep-with-next.within-column">always</xsl:attribute>
112       </xsl:when>
113       <xsl:otherwise>
114         <xsl:attribute
115                name="keep-with-previous.within-column">always</xsl:attribute>
116       </xsl:otherwise>
117     </xsl:choose>
118     <xsl:apply-templates select="$object" mode="object.title.markup">
119       <xsl:with-param name="allow-anchors" select="1"/>
120     </xsl:apply-templates>
121   </fo:block>
122 </xsl:template>
123
124 <xsl:template name="informal.object">
125   <xsl:variable name="id">
126     <xsl:call-template name="object.id"/>
127   </xsl:variable>
128
129   <xsl:variable name="keep.together">
130     <xsl:call-template name="pi.dbfo_keep-together"/>
131   </xsl:variable>
132
133   <!-- Some don't have a pgwide attribute, so may use a PI -->
134   <xsl:variable name="pgwide.pi">
135     <xsl:call-template name="pi.dbfo_pgwide"/>
136   </xsl:variable>
137
138   <xsl:variable name="pgwide">
139     <xsl:choose>
140       <xsl:when test="@pgwide">
141         <xsl:value-of select="@pgwide"/>
142       </xsl:when>
143       <xsl:when test="$pgwide.pi">
144         <xsl:value-of select="$pgwide.pi"/>
145       </xsl:when>
146       <!-- child element may set pgwide -->
147       <xsl:when test="*[@pgwide]">
148         <xsl:value-of select="*[@pgwide][1]/@pgwide"/>
149       </xsl:when>
150     </xsl:choose>
151   </xsl:variable>
152
153   <xsl:choose>
154     <!-- informaltables have their own templates and 
155          are not handled by formal.object -->
156     <xsl:when test="local-name(.) = 'equation'">
157       <xsl:choose>
158         <xsl:when test="$pgwide = '1'">
159           <fo:block id="{$id}"
160                     xsl:use-attribute-sets="pgwide.properties
161                                             equation.properties">
162             <xsl:if test="$keep.together != ''">
163               <xsl:attribute name="keep-together.within-column"><xsl:value-of
164                               select="$keep.together"/></xsl:attribute>
165             </xsl:if>
166             <xsl:call-template name="equation.without.title"/>
167           </fo:block>
168         </xsl:when>
169         <xsl:otherwise>
170           <fo:block id="{$id}"
171                     xsl:use-attribute-sets="equation.properties">
172             <xsl:if test="$keep.together != ''">
173               <xsl:attribute name="keep-together.within-column"><xsl:value-of
174                               select="$keep.together"/></xsl:attribute>
175             </xsl:if>
176             <xsl:call-template name="equation.without.title"/>
177           </fo:block>
178         </xsl:otherwise>
179       </xsl:choose>
180     </xsl:when>
181     <xsl:when test="local-name(.) = 'procedure'">
182       <fo:block id="{$id}"
183                 xsl:use-attribute-sets="procedure.properties">
184         <xsl:if test="$keep.together != ''">
185           <xsl:attribute name="keep-together.within-column"><xsl:value-of
186                           select="$keep.together"/></xsl:attribute>
187         </xsl:if>
188         <xsl:apply-templates/>
189       </fo:block>
190     </xsl:when>
191     <xsl:when test="local-name(.) = 'informalfigure'">
192       <xsl:choose>
193         <xsl:when test="$pgwide = '1'">
194           <fo:block id="{$id}"
195                     xsl:use-attribute-sets="pgwide.properties
196                                             informalfigure.properties">
197             <xsl:if test="$keep.together != ''">
198               <xsl:attribute name="keep-together.within-column"><xsl:value-of
199                               select="$keep.together"/></xsl:attribute>
200             </xsl:if>
201             <xsl:apply-templates/>
202           </fo:block>
203         </xsl:when>
204         <xsl:otherwise>
205           <fo:block id="{$id}"
206                     xsl:use-attribute-sets="informalfigure.properties">
207             <xsl:if test="$keep.together != ''">
208               <xsl:attribute name="keep-together.within-column"><xsl:value-of
209                               select="$keep.together"/></xsl:attribute>
210             </xsl:if>
211             <xsl:apply-templates/>
212           </fo:block>
213         </xsl:otherwise>
214       </xsl:choose>
215     </xsl:when>
216     <xsl:when test="local-name(.) = 'informalexample'">
217       <xsl:choose>
218         <xsl:when test="$pgwide = '1'">
219           <fo:block id="{$id}"
220                     xsl:use-attribute-sets="pgwide.properties
221                                             informalexample.properties">
222             <xsl:if test="$keep.together != ''">
223               <xsl:attribute name="keep-together.within-column"><xsl:value-of
224                               select="$keep.together"/></xsl:attribute>
225             </xsl:if>
226             <xsl:apply-templates/>
227           </fo:block>
228         </xsl:when>
229         <xsl:otherwise>
230           <fo:block id="{$id}"
231                     xsl:use-attribute-sets="informalexample.properties">
232             <xsl:if test="$keep.together != ''">
233               <xsl:attribute name="keep-together.within-column"><xsl:value-of
234                               select="$keep.together"/></xsl:attribute>
235             </xsl:if>
236             <xsl:apply-templates/>
237           </fo:block>
238         </xsl:otherwise>
239       </xsl:choose>
240     </xsl:when>
241     <xsl:when test="local-name(.) = 'informalequation'">
242       <xsl:choose>
243         <xsl:when test="$pgwide = '1'">
244           <fo:block id="{$id}"
245                     xsl:use-attribute-sets="pgwide.properties
246                                             informalequation.properties">
247             <xsl:if test="$keep.together != ''">
248               <xsl:attribute name="keep-together.within-column"><xsl:value-of
249                               select="$keep.together"/></xsl:attribute>
250             </xsl:if>
251             <xsl:apply-templates/>
252           </fo:block>
253         </xsl:when>
254         <xsl:otherwise>
255           <fo:block id="{$id}"
256                     xsl:use-attribute-sets="informalequation.properties">
257             <xsl:if test="$keep.together != ''">
258               <xsl:attribute name="keep-together.within-column"><xsl:value-of
259                               select="$keep.together"/></xsl:attribute>
260             </xsl:if>
261             <xsl:apply-templates/>
262           </fo:block>
263         </xsl:otherwise>
264       </xsl:choose>
265     </xsl:when>
266     <xsl:otherwise>
267       <fo:block id="{$id}" 
268                 xsl:use-attribute-sets="informal.object.properties">
269         <xsl:if test="$keep.together != ''">
270           <xsl:attribute name="keep-together.within-column"><xsl:value-of
271                           select="$keep.together"/></xsl:attribute>
272         </xsl:if>
273         <xsl:apply-templates/>
274       </fo:block>
275     </xsl:otherwise>
276   </xsl:choose>
277 </xsl:template>
278
279 <xsl:template name="equation.without.title">
280   <!-- Lay out equation and number next to equation using a table -->
281   <fo:table table-layout="fixed" width="100%">
282     <fo:table-column column-width="proportional-column-width(15)"/>
283     <fo:table-column column-width="proportional-column-width(1)"/>
284     <fo:table-body start-indent="0pt" end-indent="0pt">
285       <fo:table-row>
286         <fo:table-cell padding-end="6pt">
287           <fo:block>
288             <xsl:apply-templates/>
289           </fo:block>
290         </fo:table-cell>
291         <fo:table-cell xsl:use-attribute-sets="equation.number.properties">
292           <fo:block>
293             <xsl:text>(</xsl:text>
294             <xsl:apply-templates select="." mode="label.markup"/>
295             <xsl:text>)</xsl:text>
296           </fo:block>
297         </fo:table-cell>
298       </fo:table-row>
299     </fo:table-body>
300   </fo:table>
301 </xsl:template>
302
303 <xsl:template name="semiformal.object">
304   <xsl:param name="placement" select="'before'"/>
305   <xsl:choose>
306     <xsl:when test="title or info/title">
307       <xsl:call-template name="formal.object">
308         <xsl:with-param name="placement" select="$placement"/>
309       </xsl:call-template>
310     </xsl:when>
311     <xsl:otherwise>
312       <xsl:call-template name="informal.object"/>
313     </xsl:otherwise>
314   </xsl:choose>
315 </xsl:template>
316
317 <xsl:template match="figure">
318   <xsl:variable name="param.placement"
319               select="substring-after(normalize-space($formal.title.placement),
320                                       concat(local-name(.), ' '))"/>
321
322   <xsl:variable name="placement">
323     <xsl:choose>
324       <xsl:when test="contains($param.placement, ' ')">
325         <xsl:value-of select="substring-before($param.placement, ' ')"/>
326       </xsl:when>
327       <xsl:when test="$param.placement = ''">before</xsl:when>
328       <xsl:otherwise>
329         <xsl:value-of select="$param.placement"/>
330       </xsl:otherwise>
331     </xsl:choose>
332   </xsl:variable>
333
334   <xsl:variable name="figure">
335     <xsl:choose>
336       <xsl:when test="@pgwide = '1'">
337         <fo:block xsl:use-attribute-sets="pgwide.properties">
338           <xsl:call-template name="formal.object">
339             <xsl:with-param name="placement" select="$placement"/>
340           </xsl:call-template>
341         </fo:block>
342       </xsl:when>
343       <xsl:otherwise>
344         <xsl:call-template name="formal.object">
345           <xsl:with-param name="placement" select="$placement"/>
346         </xsl:call-template>
347       </xsl:otherwise>
348     </xsl:choose>
349   </xsl:variable>
350
351   <xsl:variable name="floatstyle">
352     <xsl:call-template name="floatstyle"/>
353   </xsl:variable>
354
355   <xsl:choose>
356     <xsl:when test="$floatstyle != ''">
357       <xsl:call-template name="floater">
358         <xsl:with-param name="position" select="$floatstyle"/>
359         <xsl:with-param name="content" select="$figure"/>
360       </xsl:call-template>
361     </xsl:when>
362     <xsl:otherwise>
363       <xsl:copy-of select="$figure"/>
364     </xsl:otherwise>
365   </xsl:choose>
366 </xsl:template>
367
368 <xsl:template match="example">
369   <xsl:variable name="param.placement"
370              select="substring-after(normalize-space($formal.title.placement),
371                                      concat(local-name(.), ' '))"/>
372
373   <xsl:variable name="placement">
374     <xsl:choose>
375       <xsl:when test="contains($param.placement, ' ')">
376         <xsl:value-of select="substring-before($param.placement, ' ')"/>
377       </xsl:when>
378       <xsl:when test="$param.placement = ''">before</xsl:when>
379       <xsl:otherwise>
380         <xsl:value-of select="$param.placement"/>
381       </xsl:otherwise>
382     </xsl:choose>
383   </xsl:variable>
384
385   <!-- Example doesn't have a pgwide attribute, so may use a PI -->
386   <xsl:variable name="pgwide.pi">
387     <xsl:call-template name="pi.dbfo_pgwide"/>
388   </xsl:variable>
389
390   <xsl:variable name="pgwide">
391     <xsl:choose>
392       <xsl:when test="$pgwide.pi">
393         <xsl:value-of select="$pgwide.pi"/>
394       </xsl:when>
395       <!-- child element may set pgwide -->
396       <xsl:when test="*[@pgwide]">
397         <xsl:value-of select="*[@pgwide][1]/@pgwide"/>
398       </xsl:when>
399     </xsl:choose>
400   </xsl:variable>
401
402   <!-- Get align value from internal mediaobject -->
403   <xsl:variable name="align">
404     <xsl:if test="mediaobject|mediaobjectco">
405       <xsl:variable name="olist" select="mediaobject/imageobject
406                      |mediaobjectco/imageobjectco
407                      |mediaobject/videoobject
408                      |mediaobject/audioobject
409                      |mediaobject/textobject"/>
410
411       <xsl:variable name="object.index">
412         <xsl:call-template name="select.mediaobject.index">
413           <xsl:with-param name="olist" select="$olist"/>
414           <xsl:with-param name="count" select="1"/>
415         </xsl:call-template>
416       </xsl:variable>
417
418       <xsl:variable name="object" select="$olist[position() = $object.index]"/>
419
420       <xsl:value-of select="$object/descendant::imagedata[@align][1]/@align"/>
421     </xsl:if>
422   </xsl:variable>
423
424   <xsl:variable name="example">
425     <xsl:choose>
426       <xsl:when test="$pgwide = '1'">
427         <fo:block xsl:use-attribute-sets="pgwide.properties">
428           <xsl:if test="$align != ''">
429             <xsl:attribute name="text-align">
430               <xsl:value-of select="$align"/>
431             </xsl:attribute>
432           </xsl:if>
433           <xsl:call-template name="formal.object">
434             <xsl:with-param name="placement" select="$placement"/>
435           </xsl:call-template>
436         </fo:block>
437       </xsl:when>
438       <xsl:otherwise>
439         <fo:block>
440           <xsl:if test="$align != ''">
441             <xsl:attribute name="text-align">
442               <xsl:value-of select="$align"/>
443             </xsl:attribute>
444           </xsl:if>
445           <xsl:call-template name="formal.object">
446             <xsl:with-param name="placement" select="$placement"/>
447           </xsl:call-template>
448         </fo:block>
449       </xsl:otherwise>
450     </xsl:choose>
451   </xsl:variable>
452
453   <xsl:variable name="floatstyle">
454     <xsl:call-template name="floatstyle"/>
455   </xsl:variable>
456
457   <xsl:choose>
458     <xsl:when test="$floatstyle != ''">
459       <xsl:call-template name="floater">
460         <xsl:with-param name="position" select="$floatstyle"/>
461         <xsl:with-param name="content" select="$example"/>
462       </xsl:call-template>
463     </xsl:when>
464     <xsl:otherwise>
465       <xsl:copy-of select="$example"/>
466     </xsl:otherwise>
467   </xsl:choose>
468
469 </xsl:template>
470
471 <!-- Unified handling of CALS and HTML tables, formal and not -->
472 <!-- Creates a hierarchy of nested containers:
473      - Outer container does a float.
474      - Nested container does block-container for rotation
475      - Nested block contains title, layout table and footnotes
476      - Nested layout table placeholder template supports extensions.
477      - fo:table is innermost.
478      Created from the innermost and working out.
479      Not all layers apply to every table.
480 -->
481 <xsl:template match="table|informaltable">
482   <xsl:if test="tgroup/tbody/tr
483                 |tgroup/thead/tr
484                 |tgroup/tfoot/tr">
485     <xsl:message terminate="yes">
486       <xsl:text>Broken table: tr descendent of CALS Table.</xsl:text>
487       <xsl:text>The text in the first tr is:&#10;</xsl:text>
488       <xsl:value-of 
489                select="(tgroup//tr)[1]"/>
490     </xsl:message>
491   </xsl:if>
492   <xsl:if test="not(tgroup) and .//row">
493     <xsl:message terminate="yes">
494       <xsl:text>Broken table: row descendent of HTML table.</xsl:text>
495       <xsl:text>The text in the first row is:&#10;</xsl:text>
496       <xsl:value-of 
497                select=".//row[1]"/>
498     </xsl:message>
499   </xsl:if>
500
501   <!-- Contains fo:table, not title or footnotes -->
502   <xsl:variable name="table.content">
503     <xsl:call-template name="make.table.content"/>
504   </xsl:variable>
505
506   <!-- Optional layout table template for extensions -->
507   <xsl:variable name="table.layout">
508     <xsl:call-template name="table.layout">
509       <xsl:with-param name="table.content" select="$table.content"/>
510     </xsl:call-template>
511   </xsl:variable>
512
513   <!-- fo:block contains title, layout table, and footnotes  -->
514   <xsl:variable name="table.block">
515     <xsl:call-template name="table.block">
516       <xsl:with-param name="table.layout" select="$table.layout"/>
517     </xsl:call-template>
518   </xsl:variable>
519
520   <!-- pgwide or orient container -->
521   <xsl:variable name="table.container">
522     <xsl:call-template name="table.container">
523       <xsl:with-param name="table.block" select="$table.block"/>
524     </xsl:call-template>
525   </xsl:variable>
526
527   <!-- float or not -->
528   <xsl:variable name="floatstyle">
529     <xsl:call-template name="floatstyle"/>
530   </xsl:variable>
531
532   <xsl:choose>
533     <xsl:when test="$floatstyle != ''">
534       <xsl:call-template name="floater">
535         <xsl:with-param name="position" select="$floatstyle"/>
536         <xsl:with-param name="content" select="$table.container"/>
537       </xsl:call-template>
538     </xsl:when>
539     <xsl:otherwise>
540       <xsl:copy-of select="$table.container"/>
541     </xsl:otherwise>
542   </xsl:choose>
543 </xsl:template>
544
545
546 <xsl:template match="equation">
547   <xsl:variable name="param.placement"
548               select="substring-after(normalize-space($formal.title.placement),
549                                       concat(local-name(.), ' '))"/>
550
551   <xsl:variable name="placement">
552     <xsl:choose>
553       <xsl:when test="contains($param.placement, ' ')">
554         <xsl:value-of select="substring-before($param.placement, ' ')"/>
555       </xsl:when>
556       <xsl:when test="$param.placement = ''">before</xsl:when>
557       <xsl:otherwise>
558         <xsl:value-of select="$param.placement"/>
559       </xsl:otherwise>
560     </xsl:choose>
561   </xsl:variable>
562
563   <!-- Equation doesn't have a pgwide attribute, so may use a PI -->
564   <xsl:variable name="pgwide">
565     <xsl:call-template name="pi.dbfo_pgwide"/>
566   </xsl:variable>
567
568   <xsl:variable name="equation">
569     <xsl:choose>
570       <xsl:when test="$pgwide = '1'">
571         <fo:block xsl:use-attribute-sets="pgwide.properties">
572           <xsl:call-template name="semiformal.object">
573             <xsl:with-param name="placement" select="$placement"/>
574           </xsl:call-template>
575         </fo:block>
576       </xsl:when>
577       <xsl:otherwise>
578         <xsl:call-template name="semiformal.object">
579           <xsl:with-param name="placement" select="$placement"/>
580         </xsl:call-template>
581       </xsl:otherwise>
582     </xsl:choose>
583   </xsl:variable>
584
585   <xsl:variable name="floatstyle">
586     <xsl:call-template name="floatstyle"/>
587   </xsl:variable>
588
589   <xsl:choose>
590     <xsl:when test="$floatstyle != ''">
591       <xsl:call-template name="floater">
592         <xsl:with-param name="position" select="$floatstyle"/>
593         <xsl:with-param name="content" select="$equation"/>
594       </xsl:call-template>
595     </xsl:when>
596     <xsl:otherwise>
597       <xsl:copy-of select="$equation"/>
598     </xsl:otherwise>
599   </xsl:choose>
600 </xsl:template>
601
602 <xsl:template match="figure/title"></xsl:template>
603 <xsl:template match="figure/titleabbrev"></xsl:template>
604 <xsl:template match="table/title"></xsl:template>
605 <xsl:template match="table/titleabbrev"></xsl:template>
606 <xsl:template match="table/textobject"></xsl:template>
607 <xsl:template match="example/title"></xsl:template>
608 <xsl:template match="example/titleabbrev"></xsl:template>
609 <xsl:template match="equation/title"></xsl:template>
610 <xsl:template match="equation/titleabbrev"></xsl:template>
611
612 <xsl:template match="informalfigure">
613   <xsl:call-template name="informal.object"/>
614 </xsl:template>
615
616 <xsl:template match="informalexample">
617   <xsl:call-template name="informal.object"/>
618 </xsl:template>
619
620 <xsl:template match="informaltable/textobject"></xsl:template>
621
622 <xsl:template match="informalequation">
623   <xsl:call-template name="informal.object"/>
624 </xsl:template>
625
626 <xsl:template name="floatstyle">
627   <xsl:if test="(@float and @float != '0') or @floatstyle != ''">
628     <xsl:choose>
629       <xsl:when test="@floatstyle != ''">
630         <xsl:value-of select="@floatstyle"/>
631       </xsl:when>
632       <xsl:when test="@float = '1'">
633         <xsl:value-of select="$default.float.class"/>
634       </xsl:when>
635       <xsl:otherwise>
636         <xsl:value-of select="@float"/>
637       </xsl:otherwise>
638     </xsl:choose>
639   </xsl:if>
640 </xsl:template>
641
642 </xsl:stylesheet>