1<?xml version="1.0"?>
2
3<!--
4   - nroff.xsl -
5   -
6   - Copyright (c) 2000 Zveno Pty Ltd
7   -
8   -	XSLT stylesheet to convert DocBook+Tcl mods to nroff.
9   -	NB. Tcl man macros are used.
10   -
11   - $Id: nroff.xsl,v 1.3 2002/11/11 22:45:19 balls Exp $
12   -->
13
14<xsl:stylesheet version='1.0'
15  xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
16
17<xsl:output method="text"/>
18
19<xsl:variable name="tclversion" select='""'/>
20<xsl:variable name="maxlinelen" select="60"/>
21
22<xsl:template match="refentry">'\"
23<xsl:apply-templates select="docinfo"/>
24'\" 
25'\" RCS: @(#) $Id: nroff.xsl,v 1.3 2002/11/11 22:45:19 balls Exp $
26'\" 
27'\" The definitions below are for supplemental macros used in Tcl/Tk
28'\" manual entries.
29'\"
30'\" .AP type name in/out ?indent?
31'\"	Start paragraph describing an argument to a library procedure.
32'\"	type is type of argument (int, etc.), in/out is either "in", "out",
33'\"	or "in/out" to describe whether procedure reads or modifies arg,
34'\"	and indent is equivalent to second arg of .IP (shouldn't ever be
35'\"	needed;  use .AS below instead)
36'\"
37'\" .AS ?type? ?name?
38'\"	Give maximum sizes of arguments for setting tab stops.  Type and
39'\"	name are examples of largest possible arguments that will be passed
40'\"	to .AP later.  If args are omitted, default tab stops are used.
41'\"
42'\" .BS
43'\"	Start box enclosure.  From here until next .BE, everything will be
44'\"	enclosed in one large box.
45'\"
46'\" .BE
47'\"	End of box enclosure.
48'\"
49'\" .CS
50'\"	Begin code excerpt.
51'\"
52'\" .CE
53'\"	End code excerpt.
54'\"
55'\" .VS ?version? ?br?
56'\"	Begin vertical sidebar, for use in marking newly-changed parts
57'\"	of man pages.  The first argument is ignored and used for recording
58'\"	the version when the .VS was added, so that the sidebars can be
59'\"	found and removed when they reach a certain age.  If another argument
60'\"	is present, then a line break is forced before starting the sidebar.
61'\"
62'\" .VE
63'\"	End of vertical sidebar.
64'\"
65'\" .DS
66'\"	Begin an indented unfilled display.
67'\"
68'\" .DE
69'\"	End of indented unfilled display.
70'\"
71'\" .SO
72'\"	Start of list of standard options for a Tk widget.  The
73'\"	options follow on successive lines, in four columns separated
74'\"	by tabs.
75'\"
76'\" .SE
77'\"	End of list of standard options for a Tk widget.
78'\"
79'\" .OP cmdName dbName dbClass
80'\"	Start of description of a specific option.  cmdName gives the
81'\"	option's name as specified in the class command, dbName gives
82'\"	the option's name in the option database, and dbClass gives
83'\"	the option's class in the option database.
84'\"
85'\" .UL arg1 arg2
86'\"	Print arg1 underlined, then print arg2 normally.
87'\"
88'\" RCS: @(#) $Id: nroff.xsl,v 1.3 2002/11/11 22:45:19 balls Exp $
89'\"
90'\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
91.if t .wh -1.3i ^B
92.nr ^l \n(.l
93.ad b
94'\"	# Start an argument description
95.de AP
96.ie !"\\$4"" .TP \\$4
97.el \{\
98.   ie !"\\$2"" .TP \\n()Cu
99.   el          .TP 15
100.\}
101.ta \\n()Au \\n()Bu
102.ie !"\\$3"" \{\
103\&amp;\\$1	\\fI\\$2\\fP	(\\$3)
104.\".b
105.\}
106.el \{\
107.br
108.ie !"\\$2"" \{\
109\&amp;\\$1	\\fI\\$2\\fP
110.\}
111.el \{\
112\&amp;\\fI\\$1\\fP
113.\}
114.\}
115..
116'\"	# define tabbing values for .AP
117.de AS
118.nr )A 10n
119.if !"\\$1"" .nr )A \\w'\\$1'u+3n
120.nr )B \\n()Au+15n
121.\"
122.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
123.nr )C \\n()Bu+\\w'(in/out)'u+2n
124..
125.AS Tcl_Interp Tcl_CreateInterp in/out
126'\"	# BS - start boxed text
127'\"	# ^y = starting y location
128'\"	# ^b = 1
129.de BS
130.br
131.mk ^y
132.nr ^b 1u
133.if n .nf
134.if n .ti 0
135.if n \l'\\n(.lu\(ul'
136.if n .fi
137..
138'\"	# BE - end boxed text (draw box now)
139.de BE
140.nf
141.ti 0
142.mk ^t
143.ie n \l'\\n(^lu\(ul'
144.el \{\
145.\"	Draw four-sided box normally, but don't draw top of
146.\"	box if the box started on an earlier page.
147.ie !\\n(^b-1 \{\
148\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
149.\}
150.el \}\
151\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
152.\}
153.\}
154.fi
155.br
156.nr ^b 0
157..
158'\"	# VS - start vertical sidebar
159'\"	# ^Y = starting y location
160'\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
161.de VS
162.if !"\\$2"" .br
163.mk ^Y
164.ie n 'mc \s12\(br\s0
165.el .nr ^v 1u
166..
167'\"	# VE - end of vertical sidebar
168.de VE
169.ie n 'mc
170.el \{\
171.ev 2
172.nf
173.ti 0
174.mk ^t
175\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
176.sp -1
177.fi
178.ev
179.\}
180.nr ^v 0
181..
182'\"	# Special macro to handle page bottom:  finish off current
183'\"	# box/sidebar if in box/sidebar mode, then invoked standard
184'\"	# page bottom macro.
185.de ^B
186.ev 2
187'ti 0
188'nf
189.mk ^t
190.if \\n(^b \{\
191.\"	Draw three-sided box if this is the box's first page,
192.\"	draw two sides but no top otherwise.
193.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
194.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
195.\}
196.if \\n(^v \{\
197.nr ^x \\n(^tu+1v-\\n(^Yu
198\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
199.\}
200.bp
201'fi
202.ev
203.if \\n(^b \{\
204.mk ^y
205.nr ^b 2
206.\}
207.if \\n(^v \{\
208.mk ^Y
209.\}
210..
211'\"	# DS - begin display
212.de DS
213.RS
214.nf
215.sp
216..
217'\"	# DE - end display
218.de DE
219.fi
220.RE
221.sp
222..
223'\"	# SO - start of list of standard options
224.de SO
225.SH "STANDARD OPTIONS"
226.LP
227.nf
228.ta 4c 8c 12c
229.ft B
230..
231'\"	# SE - end of list of standard options
232.de SE
233.fi
234.ft R
235.LP
236See the \\fBoptions\\fR manual entry for details on the standard options.
237..
238'\"	# OP - start of full description for a single option
239.de OP
240.LP
241.nf
242.ta 4c
243Command-Line Name:	\\fB\\$1\\fR
244Database Name:	\\fB\\$2\\fR
245Database Class:	\\fB\\$3\\fR
246.fi
247.IP
248..
249'\"	# CS - begin code excerpt
250.de CS
251.RS
252.nf
253.ta .25i .5i .75i 1i
254..
255'\"	# CE - end code excerpt
256.de CE
257.fi
258.RE
259..
260.de UL
261\\$1\l'|0\(ul'\\$2
262..
263<xsl:apply-templates select="refmeta"/>
264.BS
265<xsl:apply-templates select="*[name() != 'docinfo' and name() != 'refmeta']"/>
266</xsl:template>
267
268  <xsl:template match="docinfo|docinfo/legalnotice">
269    <xsl:apply-templates/>
270  </xsl:template>
271
272  <xsl:template match="docinfo/copyright">
273    <xsl:text>'\" Copyright (c) </xsl:text><xsl:value-of select="year"/><xsl:text> </xsl:text><xsl:value-of select="holder"/><xsl:text>
274'\"
275</xsl:text>
276  </xsl:template>
277
278  <!-- We need a way of finding the last space char on each line,
279     - trimming the line at that point and then continuing with
280     - string after that space char.  It's in the "too-hard" basket for now.
281     -
282     - SRB 20021030: xsltsl should provide this functionality.
283    -->
284
285  <xsl:template match="docinfo/legalnotice/para[1]">
286    <xsl:call-template name="comment.line">
287      <xsl:with-param name="line" select="substring(.,1,$maxlinelen)"/>
288    </xsl:call-template>
289    <xsl:call-template name="comment.line.continue">
290      <xsl:with-param name="text" select="substring(.,$maxlinelen + 1)"/>
291    </xsl:call-template>
292  </xsl:template>
293<xsl:template match="docinfo/legalnotice/para[position() > 1]">
294'\"
295<xsl:call-template name="comment.line">
296  <xsl:with-param name="line" select="substring(.,1,$maxlinelen)"/>
297</xsl:call-template>
298<xsl:call-template name="comment.line.continue">
299  <xsl:with-param name="text" select="substring(.,$maxlinelen + 1)"/>
300</xsl:call-template>
301</xsl:template>
302
303<xsl:template name="comment.line">
304  <xsl:param name="line"/>
305  <xsl:text>'\" </xsl:text>
306  <xsl:value-of select="$line"/>
307</xsl:template>
308<xsl:template name="comment.line.continue">
309  <xsl:param name="text"/>
310  <xsl:choose>
311    <xsl:when test="string-length($text) > 0">
312      <xsl:text>
313</xsl:text>
314      <xsl:call-template name="comment.line">
315	<xsl:with-param name="line" select="substring($text,1,$maxlinelen)"/>
316      </xsl:call-template>
317      <xsl:call-template name="comment.line.continue">
318	<xsl:with-param name="text" select="substring($text,$maxlinelen + 1)"/>
319      </xsl:call-template>
320    </xsl:when>
321    <xsl:otherwise/>
322  </xsl:choose>
323</xsl:template>
324
325<xsl:template match="refmeta">
326  <xsl:text>.TH </xsl:text>
327  <xsl:value-of select="refentrytitle"/>
328  <xsl:text> </xsl:text>
329  <xsl:value-of select="manvolnum"/>
330  <xsl:text> </xsl:text>
331  <xsl:value-of select="$tclversion"/>
332  <xsl:text> Tcl "Tcl Built-In Commands"</xsl:text>
333</xsl:template>
334
335<xsl:template match="refnamediv">
336  <xsl:text>'\" Note:  do not modify the .SH NAME line immediately below!
337.SH NAME
338</xsl:text>
339  <xsl:value-of select="refname[1]"/>
340  <xsl:text> \- </xsl:text>
341  <xsl:value-of select="refpurpose"/>
342  <xsl:text>
343</xsl:text>
344</xsl:template>
345
346<xsl:template match="refsynopsisdiv">
347  <xsl:text>.SH SYNOPSIS
348</xsl:text>
349  <xsl:apply-templates/>
350  <xsl:text>
351.BE
352</xsl:text>
353</xsl:template>
354
355<xsl:template match="tclcmdsynopsis|tcloptionsynopsis|tclpkgsynopsis|tclnamespacesynopsis">
356  <xsl:apply-templates/>
357  <xsl:choose>
358    <xsl:when test="command/node()[position() = last() and self::*]">
359      <!-- last element would have reset font -->
360    </xsl:when>
361    <xsl:otherwise>
362      <xsl:text>\fP</xsl:text>
363    </xsl:otherwise>
364  </xsl:choose>
365  <xsl:text>
366.sp
367</xsl:text>
368</xsl:template>
369<xsl:template match="tclcmdsynopsis[position() = last()]|tcloptionsynopsis[position() = last()]">
370  <xsl:apply-templates/>
371  <xsl:choose>
372    <xsl:when test="command/node()[position() = last() and self::*]">
373      <!-- last element would have reset font -->
374    </xsl:when>
375    <xsl:otherwise>
376      <xsl:text>\fP</xsl:text>
377    </xsl:otherwise>
378  </xsl:choose>
379</xsl:template>
380
381<xsl:template match="tclcmdsynopsis/command">
382  <xsl:text>\fB</xsl:text>
383  <xsl:apply-templates/>
384</xsl:template>
385
386<xsl:template match="option">
387  <xsl:text>\fI </xsl:text>
388  <xsl:apply-templates/>
389  <xsl:text>\fR</xsl:text>
390</xsl:template>
391
392<xsl:template match="group">
393  <xsl:apply-templates/>
394</xsl:template>
395<xsl:template match="group[@choice='opt']">
396  <xsl:text> ?</xsl:text>
397  <xsl:apply-templates/>
398  <xsl:text>?</xsl:text>
399</xsl:template>
400<xsl:template match="group[@choice='opt' and @rep='repeat']">
401  <xsl:text> ?</xsl:text>
402  <xsl:apply-templates/>
403  <xsl:text> ... ?</xsl:text>
404</xsl:template>
405
406<xsl:template match="arg">
407  <xsl:text>\fI </xsl:text>
408  <xsl:apply-templates/>
409</xsl:template>
410
411<xsl:template match="replaceable">
412  <xsl:text>\fI</xsl:text>
413  <xsl:apply-templates/>
414  <xsl:text>\fR</xsl:text>
415</xsl:template>
416
417  <xsl:template match="tclcommand|tclnamespace">
418    <xsl:call-template name='inline.bold'/>
419  </xsl:template>
420  <xsl:template name='inline.bold'>
421    <xsl:text>\fB</xsl:text>
422    <xsl:apply-templates/>
423    <xsl:text>\fR</xsl:text>
424  </xsl:template>
425
426<xsl:template match="refsect1">
427  <xsl:text>
428.SH </xsl:text>
429  <xsl:value-of select="translate(title,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
430  <xsl:text>
431</xsl:text>
432  <xsl:apply-templates select='*[not(self::title)]'/>
433</xsl:template>
434
435<xsl:template match="para">
436  <xsl:text>
437.PP
438</xsl:text>
439  <xsl:apply-templates/>
440  <xsl:text>
441</xsl:text>
442</xsl:template>
443
444<xsl:template match="para/text()">
445  <xsl:value-of select="."/>
446</xsl:template>
447
448  <xsl:template match="refsect2">
449    <xsl:apply-templates select="para|title"/>
450    <xsl:text>
451.RS
452</xsl:text>
453    <xsl:apply-templates select="refsect3"/>
454    <xsl:text>
455.RE
456</xsl:text>
457  </xsl:template>
458
459  <xsl:template match="refsect3">
460    <xsl:apply-templates/>
461  </xsl:template>
462
463  <xsl:template match="acronym">
464    <xsl:apply-templates/>
465  </xsl:template>
466
467<xsl:template match="refsect2/title|refsect3/title">
468  <xsl:text>.TP
469</xsl:text>
470  <xsl:apply-templates/>
471  <xsl:text>
472</xsl:text>
473</xsl:template>
474
475<xsl:template match="refsect1[title = 'Commands'][refsect2/title]//tclcmdsynopsis/*[position() = 1 and name() = 'option']">
476  <xsl:choose>
477    <xsl:when test="ancestor::refsect3//*[@role='subject']">
478      <xsl:text>.TP
479\fI</xsl:text>
480      <xsl:value-of select="ancestor::refsect3//*[@role='subject']"/>
481      <xsl:text>\fR</xsl:text>
482    </xsl:when>
483    <xsl:when test="ancestor::refsect2/title">
484      <xsl:text>.TP
485</xsl:text>
486      <xsl:value-of select="ancestor::refsect2/title"/>
487    </xsl:when>
488    <xsl:otherwise/>
489  </xsl:choose>
490  <xsl:text> </xsl:text>
491  <xsl:apply-templates/>
492</xsl:template>
493
494  <xsl:template match="segmentedlist|variablelist">
495    <xsl:text>
496.TP
497.RS
498</xsl:text>
499    <xsl:apply-templates/>
500    <xsl:text>.RE
501</xsl:text>
502  </xsl:template>
503
504  <xsl:template match="seglistitem">
505    <xsl:text>.TP
506\fI</xsl:text>
507    <xsl:value-of select="seg[1]"/>
508    <xsl:text>\fP </xsl:text>
509    <xsl:value-of select="seg[2]"/>
510    <xsl:text>
511</xsl:text>
512  </xsl:template>
513
514  <xsl:template match="varlistentry">
515    <xsl:text>.TP
516\fI</xsl:text>
517    <xsl:apply-templates select="term"/>
518    <xsl:text>\fP </xsl:text>
519    <xsl:apply-templates select="listitem"/>
520    <xsl:text>
521</xsl:text>
522  </xsl:template>
523  <xsl:template match='term'>
524    <xsl:call-template name='inline.bold'/>
525  </xsl:template>
526  <xsl:template match='listitem'>
527    <xsl:apply-templates/>
528  </xsl:template>
529
530  <xsl:template match='methodname|version|package'>
531    <xsl:call-template name='inline.bold'/>
532  </xsl:template>
533
534<xsl:template match="informalexample">
535  <xsl:text>.PP
536</xsl:text>
537  <xsl:apply-templates/>
538</xsl:template>
539
540<xsl:template match="programlisting">
541  <xsl:text>.CS
542</xsl:text>
543  <xsl:apply-templates/>
544  <xsl:text>
545.CE
546</xsl:text>
547</xsl:template>
548
549  <xsl:template match='author'>
550    <xsl:apply-templates select='firstname'/>
551    <xsl:text> </xsl:text>
552    <xsl:apply-templates select='surname'/>
553  </xsl:template>
554
555  <xsl:template match='firstname|surname'>
556    <xsl:apply-templates/>
557  </xsl:template>
558
559<!-- Override built-in rules to omit unwanted content -->
560
561<xsl:template match="*">
562  <xsl:message>No template matching <xsl:value-of select="name()"/> (parent <xsl:value-of select="name(..)"/>)</xsl:message>
563</xsl:template>
564<xsl:template match="text()[string-length(normalize-space()) = 0]|@*">
565  <!-- Don't emit white space -->
566</xsl:template>
567
568</xsl:stylesheet>
569