os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/tools/man2html2.tcl
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
# man2html2.tcl --
sl@0
     2
#
sl@0
     3
# This file defines procedures that are used during the second pass of the
sl@0
     4
# man page to html conversion process. It is sourced by man2html.tcl.
sl@0
     5
#
sl@0
     6
# Copyright (c) 1996 by Sun Microsystems, Inc.
sl@0
     7
#
sl@0
     8
# SCCS: @(#) man2html2.tcl 1.2 96/03/21 10:48:30
sl@0
     9
#
sl@0
    10
sl@0
    11
# Global variables used by these scripts:
sl@0
    12
#
sl@0
    13
# NAME_file -	array indexed by NAME and containing file names used
sl@0
    14
#		for hyperlinks.
sl@0
    15
#
sl@0
    16
# textState -	state variable defining action of 'text' proc.
sl@0
    17
#
sl@0
    18
# nestStk -	stack oriented list containing currently active
sl@0
    19
#		HTML tags (UL, OL, DL). Local to 'nest' proc.
sl@0
    20
#
sl@0
    21
# inDT -	set by 'TPmacro', cleared by 'newline'. Used to insert
sl@0
    22
#		the <DT> tag while in a dictionary list <DL>.
sl@0
    23
#
sl@0
    24
# curFont -	Name of special font that is currently in
sl@0
    25
#		use.  Null means the default paragraph font
sl@0
    26
#		is being used.
sl@0
    27
#
sl@0
    28
# file -	Where to output the generated HTML.
sl@0
    29
#
sl@0
    30
# fontStart -	Array to map font names to starting sequences.
sl@0
    31
#
sl@0
    32
# fontEnd -	Array to map font names to ending sequences.
sl@0
    33
#
sl@0
    34
# noFillCount -	Non-zero means don't fill the next $noFillCount
sl@0
    35
#		lines: force a line break at each newline.  Zero
sl@0
    36
#		means filling is enabled, so don't output line
sl@0
    37
#		breaks for each newline.
sl@0
    38
#
sl@0
    39
# footer -	info inserted at bottom of each page. Normally read
sl@0
    40
#		from the xref.tcl file
sl@0
    41
	
sl@0
    42
# initGlobals --
sl@0
    43
#
sl@0
    44
# This procedure is invoked to set the initial values of all of the
sl@0
    45
# global variables, before processing a man page.
sl@0
    46
#
sl@0
    47
# Arguments:
sl@0
    48
# None.
sl@0
    49
sl@0
    50
proc initGlobals {} {
sl@0
    51
    global file noFillCount textState
sl@0
    52
    global fontStart fontEnd curFont inPRE charCnt
sl@0
    53
sl@0
    54
    nest init
sl@0
    55
    set inPRE 0
sl@0
    56
    set textState 0
sl@0
    57
    set curFont ""
sl@0
    58
    set fontStart(Code) "<B>"
sl@0
    59
    set fontStart(Emphasis) "<I>"
sl@0
    60
    set fontEnd(Code) "</B>"
sl@0
    61
    set fontEnd(Emphasis) "</I>"
sl@0
    62
    set noFillCount 0
sl@0
    63
    set charCnt 0
sl@0
    64
    setTabs 0.5i
sl@0
    65
}
sl@0
    66
sl@0
    67
sl@0
    68
# beginFont --
sl@0
    69
#
sl@0
    70
# Arranges for future text to use a special font, rather than
sl@0
    71
# the default paragraph font.
sl@0
    72
#
sl@0
    73
# Arguments:
sl@0
    74
# font -		Name of new font to use.
sl@0
    75
sl@0
    76
proc beginFont font {
sl@0
    77
    global curFont file fontStart
sl@0
    78
sl@0
    79
    if {$curFont == $font} {
sl@0
    80
	return
sl@0
    81
    }
sl@0
    82
    endFont
sl@0
    83
    puts -nonewline $file $fontStart($font)
sl@0
    84
    set curFont $font
sl@0
    85
}
sl@0
    86
sl@0
    87
sl@0
    88
# endFont --
sl@0
    89
#
sl@0
    90
# Reverts to the default font for the paragraph type.
sl@0
    91
#
sl@0
    92
# Arguments:
sl@0
    93
# None.
sl@0
    94
sl@0
    95
proc endFont {} {
sl@0
    96
    global curFont file fontEnd
sl@0
    97
sl@0
    98
    if {$curFont != ""} {
sl@0
    99
    puts -nonewline $file $fontEnd($curFont)
sl@0
   100
    set curFont ""
sl@0
   101
    }
sl@0
   102
}
sl@0
   103
sl@0
   104
sl@0
   105
sl@0
   106
# text --
sl@0
   107
#
sl@0
   108
# This procedure adds text to the current paragraph.  If this is
sl@0
   109
# the first text in the paragraph then header information for the
sl@0
   110
# paragraph is output before the text.
sl@0
   111
#
sl@0
   112
# Arguments:
sl@0
   113
# string -		Text to output in the paragraph.
sl@0
   114
sl@0
   115
proc text string {
sl@0
   116
    global file textState inDT charCnt
sl@0
   117
sl@0
   118
    set pos [string first "\t" $string]
sl@0
   119
    if {$pos >= 0} {
sl@0
   120
    	text [string range $string 0 [expr $pos-1]]
sl@0
   121
    	tab
sl@0
   122
    	text [string range $string [expr $pos+1] end]
sl@0
   123
	return    	
sl@0
   124
    }
sl@0
   125
    incr charCnt [string length $string]
sl@0
   126
    regsub -all {&} $string {\&amp;}  string
sl@0
   127
    regsub -all {<} $string {\&lt;}  string
sl@0
   128
    regsub -all {>} $string {\&gt;}  string
sl@0
   129
    regsub -all {"} $string {\&quot;}  string
sl@0
   130
    switch $textState {
sl@0
   131
	REF { 
sl@0
   132
	    if {$inDT == {}} {
sl@0
   133
		set string [insertRef $string]
sl@0
   134
	    }
sl@0
   135
	}
sl@0
   136
	SEE { 
sl@0
   137
	    global NAME_file
sl@0
   138
	    foreach i [split $string] {
sl@0
   139
		if ![regexp -nocase {^[a-z_]+} [string trim $i] i ] {
sl@0
   140
# 		    puts "Warning: $i in SEE ALSO not found"
sl@0
   141
		    continue
sl@0
   142
		}
sl@0
   143
		if ![catch {set ref $NAME_file($i)} ] {
sl@0
   144
		    regsub $i $string "<A HREF=\"$ref.html\">$i</A>" string
sl@0
   145
		}
sl@0
   146
	    }
sl@0
   147
	}
sl@0
   148
    }
sl@0
   149
    puts -nonewline $file "$string"
sl@0
   150
}
sl@0
   151
sl@0
   152
sl@0
   153
sl@0
   154
# insertRef --
sl@0
   155
#
sl@0
   156
#
sl@0
   157
# Arguments:
sl@0
   158
# string -		Text to output in the paragraph.
sl@0
   159
sl@0
   160
proc insertRef string {
sl@0
   161
    global NAME_file self
sl@0
   162
    set path {}
sl@0
   163
    if ![catch {set ref $NAME_file([string trim $string])} ] {
sl@0
   164
	if {"$ref.html" != $self} {
sl@0
   165
	    set string "<A HREF=\"${path}$ref.html\">$string</A>"
sl@0
   166
#	    puts "insertRef: $self $ref.html ---$string--"
sl@0
   167
	}
sl@0
   168
    }
sl@0
   169
    return $string
sl@0
   170
}
sl@0
   171
sl@0
   172
sl@0
   173
sl@0
   174
# macro --
sl@0
   175
#
sl@0
   176
# This procedure is invoked to process macro invocations that start
sl@0
   177
# with "." (instead of ').
sl@0
   178
#
sl@0
   179
# Arguments:
sl@0
   180
# name -		The name of the macro (without the ".").
sl@0
   181
# args -		Any additional arguments to the macro.
sl@0
   182
sl@0
   183
proc macro {name args} {
sl@0
   184
    switch $name {
sl@0
   185
	AP {
sl@0
   186
	    if {[llength $args] != 3} {
sl@0
   187
		puts stderr "Bad .AP macro: .$name [join $args " "]"
sl@0
   188
	    }
sl@0
   189
	    setTabs {1.25i 2.5i 3.75i}
sl@0
   190
	    TPmacro {}
sl@0
   191
	    font B
sl@0
   192
	    text "[lindex $args 0]  "
sl@0
   193
	    font I
sl@0
   194
	    text "[lindex $args 1]"
sl@0
   195
	    font R
sl@0
   196
	    text " ([lindex $args 2])"
sl@0
   197
	    newline
sl@0
   198
	}
sl@0
   199
	AS {}				;# next page and previous page
sl@0
   200
	br {
sl@0
   201
	    lineBreak	
sl@0
   202
	}
sl@0
   203
	BS {}
sl@0
   204
	BE {}
sl@0
   205
	CE {
sl@0
   206
	    global file noFillCount inPRE
sl@0
   207
	    puts $file </PRE></BLOCKQUOTE>
sl@0
   208
	    set inPRE 0
sl@0
   209
	}
sl@0
   210
	CS {				;# code section
sl@0
   211
	    global file noFillCount inPRE
sl@0
   212
	    puts -nonewline $file <BLOCKQUOTE><PRE>
sl@0
   213
	    set inPRE 1
sl@0
   214
	}
sl@0
   215
	DE {
sl@0
   216
	    global file noFillCount inPRE
sl@0
   217
	    puts $file </PRE></BLOCKQUOTE>
sl@0
   218
	    set inPRE 0
sl@0
   219
	    set noFillCount 0
sl@0
   220
	}
sl@0
   221
	DS {
sl@0
   222
	    global file noFillCount inPRE
sl@0
   223
	    puts -nonewline $file <BLOCKQUOTE><PRE>
sl@0
   224
	    set noFillCount 10000000
sl@0
   225
	    set inPRE 1
sl@0
   226
	}
sl@0
   227
	fi {
sl@0
   228
	    global noFillCount
sl@0
   229
	    set noFillCount 0
sl@0
   230
	}
sl@0
   231
	IP {
sl@0
   232
	    IPmacro $args
sl@0
   233
	}
sl@0
   234
	LP {
sl@0
   235
	    nest decr
sl@0
   236
	    nest incr
sl@0
   237
	    newPara
sl@0
   238
	}
sl@0
   239
	ne {
sl@0
   240
	}
sl@0
   241
	nf {
sl@0
   242
	    global noFillCount
sl@0
   243
	    set noFillCount 1000000
sl@0
   244
	}
sl@0
   245
	OP {
sl@0
   246
	    global inDT file inPRE 
sl@0
   247
	    if {[llength $args] != 3} {
sl@0
   248
		puts stderr "Bad .OP macro: .$name [join $args " "]"
sl@0
   249
	    }
sl@0
   250
	    nest para DL DT
sl@0
   251
	    set inPRE 1
sl@0
   252
	    puts -nonewline $file <PRE>				
sl@0
   253
	    setTabs 4c
sl@0
   254
	    text "Command-Line Name:"
sl@0
   255
	    tab
sl@0
   256
	    font B
sl@0
   257
	    set x [lindex $args 0]
sl@0
   258
	    regsub -all {\\-} $x - x
sl@0
   259
	    text $x
sl@0
   260
	    newline
sl@0
   261
	    font R
sl@0
   262
	    text "Database Name:"
sl@0
   263
	    tab
sl@0
   264
	    font B
sl@0
   265
	    text [lindex $args 1]
sl@0
   266
	    newline
sl@0
   267
	    font R
sl@0
   268
	    text "Database Class:"
sl@0
   269
	    tab
sl@0
   270
	    font B
sl@0
   271
	    text [lindex $args 2]
sl@0
   272
	    font R
sl@0
   273
	    puts -nonewline $file </PRE>				
sl@0
   274
	    set inDT "\n<DD>"			;# next newline writes inDT 
sl@0
   275
	    set inPRE 0
sl@0
   276
	    newline
sl@0
   277
	}
sl@0
   278
	PP {
sl@0
   279
	    nest decr
sl@0
   280
	    nest incr
sl@0
   281
	    newPara
sl@0
   282
	}
sl@0
   283
	RE {
sl@0
   284
	    nest decr    
sl@0
   285
	}
sl@0
   286
	RS {
sl@0
   287
	    nest incr
sl@0
   288
	}
sl@0
   289
	SE {
sl@0
   290
	    global noFillCount textState inPRE file
sl@0
   291
sl@0
   292
	    font R
sl@0
   293
	    puts -nonewline $file </PRE>
sl@0
   294
	    set inPRE 0
sl@0
   295
	    set noFillCount 0
sl@0
   296
	    nest reset
sl@0
   297
	    newPara
sl@0
   298
	    text "See the "
sl@0
   299
	    font B
sl@0
   300
	    set temp $textState
sl@0
   301
	    set textState REF
sl@0
   302
	    text options
sl@0
   303
	    set textState $temp
sl@0
   304
	    font R
sl@0
   305
	    text " manual entry for detailed descriptions of the above options."
sl@0
   306
	}
sl@0
   307
	SH {
sl@0
   308
	    SHmacro $args
sl@0
   309
	}
sl@0
   310
	SO {
sl@0
   311
	    global noFillCount inPRE file
sl@0
   312
sl@0
   313
	    SHmacro "STANDARD OPTIONS"
sl@0
   314
	    setTabs {4c 8c 12c}
sl@0
   315
	    set noFillCount 1000000
sl@0
   316
	    puts -nonewline $file <PRE>
sl@0
   317
	    set inPRE 1
sl@0
   318
	    font B
sl@0
   319
	}
sl@0
   320
	so {
sl@0
   321
	    if {$args != "man.macros"} {
sl@0
   322
		puts stderr "Unknown macro: .$name [join $args " "]"
sl@0
   323
	    }
sl@0
   324
	}
sl@0
   325
	sp {					;# needs work
sl@0
   326
	    if {$args == ""} {
sl@0
   327
		set count 1
sl@0
   328
	    } else {
sl@0
   329
		set count [lindex $args 0]
sl@0
   330
	    }
sl@0
   331
	    while {$count > 0} {
sl@0
   332
		lineBreak
sl@0
   333
		incr count -1
sl@0
   334
	    }
sl@0
   335
	}
sl@0
   336
	ta {
sl@0
   337
	    setTabs $args
sl@0
   338
	}
sl@0
   339
	TH {
sl@0
   340
	    THmacro $args
sl@0
   341
	}
sl@0
   342
	TP {
sl@0
   343
	    TPmacro $args
sl@0
   344
	}
sl@0
   345
	UL {					;# underline
sl@0
   346
	    global file
sl@0
   347
	    puts -nonewline $file "<B><U>"
sl@0
   348
	    text [lindex $args 0]
sl@0
   349
	    puts -nonewline $file "</U></B>"
sl@0
   350
	    if {[llength $args] == 2} {
sl@0
   351
		text [lindex $args 1]
sl@0
   352
	    }
sl@0
   353
	}
sl@0
   354
	VE {
sl@0
   355
#	    global file
sl@0
   356
#	    puts -nonewline $file "</FONT>"
sl@0
   357
	}
sl@0
   358
	VS {
sl@0
   359
#	    global file
sl@0
   360
#	    if {[llength $args] > 0} {
sl@0
   361
#		puts -nonewline $file "<BR>"
sl@0
   362
#	    }
sl@0
   363
#	    puts -nonewline $file "<FONT COLOR=\"GREEN\">"
sl@0
   364
	}
sl@0
   365
	default {
sl@0
   366
	    puts stderr "Unknown macro: .$name [join $args " "]"
sl@0
   367
	}
sl@0
   368
    }
sl@0
   369
sl@0
   370
#	global nestStk; puts "$name [format "%-20s" $args] $nestStk"
sl@0
   371
#	flush stdout; flush stderr
sl@0
   372
}
sl@0
   373
sl@0
   374
sl@0
   375
# font --
sl@0
   376
#
sl@0
   377
# This procedure is invoked to handle font changes in the text
sl@0
   378
# being output.
sl@0
   379
#
sl@0
   380
# Arguments:
sl@0
   381
# type -		Type of font: R, I, B, or S.
sl@0
   382
sl@0
   383
proc font type {
sl@0
   384
    global textState
sl@0
   385
    switch $type {
sl@0
   386
	P -
sl@0
   387
	R {
sl@0
   388
	    endFont
sl@0
   389
	    if {$textState == "REF"} {
sl@0
   390
		set textState INSERT
sl@0
   391
	    }
sl@0
   392
	}
sl@0
   393
	B {
sl@0
   394
	    beginFont Code
sl@0
   395
	    if {$textState == "INSERT"} {
sl@0
   396
		set textState REF
sl@0
   397
	    }
sl@0
   398
	}
sl@0
   399
	I {
sl@0
   400
	    beginFont Emphasis
sl@0
   401
	}
sl@0
   402
	S {
sl@0
   403
	}
sl@0
   404
	default {
sl@0
   405
	    puts stderr "Unknown font: $type"
sl@0
   406
	}
sl@0
   407
    }
sl@0
   408
}
sl@0
   409
sl@0
   410
sl@0
   411
sl@0
   412
# formattedText --
sl@0
   413
#
sl@0
   414
# Insert a text string that may also have \fB-style font changes
sl@0
   415
# and a few other backslash sequences in it.
sl@0
   416
#
sl@0
   417
# Arguments:
sl@0
   418
# text -		Text to insert.
sl@0
   419
sl@0
   420
proc formattedText text {
sl@0
   421
#	puts "formattedText: $text"
sl@0
   422
    while {$text != ""} {
sl@0
   423
	set index [string first \\ $text]
sl@0
   424
	if {$index < 0} {
sl@0
   425
	    text $text
sl@0
   426
	    return
sl@0
   427
	}
sl@0
   428
	text [string range $text 0 [expr $index-1]]
sl@0
   429
	set c [string index $text [expr $index+1]]
sl@0
   430
	switch -- $c {
sl@0
   431
	    f {
sl@0
   432
		font [string index $text [expr $index+2]]
sl@0
   433
		set text [string range $text [expr $index+3] end]
sl@0
   434
	    }
sl@0
   435
	    e {
sl@0
   436
		text \\
sl@0
   437
		set text [string range $text [expr $index+2] end]
sl@0
   438
	    }
sl@0
   439
	    - {
sl@0
   440
		dash
sl@0
   441
		set text [string range $text [expr $index+2] end]
sl@0
   442
	    }
sl@0
   443
	    | {
sl@0
   444
		set text [string range $text [expr $index+2] end]
sl@0
   445
	    }
sl@0
   446
	    default {
sl@0
   447
		puts stderr "Unknown sequence: \\$c"
sl@0
   448
		set text [string range $text [expr $index+2] end]
sl@0
   449
	    }
sl@0
   450
	}
sl@0
   451
    }
sl@0
   452
}
sl@0
   453
sl@0
   454
sl@0
   455
sl@0
   456
# dash --
sl@0
   457
#
sl@0
   458
# This procedure is invoked to handle dash characters ("\-" in
sl@0
   459
# troff).  It outputs a special dash character.
sl@0
   460
#
sl@0
   461
# Arguments:
sl@0
   462
# None.
sl@0
   463
sl@0
   464
proc dash {} {
sl@0
   465
    global textState charCnt
sl@0
   466
    if {$textState == "NAME"} {
sl@0
   467
    	set textState 0
sl@0
   468
    }
sl@0
   469
    incr charCnt
sl@0
   470
    text "-"
sl@0
   471
}
sl@0
   472
sl@0
   473
sl@0
   474
# tab --
sl@0
   475
#
sl@0
   476
# This procedure is invoked to handle tabs in the troff input.
sl@0
   477
# Right now it does nothing.
sl@0
   478
#
sl@0
   479
# Arguments:
sl@0
   480
# None.
sl@0
   481
sl@0
   482
proc tab {} {
sl@0
   483
    global inPRE charCnt tabString
sl@0
   484
#	? charCnt
sl@0
   485
    if {$inPRE == 1} {
sl@0
   486
	set pos [expr $charCnt % [string length $tabString] ]
sl@0
   487
	set spaces [string first "1" [string range $tabString $pos end] ]
sl@0
   488
	text [format "%*s" [incr spaces] " "]
sl@0
   489
    } else {
sl@0
   490
#	puts "tab: found tab outside of <PRE> block"
sl@0
   491
    }
sl@0
   492
}
sl@0
   493
sl@0
   494
sl@0
   495
# setTabs --
sl@0
   496
#
sl@0
   497
# This procedure handles the ".ta" macro, which sets tab stops.
sl@0
   498
#
sl@0
   499
# Arguments:
sl@0
   500
# tabList -	List of tab stops, each consisting of a number
sl@0
   501
#			followed by "i" (inch) or "c" (cm).
sl@0
   502
sl@0
   503
proc setTabs {tabList} {
sl@0
   504
    global file breakPending tabString
sl@0
   505
sl@0
   506
#	puts "setTabs: --$tabList--"
sl@0
   507
    set last 0
sl@0
   508
    set tabString {}
sl@0
   509
    set charsPerInch 14.
sl@0
   510
    set numTabs [llength $tabList]
sl@0
   511
    foreach arg $tabList {
sl@0
   512
	if {[scan $arg "%f%s" distance units] != 2} {
sl@0
   513
	    puts stderr "bad distance \"$arg\""
sl@0
   514
	    return 0
sl@0
   515
    	}
sl@0
   516
	switch -- $units {
sl@0
   517
	    c	{
sl@0
   518
		set distance [expr $distance * $charsPerInch / 2.54 ]
sl@0
   519
	    }
sl@0
   520
	    i	{
sl@0
   521
		set distance [expr $distance * $charsPerInch]
sl@0
   522
	    }
sl@0
   523
	    default {
sl@0
   524
		puts stderr "bad units in distance \"$arg\""
sl@0
   525
		continue
sl@0
   526
	    }
sl@0
   527
    	}
sl@0
   528
#		? distance
sl@0
   529
    	lappend tabString [format "%*s1" [expr round($distance-$last-1)] " "]
sl@0
   530
    	set last $distance
sl@0
   531
    }
sl@0
   532
    set tabString [join $tabString {}]
sl@0
   533
#	puts "setTabs: --$tabString--"
sl@0
   534
}
sl@0
   535
sl@0
   536
sl@0
   537
sl@0
   538
# lineBreak --
sl@0
   539
#
sl@0
   540
# Generates a line break in the HTML output.
sl@0
   541
#
sl@0
   542
# Arguments:
sl@0
   543
# None.
sl@0
   544
sl@0
   545
proc lineBreak {} {
sl@0
   546
    global file inPRE
sl@0
   547
    puts $file "<BR>"
sl@0
   548
}
sl@0
   549
sl@0
   550
sl@0
   551
sl@0
   552
# newline --
sl@0
   553
#
sl@0
   554
# This procedure is invoked to handle newlines in the troff input.
sl@0
   555
# It outputs either a space character or a newline character, depending
sl@0
   556
# on fill mode.
sl@0
   557
#
sl@0
   558
# Arguments:
sl@0
   559
# None.
sl@0
   560
sl@0
   561
proc newline {} {
sl@0
   562
    global noFillCount file inDT inPRE charCnt
sl@0
   563
sl@0
   564
    if {$inDT != {} } {
sl@0
   565
    	puts $file "\n$inDT"
sl@0
   566
    	set inDT {}
sl@0
   567
    } elseif {$noFillCount == 0 || $inPRE == 1} {
sl@0
   568
	puts $file {}
sl@0
   569
    } else {
sl@0
   570
	lineBreak
sl@0
   571
	incr noFillCount -1
sl@0
   572
    }
sl@0
   573
    set charCnt 0
sl@0
   574
}
sl@0
   575
sl@0
   576
sl@0
   577
sl@0
   578
# char --
sl@0
   579
#
sl@0
   580
# This procedure is called to handle a special character.
sl@0
   581
#
sl@0
   582
# Arguments:
sl@0
   583
# name -		Special character named in troff \x or \(xx construct.
sl@0
   584
sl@0
   585
proc char name {
sl@0
   586
    global file charCnt
sl@0
   587
sl@0
   588
    incr charCnt
sl@0
   589
#	puts "char: $name"
sl@0
   590
    switch -exact $name {
sl@0
   591
	\\0 {					;#  \0
sl@0
   592
	    puts -nonewline $file " "
sl@0
   593
	}
sl@0
   594
	\\\\ {					;#  \
sl@0
   595
	    puts -nonewline $file "\\"
sl@0
   596
	}
sl@0
   597
	\\(+- { 				;#  +/-
sl@0
   598
	    puts -nonewline $file "&#177;"
sl@0
   599
	}
sl@0
   600
	\\% {}					;#  \%
sl@0
   601
	\\| {					;#  \|
sl@0
   602
	}
sl@0
   603
	default {
sl@0
   604
	    puts stderr "Unknown character: $name"
sl@0
   605
	}
sl@0
   606
    }
sl@0
   607
}
sl@0
   608
sl@0
   609
sl@0
   610
# macro2 --
sl@0
   611
#
sl@0
   612
# This procedure handles macros that are invoked with a leading "'"
sl@0
   613
# character instead of space.  Right now it just generates an
sl@0
   614
# error diagnostic.
sl@0
   615
#
sl@0
   616
# Arguments:
sl@0
   617
# name -		The name of the macro (without the ".").
sl@0
   618
# args -		Any additional arguments to the macro.
sl@0
   619
sl@0
   620
proc macro2 {name args} {
sl@0
   621
    puts stderr "Unknown macro: '$name [join $args " "]"
sl@0
   622
}
sl@0
   623
sl@0
   624
sl@0
   625
sl@0
   626
# SHmacro --
sl@0
   627
#
sl@0
   628
# Subsection head; handles the .SH macro.
sl@0
   629
#
sl@0
   630
# Arguments:
sl@0
   631
# name -		Section name.
sl@0
   632
sl@0
   633
proc SHmacro argList {
sl@0
   634
    global file noFillCount textState charCnt
sl@0
   635
sl@0
   636
    set args [join $argList " "]
sl@0
   637
    if {[llength $argList] < 1} {
sl@0
   638
	puts stderr "Bad .SH macro: .$name $args"
sl@0
   639
    }
sl@0
   640
sl@0
   641
    set noFillCount 0
sl@0
   642
    nest reset
sl@0
   643
sl@0
   644
    puts -nonewline $file "<H3>"
sl@0
   645
    text $args
sl@0
   646
    puts $file "</H3>"
sl@0
   647
sl@0
   648
#	? args textState
sl@0
   649
sl@0
   650
    # control what the text proc does with text
sl@0
   651
    
sl@0
   652
    switch $args {
sl@0
   653
	NAME {set textState NAME}
sl@0
   654
	DESCRIPTION {set textState INSERT}
sl@0
   655
	INTRODUCTION {set textState INSERT}
sl@0
   656
	"WIDGET-SPECIFIC OPTIONS" {set textState INSERT}
sl@0
   657
	"SEE ALSO" {set textState SEE}
sl@0
   658
	KEYWORDS {set textState 0}
sl@0
   659
    }
sl@0
   660
    set charCnt 0
sl@0
   661
}
sl@0
   662
sl@0
   663
sl@0
   664
sl@0
   665
# IPmacro --
sl@0
   666
#
sl@0
   667
# This procedure is invoked to handle ".IP" macros, which may take any
sl@0
   668
# of the following forms:
sl@0
   669
#
sl@0
   670
# .IP [1]			Translate to a "1Step" paragraph.
sl@0
   671
# .IP [x] (x > 1)	Translate to a "Step" paragraph.
sl@0
   672
# .IP				Translate to a "Bullet" paragraph.
sl@0
   673
# .IP text count	Translate to a FirstBody paragraph with special
sl@0
   674
#					indent and tab stop based on "count", and tab after
sl@0
   675
#					"text".
sl@0
   676
#
sl@0
   677
# Arguments:
sl@0
   678
# argList -		List of arguments to the .IP macro.
sl@0
   679
#
sl@0
   680
# HTML limitations: 'count' in '.IP text count' is ignored.
sl@0
   681
sl@0
   682
proc IPmacro argList {
sl@0
   683
    global file
sl@0
   684
sl@0
   685
    setTabs 0.5i
sl@0
   686
    set length [llength $argList]
sl@0
   687
    if {$length == 0} {
sl@0
   688
    	nest para UL LI
sl@0
   689
	return
sl@0
   690
    }
sl@0
   691
    if {$length == 1} {
sl@0
   692
    	nest para OL LI
sl@0
   693
	    return
sl@0
   694
	}
sl@0
   695
    if {$length > 1} {
sl@0
   696
    	nest para DL DT
sl@0
   697
	    formattedText [lindex $argList 0]
sl@0
   698
	    puts $file "\n<DD>"
sl@0
   699
	    return
sl@0
   700
    }
sl@0
   701
    puts stderr "Bad .IP macro: .IP [join $argList " "]"
sl@0
   702
}
sl@0
   703
sl@0
   704
sl@0
   705
# TPmacro --
sl@0
   706
#
sl@0
   707
# This procedure is invoked to handle ".TP" macros, which may take any
sl@0
   708
# of the following forms:
sl@0
   709
#
sl@0
   710
# .TP x		Translate to an indented paragraph with the
sl@0
   711
# 			specified indent (in 100 twip units).
sl@0
   712
# .TP		Translate to an indented paragraph with
sl@0
   713
# 			default indent.
sl@0
   714
#
sl@0
   715
# Arguments:
sl@0
   716
# argList -		List of arguments to the .IP macro.
sl@0
   717
#
sl@0
   718
# HTML limitations: 'x' in '.TP x' is ignored.
sl@0
   719
sl@0
   720
sl@0
   721
proc TPmacro {argList} {
sl@0
   722
    global inDT
sl@0
   723
    nest para DL DT
sl@0
   724
    set inDT "\n<DD>"			;# next newline writes inDT 
sl@0
   725
    setTabs 0.5i
sl@0
   726
}
sl@0
   727
sl@0
   728
sl@0
   729
sl@0
   730
# THmacro --
sl@0
   731
#
sl@0
   732
# This procedure handles the .TH macro.  It generates the non-scrolling
sl@0
   733
# header section for a given man page, and enters information into the
sl@0
   734
# table of contents.  The .TH macro has the following form:
sl@0
   735
#
sl@0
   736
# .TH name section date footer header
sl@0
   737
#
sl@0
   738
# Arguments:
sl@0
   739
# argList -		List of arguments to the .TH macro.
sl@0
   740
sl@0
   741
proc THmacro {argList} {
sl@0
   742
    global file
sl@0
   743
sl@0
   744
    if {[llength $argList] != 5} {
sl@0
   745
	set args [join $argList " "]
sl@0
   746
	puts stderr "Bad .TH macro: .$name $args"
sl@0
   747
    }
sl@0
   748
    set name  [lindex $argList 0]		;# Tcl_UpVar
sl@0
   749
    set page  [lindex $argList 1]		;# 3
sl@0
   750
    set vers  [lindex $argList 2]		;# 7.4
sl@0
   751
    set lib   [lindex $argList 3]		;# Tcl
sl@0
   752
    set pname [lindex $argList 4]		;# {Tcl Library Procedures}
sl@0
   753
sl@0
   754
    puts -nonewline $file "<HTML><HEAD><TITLE>"
sl@0
   755
    text "$lib - $name ($page)"
sl@0
   756
    puts $file "</TITLE></HEAD><BODY>\n"
sl@0
   757
    
sl@0
   758
    puts -nonewline $file "<H1><CENTER>"
sl@0
   759
    text $pname
sl@0
   760
    puts $file "</CENTER></H1>\n"
sl@0
   761
}
sl@0
   762
sl@0
   763
sl@0
   764
sl@0
   765
# newPara --
sl@0
   766
#
sl@0
   767
# This procedure sets the left and hanging indents for a line.
sl@0
   768
# Indents are specified in units of inches or centimeters, and are
sl@0
   769
# relative to the current nesting level and left margin.
sl@0
   770
#
sl@0
   771
# Arguments:
sl@0
   772
# None
sl@0
   773
sl@0
   774
proc newPara {} {
sl@0
   775
    global file nestStk
sl@0
   776
	
sl@0
   777
    if {[lindex $nestStk end] != "NEW" } {
sl@0
   778
	nest decr    
sl@0
   779
    }
sl@0
   780
    puts -nonewline $file "<P>"
sl@0
   781
}
sl@0
   782
sl@0
   783
sl@0
   784
sl@0
   785
# nest --
sl@0
   786
#
sl@0
   787
# This procedure takes care of inserting the tags associated with the
sl@0
   788
# IP, TP, RS, RE, LP and PP macros. Only 'nest para' takes arguments.
sl@0
   789
#
sl@0
   790
# Arguments:
sl@0
   791
# op -				operation: para, incr, decr, reset, init
sl@0
   792
# listStart -		begin list tag: OL, UL, DL.
sl@0
   793
# listItem -		item tag:       LI, LI, DT.
sl@0
   794
sl@0
   795
proc nest {op {listStart "NEW"} {listItem {} } } {
sl@0
   796
    global file nestStk inDT charCnt
sl@0
   797
#	puts "nest: $op $listStart $listItem"
sl@0
   798
    switch $op {
sl@0
   799
	para {
sl@0
   800
	    set top [lindex $nestStk end]
sl@0
   801
	    if {$top == "NEW" } {
sl@0
   802
		set nestStk [lreplace $nestStk end end $listStart]
sl@0
   803
		puts $file "<$listStart>"
sl@0
   804
	    } elseif {$top != $listStart} {
sl@0
   805
		puts stderr "nest para: bad stack"
sl@0
   806
		exit 1
sl@0
   807
	    }
sl@0
   808
	    puts $file "\n<$listItem>"
sl@0
   809
	    set charCnt 0
sl@0
   810
	}
sl@0
   811
	incr {
sl@0
   812
	   lappend nestStk NEW
sl@0
   813
	}
sl@0
   814
	decr {
sl@0
   815
	    if {[llength $nestStk] == 0} {
sl@0
   816
		puts stderr "nest error: nest length is zero"
sl@0
   817
		set nestStk NEW
sl@0
   818
	    }
sl@0
   819
	    set tag [lindex $nestStk end]
sl@0
   820
	    if {$tag != "NEW"} {
sl@0
   821
		puts $file "</$tag>"
sl@0
   822
	    }
sl@0
   823
	    set nestStk [lreplace $nestStk end end]
sl@0
   824
	}
sl@0
   825
	reset {
sl@0
   826
	    while {[llength $nestStk] > 0} {
sl@0
   827
		nest decr
sl@0
   828
	    }
sl@0
   829
	    set nestStk NEW
sl@0
   830
	}
sl@0
   831
	init {
sl@0
   832
	    set nestStk NEW
sl@0
   833
	    set inDT {}
sl@0
   834
	}
sl@0
   835
    }
sl@0
   836
    set charCnt 0
sl@0
   837
}
sl@0
   838
sl@0
   839
sl@0
   840
sl@0
   841
# do --
sl@0
   842
#
sl@0
   843
# This is the toplevel procedure that translates a man page
sl@0
   844
# to Frame.  It runs the man2tcl program to turn the man page
sl@0
   845
# into a script, then it evals that script.
sl@0
   846
#
sl@0
   847
# Arguments:
sl@0
   848
# fileName -		Name of the file to translate.
sl@0
   849
sl@0
   850
proc do fileName {
sl@0
   851
    global file self html_dir package footer
sl@0
   852
    set self "[file tail $fileName].html"
sl@0
   853
    set file [open "$html_dir/$package/$self" w]
sl@0
   854
    puts "  Pass 2 -- $fileName"
sl@0
   855
    flush stdout
sl@0
   856
    initGlobals
sl@0
   857
    if [catch {eval [exec man2tcl [glob $fileName]]} msg] {
sl@0
   858
	global errorInfo
sl@0
   859
	puts stderr $msg
sl@0
   860
	puts "in"
sl@0
   861
	puts stderr $errorInfo
sl@0
   862
	exit 1
sl@0
   863
    }
sl@0
   864
    nest reset
sl@0
   865
    puts $file $footer
sl@0
   866
    puts $file "</BODY></HTML>"
sl@0
   867
    close $file
sl@0
   868
}
sl@0
   869
sl@0
   870
sl@0
   871