1# -*- tcl -*-
2#
3# fmt.text -- Engine to convert a doctools document into plain text.
4#
5# Copyright (c) 2003 Andreas Kupries <andreas_kupries@sourceforge.net>
6#
7################################################################
8################################################################
9
10# Load shared code and modify it to our needs.
11
12dt_source _common.tcl
13dt_source _text.tcl
14proc c_copyrightsymbol {} {return "(c)"}
15
16rename fmt_initialize     BaseInitialize
17proc   fmt_initialize {} {BaseInitialize ; TextInitialize ; return}
18
19################################################################
20# Special manpage environments
21
22proc NewExample {} {
23    global currentEnv
24    return [NewEnv Example {
25	set    currentEnv(verbatim) 1
26	append currentEnv(prefix)   "| "
27	set    currentEnv(example) .
28    }] ; # {}
29}
30
31proc Example {} {
32    global currentEnv
33    if {![info exists currentEnv(exenv)]} {
34	SaveContext
35	set verb [NewExample]
36	RestoreContext
37
38	# Remember verbatim mode in the base environment
39	set currentEnv(exenv) $verb
40	SaveEnv
41    }
42    return $currentEnv(exenv)
43}
44
45proc NewList {what} {
46    # List environments
47    # Per list several environments are required.
48
49    switch -exact -- $what {
50	enumerated {NewOrderedList}
51	itemized   {NewUnorderedList}
52	arguments -
53	commands  -
54	options   -
55	tkoptions -
56	definitions {NewDefinitionList}
57    }
58}
59
60proc NewUnorderedList {} {
61    global currentEnv lmarginIncrement
62
63    # Itemized list - unordered list - bullet
64    # 1. Base environment provides indentation.
65    # 2. First paragraph in a list item.
66    # 3. All other paragraphs.
67
68    set base [NewEnv Itemized {
69	incr currentEnv(lmargin)   $lmarginIncrement
70
71	set bullet [Bullet currentEnv(bulleting)]
72    }] ; # {}
73    set first [NewEnv First {
74	set currentEnv(wspfx) [::textutil::repeat::blank $lmarginIncrement]
75	set currentEnv(listtype)  bullet
76	set currentEnv(bullet) $bullet
77    }] ; SetContext $base ; # {}
78
79    set next [NewEnv Next {
80	incr currentEnv(lmargin)   $lmarginIncrement
81    }] ; SetContext $base ; # {}
82
83    set currentEnv(_first) $first
84    set currentEnv(_next)  $next
85    set currentEnv(pcount) 0
86    SaveEnv
87    return
88}
89
90proc NewOrderedList {} {
91    global currentEnv lmarginIncrement
92
93    # Ordered list - enumeration - enum
94    # 1. Base environment provides indentation.
95    # 2. First paragraph in a list item.
96    # 3. All other paragraphs.
97
98    set base [NewEnv Enumerated {
99	incr currentEnv(lmargin)   $lmarginIncrement
100
101	set bullet [EnumBullet currentEnv(enumeration)]
102    }] ; # {}
103    set first [NewEnv First {
104	set currentEnv(wspfx)  [::textutil::repeat::blank $lmarginIncrement]
105	set currentEnv(listtype)  enum
106	set currentEnv(bullet) $bullet
107    }] ; SetContext $base ; # {}
108
109    set next [NewEnv Next {
110	incr currentEnv(lmargin)   $lmarginIncrement
111    }] ; SetContext $base ; # {}
112
113    set currentEnv(_first) $first
114    set currentEnv(_next)  $next
115    set currentEnv(pcount) 0
116    SaveEnv
117    return
118}
119
120proc NewDefinitionList {} {
121    global currentEnv lmarginIncrement
122
123    # Definition list - terms & definitions
124    # 1. Base environment provides indentation.
125    # 2. Term environment
126    # 3. Definition environment
127
128    set base [NewEnv DefL {
129	incr currentEnv(lmargin)   $lmarginIncrement
130    }] ; # {}
131    set term [NewEnv Term {
132	set currentEnv(verbatim) 1
133    }] ; SetContext $base ; # {}
134
135    set def [NewEnv Def {
136	incr currentEnv(lmargin) $lmarginIncrement
137    }] ; SetContext $base ; # {}
138
139    set currentEnv(_term)       $term
140    set currentEnv(_definition) $def
141    SaveEnv
142    return
143}
144
145################################################################
146# Final layouting.
147
148c_holdBuffers require
149
150proc fmt_postprocess {text} {text_postprocess $text}
151
152
153################################################################
154# Implementations of the formatting commands.
155
156c_pass 1 fmt_plain_text {text} NOP
157c_pass 2 fmt_plain_text {text} {text_plain_text $text}
158
159c_pass 1 fmt_manpage_begin {title section version} NOP
160c_pass 2 fmt_manpage_begin {title section version} {
161    Off
162    set module      [dt_module]
163    set shortdesc   [c_get_module]
164    set description [c_get_title]
165    set copyright   [c_get_copyright]
166
167    set     hdr [list]
168    lappend hdr "$title - $shortdesc"
169    lappend hdr [c_provenance]
170    lappend hdr "[string trimleft $title :]($section) $version $module \"$shortdesc\""
171    set     hdr [join $hdr \n]
172
173    Text $hdr
174    CloseParagraph [Verbatim]
175    Section NAME
176    Text "$title - $description"
177    CloseParagraph
178    return
179}
180
181c_pass 1 fmt_moddesc   {desc} {c_set_module $desc}
182c_pass 2 fmt_moddesc   {desc} NOP
183
184c_pass 1 fmt_titledesc {desc} {c_set_title $desc}
185c_pass 2 fmt_titledesc {desc} NOP
186
187c_pass 1 fmt_copyright {desc} {c_set_copyright $desc}
188c_pass 2 fmt_copyright {desc} NOP
189
190c_pass 1 fmt_manpage_end {} NOP
191c_pass 2 fmt_manpage_end {} {
192    set sa [c_xref_seealso]
193    set kw [c_xref_keywords]
194    set ca [c_xref_category]
195    set ct [c_get_copyright]
196
197    CloseParagraph
198    if {[llength $sa] > 0} {Section {SEE ALSO} ; Text [join [lsort $sa] ", "] ; CloseParagraph}
199    if {[llength $kw] > 0} {Section KEYWORDS   ; Text [join [lsort $kw] ", "] ; CloseParagraph}
200    if {$ca ne ""}         {Section CATEGORY   ; Text $ca                     ; CloseParagraph}
201    if {$ct != {}}         {Section COPYRIGHT  ; Text $ct ; CloseParagraph [Verbatim]}
202    return
203}
204
205c_pass 1 fmt_section     {name {id {}}} NOP
206c_pass 2 fmt_section     {name {id {}}} {CloseParagraph ; Section $name ; return}
207
208c_pass 1 fmt_subsection  {name {id {}}} NOP
209c_pass 2 fmt_subsection  {name {id {}}} {CloseParagraph ; Subsection $name ; return}
210
211c_pass 1 fmt_para {} NOP
212c_pass 2 fmt_para {} {CloseParagraph ; return}
213
214c_pass 2 fmt_require {pkg {version {}}} NOP
215c_pass 1 fmt_require {pkg {version {}}} {
216    set result "package require $pkg"
217    if {$version != {}} {append result " $version"}
218    c_hold require $result
219    return
220}
221
222c_pass 1 fmt_usage {cmd args} {c_hold synopsis "$cmd [join $args " "]"}
223c_pass 2 fmt_usage {cmd args} NOP
224
225c_pass 1 fmt_call  {cmd args} {c_hold synopsis "$cmd [join $args " "]"}
226c_pass 2 fmt_call  {cmd args} {fmt_lst_item "$cmd [join $args " "]"}
227
228
229c_pass 1 fmt_description {id} NOP
230c_pass 2 fmt_description {id} {
231    On
232    set syn [c_held synopsis]
233    set req [c_held require]
234
235    if {$syn != {} || $req != {}} {
236	Section SYNOPSIS
237	if {($req != {}) && ($syn != {})} {
238	    Text $req\n\n$syn
239	} else {
240	    if {$req != {}} {Text $req}
241	    if {$syn != {}} {Text $syn}
242	}
243	CloseParagraph [Verbatim]
244    }
245
246    Section DESCRIPTION
247    return
248}
249
250################################################################
251
252c_pass 1 fmt_list_begin {what {hint {}}} NOP
253c_pass 2 fmt_list_begin {what {hint {}}} {
254    #puts_stderr "<<fmt_list_begin $what>>"
255
256    global currentEnv
257    if {[info exists currentEnv(_definition)]} {
258	CloseParagraph $currentEnv(_definition)
259    } elseif {[info exists currentEnv(pcount)]} {
260	if {$currentEnv(pcount) == 0} {CloseParagraph $currentEnv(_first)}
261	if {$currentEnv(pcount) >  0} {CloseParagraph $currentEnv(_next)}
262	incr currentEnv(pcount)
263    } else {
264	CloseParagraph
265    }
266    SaveContext
267    NewList $what
268    Off
269
270    #puts_stderr "<<fmt_list_begin _____>>"
271    return
272}
273
274c_pass 1 fmt_list_end {} NOP
275c_pass 2 fmt_list_end {} {
276    #puts_stderr "<<fmt_list_end>>"
277
278    global currentEnv
279    if {[info exists currentEnv(_definition)]} {
280	CloseParagraph $currentEnv(_definition)
281    } else {
282	if {$currentEnv(pcount) == 0} {CloseParagraph $currentEnv(_first)}
283	if {$currentEnv(pcount) >  0} {CloseParagraph $currentEnv(_next)}
284    }
285    RestoreContext
286
287    #puts_stderr "<<fmt_list_end ____>>"
288    return
289}
290
291c_pass 1 fmt_lst_item {text} NOP
292c_pass 2 fmt_lst_item {text} {
293    global currentEnv
294
295    #puts_stderr "<<fmt_lst_item \{$text\}>>"
296
297    if {[IsOff]} {
298	On
299    } else {
300	CloseParagraph $currentEnv(_definition)
301    }
302    Text $text
303    CloseParagraph $currentEnv(_term)
304
305    #puts_stderr "<<fmt_lst_item _____>>"
306    return
307}
308
309c_pass 1 fmt_bullet {} NOP
310c_pass 2 fmt_bullet {} {
311    global currentEnv
312    if {[IsOff]} {On ; return}
313    if {$currentEnv(pcount) == 0} {CloseParagraph $currentEnv(_first)}
314    if {$currentEnv(pcount) >  0} {CloseParagraph $currentEnv(_next)}
315    set  currentEnv(pcount) 0
316    return
317}
318
319c_pass 1 fmt_enum {} NOP
320c_pass 2 fmt_enum {} {
321    global currentEnv
322    if {[IsOff]} {On ; return}
323    if {$currentEnv(pcount) == 0} {CloseParagraph $currentEnv(_first)}
324    if {$currentEnv(pcount) >  0} {CloseParagraph $currentEnv(_next)}
325    set  currentEnv(pcount) 0
326    return
327}
328
329c_pass 1 fmt_cmd_def  {command} NOP
330c_pass 2 fmt_cmd_def  {command} {fmt_lst_item [fmt_cmd $command]}
331
332c_pass 1 fmt_arg_def {type name {mode {}}} NOP
333c_pass 2 fmt_arg_def {type name {mode {}}} {
334    set text "$type [fmt_arg $name]"
335    if {$mode != {}} {append text " ($mode)"}
336    fmt_lst_item $text
337    return
338}
339
340c_pass 1 fmt_opt_def {name {arg {}}} NOP
341c_pass 2 fmt_opt_def {name {arg {}}} {
342    set text [fmt_option $name]
343    if {$arg != {}} {append text " $arg"}
344    fmt_lst_item $text
345    return
346}
347
348c_pass 1 fmt_tkoption_def {name dbname dbclass} NOP
349c_pass 2 fmt_tkoption_def {name dbname dbclass} {
350    set    text ""
351    append text "Command-Line Switch:\t[fmt_option $name]\n"
352    append text "Database Name:\t[strong $dbname]\n"
353    append text "Database Class:\t[strong $dbclass]\n"
354    fmt_lst_item $text
355}
356
357################################################################
358
359c_pass 1 fmt_example_begin {} NOP
360c_pass 2 fmt_example_begin {} {
361    global currentEnv para
362    if {[info exists currentEnv(_definition)]} {
363	CloseParagraph $currentEnv(_definition)
364    } elseif {[info exists currentEnv(pcount)]} {
365	if {$para != {}} {
366	    if {$currentEnv(pcount) == 0} {CloseParagraph $currentEnv(_first)}
367	    if {$currentEnv(pcount) >  0} {CloseParagraph $currentEnv(_next)}
368	    incr currentEnv(pcount)
369	}
370    } else {
371	CloseParagraph
372    }
373    return
374}
375
376c_pass 1 fmt_example_end {} NOP
377c_pass 2 fmt_example_end {} {
378    global currentEnv para
379    set penv {}
380    if {[info exists currentEnv(_definition)]} {
381	set penv $currentEnv(_definition)
382    } elseif {[info exists currentEnv(pcount)]} {
383	if {$currentEnv(pcount) == 0} {set penv $currentEnv(_first)}
384	if {$currentEnv(pcount) >  0} {set penv $currentEnv(_next)}
385	incr currentEnv(pcount)
386    }
387    if {$penv != {}} {
388	# Save current list context, get chosen paragraph context and
389	# then create an example context form this. After closing the
390	# paragraph we get back our main list context.
391
392	SaveContext
393	SetContext $penv
394	CloseParagraph [Example]
395	RestoreContext
396    } else {
397	CloseParagraph [Example]
398    }
399    return
400}
401
402c_pass 1 fmt_example {code} NOP
403c_pass 2 fmt_example {code} {
404    fmt_example_begin
405    fmt_plain_text $code
406    fmt_example_end
407    return
408}
409
410c_pass 1 fmt_nl {} NOP
411c_pass 2 fmt_nl {} {
412    global currentEnv
413    if {[info exists currentEnv(_definition)]} {
414	CloseParagraph $currentEnv(_definition)
415    } else {
416	if {$currentEnv(pcount) == 0} {CloseParagraph $currentEnv(_first)}
417	if {$currentEnv(pcount) >  0} {CloseParagraph $currentEnv(_next)}
418	incr currentEnv(pcount)
419    }
420    return
421}
422
423################################################################
424# Visual markup of words and phrases.
425
426proc fmt_arg     {text} {return $text}
427proc fmt_cmd     {text} {return $text}
428proc fmt_emph	 {text} {em     $text }
429proc fmt_opt     {text} {return "?$text?" }
430proc fmt_comment {text} {return}
431proc fmt_sectref {text {label {}}} {
432    if {![string length $label]} {set label $text}
433    return "-> $text"
434}
435proc fmt_syscmd  {text} {strong $text}
436proc fmt_method  {text} {return $text}
437proc fmt_option  {text} {return $text}
438proc fmt_widget  {text} {strong $text}
439proc fmt_fun     {text} {strong $text}
440proc fmt_type    {text} {strong $text}
441proc fmt_package {text} {strong $text}
442proc fmt_class   {text} {strong $text}
443proc fmt_var     {text} {strong $text}
444proc fmt_file    {text} {return "\"$text\""}
445proc fmt_namespace     {text} {strong $text}
446proc fmt_uri     {text {label {}}} {
447    if {$label == {}} {
448	# Without label we use the link directly as part of the text.
449	return "<URL:$text>"
450    } else {
451	return "[em $label] <URL:$text>"
452    }
453}
454proc fmt_image {text {label {}}} {
455    # text = symbolic name of the image.
456
457    set img [dt_imgdata $text {txt}]
458    if {$img eq {}} {
459	if {$label eq {}} {
460	    return "IMAGE: $text"
461	} else {
462	    return "IMAGE: $text $label"
463	}
464    }
465
466    return $img
467}
468proc fmt_term    {text} {em     $text}
469proc fmt_const   {text} {strong $text}
470proc fmt_mdash {} { return " --- " }
471proc fmt_ndash {} { return " -- " }
472
473################################################################
474