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" version='1.0'>
5
6<!--############################################################################
7    XSLT Stylesheet DocBook -> LaTeX
8    ############################################################################ -->
9
10<!-- Lists parameters -->
11<xsl:param name="seg.item.separator">, </xsl:param>
12<xsl:param name="variablelist.term.separator">, </xsl:param>
13<xsl:param name="term.breakline">0</xsl:param>
14<xsl:param name="segmentedlist.as.table" select="0"/>
15
16
17<xsl:template match="variablelist/title|
18                     orderedlist/title | itemizedlist/title | simplelist/title">
19  <xsl:text>&#10;{\sc </xsl:text>
20  <xsl:apply-templates/>
21  <xsl:text>}&#10;</xsl:text>
22  <xsl:call-template name="label.id">
23    <xsl:with-param name="object" select=".."/>
24  </xsl:call-template>
25  <!-- Ask to latex to let the title with its list -->
26  <xsl:text>\nopagebreak&#10;</xsl:text>
27</xsl:template>
28
29<!-- In latex, the list nesting depth is limited. The depths are checked in
30     order to prevent from compilation crash. If the depth is correct
31     the templates that actually do the work are called.
32 -->
33<xsl:template match="itemizedlist|orderedlist|variablelist">
34  <xsl:variable name="ditem" select="count(ancestor-or-self::itemizedlist)"/>
35  <xsl:variable name="dorder" select="count(ancestor-or-self::orderedlist)"/>
36  <xsl:variable name="dvar" select="count(ancestor-or-self::variablelist)"/>
37  <xsl:choose>
38  <xsl:when test="$ditem &gt; 4">
39    <xsl:message>*** Error: itemizedlist too deeply nested (&gt; 4)</xsl:message>
40    <xsl:text>[Error: itemizedlist too deeply nested]</xsl:text>
41  </xsl:when>
42  <xsl:when test="$dorder &gt; 4">
43    <xsl:message>*** Error: orderedlist too deeply nested (&gt; 4)</xsl:message>
44    <xsl:text>[Error: orderedlist too deeply nested]</xsl:text>
45  </xsl:when>
46  <xsl:when test="($ditem+$dorder+$dvar) &gt; 6">
47    <xsl:message>*** Error: lists too deeply nested (&gt; 6)</xsl:message>
48    <xsl:text>[Error: lists too deeply nested]</xsl:text>
49  </xsl:when>
50  <xsl:otherwise>
51    <!-- Ok, can print the list -->
52    <xsl:apply-templates select="." mode="print"/>
53  </xsl:otherwise>
54  </xsl:choose>
55</xsl:template>
56
57<xsl:template match="itemizedlist" mode="print">
58  <xsl:apply-templates select="title"/>
59  <xsl:apply-templates select="*[not(self::title or
60                                     self::titleabbrev or
61                                     self::listitem)]"/>
62  <xsl:text>\begin{itemize}</xsl:text>
63  <!-- Process the option -->
64  <xsl:call-template name="opt.group">
65    <xsl:with-param name="opts" select="@spacing"/>
66    <xsl:with-param name="mode" select="'enumitem'"/>
67  </xsl:call-template>
68  <xsl:text>&#10;</xsl:text>
69  <xsl:apply-templates select="listitem"/>
70  <xsl:text>\end{itemize}&#10;</xsl:text>
71</xsl:template>
72
73<xsl:template match="orderedlist" mode="print">
74  <xsl:apply-templates select="title"/>
75  <xsl:apply-templates select="*[not(self::title or
76                                     self::titleabbrev or
77                                     self::listitem)]"/>
78  <xsl:text>\begin{enumerate}</xsl:text>
79  <!-- Process the options -->
80  <xsl:call-template name="opt.group">
81    <xsl:with-param name="opts" select="@numeration|@continuation|@spacing"/>
82    <xsl:with-param name="mode" select="'enumitem'"/>
83  </xsl:call-template>
84  <xsl:text>&#10;</xsl:text>
85  <xsl:apply-templates select="listitem"/>
86  <xsl:text>\end{enumerate}&#10;</xsl:text>
87</xsl:template>
88
89<xsl:template match="variablelist" mode="print">
90  <xsl:apply-templates select="title"/>
91  <xsl:apply-templates select="*[not(self::title or
92                                     self::titleabbrev or
93                                     self::varlistentry)]"/>
94  <xsl:text>&#10;\noindent&#10;</xsl:text>
95  <xsl:text>\begin{description}&#10;</xsl:text>
96  <xsl:apply-templates select="varlistentry"/>
97  <xsl:text>\end{description}&#10;</xsl:text>
98</xsl:template>
99
100<xsl:template match="listitem">
101  <!-- Add {} to avoid some mess with following square brackets [...] -->
102  <xsl:text>&#10;\item{}</xsl:text>
103  <xsl:call-template name="label.id"/>
104  <xsl:apply-templates/>
105  <xsl:text>&#10;</xsl:text>
106</xsl:template>
107
108<xsl:template match="varlistentry">
109  <xsl:text>\item[{</xsl:text>
110  <xsl:apply-templates select="term"/>
111  <xsl:text>}] </xsl:text>
112  <xsl:call-template name="label.id">
113    <xsl:with-param name="object" select="."/>
114  </xsl:call-template>
115  <xsl:call-template name="label.id">
116    <xsl:with-param name="object" select="term"/>
117  </xsl:call-template>
118  <xsl:apply-templates select="term" mode="foottext"/>
119  <xsl:apply-templates select="listitem"/>
120</xsl:template>
121
122<xsl:template match="varlistentry/term">
123  <xsl:apply-templates/>
124  <xsl:if test="position()!=last()">
125    <xsl:value-of select="$variablelist.term.separator"/>
126  </xsl:if>
127</xsl:template>
128
129<xsl:template match="varlistentry/listitem">
130  <xsl:choose>
131  <!-- add a space to force linebreaks for immediate following lists -->
132  <xsl:when test="child::*[1][self::itemizedlist or
133                              self::orderedlist or
134                              self::variablelist][not(child::title)]">
135    <xsl:text>~</xsl:text>
136  </xsl:when>
137  <!-- add a space to force linebreaks for immediate following listings -->
138  <xsl:when test="child::*[1][self::programlisting][not(child::title)]">
139    <xsl:text>~</xsl:text>
140  </xsl:when>
141  <!-- add a space to avoid the term be centered -->
142  <xsl:when test="child::*[not(self::indexterm)][1][self::figure]">
143    <xsl:text>~ </xsl:text>
144  </xsl:when>
145  <!-- force linebreak after the term. The space is to avoid side effect
146       with immediate following brackets [...]-->
147  <xsl:when test="$term.breakline='1'">
148    <xsl:text>\hspace{0em}\\~&#10;</xsl:text>
149  </xsl:when>
150  </xsl:choose>
151  <xsl:apply-templates/>
152</xsl:template>
153
154
155<!-- ################
156     # List Options #
157     ################ -->
158
159<!-- Process a group of options (reusable) -->
160<xsl:template name="opt.group">
161  <xsl:param name="opts"/>
162  <xsl:param name="mode" select="'opt'"/>
163  <xsl:param name="left" select="'['"/>
164  <xsl:param name="right" select="']'"/>
165
166  <xsl:variable name="result">
167    <xsl:for-each select="$opts">
168      <xsl:variable name="str">
169        <xsl:apply-templates select="." mode="enumitem"/>
170      </xsl:variable>
171      <!-- Put a separator only if something really printed -->
172      <xsl:if test="$str!='' and position()!=1">
173        <xsl:text>,</xsl:text>
174      </xsl:if>
175      <xsl:value-of select="$str"/>
176    </xsl:for-each>
177  </xsl:variable>
178
179  <xsl:if test="$result != ''">
180    <xsl:value-of select="$left"/>
181    <!-- Remove spurious first comma -->
182    <xsl:choose>
183      <xsl:when test="starts-with($result, ',')">
184        <xsl:value-of select="substring-after($result, ',')"/>
185      </xsl:when>
186      <xsl:otherwise>
187        <xsl:value-of select="$result"/>
188      </xsl:otherwise>
189    </xsl:choose>
190    <xsl:value-of select="$right"/>
191  </xsl:if>
192</xsl:template>
193
194<xsl:template match="@numeration" mode="enumitem">
195  <xsl:text>label=</xsl:text>
196  <xsl:choose>
197    <xsl:when test=".='arabic'">\arabic*.</xsl:when>
198    <xsl:when test=".='upperalpha'">\Alph*.</xsl:when>
199    <xsl:when test=".='loweralpha'">\alph*.</xsl:when>
200    <xsl:when test=".='upperroman'">\Roman*.</xsl:when>
201    <xsl:when test=".='lowerroman'">\roman*.</xsl:when>
202    <xsl:otherwise>\arabic*.</xsl:otherwise>
203  </xsl:choose>
204</xsl:template>
205
206<xsl:template match="@continuation" mode="enumitem">
207  <xsl:if test=". = 'continues'">
208    <xsl:text>resume</xsl:text>
209  </xsl:if>
210</xsl:template>
211
212<xsl:template match="@spacing" mode="enumitem">
213  <xsl:if test=". = 'compact'">
214    <xsl:text>itemsep=0pt</xsl:text>
215  </xsl:if>
216</xsl:template>
217
218
219<!-- ##############
220     # Simplelist #
221     ############## -->
222
223<xsl:template name="tabular.string">
224  <xsl:param name="cols" select="1"/>
225  <xsl:param name="i" select="1"/>
226  <xsl:if test="$i &lt;= $cols">
227    <xsl:text>l</xsl:text>
228    <xsl:call-template name="tabular.string">
229      <xsl:with-param name="i" select="$i+1"/>
230      <xsl:with-param name="cols" select="$cols"/>
231    </xsl:call-template>
232  </xsl:if>
233</xsl:template>
234
235<xsl:template match="member">
236  <!-- Put in a group to protect each member from side effects (esp. \\) -->
237  <xsl:text>{</xsl:text>
238  <xsl:apply-templates/>
239  <xsl:text>}</xsl:text>
240</xsl:template>
241
242
243<!-- Inline simplelist is a comma separated list of items -->
244
245<xsl:template match="simplelist[@type='inline']">
246  <xsl:apply-templates/>
247</xsl:template>
248
249<xsl:template match="simplelist[@type='inline']/member">
250  <xsl:apply-templates/>
251  <xsl:if test="position()!=last()">
252    <xsl:text>, </xsl:text>
253  </xsl:if>
254</xsl:template>
255
256
257<!-- Horizontal simplelist, is actually a tabular -->
258
259<xsl:template match="simplelist[@type='horiz']">
260  <xsl:variable name="cols">
261    <xsl:choose>
262      <xsl:when test="@columns">
263        <xsl:value-of select="@columns"/>
264      </xsl:when>
265      <xsl:otherwise>1</xsl:otherwise>
266    </xsl:choose>
267  </xsl:variable>
268  <xsl:text>&#10;\begin{tabular*}{\linewidth}{</xsl:text>
269  <xsl:call-template name="tabular.string">
270    <xsl:with-param name="cols" select="$cols"/>
271  </xsl:call-template>
272  <xsl:text>}&#10;</xsl:text>
273  <xsl:for-each select="member">
274    <xsl:apply-templates select="."/>
275    <xsl:choose>
276    <xsl:when test="position()=last()">
277      <xsl:text> \\&#10;</xsl:text>
278    </xsl:when>
279    <xsl:when test="position() mod $cols">
280      <xsl:text> &amp; </xsl:text>
281    </xsl:when>
282    <xsl:otherwise>
283      <xsl:text> \\&#10;</xsl:text>
284    </xsl:otherwise>
285    </xsl:choose>
286  </xsl:for-each>
287  <xsl:text>&#10;\end{tabular*}&#10;</xsl:text>
288</xsl:template>
289
290<!-- Vertical simplelist, a tabular too -->
291
292<xsl:template match="simplelist|simplelist[@type='vert']">
293  <xsl:variable name="cols">
294    <xsl:choose>
295      <xsl:when test="@columns">
296        <xsl:value-of select="@columns"/>
297      </xsl:when>
298      <xsl:otherwise>1</xsl:otherwise>
299    </xsl:choose>
300  </xsl:variable>
301  <xsl:text>&#10;\begin{tabular*}{\linewidth}{</xsl:text>
302  <xsl:call-template name="tabular.string">
303    <xsl:with-param name="cols" select="$cols"/>
304  </xsl:call-template>
305  <xsl:text>}&#10;</xsl:text>
306
307  <!-- recusively display each row -->
308  <xsl:call-template name="simplelist.vert.row">
309    <xsl:with-param name="rows" select="floor((count(member)+$cols - 1) div $cols)"/>
310  </xsl:call-template>
311  <xsl:text>&#10;\end{tabular*}&#10;</xsl:text>
312</xsl:template>
313
314<xsl:template name="simplelist.vert.row">
315  <xsl:param name="cell">0</xsl:param>
316  <xsl:param name="rows"/>
317  <xsl:if test="$cell &lt; $rows">
318    <xsl:for-each select="member[((position()-1) mod $rows) = $cell]">
319      <xsl:apply-templates select="."/>
320      <xsl:if test="position()!=last()">
321        <xsl:text> &amp; </xsl:text>
322      </xsl:if>
323    </xsl:for-each>
324    <xsl:text> \\&#10;</xsl:text>
325    <xsl:call-template name="simplelist.vert.row">
326      <xsl:with-param name="cell" select="$cell+1"/>
327      <xsl:with-param name="rows" select="$rows"/>
328    </xsl:call-template>
329  </xsl:if>
330</xsl:template>
331
332<!-- ==================================================================== -->
333<!-- Segmentedlist stuff -->
334
335<xsl:template match="segmentedlist">
336  <xsl:variable name="presentation">
337    <xsl:call-template name="pi.dblatex_list-presentation"/>
338  </xsl:variable>
339
340  <xsl:choose>
341    <xsl:when test="$presentation = 'table'">
342      <xsl:apply-templates select="." mode="seglist-table"/>
343    </xsl:when>
344    <xsl:when test="$presentation = 'list'">
345      <xsl:apply-templates select="." mode="seglist-inline"/>
346    </xsl:when>
347    <xsl:when test="$segmentedlist.as.table != 0">
348      <xsl:apply-templates select="." mode="seglist-table"/>
349    </xsl:when>
350    <xsl:otherwise>
351      <xsl:apply-templates select="." mode="seglist-inline"/>
352    </xsl:otherwise>
353  </xsl:choose>
354</xsl:template>
355
356
357<xsl:template match="segmentedlist" mode="seglist-inline">
358  <xsl:text>\noindent </xsl:text>
359  <xsl:apply-templates/>
360  <xsl:text>&#10;</xsl:text>
361</xsl:template>
362
363<xsl:template match="segmentedlist/title">
364  <xsl:text>{\bf </xsl:text>
365  <xsl:apply-templates/>
366  <xsl:text>}\\&#10;</xsl:text>
367</xsl:template>
368
369<xsl:template match="segtitle">
370</xsl:template>
371
372<xsl:template match="segtitle" mode="segtitle-in-seg">
373  <xsl:apply-templates/>
374</xsl:template>
375
376<xsl:template match="seglistitem">
377  <xsl:apply-templates/>
378  <xsl:if test="following-sibling::seglistitem">
379    <xsl:text> \\</xsl:text>
380  </xsl:if>
381  <xsl:text>&#10;</xsl:text>
382</xsl:template>
383
384<!-- We trust in the right count of segtitle declarations -->
385
386<xsl:template match="seg">
387  <xsl:variable name="segnum" select="count(preceding-sibling::seg)+1"/>
388  <xsl:variable name="seglist" select="ancestor::segmentedlist"/>
389  <xsl:variable name="segtitles" select="$seglist/segtitle"/>
390
391  <!--
392     Note: segtitle is only going to be the right thing in a well formed
393     SegmentedList.  If there are too many Segs or too few SegTitles,
394     you'll get something odd...maybe an error
395  -->
396
397  <xsl:text>\emph{</xsl:text>
398  <xsl:apply-templates select="$segtitles[$segnum=position()]"
399                       mode="segtitle-in-seg"/>
400  <xsl:text>:} </xsl:text>
401  <xsl:apply-templates/>
402  <xsl:if test="following-sibling::seg">
403    <xsl:value-of select="$seg.item.separator"/>
404  </xsl:if>
405</xsl:template>
406
407<!-- ==================================================================== -->
408<!-- Segmentedlist table presentation by Karl O. Pinc -->
409<!--
410      To make a LaTeX table we want to know:
411
412      A) How much overall columnar space there is so we can equally
413      apportion any leftover space using the proportional space
414      allocator, '*'.
415
416      B) Whether to autosize columns, letting LaTeX base the width on
417      content, and B.1) which ones to autosize.
418
419      Unfortunately these 2 types of information may be transmitted to
420      us via one value, either the default.table.width param or the
421      dblatex table-width PI.  We operate on the principal that the
422      dblatex table-width PI completely overrides the
423      default.table.width param, so we've really only one value to
424      work with at any one time.  Since we get a single value we
425      receive only one of A or B and must assume the other.
426
427      We may or may not receive additional information regards A or B
428      via the newtbl.autowidth param or the dblatex newtbl-autowidth
429      PI or the dblatex colwidth PI.
430
431      This is resolved as follows:
432       o When B is specified, assume page width for A.
433       o When A is specified, assume every column is equally apportioned.
434       o When nothing is specified, assume page width for A and
435         autosizing of every column.
436
437      Note that page width is not a universally good default for
438      table width.  Proportionally spaced columns will "appropriately"
439      fill the page, but adding any fixed width columns or
440      autowidth columns will result in a table that's wider than
441      a page.
442
443      To gain complete control the user must specify A, the overall
444      table width, using param or PI above.  Then specify the width of
445      each column, whether fixed, proportional, proportional + fixed,
446      or autosized, via other methods.
447
448      This works because the PIs and params that otherwise control
449      table layout have precedence over the table width controls.  The
450      dblatex colwidth PI only occurs within a lexically "inner"
451      portion of the document so it always has priority.
452      newtbl.autowidth (and the newtbl-autowidth PI) is defined to
453      have priority over table.width (and it's PI).
454      -->
455
456<!-- Table width specifier from PI or param? -->
457<xsl:template name="segtable.table-width">
458  <xsl:variable name="table-width">
459    <xsl:call-template name="pi.dblatex_table-width"/>
460  </xsl:variable>
461  <xsl:choose>
462    <xsl:when test="$table-width = ''">
463      <xsl:value-of select="$default.table.width"/>
464    </xsl:when>
465    <xsl:otherwise>
466      <xsl:value-of select="$table-width"/>
467    </xsl:otherwise>
468  </xsl:choose>
469</xsl:template>
470
471<!-- The user-specified list of autowidth columns.  -->
472<!-- (A "column:..." keyword denoting which columns are autowidth.) -->
473<xsl:template name="segtable.autocols">
474  <xsl:param name="autowidth-pi"/>  <!-- the latex newtbl-autowidth PI -->
475  <xsl:param name="table-width"/>   <!-- user specified table width    -->
476
477  <xsl:choose>
478    <xsl:when test="contains($autowidth-pi, 'column:')">
479      <xsl:value-of select="$autowidth-pi"/>
480    </xsl:when>
481    <xsl:when test="$autowidth-pi = ''
482                    and contains($table-width, 'column:')">
483      <xsl:value-of select="$table-width"/>
484    </xsl:when>
485  </xsl:choose>
486  <!-- End with a space so we can use contains() to test content.  -->
487  <xsl:text> </xsl:text>
488</xsl:template>
489
490<!-- Let LaTeX determine column width or space columns equally? -->
491<xsl:template name="segtable.autowidth">
492  <xsl:param name="autowidth.pi"/>  <!-- the latex newtbl-autowidth PI -->
493  <xsl:param name="table-width"/>   <!-- user specified table width    -->
494
495  <!-- Autowidth specifier from PI or param? -->
496  <xsl:variable name="autowidth">
497    <xsl:choose>
498      <xsl:when test="$autowidth.pi = ''">
499        <xsl:value-of select="$newtbl.autowidth"/>
500      </xsl:when>
501      <xsl:otherwise>
502        <xsl:value-of select="$autowidth.pi"/>
503      </xsl:otherwise>
504    </xsl:choose>
505  </xsl:variable>
506
507  <!-- Normalize to "0" or "1" for sanity. -->
508  <xsl:choose>
509    <xsl:when test="$autowidth = ''">
510      <!-- Fall back to the table width specification. -->
511      <xsl:choose>
512        <xsl:when test="$table-width = ''">
513          <!-- no info, default to autowidth -->
514          <xsl:text>1</xsl:text>
515        </xsl:when>
516        <xsl:when test="contains($table-width, 'auto')">
517          <xsl:choose>
518            <xsl:when test="contains($table-width, 'none')
519                            or contains($table-width, 'column:')">
520              <!-- explicit "none", or only some but not all -->
521              <xsl:text>none</xsl:text>
522            </xsl:when>
523            <xsl:otherwise>
524              <!-- "default" and "all" mean "all" -->
525              <xsl:text>1</xsl:text>
526            </xsl:otherwise>
527          </xsl:choose>
528        </xsl:when>
529        <xsl:otherwise>
530          <!-- Explicit table width absent explicit autowidth -->
531          <!-- Do proportional spacing -->
532          <xsl:text>0</xsl:text>
533        </xsl:otherwise>
534      </xsl:choose>
535    </xsl:when>
536
537    <xsl:otherwise>
538      <!-- use autowidth data -->
539      <xsl:choose>
540        <xsl:when test="contains($autowidth, 'column:')">
541          <!-- The unspecified columns are proportionally spaced. -->
542          <xsl:text>0</xsl:text>
543        </xsl:when>
544        <xsl:otherwise>
545          <xsl:choose>
546            <xsl:when test="$autowidth = 'none'">
547              <xsl:text>0</xsl:text>
548            </xsl:when>
549            <xsl:otherwise>
550              <xsl:text>1</xsl:text>
551            </xsl:otherwise>
552          </xsl:choose>
553        </xsl:otherwise>
554      </xsl:choose>
555    </xsl:otherwise>
556  </xsl:choose>
557</xsl:template>
558
559<!-- Make colspec for a constructed proportional column. -->
560<xsl:template name="proportional.column">
561  <colspec
562      colwidth="\newtblstarfactor"
563      star="1"/>
564</xsl:template>
565
566<!-- Make colspec for a constructed autowidth column. -->
567<xsl:template name="autowidth.column">
568  <colspec
569      autowidth="1"/>
570</xsl:template>
571
572<!-- Make colspec for a column where the user specifies the column width. -->
573<xsl:template name="user.specified.column">
574  <xsl:param name="colwidth.pi"/>  <!-- the latex colwidth PI -->
575
576  <xsl:variable name="fixed">
577    <xsl:call-template name="colfixed.get">
578      <xsl:with-param name="width" select="$colwidth.pi"/>
579    </xsl:call-template>
580  </xsl:variable>
581
582  <colspec>
583    <xsl:if test="$fixed != ''">
584      <xsl:attribute name="fixedwidth">
585        <xsl:value-of select="$fixed"/>
586      </xsl:attribute>
587    </xsl:if>
588
589    <xsl:choose>
590      <xsl:when test="contains($colwidth.pi, '*')">
591        <xsl:attribute name="colwidth">
592          <!-- This call duplicates code in newtbl.xsl -->
593          <xsl:call-template name="replace-string">
594            <xsl:with-param name="text" select="$colwidth.pi"/>
595            <xsl:with-param name="replace">*</xsl:with-param>
596            <xsl:with-param name="with">\newtblstarfactor</xsl:with-param>
597          </xsl:call-template>
598        </xsl:attribute>
599
600        <xsl:attribute name="star">
601          <xsl:call-template name="colstar.get">
602            <!-- This also is a duplicate of code in newtbl.xsl -->
603            <xsl:with-param
604                name="width"
605                select="substring-before($colwidth.pi, '*')"/>
606          </xsl:call-template>
607        </xsl:attribute>
608      </xsl:when>
609
610      <xsl:otherwise>
611        <xsl:attribute name="colwidth">
612          <xsl:value-of select="$colwidth.pi"/>
613        </xsl:attribute>
614      </xsl:otherwise>
615    </xsl:choose>
616  </colspec>
617</xsl:template>
618
619<!-- Use newtbl.xsl templates to calculate proportional column widths:
620   - tbl.sizes wants colspecs so build a set of fake colspec elements.
621   -
622   - tbl.sizes takes a collection of colspec elements, each having
623   - the following (optional) attributes:
624   -
625   - fixedwidth
626   -   String.  The fixed part (from colfixed.get) of a specified
627   -   column width.
628   -
629   - star
630   -   String (that we know can be converted to a number).
631   -   The "prefix count" of the * (from colstar.get).
632   -
633   - colwidth
634   -   String.  The user-specified column width with * replaced with
635   -   "\newtblstarfactor".
636   -
637   - The code in this file uses the (optional) attributes:
638   -   colwidth
639   -   autowidth
640   -     String (always "1").  When present (regardless of value!)
641   -     autowidth means the column is latex spaced.
642-->
643
644<!-- Build up a complete colspec for each column -->
645<xsl:template name="segtable.colspecs">
646  <xsl:param name="table-width"/>   <!-- user specified table width    -->
647
648  <xsl:variable name="autowidth.pi">
649    <xsl:call-template name="pi.dblatex_autowidth"/>
650  </xsl:variable>
651
652  <!-- Let LaTeX determine column width or space columns equally? -->
653  <xsl:variable name="autowidth">
654    <xsl:call-template name="segtable.autowidth">
655      <xsl:with-param name="autowidth.pi" select="$autowidth.pi"/>
656      <xsl:with-param name="table-width"  select="$table-width"/>
657    </xsl:call-template>
658  </xsl:variable>
659
660  <!-- The user-specified list of autowidth columns.  -->
661  <xsl:variable name="autocols">
662    <xsl:call-template name="segtable.autocols">
663      <xsl:with-param name="autowidth.pi" select="$autowidth.pi"/>
664      <xsl:with-param name="table-width"  select="$table-width"/>
665    </xsl:call-template>
666  </xsl:variable>
667
668  <!-- Build the colspecs -->
669  <xsl:for-each select="segtitle">
670    <xsl:variable name="colwidth.pi">
671      <xsl:call-template name="pi.dblatex_colwidth"/>
672    </xsl:variable>
673    <xsl:choose>
674      <xsl:when test="$colwidth.pi = ''">
675        <!-- Make up a colwidth -->
676        <xsl:choose>
677          <xsl:when test="contains($autocols,
678                                   concat(' ', position(), ' '))
679                          or $autowidth = '1'">
680            <xsl:call-template name="autowidth.column"/>
681          </xsl:when>
682          <xsl:otherwise>
683            <xsl:call-template name="proportional.column"/>
684          </xsl:otherwise>
685        </xsl:choose>
686      </xsl:when>
687
688      <xsl:when test="$colwidth.pi = 'autowidth.default'
689                      or $colwidth.pi = 'autowidth.all'">
690        <xsl:call-template name="autowidth.column"/>
691      </xsl:when>
692
693      <xsl:when test="$colwidth.pi = 'autowidth.none'">
694        <xsl:call-template name="proportional.column"/>
695      </xsl:when>
696
697      <xsl:otherwise>
698        <!-- The user specified an actual column width. -->
699        <xsl:call-template name="user.specified.column">
700          <xsl:with-param name="colwidth.pi" select="$colwidth.pi"/>
701        </xsl:call-template>
702      </xsl:otherwise>
703    </xsl:choose>
704  </xsl:for-each>
705</xsl:template>
706
707<!-- Output latex to compute latex lengths needed for tables. -->
708<xsl:template name="segtable.length.setup">
709  <xsl:param name="table-width"/>   <!-- user specified table width    -->
710  <xsl:param name="colspecs"/>      <!-- constructed column specifiers -->
711
712  <!-- What is the latex table width? -->
713  <xsl:variable name="width">
714    <!-- The $fullwidth value written here is also hardcoded into -->
715    <!-- newtbl.xsl, htmltbl.xsl, and tablen.xsl. (!) Cleanup is -->
716    <!-- likely called for. -->
717    <xsl:variable name="fullwidth">\linewidth-2\tabcolsep</xsl:variable>
718    <xsl:choose>
719    <xsl:when test="$table-width = ''
720                    or contains($table-width, 'auto')">
721      <xsl:value-of select="$fullwidth"/>
722    </xsl:when>
723    <xsl:when test="contains($table-width, '%')">
724      <xsl:value-of select="number(substring-before($table-width, '%'))
725                            div 100"/>
726      <xsl:value-of select="$fullwidth"/>
727    </xsl:when>
728    <xsl:otherwise>
729      <xsl:value-of select="$table-width"/>
730    </xsl:otherwise>
731    </xsl:choose>
732  </xsl:variable>
733
734  <!-- Setup latex for fixed table width. -->
735  <xsl:call-template name="tbl.sizes">
736    <xsl:with-param name="colspec" select="$colspecs"/>
737    <xsl:with-param name="width" select="$width"/>
738  </xsl:call-template>
739</xsl:template>
740
741
742<xsl:template match="segmentedlist" mode="seglist-table">
743  <!-- Bug: <info> elements are ignored, except for their <title> -->
744  <!-- and <titleabbrev> elements. -->
745
746  <!-- Which table width value are we using, PI or param? -->
747  <xsl:variable name="table-width">
748    <xsl:call-template name="segtable.table-width"/>
749  </xsl:variable>
750
751  <!-- Build up a complete colspec for each column -->
752  <xsl:variable name="colspecs-text">
753    <xsl:call-template name="segtable.colspecs">
754      <xsl:with-param name="table-width" select="$table-width"/>
755    </xsl:call-template>
756  </xsl:variable>
757  <!-- Convert to nodes so we can use it.  -->
758  <xsl:variable name="colspecs" select="exsl:node-set($colspecs-text)"/>
759
760  <!-- Setup latex (nested) group(s) for table. -->
761  <xsl:text>&#10;&#10;{\raggedright\savetablecounter</xsl:text>
762  <xsl:text>\begingroup%&#10;</xsl:text>
763
764  <!-- Output latex to compute latex lengths needed for tables. -->
765  <xsl:call-template name="segtable.length.setup">
766    <xsl:with-param name="table-width" select="$table-width"/>
767    <xsl:with-param name="colspecs"    select="$colspecs"/>
768  </xsl:call-template>
769
770  <!-- Start table. -->
771  <!-- Title goes in table; it's in the heading so if the table -->
772  <!-- spans multiple pages there's always a title. -->
773
774  <!-- No "custom" padding before or after the longtable. -->
775  <!-- The content of a segmentedlist (aside from the <info> content, -->
776  <!-- which presumably isn't rendered in the table itself except for -->
777  <!-- <title> and <titleabbrev>) is all inline so we don't need to   -->
778  <!-- worry about nested tables and can safely set LTpre and LTpost. -->
779  <xsl:text>\setlength{\LTpre}{\parskip}</xsl:text>
780
781  <!-- longtable puts an extra empty row at the bottom so              -->
782  <!-- offset the bottom padding by one row height.                    -->
783  <!-- Near as I can tell the extra row is the "dummy" row, consisting -->
784  <!-- of a bunch of "m" chars followed by an "i".  So use the height  -->
785  <!-- of an "i" as the height of the extra row.                       -->
786  <xsl:text>\setlength{\LTpost}{\parskip-\fontcharht\font`i}%&#10;</xsl:text>
787
788  <xsl:text>\begin{longtable}[l]{</xsl:text>
789  <xsl:for-each select="$colspecs/colspec">
790    <xsl:text>l</xsl:text>
791  </xsl:for-each>
792  <xsl:text>}&#10;</xsl:text>
793
794  <!-- Apply templates to children separately so we can use position() -->
795  <!-- when processing segtitle. -->
796
797  <xsl:apply-templates mode="seg-table"
798                       select="title|info/title|titleabbrev|info/titleabbrev">
799    <xsl:with-param name="colspecs" select="$colspecs"/>
800  </xsl:apply-templates>
801
802  <xsl:apply-templates mode="seg-table" select="segtitle">
803    <xsl:with-param name="colspecs" select="$colspecs"/>
804  </xsl:apply-templates>
805
806  <xsl:apply-templates mode="seg-table" select="seglistitem">
807    <xsl:with-param name="colspecs" select="$colspecs"/>
808  </xsl:apply-templates>
809
810  <xsl:text>\end{longtable}\endgroup%&#10;</xsl:text>
811  <xsl:text>\restoretablecounter%&#10;</xsl:text>
812
813  <xsl:text>}</xsl:text>
814</xsl:template>
815
816<xsl:template match="title|titleabbrev" mode="seglist-title">
817  <xsl:text>{\bf </xsl:text>
818  <xsl:apply-templates/>
819  <xsl:text>}</xsl:text>
820</xsl:template>
821
822<xsl:template match="segmentedlist/title
823                     | segmentedlist/info/title
824                     | segmentedlist/titleabbrev[not(../title)]
825                     | segmentedlist/info/titleabbrev[not(../title)]"
826              mode="seg-table">
827  <xsl:param name="colspecs"/>
828
829  <!-- Autowidth in any column then use autowidth for title, -->
830  <!-- otherwise, use the sum of the column widths. -->
831
832  <xsl:text>\multicolumn{</xsl:text>
833  <xsl:value-of select="count($colspecs/colspec)"/>
834  <xsl:text>}{</xsl:text>
835  <xsl:choose>
836    <xsl:when test="$colspecs/colspec/@autowidth">
837      <xsl:text>l</xsl:text>
838    </xsl:when>
839    <xsl:otherwise>
840      <xsl:text>p{</xsl:text>
841      <xsl:for-each select="$colspecs/colspec">
842        <xsl:value-of select="@colwidth"/>
843        <xsl:if test="following-sibling::colspec">
844          <xsl:text>+\tabcolsep+</xsl:text>
845        </xsl:if>
846      </xsl:for-each>
847      <xsl:text>}</xsl:text>
848    </xsl:otherwise>
849  </xsl:choose>
850  <xsl:text>}{\raggedright%&#10;</xsl:text>
851  <xsl:apply-templates select="." mode="seglist-title"/>
852  <xsl:text>%&#10;}\tabularnewline&#10;</xsl:text>
853</xsl:template>
854
855<xsl:template name="segmentedlist.col">
856  <!-- Make segmentedlist column -->
857  <xsl:param name="colspecs"/>
858  <xsl:param name="format"/>
859  <xsl:param name="heading" select="0"/>
860
861  <xsl:variable name="position">
862    <xsl:value-of select="position()"/>
863  </xsl:variable>
864
865  <xsl:variable name="colspec"
866                select="$colspecs/colspec[position()=$position]"/>
867
868  <xsl:variable name="colwidth">
869    <xsl:value-of select="$colspec/@colwidth"/>
870  </xsl:variable>
871
872  <!-- value-of a missing attribute returns a empty text node,
873       - but we want to know about the _existance_ of the attribute,
874       - not it's content, and testing for "" is ugly.
875       - So "select=..." in variable. -->
876  <xsl:variable name="autowidth"
877                select="$colspec/@autowidth"/>
878
879  <xsl:text>\multicolumn{1}{</xsl:text>
880  <!-- centering/justification and column width -->
881  <!-- (and open { for cell content) -->
882  <xsl:choose>
883  <xsl:when test="$autowidth">
884    <xsl:choose>
885      <xsl:when test="$format = 'p'">
886	<xsl:text>l</xsl:text>
887      </xsl:when>
888      <xsl:otherwise>
889	<xsl:text>c</xsl:text>
890      </xsl:otherwise>
891    </xsl:choose>
892    <xsl:text>}{%&#10;</xsl:text>
893  </xsl:when>
894  <xsl:otherwise>
895    <xsl:value-of select="$format"/>
896    <xsl:text>{</xsl:text>
897    <xsl:value-of select="$colwidth"/>
898    <xsl:text>}}{</xsl:text>
899    <xsl:choose>
900      <xsl:when test="$format = 'p'">
901	<xsl:text>\raggedright</xsl:text>
902      </xsl:when>
903      <xsl:otherwise>
904	<xsl:text>\centering</xsl:text>
905      </xsl:otherwise>
906    </xsl:choose>
907    <xsl:text>%&#10;</xsl:text>
908  </xsl:otherwise>
909  </xsl:choose>
910  <!-- cell content -->
911  <xsl:choose>
912    <xsl:when test="$heading">
913      <xsl:text>\emph{</xsl:text>
914      <xsl:apply-templates select="."
915			   mode="segtitle-in-seg"/>
916      <xsl:text>}</xsl:text>
917    </xsl:when>
918    <xsl:otherwise>
919      <xsl:apply-templates/>
920    </xsl:otherwise>
921  </xsl:choose>
922  <xsl:text>%&#10;}</xsl:text>
923  <!-- separate from future content -->
924  <xsl:choose>
925    <xsl:when test="position() != last()">
926      <xsl:text>&amp;</xsl:text>
927    </xsl:when>
928    <xsl:otherwise>
929      <xsl:choose>
930        <xsl:when
931            test="self::segtitle
932                  or parent::seglistitem[following-sibling::seglistitem]">
933          <xsl:text>\tabularnewline</xsl:text>
934        </xsl:when>
935        <xsl:otherwise>
936          <xsl:text>%</xsl:text>
937        </xsl:otherwise>
938      </xsl:choose>
939      <xsl:text>&#10;</xsl:text>
940    </xsl:otherwise>
941  </xsl:choose>
942</xsl:template>
943
944<xsl:template match="segtitle" mode="seg-table">
945  <xsl:param name="colspecs"/>
946
947  <xsl:call-template name="segmentedlist.col">
948    <xsl:with-param name="colspecs" select="$colspecs"/>
949    <xsl:with-param name="format">m</xsl:with-param>
950    <xsl:with-param name="heading" select="1"/>
951  </xsl:call-template>
952  <xsl:if test="not(following-sibling::segtitle)">
953    <xsl:text>\endhead&#10;</xsl:text>
954  </xsl:if>
955</xsl:template>
956
957<xsl:template match="seglistitem" mode="seg-table">
958  <xsl:param name="colspecs"/>
959  <xsl:apply-templates mode="seg-table">
960    <xsl:with-param name="colspecs" select="$colspecs"/>
961  </xsl:apply-templates>
962</xsl:template>
963
964<xsl:template match="seg" mode="seg-table">
965  <xsl:param name="colspecs"/>
966
967  <xsl:call-template name="segmentedlist.col">
968    <xsl:with-param name="colspecs" select="$colspecs"/>
969    <xsl:with-param name="format">p</xsl:with-param>
970  </xsl:call-template>
971</xsl:template>
972
973</xsl:stylesheet>
974
975