sl@0: #!/bin/sh
sl@0: # The next line is executed by /bin/sh, but not tcl \
sl@0: exec tclsh8.4 "$0" ${1+"$@"}
sl@0: 
sl@0: package require Tcl 8.4
sl@0: 
sl@0: # Convert Ousterhout format man pages into highly crosslinked
sl@0: # hypertext.
sl@0: #
sl@0: # Along the way detect many unmatched font changes and other odd
sl@0: # things.
sl@0: #
sl@0: # Note well, this program is a hack rather than a piece of software
sl@0: # engineering.  In that sense it's probably a good example of things
sl@0: # that a scripting language, like Tcl, can do well.  It is offered as
sl@0: # an example of how someone might convert a specific set of man pages
sl@0: # into hypertext, not as a general solution to the problem.  If you
sl@0: # try to use this, you'll be very much on your own.
sl@0: #
sl@0: # Copyright (c) 1995-1997 Roger E. Critchlow Jr
sl@0: #
sl@0: # The authors hereby grant permission to use, copy, modify, distribute,
sl@0: # and license this software and its documentation for any purpose, provided
sl@0: # that existing copyright notices are retained in all copies and that this
sl@0: # notice is included verbatim in any distributions. No written agreement,
sl@0: # license, or royalty fee is required for any of the authorized uses.
sl@0: # Modifications to this software may be copyrighted by their authors
sl@0: # and need not follow the licensing terms described here, provided that
sl@0: # the new terms are clearly indicated on the first page of each file where
sl@0: # they apply.
sl@0: # 
sl@0: # IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
sl@0: # FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
sl@0: # ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
sl@0: # DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
sl@0: # POSSIBILITY OF SUCH DAMAGE.
sl@0: # 
sl@0: # THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
sl@0: # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
sl@0: # FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
sl@0: # IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
sl@0: # NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
sl@0: # MODIFICATIONS.
sl@0: #
sl@0: # Revisions:
sl@0: #  May 15, 1995 - initial release
sl@0: #  May 16, 1995 - added a back to home link to toplevel table of
sl@0: #	contents.
sl@0: #  May 18, 1995 - broke toplevel table of contents into separate
sl@0: #	pages for each section, and broke long table of contents
sl@0: #	into a one page for each man page.
sl@0: #  Mar 10, 1996 - updated for tcl7.5b3/tk4.1b3
sl@0: #  Apr 14, 1996 - incorporated command line parsing from Tom Tromey,
sl@0: #		  <tromey@creche.cygnus.com> -- thanks Tom.
sl@0: #		- updated for tcl7.5/tk4.1 final release.
sl@0: #		- converted to same copyright as the man pages.
sl@0: #  Sep 14, 1996 - made various modifications for tcl7.6b1/tk4.2b1
sl@0: #  Oct 18, 1996 - added tcl7.6/tk4.2 to the list of distributions.
sl@0: #  Oct 22, 1996 - major hacking on indentation code and elsewhere.
sl@0: #  Mar  4, 1997 - 
sl@0: #  May 28, 1997 - added tcl8.0b1/tk8.0b1 to the list of distributions
sl@0: #		- cleaned source for tclsh8.0 execution
sl@0: #		- renamed output files for windoze installation
sl@0: #		- added spaces to tables
sl@0: #  Oct 24, 1997 - moved from 8.0b1 to 8.0 release
sl@0: #
sl@0: 
sl@0: set Version "0.32"
sl@0: 
sl@0: proc parse_command_line {} {
sl@0:     global argv Version
sl@0: 
sl@0:     # These variables determine where the man pages come from and where
sl@0:     # the converted pages go to.
sl@0:     global tcltkdir tkdir tcldir webdir build_tcl build_tk
sl@0: 
sl@0:     # Set defaults based on original code.
sl@0:     set tcltkdir ../..
sl@0:     set tkdir {}
sl@0:     set tcldir {}
sl@0:     set webdir ../html
sl@0:     set build_tcl 0
sl@0:     set build_tk 0
sl@0:     # Default search version is a glob pattern
sl@0:     set useversion {{,[8-9].[0-9]{,.[0-9]{,[0-9]}}}}
sl@0: 
sl@0:     # Handle arguments a la GNU:
sl@0:     #   --version
sl@0:     #   --useversion=<version>
sl@0:     #   --help
sl@0:     #   --srcdir=/path
sl@0:     #   --htmldir=/path
sl@0: 
sl@0:     foreach option $argv {
sl@0: 	switch -glob -- $option {
sl@0: 	    --version {
sl@0: 		puts "tcltk-man-html $Version"
sl@0: 		exit 0
sl@0: 	    }
sl@0: 
sl@0: 	    --help {
sl@0: 		puts "usage: tcltk-man-html \[OPTION\] ...\n"
sl@0: 		puts "  --help              print this help, then exit"
sl@0: 		puts "  --version           print version number, then exit"
sl@0: 		puts "  --srcdir=DIR        find tcl and tk source below DIR"
sl@0: 		puts "  --htmldir=DIR       put generated HTML in DIR"
sl@0: 		puts "  --tcl               build tcl help"
sl@0: 		puts "  --tk                build tk help"
sl@0: 		puts "  --useversion        version of tcl/tk to search for"
sl@0: 		exit 0
sl@0: 	    }
sl@0: 
sl@0: 	    --srcdir=* {
sl@0: 		# length of "--srcdir=" is 9.
sl@0: 		set tcltkdir [string range $option 9 end]
sl@0: 	    }
sl@0: 
sl@0: 	    --htmldir=* {
sl@0: 		# length of "--htmldir=" is 10
sl@0: 		set webdir [string range $option 10 end]
sl@0: 	    }
sl@0: 
sl@0: 	    --useversion=* {
sl@0: 		# length of "--useversion=" is 13
sl@0: 		set useversion [string range $option 13 end]
sl@0: 	    }
sl@0: 
sl@0: 	    --tcl {
sl@0: 		set build_tcl 1
sl@0: 	    }
sl@0: 
sl@0: 	    --tk {
sl@0: 		set build_tk 1
sl@0: 	    }
sl@0: 
sl@0: 	    default {
sl@0: 		puts stderr "tcltk-man-html: unrecognized option -- `$option'"
sl@0: 		exit 1
sl@0: 	    }
sl@0: 	}
sl@0:     }
sl@0: 
sl@0:     if {!$build_tcl && !$build_tk} {set build_tcl 1; set build_tk 1}
sl@0: 
sl@0:     if {$build_tcl} {
sl@0: 	# Find Tcl.
sl@0: 	set tcldir [lindex [lsort [glob -nocomplain -tails -type d \
sl@0: 				       -directory $tcltkdir tcl$useversion]] end]
sl@0: 	if {$tcldir == ""} then {
sl@0: 	    puts stderr "tcltk-man-html: couldn't find Tcl below $tcltkdir"
sl@0: 	    exit 1
sl@0: 	}
sl@0: 	puts "using Tcl source directory $tcldir"
sl@0:     }
sl@0: 
sl@0:     if {$build_tk} {
sl@0: 	# Find Tk.
sl@0: 	set tkdir [lindex [lsort [glob -nocomplain -tails -type d \
sl@0: 				      -directory $tcltkdir tk$useversion]] end]
sl@0: 	if {$tkdir == ""} then {
sl@0: 	    puts stderr "tcltk-man-html: couldn't find Tk below $tcltkdir"
sl@0: 	    exit 1
sl@0: 	}
sl@0: 	puts "using Tk source directory $tkdir"
sl@0:     }
sl@0: 
sl@0:     # the title for the man pages overall
sl@0:     global overall_title
sl@0:     set overall_title ""
sl@0:     if {$build_tcl} {append overall_title "[capitalize $tcldir]"}
sl@0:     if {$build_tcl && $build_tk} {append overall_title "/"}
sl@0:     if {$build_tk} {append overall_title "[capitalize $tkdir]"}
sl@0:     append overall_title " Manual"
sl@0: }
sl@0: 
sl@0: proc capitalize {string} {
sl@0:     return [string toupper $string 0]
sl@0: }
sl@0: 
sl@0: ##
sl@0: ##
sl@0: ##
sl@0: set manual(report-level) 1
sl@0: 
sl@0: proc manerror {msg} {
sl@0:     global manual
sl@0:     set name {}
sl@0:     set subj {}
sl@0:     if {[info exists manual(name)]} {
sl@0: 	set name $manual(name)
sl@0:     }
sl@0:     if {[info exists manual(section)] && [string length $manual(section)]} {
sl@0: 	puts stderr "$name: $manual(section):  $msg"
sl@0:     } else {
sl@0: 	puts stderr "$name: $msg"
sl@0:     }
sl@0: }
sl@0: 
sl@0: proc manreport {level msg} {
sl@0:     global manual
sl@0:     if {$level < $manual(report-level)} {
sl@0: 	manerror $msg
sl@0:     }
sl@0: }
sl@0: 
sl@0: proc fatal {msg} {
sl@0:     global manual
sl@0:     manerror $msg
sl@0:     exit 1
sl@0: }
sl@0: ##
sl@0: ## parsing
sl@0: ##
sl@0: proc unquote arg {
sl@0:     return [string map [list \" {}] $arg]
sl@0: }
sl@0: 
sl@0: proc parse-directive {line codename restname} {
sl@0:     upvar $codename code $restname rest
sl@0:     return [regexp {^(\.[.a-zA-Z0-9]*) *(.*)} $line all code rest]
sl@0: }
sl@0: 
sl@0: proc process-text {text} {
sl@0:     global manual
sl@0:     # preprocess text
sl@0:     set text [string map [list \
sl@0: 	    {\&}	"\t" \
sl@0: 	    {&}		{&amp;} \
sl@0: 	    {\\}	{&#92;} \
sl@0: 	    {\e}	{&#92;} \
sl@0: 	    {\ }	{&nbsp;} \
sl@0: 	    {\|}	{&nbsp;} \
sl@0: 	    {\0}	{ } \
sl@0: 	    {\%}	{} \
sl@0: 	    "\\\n"	"\n" \
sl@0: 	    \"		{&quot;} \
sl@0: 	    {<}		{&lt;} \
sl@0: 	    {>}		{&gt;} \
sl@0: 	    {\(+-}	{&#177;} \
sl@0: 	    {\fP}	{\fR} \
sl@0: 	    {\.}	. \
sl@0: 	    {\(bu}	{&#8226;} \
sl@0: 	    ] $text]
sl@0:     regsub -all {\\o'o\^'} $text {\&ocirc;} text; # o-circumflex in re_syntax.n
sl@0:     regsub -all {\\-\\\|\\-} $text -- text;	# two hyphens
sl@0:     regsub -all -- {\\-\\\^\\-} $text -- text;	# two hyphens
sl@0:     regsub -all {\\-} $text - text;		# a hyphen
sl@0:     regsub -all "\\\\\n" $text "\\&#92;\n" text; # backslashed newline
sl@0:     while {[string first "\\" $text] >= 0} {
sl@0: 	# C R
sl@0: 	if {[regsub {^([^\\]*)\\fC([^\\]*)\\fR(.*)$} $text \
sl@0: 		{\1<TT>\2</TT>\3} text]} continue
sl@0: 	# B R
sl@0: 	if {[regsub {^([^\\]*)\\fB([^\\]*)\\fR(.*)$} $text \
sl@0: 		{\1<B>\2</B>\3} text]} continue
sl@0: 	# B I
sl@0: 	if {[regsub {^([^\\]*)\\fB([^\\]*)\\fI(.*)$} $text \
sl@0: 		{\1<B>\2</B>\\fI\3} text]} continue
sl@0: 	# I R
sl@0: 	if {[regsub {^([^\\]*)\\fI([^\\]*)\\fR(.*)$} $text \
sl@0: 		{\1<I>\2</I>\3} text]} continue
sl@0: 	# I B
sl@0: 	if {[regsub {^([^\\]*)\\fI([^\\]*)\\fB(.*)$} $text \
sl@0: 		{\1<I>\2</I>\\fB\3} text]} continue
sl@0: 	# B B, I I, R R
sl@0: 	if {[regsub {^([^\\]*)\\fB([^\\]*)\\fB(.*)$} $text \
sl@0: 		{\1\\fB\2\3} ntext]
sl@0: 	    || [regsub {^([^\\]*)\\fI([^\\]*)\\fI(.*)$} $text \
sl@0: 		    {\1\\fI\2\3} ntext]
sl@0: 	    || [regsub {^([^\\]*)\\fR([^\\]*)\\fR(.*)$} $text \
sl@0: 		    {\1\\fR\2\3} ntext]} {
sl@0: 	    manerror "process-text: impotent font change: $text"
sl@0: 	    set text $ntext
sl@0: 	    continue
sl@0: 	}
sl@0: 	# unrecognized
sl@0: 	manerror "process-text: uncaught backslash: $text"
sl@0: 	set text [string map [list "\\" "#92;"] $text]
sl@0:     }
sl@0:     return $text
sl@0: }
sl@0: ##
sl@0: ## pass 2 text input and matching
sl@0: ##
sl@0: proc open-text {} {
sl@0:     global manual
sl@0:     set manual(text-length) [llength $manual(text)]
sl@0:     set manual(text-pointer) 0
sl@0: }
sl@0: proc more-text {} {
sl@0:     global manual
sl@0:     return [expr {$manual(text-pointer) < $manual(text-length)}]
sl@0: }
sl@0: proc next-text {} {
sl@0:     global manual
sl@0:     if {[more-text]} {
sl@0: 	set text [lindex $manual(text) $manual(text-pointer)]
sl@0: 	incr manual(text-pointer)
sl@0: 	return $text
sl@0:     }
sl@0:     manerror "read past end of text"
sl@0:     error "fatal"
sl@0: }
sl@0: proc is-a-directive {line} {
sl@0:     return [string match .* $line]
sl@0: }
sl@0: proc split-directive {line opname restname} {
sl@0:     upvar $opname op $restname rest
sl@0:     set op [string range $line 0 2]
sl@0:     set rest [string trim [string range $line 3 end]]
sl@0: }
sl@0: proc next-op-is {op restname} {
sl@0:     global manual
sl@0:     upvar $restname rest
sl@0:     if {[more-text]} {
sl@0: 	set text [lindex $manual(text) $manual(text-pointer)]
sl@0: 	if {[string equal -length 3 $text $op]} {
sl@0: 	    set rest [string range $text 4 end]
sl@0: 	    incr manual(text-pointer)
sl@0: 	    return 1
sl@0: 	}
sl@0:     }
sl@0:     return 0
sl@0: }
sl@0: proc backup-text {n} {
sl@0:     global manual
sl@0:     if {$manual(text-pointer)-$n >= 0} {
sl@0: 	incr manual(text-pointer) -$n
sl@0:     }
sl@0: }
sl@0: proc match-text args {
sl@0:     global manual
sl@0:     set nargs [llength $args]
sl@0:     if {$manual(text-pointer) + $nargs > $manual(text-length)} {
sl@0: 	return 0
sl@0:     }
sl@0:     set nback 0
sl@0:     foreach arg $args {
sl@0: 	if {![more-text]} {
sl@0: 	    backup-text $nback
sl@0: 	    return 0
sl@0: 	}
sl@0: 	set arg [string trim $arg]
sl@0: 	set targ [string trim [lindex $manual(text) $manual(text-pointer)]]
sl@0: 	if {[string equal $arg $targ]} {
sl@0: 	    incr nback
sl@0: 	    incr manual(text-pointer)
sl@0: 	    continue
sl@0: 	}
sl@0: 	if {[regexp {^@(\w+)$} $arg all name]} {
sl@0: 	    upvar $name var
sl@0: 	    set var $targ
sl@0: 	    incr nback
sl@0: 	    incr manual(text-pointer)
sl@0: 	    continue
sl@0: 	}
sl@0: 	if {[regexp -nocase {^(\.[A-Z][A-Z])@(\w+)$} $arg all op name]\
sl@0: 		&& [string equal $op [lindex $targ 0]]} {
sl@0: 	    upvar $name var
sl@0: 	    set var [lrange $targ 1 end]
sl@0: 	    incr nback
sl@0: 	    incr manual(text-pointer)
sl@0: 	    continue
sl@0: 	}
sl@0: 	backup-text $nback
sl@0: 	return 0
sl@0:     }
sl@0:     return 1
sl@0: }
sl@0: proc expand-next-text {n} {
sl@0:     global manual
sl@0:     return [join [lrange $manual(text) $manual(text-pointer) \
sl@0: 	    [expr {$manual(text-pointer)+$n-1}]] \n\n]
sl@0: }
sl@0: ##
sl@0: ## pass 2 output
sl@0: ##
sl@0: proc man-puts {text} {
sl@0:     global manual
sl@0:     lappend manual(output-$manual(wing-file)-$manual(name)) $text
sl@0: }
sl@0: 
sl@0: ##
sl@0: ## build hypertext links to tables of contents
sl@0: ##
sl@0: proc long-toc {text} {
sl@0:     global manual
sl@0:     set here M[incr manual(section-toc-n)]
sl@0:     set there L[incr manual(long-toc-n)]
sl@0:     lappend manual(section-toc) \
sl@0: 	    "<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$text</A>"
sl@0:     return "<A NAME=\"$here\">$text</A>"
sl@0: }
sl@0: proc option-toc {name class switch} {
sl@0:     global manual
sl@0:     if {[string equal $manual(section) "WIDGET-SPECIFIC OPTIONS"]} {
sl@0: 	# link the defined option into the long table of contents
sl@0: 	set link [long-toc "$switch, $name, $class"]
sl@0: 	regsub -- "$switch, $name, $class" $link "$switch" link
sl@0: 	return $link
sl@0:     } elseif {[string equal $manual(name):$manual(section) \
sl@0: 	    "options:DESCRIPTION"]} {
sl@0: 	# link the defined standard option to the long table of
sl@0: 	# contents and make a target for the standard option references
sl@0: 	# from other man pages.
sl@0: 	set first [lindex $switch 0]
sl@0: 	set here M$first
sl@0: 	set there L[incr manual(long-toc-n)]
sl@0: 	set manual(standard-option-$first) "<A HREF=\"$manual(name).htm#$here\">$switch, $name, $class</A>"
sl@0: 	lappend manual(section-toc) "<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$switch, $name, $class</A>"
sl@0: 	return "<A NAME=\"$here\">$switch</A>"
sl@0:     } else {
sl@0: 	error "option-toc in $manual(name) section $manual(section)"
sl@0:     }
sl@0: }
sl@0: proc std-option-toc {name} {
sl@0:     global manual
sl@0:     if {[info exists manual(standard-option-$name)]} {
sl@0: 	lappend manual(section-toc) <DD>$manual(standard-option-$name)
sl@0: 	return $manual(standard-option-$name)
sl@0:     }
sl@0:     set here M[incr manual(section-toc-n)]
sl@0:     set there L[incr manual(long-toc-n)]
sl@0:     set other M$name
sl@0:     lappend manual(section-toc) "<DD><A HREF=\"options.htm#$other\">$name</A>"
sl@0:     return "<A HREF=\"options.htm#$other\">$name</A>"
sl@0: }
sl@0: ##
sl@0: ## process the widget option section
sl@0: ## in widget and options man pages
sl@0: ##
sl@0: proc output-widget-options {rest} {
sl@0:     global manual
sl@0:     man-puts <DL>
sl@0:     lappend manual(section-toc) <DL>
sl@0:     backup-text 1
sl@0:     set para {}
sl@0:     while {[next-op-is .OP rest]} {
sl@0: 	switch -exact [llength $rest] {
sl@0: 	    3 { foreach {switch name class} $rest { break } }
sl@0: 	    5 {
sl@0: 		set switch [lrange $rest 0 2]
sl@0: 		set name [lindex $rest 3]
sl@0: 		set class [lindex $rest 4]
sl@0: 	    }
sl@0: 	    default {
sl@0: 		fatal "bad .OP $rest"
sl@0: 	    }
sl@0: 	}
sl@0: 	if {![regexp {^(<.>)([-\w ]+)(</.>)$} $switch all oswitch switch cswitch]} {
sl@0: 	    if {![regexp {^(<.>)([-\w ]+) or ([-\w ]+)(</.>)$} $switch all oswitch switch1 switch2 cswitch]} {
sl@0: 		error "not Switch: $switch"
sl@0: 	    } else {
sl@0: 		set switch "$switch1$cswitch or $oswitch$switch2"
sl@0: 	    }
sl@0: 	}
sl@0: 	if {![regexp {^(<.>)([\w]*)(</.>)$} $name all oname name cname]} {
sl@0: 	    error "not Name: $name"
sl@0: 	}
sl@0: 	if {![regexp {^(<.>)([\w]*)(</.>)$} $class all oclass class cclass]} {
sl@0: 	    error "not Class: $class"
sl@0: 	}
sl@0: 	man-puts "$para<DT>Command-Line Name: $oswitch[option-toc $name $class $switch]$cswitch"
sl@0: 	man-puts "<DT>Database Name: $oname$name$cname"
sl@0: 	man-puts "<DT>Database Class: $oclass$class$cclass"
sl@0: 	man-puts <DD>[next-text]
sl@0: 	set para <P>
sl@0:     }
sl@0:     man-puts </DL>
sl@0:     lappend manual(section-toc) </DL>
sl@0: }
sl@0: 
sl@0: ##
sl@0: ## process .RS lists
sl@0: ##
sl@0: proc output-RS-list {} {
sl@0:     global manual
sl@0:     if {[next-op-is .IP rest]} {
sl@0: 	output-IP-list .RS .IP $rest
sl@0: 	if {[match-text .RE .sp .RS @rest .IP @rest2]} {
sl@0: 	    man-puts <P>$rest
sl@0: 	    output-IP-list .RS .IP $rest2
sl@0: 	}
sl@0: 	if {[match-text .RE .sp .RS @rest .RE]} {
sl@0: 	    man-puts <P>$rest
sl@0: 	    return
sl@0: 	}
sl@0: 	if {[next-op-is .RE rest]} {
sl@0: 	    return
sl@0: 	}
sl@0:     }
sl@0:     man-puts <DL><DD>
sl@0:     while {[more-text]} {
sl@0: 	set line [next-text]
sl@0: 	if {[is-a-directive $line]} {
sl@0: 	    split-directive $line code rest
sl@0: 	    switch -exact $code {
sl@0: 		.RE {
sl@0: 		    break
sl@0: 		}
sl@0: 		.SH - .SS {
sl@0: 		    manerror "unbalanced .RS at section end"
sl@0: 		    backup-text 1
sl@0: 		    break
sl@0: 		}
sl@0: 		default {
sl@0: 		    output-directive $line
sl@0: 		}
sl@0: 	    }
sl@0: 	} else {
sl@0: 	    man-puts $line
sl@0: 	}
sl@0:     }	
sl@0:     man-puts </DL>
sl@0: }
sl@0: 
sl@0: ##
sl@0: ## process .IP lists which may be plain indents,
sl@0: ## numeric lists, or definition lists
sl@0: ##
sl@0: proc output-IP-list {context code rest} {
sl@0:     global manual
sl@0:     if {![string length $rest]} {
sl@0: 	# blank label, plain indent, no contents entry
sl@0: 	man-puts <DL><DD>
sl@0: 	while {[more-text]} {
sl@0: 	    set line [next-text]
sl@0: 	    if {[is-a-directive $line]} {
sl@0: 		split-directive $line code rest
sl@0: 		if {[string equal $code ".IP"] && [string equal $rest {}]} {
sl@0: 		    man-puts "<P>"
sl@0: 		    continue
sl@0: 		}
sl@0: 		if {[lsearch {.br .DS .RS} $code] >= 0} {
sl@0: 		    output-directive $line
sl@0: 		} else {
sl@0: 		    backup-text 1
sl@0: 		    break
sl@0: 		}
sl@0: 	    } else {
sl@0: 		man-puts $line
sl@0: 	    }
sl@0: 	}
sl@0: 	man-puts </DL>
sl@0:     } else {
sl@0: 	# labelled list, make contents
sl@0: 	if {
sl@0: 	    [string compare $context ".SH"] &&
sl@0: 	    [string compare $context ".SS"]
sl@0: 	} then {
sl@0: 	    man-puts <P>
sl@0: 	}
sl@0: 	man-puts <DL>
sl@0: 	lappend manual(section-toc) <DL>
sl@0: 	backup-text 1
sl@0: 	set accept_RE 0
sl@0: 	set para {}
sl@0: 	while {[more-text]} {
sl@0: 	    set line [next-text]
sl@0: 	    if {[is-a-directive $line]} {
sl@0: 		split-directive $line code rest
sl@0: 		switch -exact $code {
sl@0: 		    .IP {
sl@0: 			if {$accept_RE} {
sl@0: 			    output-IP-list .IP $code $rest
sl@0: 			    continue
sl@0: 			}
sl@0: 			if {[string equal $manual(section) "ARGUMENTS"] || \
sl@0: 				[regexp {^\[\d+\]$} $rest]} {
sl@0: 			    man-puts "$para<DT>$rest<DD>"
sl@0: 			} elseif {[string equal {&#8226;} $rest]} {
sl@0: 			   man-puts "$para<DT><DD>$rest&nbsp;"
sl@0: 			} else {
sl@0: 			    man-puts "$para<DT>[long-toc $rest]<DD>"
sl@0: 			}
sl@0: 			if {[string equal $manual(name):$manual(section) \
sl@0: 				"selection:DESCRIPTION"]} {
sl@0: 			    if {[match-text .RE @rest .RS .RS]} {
sl@0: 				man-puts <DT>[long-toc $rest]<DD>
sl@0: 			    }
sl@0: 			}
sl@0: 		    }
sl@0: 		    .sp -
sl@0: 		    .br -
sl@0: 		    .DS -
sl@0: 		    .CS {
sl@0: 			output-directive $line
sl@0: 		    }
sl@0: 		    .RS {
sl@0: 			if {[match-text .RS]} {
sl@0: 			    output-directive $line
sl@0: 			    incr accept_RE 1
sl@0: 			} elseif {[match-text .CS]} {
sl@0: 			    output-directive .CS
sl@0: 			    incr accept_RE 1
sl@0: 			} elseif {[match-text .PP]} {
sl@0: 			    output-directive .PP
sl@0: 			    incr accept_RE 1
sl@0: 			} elseif {[match-text .DS]} {
sl@0: 			    output-directive .DS
sl@0: 			    incr accept_RE 1
sl@0: 			} else {
sl@0: 			    output-directive $line
sl@0: 			}
sl@0: 		    }
sl@0: 		    .PP {
sl@0: 			if {[match-text @rest1 .br @rest2 .RS]} {
sl@0: 			    # yet another nroff kludge as above
sl@0: 			    man-puts "$para<DT>[long-toc $rest1]"
sl@0: 			    man-puts "<DT>[long-toc $rest2]<DD>"
sl@0: 			    incr accept_RE 1
sl@0: 			} elseif {[match-text @rest .RE]} {
sl@0: 			    # gad, this is getting ridiculous
sl@0: 			    if {!$accept_RE} {
sl@0: 				man-puts "</DL><P>$rest<DL>"
sl@0: 				backup-text 1
sl@0: 				set para {}
sl@0: 				break
sl@0: 			    } else {
sl@0: 				man-puts "<P>$rest"
sl@0: 				incr accept_RE -1
sl@0: 			    }
sl@0: 			} elseif {$accept_RE} {
sl@0: 			    output-directive $line
sl@0: 			} else {
sl@0: 			    backup-text 1
sl@0: 			    break
sl@0: 			}
sl@0: 		    }
sl@0: 		    .RE {
sl@0: 			if {!$accept_RE} {
sl@0: 			    backup-text 1
sl@0: 			    break
sl@0: 			}
sl@0: 			incr accept_RE -1
sl@0: 		    }
sl@0: 		    default {
sl@0: 			backup-text 1
sl@0: 			break
sl@0: 		    }
sl@0: 		}
sl@0: 	    } else {
sl@0: 		man-puts $line
sl@0: 	    }
sl@0: 	    set para <P>
sl@0: 	}
sl@0: 	man-puts "$para</DL>"
sl@0: 	lappend manual(section-toc) </DL>
sl@0: 	if {$accept_RE} {
sl@0: 	    manerror "missing .RE in output-IP-list"
sl@0: 	}
sl@0:     }
sl@0: }
sl@0: ##
sl@0: ## handle the NAME section lines
sl@0: ## there's only one line in the NAME section,
sl@0: ## consisting of a comma separated list of names,
sl@0: ## followed by a hyphen and a short description.
sl@0: ##
sl@0: proc output-name {line} {
sl@0:     global manual
sl@0:     # split name line into pieces
sl@0:     regexp {^([^-]+) - (.*)$} $line all head tail
sl@0:     # output line to manual page untouched
sl@0:     man-puts $line
sl@0:     # output line to long table of contents
sl@0:     lappend manual(section-toc) <DL><DD>$line</DL>
sl@0:     # separate out the names for future reference
sl@0:     foreach name [split $head ,] {
sl@0: 	set name [string trim $name]
sl@0: 	if {[llength $name] > 1} {
sl@0: 	    manerror "name has a space: {$name}\nfrom: $line"
sl@0: 	}
sl@0: 	lappend manual(wing-toc) $name
sl@0: 	lappend manual(name-$name) $manual(wing-file)/$manual(name)
sl@0:     }
sl@0: }
sl@0: ##
sl@0: ## build a cross-reference link if appropriate
sl@0: ##
sl@0: proc cross-reference {ref} {
sl@0:     global manual
sl@0:     if {[string match Tcl_* $ref]} {
sl@0: 	set lref $ref
sl@0:     } elseif {[string match Tk_* $ref]} {
sl@0: 	set lref $ref
sl@0:     } elseif {[string equal $ref "Tcl"]} {
sl@0: 	set lref $ref
sl@0:     } else {
sl@0: 	set lref [string tolower $ref]
sl@0:     }
sl@0:     ##
sl@0:     ## nothing to reference
sl@0:     ##
sl@0:     if {![info exists manual(name-$lref)]} {
sl@0: 	foreach name {array file history info interp string trace
sl@0: 	after clipboard grab image option pack place selection tk tkwait update winfo wm} {
sl@0: 	    if {[regexp "^$name \[a-z0-9]*\$" $lref] && \
sl@0: 		    [info exists manual(name-$name)] && \
sl@0: 		    [string compare $manual(tail) "$name.n"]} {
sl@0: 		return "<A HREF=\"../$manual(name-$name).htm\">$ref</A>"
sl@0: 	    }
sl@0: 	}
sl@0: 	if {[lsearch {stdin stdout stderr end} $lref] >= 0} {
sl@0: 	    # no good place to send these
sl@0: 	    # tcl tokens?
sl@0: 	    # also end
sl@0: 	}
sl@0: 	return $ref
sl@0:     }
sl@0:     ##
sl@0:     ## would be a self reference
sl@0:     ##
sl@0:     foreach name $manual(name-$lref) {
sl@0: 	if {[lsearch $name $manual(wing-file)/$manual(name)] >= 0} {
sl@0: 	    return $ref
sl@0: 	}
sl@0:     }
sl@0:     ##
sl@0:     ## multiple choices for reference
sl@0:     ##
sl@0:     if {[llength $manual(name-$lref)] > 1} {
sl@0: 	set tcl_i [lsearch -glob $manual(name-$lref) *TclCmd*]
sl@0: 	set tcl_ref [lindex $manual(name-$lref) $tcl_i]
sl@0: 	set tk_i [lsearch -glob $manual(name-$lref) *TkCmd*]
sl@0: 	set tk_ref [lindex $manual(name-$lref) $tk_i]
sl@0: 	if {$tcl_i >= 0 && "$manual(wing-file)" == {TclCmd} \
sl@0: 		||  "$manual(wing-file)" == {TclLib}} {
sl@0: 	    return "<A HREF=\"../$tcl_ref.htm\">$ref</A>"
sl@0: 	}
sl@0: 	if {$tk_i >= 0 && "$manual(wing-file)" == {TkCmd} \
sl@0: 		|| "$manual(wing-file)" == {TkLib}} {
sl@0: 	    return "<A HREF=\"../$tk_ref.htm\">$ref</A>"
sl@0: 	}
sl@0: 	if {"$lref" == {exit} && "$manual(tail)" == {tclsh.1} && $tcl_i >= 0} {
sl@0: 	    return "<A HREF=\"../$tcl_ref.htm\">$ref</A>"
sl@0: 	}
sl@0: 	puts stderr "multiple cross reference to $ref in $manual(name-$lref) from $manual(wing-file)/$manual(tail)"
sl@0: 	return $ref
sl@0:     }
sl@0:     ##
sl@0:     ## exceptions, sigh, to the rule
sl@0:     ##
sl@0:     switch $manual(tail) {
sl@0: 	canvas.n {
sl@0: 	    if {$lref == {focus}} {
sl@0: 		upvar tail tail
sl@0: 		set clue [string first command $tail]
sl@0: 		if {$clue < 0 ||  $clue > 5} {
sl@0: 		    return $ref
sl@0: 		}
sl@0: 	    }
sl@0: 	    if {[lsearch {bitmap image text} $lref] >= 0} {
sl@0: 		return $ref
sl@0: 	    }
sl@0: 	}
sl@0: 	checkbutton.n -
sl@0: 	radiobutton.n {
sl@0: 	    if {[lsearch {image} $lref] >= 0} {
sl@0: 		return $ref
sl@0: 	    }
sl@0: 	}
sl@0: 	menu.n {
sl@0: 	    if {[lsearch {checkbutton radiobutton} $lref] >= 0} {
sl@0: 		return $ref
sl@0: 	    }
sl@0: 	}
sl@0: 	options.n {
sl@0: 	    if {[lsearch {bitmap image set} $lref] >= 0} {
sl@0: 		return $ref
sl@0: 	    }
sl@0: 	}
sl@0: 	regexp.n {
sl@0: 	    if {[lsearch {string} $lref] >= 0} {
sl@0: 		return $ref
sl@0: 	    }
sl@0: 	}
sl@0: 	source.n {
sl@0: 	    if {[lsearch {text} $lref] >= 0} {
sl@0: 		return $ref
sl@0: 	    }
sl@0: 	}
sl@0: 	history.n {
sl@0: 	    if {[lsearch {exec} $lref] >= 0} {
sl@0: 		return $ref
sl@0: 	    }
sl@0: 	}
sl@0: 	return.n {
sl@0: 	    if {[lsearch {error continue break} $lref] >= 0} {
sl@0: 		return $ref
sl@0: 	    }
sl@0: 	}
sl@0: 	scrollbar.n {
sl@0: 	    if {[lsearch {set} $lref] >= 0} {
sl@0: 		return $ref
sl@0: 	    }
sl@0: 	}
sl@0:     }
sl@0:     ##
sl@0:     ## return the cross reference
sl@0:     ##
sl@0:     return "<A HREF=\"../$manual(name-$lref).htm\">$ref</A>"
sl@0: }
sl@0: ##
sl@0: ## reference generation errors
sl@0: ##
sl@0: proc reference-error {msg text} {
sl@0:     global manual
sl@0:     puts stderr "$manual(tail): $msg: {$text}"
sl@0:     return $text
sl@0: }
sl@0: ##
sl@0: ## insert as many cross references into this text string as are appropriate
sl@0: ##
sl@0: proc insert-cross-references {text} {
sl@0:     global manual
sl@0:     ##
sl@0:     ## we identify cross references by:
sl@0:     ##     ``quotation''
sl@0:     ##    <B>emboldening</B>
sl@0:     ##    Tcl_ prefix
sl@0:     ##    Tk_ prefix
sl@0:     ##	  [a-zA-Z0-9]+ manual entry
sl@0:     ## and we avoid messing with already anchored text
sl@0:     ##
sl@0:     ##
sl@0:     ## find where each item lives
sl@0:     ##
sl@0:     array set offset [list \
sl@0: 	    anchor [string first {<A } $text] \
sl@0: 	    end-anchor [string first {</A>} $text] \
sl@0: 	    quote [string first {``} $text] \
sl@0: 	    end-quote [string first {''} $text] \
sl@0: 	    bold [string first {<B>} $text] \
sl@0: 	    end-bold [string first {</B>} $text] \
sl@0: 	    tcl [string first {Tcl_} $text] \
sl@0: 	    tk [string first {Tk_} $text] \
sl@0: 	    Tcl1 [string first {Tcl manual entry} $text] \
sl@0: 	    Tcl2 [string first {Tcl overview manual entry} $text] \
sl@0: 	    ]
sl@0:     ##
sl@0:     ## accumulate a list
sl@0:     ##
sl@0:     foreach name [array names offset] {
sl@0: 	if {$offset($name) >= 0} {
sl@0: 	    set invert($offset($name)) $name
sl@0: 	    lappend offsets $offset($name)
sl@0: 	}
sl@0:     }
sl@0:     ##
sl@0:     ## if nothing, then we're done.
sl@0:     ##
sl@0:     if {![info exists offsets]} {
sl@0: 	return $text
sl@0:     }
sl@0:     ##
sl@0:     ## sort the offsets
sl@0:     ##
sl@0:     set offsets [lsort -integer $offsets]
sl@0:     ##
sl@0:     ## see which we want to use
sl@0:     ##
sl@0:     switch -exact $invert([lindex $offsets 0]) {
sl@0: 	anchor {
sl@0: 	    if {$offset(end-anchor) < 0} {
sl@0: 		return [reference-error {Missing end anchor} $text]
sl@0: 	    }
sl@0: 	    set head [string range $text 0 $offset(end-anchor)]
sl@0: 	    set tail [string range $text [expr {$offset(end-anchor)+1}] end]
sl@0: 	    return $head[insert-cross-references $tail]
sl@0: 	}
sl@0: 	quote {
sl@0: 	    if {$offset(end-quote) < 0} {
sl@0: 		return [reference-error "Missing end quote" $text]
sl@0: 	    }
sl@0: 	    if {$invert([lindex $offsets 1]) == "tk"} {
sl@0: 		set offsets [lreplace $offsets 1 1]
sl@0: 	    }
sl@0: 	    if {$invert([lindex $offsets 1]) == "tcl"} {
sl@0: 		set offsets [lreplace $offsets 1 1]
sl@0: 	    }
sl@0: 	    switch -exact $invert([lindex $offsets 1]) {
sl@0: 		end-quote {
sl@0: 		    set head [string range $text 0 [expr {$offset(quote)-1}]]
sl@0: 		    set body [string range $text [expr {$offset(quote)+2}] \
sl@0: 			    [expr {$offset(end-quote)-1}]]
sl@0: 		    set tail [string range $text \
sl@0: 			    [expr {$offset(end-quote)+2}] end]
sl@0: 		    return "$head``[cross-reference $body]''[insert-cross-references $tail]"
sl@0: 		}
sl@0: 		bold -
sl@0: 		anchor {
sl@0: 		    set head [string range $text \
sl@0: 			    0 [expr {$offset(end-quote)+1}]]
sl@0: 		    set tail [string range $text \
sl@0: 			    [expr {$offset(end-quote)+2}] end]
sl@0: 		    return "$head[insert-cross-references $tail]"
sl@0: 		}
sl@0: 	    }
sl@0: 	    return [reference-error "Uncaught quote case" $text]
sl@0: 	}
sl@0: 	bold {
sl@0: 	    if {$offset(end-bold) < 0} { return $text }
sl@0: 	    if {$invert([lindex $offsets 1]) == "tk"} {
sl@0: 		set offsets [lreplace $offsets 1 1]
sl@0: 	    }
sl@0: 	    if {$invert([lindex $offsets 1]) == "tcl"} {
sl@0: 		set offsets [lreplace $offsets 1 1]
sl@0: 	    }
sl@0: 	    switch -exact $invert([lindex $offsets 1]) {
sl@0: 		end-bold {
sl@0: 		    set head [string range $text 0 [expr {$offset(bold)-1}]]
sl@0: 		    set body [string range $text [expr {$offset(bold)+3}] \
sl@0: 			    [expr {$offset(end-bold)-1}]]
sl@0: 		    set tail [string range $text \
sl@0: 			    [expr {$offset(end-bold)+4}] end]
sl@0: 		    return "$head<B>[cross-reference $body]</B>[insert-cross-references $tail]"
sl@0: 		}
sl@0: 		anchor {
sl@0: 		    set head [string range $text \
sl@0: 			    0 [expr {$offset(end-bold)+3}]]
sl@0: 		    set tail [string range $text \
sl@0: 			    [expr {$offset(end-bold)+4}] end]
sl@0: 		    return "$head[insert-cross-references $tail]"
sl@0: 		}
sl@0: 	    }
sl@0: 	    return [reference-error "Uncaught bold case" $text]
sl@0: 	}
sl@0: 	tk {
sl@0: 	    set head [string range $text 0 [expr {$offset(tk)-1}]]
sl@0: 	    set tail [string range $text $offset(tk) end]
sl@0: 	    if {![regexp {^(Tk_\w+)(.*)$} $tail all body tail]} {
sl@0: 		return [reference-error "Tk regexp failed" $text]
sl@0: 	    }
sl@0: 	    return $head[cross-reference $body][insert-cross-references $tail]
sl@0: 	}
sl@0: 	tcl {
sl@0: 	    set head [string range $text 0 [expr {$offset(tcl)-1}]]
sl@0: 	    set tail [string range $text $offset(tcl) end]
sl@0: 	    if {![regexp {^(Tcl_\w+)(.*)$} $tail all body tail]} {
sl@0: 		return [reference-error {Tcl regexp failed} $text]
sl@0: 	    }
sl@0: 	    return $head[cross-reference $body][insert-cross-references $tail]
sl@0: 	}
sl@0: 	Tcl1 -
sl@0: 	Tcl2 {
sl@0: 	    set off [lindex $offsets 0]
sl@0: 	    set head [string range $text 0 [expr {$off-1}]]
sl@0: 	    set body Tcl
sl@0: 	    set tail [string range $text [expr {$off+3}] end]
sl@0: 	    return $head[cross-reference $body][insert-cross-references $tail]
sl@0: 	}
sl@0: 	end-anchor -
sl@0: 	end-bold -
sl@0: 	end-quote {
sl@0: 	    return [reference-error "Out of place $invert([lindex $offsets 0])" $text]
sl@0: 	}
sl@0:     }
sl@0: }
sl@0: ##
sl@0: ## process formatting directives
sl@0: ##
sl@0: proc output-directive {line} {
sl@0:     global manual
sl@0:     # process format directive
sl@0:     split-directive $line code rest
sl@0:     switch -exact $code {
sl@0: 	.BS -
sl@0: 	.BE {
sl@0: 	    # man-puts <HR>
sl@0: 	}
sl@0: 	.SH - .SS {
sl@0: 	    # drain any open lists
sl@0: 	    # announce the subject
sl@0: 	    set manual(section) $rest
sl@0: 	    # start our own stack of stuff
sl@0: 	    set manual($manual(name)-$manual(section)) {}
sl@0: 	    lappend manual(has-$manual(section)) $manual(name)
sl@0: 	    if {[string compare .SS $code]} {
sl@0: 		man-puts "<H3>[long-toc $manual(section)]</H3>"
sl@0: 	    } else {
sl@0: 		man-puts "<H4>[long-toc $manual(section)]</H4>"
sl@0: 	    }
sl@0: 	    # some sections can simply free wheel their way through the text
sl@0: 	    # some sections can be processed in their own loops
sl@0: 	    switch -exact $manual(section) {
sl@0: 		NAME {
sl@0: 		    if {[lsearch {CrtImgType.3 CrtItemType.3 CrtPhImgFmt.3} $manual(tail)] >= 0} {
sl@0: 			# these manual pages have two NAME sections
sl@0: 			if {[info exists manual($manual(tail)-NAME)]} {
sl@0: 			    return
sl@0: 			}
sl@0: 			set manual($manual(tail)-NAME) 1
sl@0: 		    }
sl@0: 		    set names {}
sl@0: 		    while {1} {
sl@0: 			set line [next-text]
sl@0: 			if {[is-a-directive $line]} {
sl@0: 			    backup-text 1
sl@0: 			    output-name [join $names { }]
sl@0: 			    return
sl@0: 			} else {
sl@0: 			    lappend names [string trim $line]
sl@0: 			}
sl@0: 		    }
sl@0: 		}
sl@0: 		SYNOPSIS {
sl@0: 		    lappend manual(section-toc) <DL>
sl@0: 		    while {1} {
sl@0: 			if {[next-op-is .nf rest]
sl@0: 			 || [next-op-is .br rest]
sl@0: 			 || [next-op-is .fi rest]} {
sl@0: 			    continue
sl@0: 			}
sl@0: 			if {[next-op-is .SH rest]
sl@0: 		         || [next-op-is .SS rest]
sl@0: 		         || [next-op-is .BE rest]
sl@0: 			 || [next-op-is .SO rest]} {
sl@0: 			    backup-text 1
sl@0: 			    break
sl@0: 			}
sl@0: 			if {[next-op-is .sp rest]} {
sl@0: 			    #man-puts <P>
sl@0: 			    continue
sl@0: 			}
sl@0: 			set more [next-text]
sl@0: 			if {[is-a-directive $more]} {
sl@0: 			    manerror "in SYNOPSIS found $more"
sl@0: 			    backup-text 1
sl@0: 			    break
sl@0: 			} else {
sl@0: 			    foreach more [split $more \n] {
sl@0: 				man-puts $more<BR>
sl@0: 				if {[lsearch {TclLib TkLib} $manual(wing-file)] < 0} {
sl@0: 				    lappend manual(section-toc) <DD>$more
sl@0: 				}
sl@0: 			    }
sl@0: 			}
sl@0: 		    }
sl@0: 		    lappend manual(section-toc) </DL>
sl@0: 		    return
sl@0: 		}
sl@0: 		{SEE ALSO} {
sl@0: 		    while {[more-text]} {
sl@0: 			if {[next-op-is .SH rest] || [next-op-is .SS rest]} {
sl@0: 			    backup-text 1
sl@0: 			    return
sl@0: 			}
sl@0: 			set more [next-text]
sl@0: 			if {[is-a-directive $more]} {
sl@0: 			    manerror "$more"
sl@0: 			    backup-text 1
sl@0: 			    return
sl@0: 			}
sl@0: 			set nmore {}
sl@0: 			foreach cr [split $more ,] {
sl@0: 			    set cr [string trim $cr]
sl@0: 			    if {![regexp {^<B>.*</B>$} $cr]} {
sl@0: 				set cr <B>$cr</B>
sl@0: 			    }
sl@0: 			    if {[regexp {^<B>(.*)\([13n]\)</B>$} $cr all name]} {
sl@0: 				set cr <B>$name</B>
sl@0: 			    }
sl@0: 			    lappend nmore $cr
sl@0: 			}
sl@0: 			man-puts [join $nmore {, }]
sl@0: 		    }
sl@0: 		    return
sl@0: 		}
sl@0: 		KEYWORDS {
sl@0: 		    while {[more-text]} {
sl@0: 			if {[next-op-is .SH rest] || [next-op-is .SS rest]} {
sl@0: 			    backup-text 1
sl@0: 			    return
sl@0: 			}
sl@0: 			set more [next-text]
sl@0: 			if {[is-a-directive $more]} {
sl@0: 			    manerror "$more"
sl@0: 			    backup-text 1
sl@0: 			    return
sl@0: 			}
sl@0: 			set keys {}
sl@0: 			foreach key [split $more ,] {
sl@0: 			    set key [string trim $key]
sl@0: 			    lappend manual(keyword-$key) [list $manual(name) $manual(wing-file)/$manual(name).htm]
sl@0: 			    set initial [string toupper [string index $key 0]]
sl@0: 			    lappend keys "<A href=\"../Keywords/$initial.htm\#$key\">$key</A>"
sl@0: 			}
sl@0: 			man-puts [join $keys {, }]
sl@0: 		    }
sl@0: 		    return
sl@0: 		}
sl@0: 	    }
sl@0: 	    if {[next-op-is .IP rest]} {
sl@0: 		output-IP-list $code .IP $rest
sl@0: 		return
sl@0: 	    }
sl@0: 	    if {[next-op-is .PP rest]} {
sl@0: 		return
sl@0: 	    }
sl@0: 	    return
sl@0: 	}
sl@0: 	.SO {
sl@0: 	    if {[match-text @stuff .SE]} {
sl@0: 		output-directive {.SH STANDARD OPTIONS}
sl@0: 		set opts {}
sl@0: 		foreach line [split $stuff \n] {
sl@0: 		    foreach option [split $line \t] {
sl@0: 			lappend opts $option
sl@0: 		    }
sl@0: 		}
sl@0: 		man-puts <DL>
sl@0: 		lappend manual(section-toc) <DL>
sl@0: 		foreach option [lsort $opts] {
sl@0: 		    man-puts "<DT><B>[std-option-toc $option]</B>"
sl@0: 		}
sl@0: 		man-puts </DL>
sl@0: 		lappend manual(section-toc) </DL>
sl@0: 	    } else {
sl@0: 		manerror "unexpected .SO format:\n[expand-next-text 2]"
sl@0: 	    }
sl@0: 	}
sl@0: 	.OP {
sl@0: 	    output-widget-options $rest
sl@0: 	    return
sl@0: 	}
sl@0: 	.IP {
sl@0: 	    output-IP-list .IP .IP $rest
sl@0: 	    return
sl@0: 	}
sl@0: 	.PP {
sl@0: 	    man-puts <P>
sl@0: 	}
sl@0: 	.RS {
sl@0: 	    output-RS-list
sl@0: 	    return
sl@0: 	}
sl@0: 	.RE {
sl@0: 	    manerror "unexpected .RE"
sl@0: 	    return
sl@0: 	}
sl@0: 	.br {
sl@0: 	    man-puts <BR>
sl@0: 	    return
sl@0: 	}
sl@0: 	.DE {
sl@0: 	    manerror "unexpected .DE"
sl@0: 	    return
sl@0: 	}
sl@0: 	.DS {
sl@0: 	    if {[next-op-is .ta rest]} {
sl@0: 		
sl@0: 	    }
sl@0: 	    if {[match-text @stuff .DE]} {
sl@0: 		man-puts <PRE>$stuff</PRE>
sl@0: 	    } elseif {[match-text .fi @ul1 @ul2 .nf @stuff .DE]} {
sl@0: 		man-puts "<PRE>[lindex $ul1 1][lindex $ul2 1]\n$stuff</PRE>"
sl@0: 	    } else {
sl@0: 		manerror "unexpected .DS format:\n[expand-next-text 2]"
sl@0: 	    }
sl@0: 	    return
sl@0: 	}
sl@0: 	.CS {
sl@0: 	    if {[next-op-is .ta rest]} {
sl@0: 		
sl@0: 	    }
sl@0: 	    if {[match-text @stuff .CE]} {
sl@0: 		man-puts <PRE>$stuff</PRE>
sl@0: 	    } else {
sl@0: 		manerror "unexpected .CS format:\n[expand-next-text 2]"
sl@0: 	    }
sl@0: 	    return
sl@0: 	}
sl@0: 	.CE {
sl@0: 	    manerror "unexpected .CE"
sl@0: 	    return
sl@0: 	}
sl@0: 	.sp {
sl@0: 	    man-puts <P>
sl@0: 	}
sl@0: 	.ta {
sl@0: 	    # these are tab stop settings for short tables
sl@0: 	    switch -exact $manual(name):$manual(section) {
sl@0: 		{bind:MODIFIERS} -
sl@0: 		{bind:EVENT TYPES} -
sl@0: 		{bind:BINDING SCRIPTS AND SUBSTITUTIONS} -
sl@0: 		{expr:OPERANDS} -
sl@0: 		{expr:MATH FUNCTIONS} -
sl@0: 		{history:DESCRIPTION} -
sl@0: 		{history:HISTORY REVISION} -
sl@0: 		{re_syntax:BRACKET EXPRESSIONS} -
sl@0: 		{switch:DESCRIPTION} -
sl@0: 		{upvar:DESCRIPTION} {
sl@0: 		    return;			# fix.me
sl@0: 		}
sl@0: 		default {
sl@0: 		    manerror "ignoring $line"
sl@0: 		}
sl@0: 	    }
sl@0: 	}
sl@0: 	.nf {
sl@0: 	    if {[match-text @more .fi]} {
sl@0: 		foreach more [split $more \n] {
sl@0: 		    man-puts $more<BR>
sl@0: 		}
sl@0: 	    } elseif {[match-text .RS @more .RE .fi]} {
sl@0: 		man-puts <DL><DD>
sl@0: 		foreach more [split $more \n] {
sl@0: 		    man-puts $more<BR>
sl@0: 		}
sl@0: 		man-puts </DL>
sl@0: 	    } elseif {[match-text .RS @more .RS @more2 .RE .RE .fi]} {
sl@0: 		man-puts <DL><DD>
sl@0: 		foreach more [split $more \n] {
sl@0: 		    man-puts $more<BR>
sl@0: 		}
sl@0: 		man-puts <DL><DD>
sl@0: 		foreach more2 [split $more2 \n] {
sl@0: 		    man-puts $more2<BR>
sl@0: 		}
sl@0: 		man-puts </DL></DL>
sl@0: 	    } elseif {[match-text .RS @more .RS @more2 .RE @more3 .RE .fi]} {
sl@0: 		man-puts <DL><DD>
sl@0: 		foreach more [split $more \n] {
sl@0: 		    man-puts $more<BR>
sl@0: 		}
sl@0: 		man-puts <DL><DD>
sl@0: 		foreach more2 [split $more2 \n] {
sl@0: 		    man-puts $more2<BR>
sl@0: 		}
sl@0: 		man-puts </DL><DD>
sl@0: 		foreach more3 [split $more3 \n] {
sl@0: 		    man-puts $more3<BR>
sl@0: 		}
sl@0: 		man-puts </DL>
sl@0: 	    } elseif {[match-text .sp .RS @more .RS @more2 .sp .RE .RE .fi]} {
sl@0: 		man-puts <P><DL><DD>
sl@0: 		foreach more [split $more \n] {
sl@0: 		    man-puts $more<BR>
sl@0: 		}
sl@0: 		man-puts <DL><DD>
sl@0: 		foreach more2 [split $more2 \n] {
sl@0: 		    man-puts $more2<BR>
sl@0: 		}
sl@0: 		man-puts </DL></DL><P>
sl@0: 	    } elseif {[match-text .RS .sp @more .sp .RE .fi]} {
sl@0: 		man-puts <P><DL><DD>
sl@0: 		foreach more [split $more \n] {
sl@0: 		    man-puts $more<BR>
sl@0: 		}
sl@0: 		man-puts </DL><P>
sl@0: 	    } else {
sl@0: 		manerror "ignoring $line"
sl@0: 	    }
sl@0: 	}
sl@0: 	.fi {
sl@0: 	    manerror "ignoring $line"
sl@0: 	}
sl@0: 	.na -
sl@0: 	.ad -
sl@0: 	.UL -
sl@0: 	.ne {
sl@0: 	    manerror "ignoring $line"
sl@0: 	}
sl@0: 	default {
sl@0: 	    manerror "unrecognized format directive: $line"
sl@0: 	}
sl@0:     }
sl@0: }
sl@0: ##
sl@0: ## merge copyright listings
sl@0: ## 
sl@0: proc merge-copyrights {l1 l2} {
sl@0:     foreach copyright [concat $l1 $l2] {
sl@0: 	if {[regexp {^Copyright +\(c\) +(\d+) +(by +)?(\w.*)$} $copyright all date by who]} {
sl@0: 	    lappend dates($who) $date
sl@0: 	    continue
sl@0: 	}
sl@0: 	if {[regexp {^Copyright +\(c\) +(\d+)-(\d+) +(by +)?(\w.*)$} $copyright all from to by who]} {
sl@0: 	    for {set date $from} {$date <= $to} {incr date} {
sl@0: 		lappend dates($who) $date
sl@0: 	    }
sl@0: 	    continue
sl@0: 	}
sl@0: 	if {[regexp {^Copyright +\(c\) +(\d+), *(\d+) +(by +)?(\w.*)$} $copyright all date1 date2 by who]} {
sl@0: 	    lappend dates($who) $date1 $date2
sl@0: 	    continue
sl@0: 	}
sl@0: 	puts "oops: $copyright"
sl@0:     }
sl@0:     foreach who [array names dates] {
sl@0: 	set list [lsort $dates($who)]
sl@0: 	if {[llength $list] == 1 || [lindex $list 0] == [lrange $list end end]} {
sl@0: 	    lappend merge "Copyright (c) [lindex $list 0] $who"
sl@0: 	} else {
sl@0: 	    lappend merge "Copyright (c) [lindex $list 0]-[lrange $list end end] $who"
sl@0: 	}
sl@0:     }
sl@0:     return [lsort $merge]
sl@0: }
sl@0: 
sl@0: proc makedirhier {dir} {
sl@0:     if {![file isdirectory $dir] && \
sl@0: 	    [catch {file mkdir $dir} error]} {
sl@0: 	return -code error "cannot create directory $dir: $error"
sl@0:     }
sl@0: }
sl@0: 
sl@0: ##
sl@0: ## foreach of the man directories specified by args
sl@0: ## convert manpages into hypertext in the directory
sl@0: ## specified by html.
sl@0: ##
sl@0: proc make-man-pages {html args} {
sl@0:     global env manual overall_title tcltkdesc
sl@0:     makedirhier $html
sl@0:     set manual(short-toc-n) 1
sl@0:     set manual(short-toc-fp) [open $html/contents.htm w]
sl@0:     puts $manual(short-toc-fp) "<HTML><HEAD><TITLE>$overall_title</TITLE></HEAD>"
sl@0:     puts $manual(short-toc-fp) "<BODY><HR><H3>$overall_title</H3><HR><DL>"
sl@0:     set manual(merge-copyrights) {}
sl@0:     foreach arg $args {
sl@0: 	if {$arg == ""} {continue}
sl@0: 	set manual(wing-glob) [lindex $arg 0]
sl@0: 	set manual(wing-name) [lindex $arg 1]
sl@0: 	set manual(wing-file) [lindex $arg 2]
sl@0: 	set manual(wing-description) [lindex $arg 3]
sl@0: 	set manual(wing-copyrights) {}
sl@0: 	makedirhier $html/$manual(wing-file)
sl@0: 	set manual(wing-toc-fp) [open $html/$manual(wing-file)/contents.htm w]
sl@0: 	# whistle
sl@0: 	puts stderr "scanning section $manual(wing-name)"
sl@0: 	# put the entry for this section into the short table of contents
sl@0: 	puts $manual(short-toc-fp) "<DT><A HREF=\"$manual(wing-file)/contents.htm\">$manual(wing-name)</A><DD>$manual(wing-description)"
sl@0: 	# initialize the wing table of contents
sl@0: 	puts $manual(wing-toc-fp) "<HTML><HEAD><TITLE>$manual(wing-name) Manual</TITLE></HEAD>"
sl@0: 	puts $manual(wing-toc-fp) "<BODY><HR><H3>$manual(wing-name)</H3><HR>"
sl@0: 	# initialize the short table of contents for this section
sl@0: 	set manual(wing-toc) {}
sl@0: 	# initialize the man directory for this section
sl@0: 	makedirhier $html/$manual(wing-file)
sl@0: 	# initialize the long table of contents for this section
sl@0: 	set manual(long-toc-n) 1
sl@0: 	# get the manual pages for this section
sl@0: 	set manual(pages) [lsort [glob $manual(wing-glob)]]
sl@0: 	if {[lsearch -glob $manual(pages) */options.n] >= 0} {
sl@0: 	    set n [lsearch $manual(pages) */options.n]
sl@0: 	    set manual(pages) "[lindex $manual(pages) $n] [lreplace $manual(pages) $n $n]"
sl@0: 	}
sl@0: 	# set manual(pages) [lrange $manual(pages) 0 5]
sl@0: 	foreach manual(page) $manual(pages) {
sl@0: 	    # whistle
sl@0: 	    puts stderr "scanning page $manual(page)"
sl@0: 	    set manual(tail) [file tail $manual(page)]
sl@0: 	    set manual(name) [file root $manual(tail)]
sl@0: 	    set manual(section) {}
sl@0: 	    if {[lsearch {case pack-old menubar} $manual(name)] >= 0} {
sl@0: 		# obsolete
sl@0: 		manerror "discarding $manual(name)"
sl@0: 		continue
sl@0: 	    }
sl@0: 	    set manual(infp) [open $manual(page)]
sl@0: 	    set manual(text) {}
sl@0: 	    set manual(partial-text) {}
sl@0: 	    foreach p {.RS .DS .CS .SO} {
sl@0: 		set manual($p) 0
sl@0: 	    }
sl@0: 	    set manual(stack) {}
sl@0: 	    set manual(section) {}
sl@0: 	    set manual(section-toc) {}
sl@0: 	    set manual(section-toc-n) 1
sl@0: 	    set manual(copyrights) {}
sl@0: 	    lappend manual(all-pages) $manual(wing-file)/$manual(tail)
sl@0: 	    manreport 100 $manual(name)
sl@0: 	    while {[gets $manual(infp) line] >= 0} {
sl@0: 		manreport 100 $line
sl@0: 		if {[regexp {^[`'][/\\]} $line]} {
sl@0: 		    if {[regexp {Copyright \(c\).*$} $line copyright]} {
sl@0: 			lappend manual(copyrights) $copyright
sl@0: 		    }
sl@0: 		    # comment
sl@0: 		    continue
sl@0: 		}
sl@0: 		if {"$line" == {'}} {
sl@0: 		    # comment
sl@0: 		    continue
sl@0: 		}
sl@0: 		if {[parse-directive $line code rest]} {
sl@0: 		    switch -exact $code {
sl@0: 			.ad - .na - .so - .ne - .AS - .VE - .VS -
sl@0: 			. {
sl@0: 			    # ignore
sl@0: 			    continue
sl@0: 			}
sl@0: 		    }
sl@0: 		    if {"$manual(partial-text)" != {}} {
sl@0: 			lappend manual(text) [process-text $manual(partial-text)]
sl@0: 			set manual(partial-text) {}
sl@0: 		    }
sl@0: 		    switch -exact $code {
sl@0: 			.SH - .SS {
sl@0: 			    if {[llength $rest] == 0} {
sl@0: 				gets $manual(infp) rest
sl@0: 			    }
sl@0: 			    lappend manual(text) "$code [unquote $rest]"
sl@0: 			}
sl@0: 			.TH {
sl@0: 			    lappend manual(text) "$code [unquote $rest]"
sl@0: 			}
sl@0: 			.HS - .UL -
sl@0: 			.ta {
sl@0: 			    lappend manual(text) "$code [unquote $rest]"
sl@0: 			}
sl@0: 			.BS - .BE - .br - .fi - .sp -
sl@0: 			.nf {
sl@0: 			    if {"$rest" != {}} {
sl@0: 				manerror "unexpected argument: $line"
sl@0: 			    }
sl@0: 			    lappend manual(text) $code
sl@0: 			}
sl@0: 			.AP {
sl@0: 			    lappend manual(text) [concat .IP [process-text "[lindex $rest 0] \\fB[lindex $rest 1]\\fR ([lindex $rest 2])"]]
sl@0: 			}
sl@0: 			.IP {
sl@0: 			    regexp {^(.*) +\d+$} $rest all rest
sl@0: 			    lappend manual(text) ".IP [process-text [unquote [string trim $rest]]]"
sl@0: 			}
sl@0: 			.TP {
sl@0: 			    while {[is-a-directive [set next [gets $manual(infp)]]]} {
sl@0: 			    	manerror "ignoring $next after .TP"
sl@0: 			    }
sl@0: 			    if {"$next" != {'}} {
sl@0: 				lappend manual(text) ".IP [process-text $next]"
sl@0: 			    }
sl@0: 			}
sl@0: 			.OP {
sl@0: 			    lappend manual(text) [concat .OP [process-text \
sl@0: 				    "\\fB[lindex $rest 0]\\fR \\fB[lindex $rest 1]\\fR \\fB[lindex $rest 2]\\fR"]]
sl@0: 			}
sl@0: 			.PP -
sl@0: 			.LP {
sl@0: 			    lappend manual(text) {.PP}
sl@0: 			}
sl@0: 			.RS {
sl@0: 			    incr manual(.RS)
sl@0: 			    lappend manual(text) $code
sl@0: 			}
sl@0: 			.RE {
sl@0: 			    incr manual(.RS) -1
sl@0: 			    lappend manual(text) $code
sl@0: 			}
sl@0: 			.SO {
sl@0: 			    incr manual(.SO)
sl@0: 			    lappend manual(text) $code
sl@0: 			}
sl@0: 			.SE {
sl@0: 			    incr manual(.SO) -1
sl@0: 			    lappend manual(text) $code
sl@0: 			}
sl@0: 			.DS {
sl@0: 			    incr manual(.DS)
sl@0: 			    lappend manual(text) $code
sl@0: 			}
sl@0: 			.DE {
sl@0: 			    incr manual(.DS) -1
sl@0: 			    lappend manual(text) $code
sl@0: 			}
sl@0: 			.CS {
sl@0: 			    incr manual(.CS)
sl@0: 			    lappend manual(text) $code
sl@0: 			}
sl@0: 			.CE {
sl@0: 			    incr manual(.CS) -1
sl@0: 			    lappend manual(text) $code
sl@0: 			}
sl@0: 			.de {
sl@0: 			    while {[gets $manual(infp) line] >= 0} {
sl@0: 				if {[string match "..*" $line]} {
sl@0: 				    break
sl@0: 				}
sl@0: 			    }
sl@0: 			}
sl@0: 			.. {
sl@0: 			    error "found .. outside of .de"
sl@0: 			}
sl@0: 			default {
sl@0: 			    manerror "unrecognized format directive: $line"
sl@0: 			}
sl@0: 		    }
sl@0: 		} else {
sl@0: 		    if {$manual(partial-text) == ""} {
sl@0: 			set manual(partial-text) $line
sl@0: 		    } else {
sl@0: 			append manual(partial-text) \n$line
sl@0: 		    }
sl@0: 		}
sl@0: 	    }
sl@0: 	    if {$manual(partial-text) != ""} {
sl@0: 		lappend manual(text) [process-text $manual(partial-text)]
sl@0: 	    }
sl@0: 	    close $manual(infp)
sl@0: 	    # fixups
sl@0: 	    if {$manual(.RS) != 0} {
sl@0: 		if {$manual(name) != "selection"} {
sl@0: 		    puts "unbalanced .RS .RE"
sl@0: 		}
sl@0: 	    }
sl@0: 	    if {$manual(.DS) != 0} {
sl@0: 		puts "unbalanced .DS .DE"
sl@0: 	    }
sl@0: 	    if {$manual(.CS) != 0} {
sl@0: 		puts "unbalanced .CS .CE"
sl@0: 	    }
sl@0: 	    if {$manual(.SO) != 0} {
sl@0: 		puts "unbalanced .SO .SE"
sl@0: 	    }
sl@0: 	    # output conversion
sl@0: 	    open-text
sl@0: 	    if {[next-op-is .HS rest]} {
sl@0: 		set manual($manual(name)-title) \
sl@0: 			"[lrange $rest 1 end] [lindex $rest 0] manual page"
sl@0: 		while {[more-text]} {
sl@0: 		    set line [next-text]
sl@0: 		    if {[is-a-directive $line]} {
sl@0: 			output-directive $line
sl@0: 		    } else {
sl@0: 			man-puts $line
sl@0: 		    }
sl@0: 		}
sl@0: 		man-puts <HR><PRE>
sl@0: 		foreach copyright $manual(copyrights) {
sl@0: 		    man-puts "<A HREF=\"../copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]"
sl@0: 		}
sl@0: 		man-puts "<A HREF=\"../copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr.</PRE>"
sl@0: 		set manual(wing-copyrights) [merge-copyrights $manual(wing-copyrights) $manual(copyrights)]
sl@0: 	    } elseif {[next-op-is .TH rest]} {
sl@0: 		set manual($manual(name)-title) "[lrange $rest 4 end] - [lindex $rest 0] manual page"
sl@0: 		while {[more-text]} {
sl@0: 		    set line [next-text]
sl@0: 		    if {[is-a-directive $line]} {
sl@0: 			output-directive $line
sl@0: 		    } else {
sl@0: 			man-puts $line
sl@0: 		    }
sl@0: 		}
sl@0: 		man-puts <HR><PRE>
sl@0: 		foreach copyright $manual(copyrights) {
sl@0: 		    man-puts "<A HREF=\"../copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]"
sl@0: 		}
sl@0: 		man-puts "<A HREF=\"../copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr.</PRE>"
sl@0: 		set manual(wing-copyrights) [merge-copyrights $manual(wing-copyrights) $manual(copyrights)]
sl@0: 	    } else {
sl@0: 		manerror "no .HS or .TH record found"
sl@0: 	    }
sl@0: 	    #
sl@0: 	    # make the long table of contents for this page
sl@0: 	    #
sl@0: 	    set manual(toc-$manual(wing-file)-$manual(name)) [concat <DL> $manual(section-toc) </DL><HR>]
sl@0: 	}
sl@0: 
sl@0: 	#
sl@0: 	# make the wing table of contents for the section
sl@0: 	#
sl@0: 	set width 0
sl@0: 	foreach name $manual(wing-toc) {
sl@0: 	    if {[string length $name] > $width} {
sl@0: 		set width [string length $name]
sl@0: 	    }
sl@0: 	}
sl@0: 	set perline [expr {120 / $width}]
sl@0: 	set nrows [expr {([llength $manual(wing-toc)]+$perline)/$perline}]
sl@0: 	set n 0
sl@0:         catch {unset rows}
sl@0: 	foreach name [lsort $manual(wing-toc)] {
sl@0: 	    set tail $manual(name-$name)
sl@0: 	    if {[llength $tail] > 1} {
sl@0: 		manerror "$name is defined in more than one file: $tail"
sl@0: 		set tail [lindex $tail [expr {[llength $tail]-1}]]
sl@0: 	    }
sl@0: 	    set tail [file tail $tail]
sl@0: 	    append rows([expr {$n%$nrows}]) \
sl@0: 		    "<td> <a href=\"$tail.htm\">$name</a>"
sl@0: 	    incr n
sl@0: 	}
sl@0: 	puts $manual(wing-toc-fp) <table>
sl@0:         foreach row [lsort -integer [array names rows]] {
sl@0: 	    puts $manual(wing-toc-fp) <tr>$rows($row)</tr>
sl@0: 	}
sl@0: 	puts $manual(wing-toc-fp) </table>
sl@0: 
sl@0: 	#
sl@0: 	# insert wing copyrights
sl@0: 	#
sl@0: 	puts $manual(wing-toc-fp) "<HR><PRE>"
sl@0: 	foreach copyright $manual(wing-copyrights) {
sl@0: 	    puts $manual(wing-toc-fp) "<A HREF=\"../copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]"
sl@0: 	}
sl@0: 	puts $manual(wing-toc-fp) "<A HREF=\"../copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr."
sl@0: 	puts $manual(wing-toc-fp) "</PRE></BODY></HTML>"
sl@0: 	close $manual(wing-toc-fp)
sl@0: 	set manual(merge-copyrights) [merge-copyrights $manual(merge-copyrights) $manual(wing-copyrights)]
sl@0:     }
sl@0: 
sl@0:     ##
sl@0:     ## build the keyword index.
sl@0:     ##
sl@0:     proc strcasecmp {a b} { return [string compare -nocase $a $b] }
sl@0:     set keys [lsort -command strcasecmp [array names manual keyword-*]]
sl@0:     makedirhier $html/Keywords
sl@0:     catch {eval file delete -- [glob $html/Keywords/*]}
sl@0:     puts $manual(short-toc-fp) "<DT><A HREF=\"Keywords/contents.htm\">Keywords</A><DD>The keywords from the $tcltkdesc man pages."
sl@0:     set keyfp [open $html/Keywords/contents.htm w]
sl@0:     puts $keyfp "<HTML><HEAD><TITLE>$tcltkdesc Keywords</TITLE></HEAD>"
sl@0:     puts $keyfp "<BODY><HR><H3>$tcltkdesc Keywords</H3><HR><H2>"
sl@0:     foreach a {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} {
sl@0: 	puts $keyfp "<A HREF=\"$a.htm\">$a</A>"
sl@0: 	set afp [open $html/Keywords/$a.htm w]
sl@0: 	puts $afp "<HTML><HEAD><TITLE>$tcltkdesc Keywords - $a</TITLE></HEAD>"
sl@0: 	puts $afp "<BODY><HR><H3>$tcltkdesc Keywords - $a</H3><HR><H2>"
sl@0: 	foreach b {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} {
sl@0: 	    puts $afp "<A HREF=\"$b.htm\">$b</A>"
sl@0: 	}
sl@0: 	puts $afp "</H2><HR><DL>"
sl@0: 	foreach k $keys {
sl@0: 	    if {[string match -nocase "keyword-${a}*" $k]} {
sl@0: 		set k [string range $k 8 end]
sl@0: 		puts $afp "<DT><A NAME=\"$k\">$k</A><DD>"
sl@0: 		set refs {}
sl@0: 		foreach man $manual(keyword-$k) {
sl@0: 		    set name [lindex $man 0]
sl@0: 		    set file [lindex $man 1]
sl@0: 		    lappend refs "<A HREF=\"../$file\">$name</A>"
sl@0: 		}
sl@0: 		puts $afp [join $refs {, }]
sl@0: 	    }
sl@0: 	}
sl@0: 	puts $afp "</DL><HR><PRE>"
sl@0: 	# insert merged copyrights
sl@0: 	foreach copyright $manual(merge-copyrights) {
sl@0: 	    puts $afp "<A HREF=\"copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]"
sl@0: 	}
sl@0: 	puts $afp "<A HREF=\"copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr."
sl@0: 	puts $afp "</PRE></BODY></HTML>"
sl@0: 	close $afp
sl@0:     }
sl@0:     puts $keyfp "</H2><HR><PRE>"
sl@0: 
sl@0:     # insert merged copyrights
sl@0:     foreach copyright $manual(merge-copyrights) {
sl@0: 	puts $keyfp "<A HREF=\"copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]"
sl@0:     }
sl@0:     puts $keyfp "<A HREF=\"copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr."
sl@0:     puts $keyfp </PRE><HR></BODY></HTML>
sl@0:     close $keyfp
sl@0: 
sl@0:     ##
sl@0:     ## finish off short table of contents
sl@0:     ##
sl@0:     puts $manual(short-toc-fp) {<DT><A HREF="http://www.elf.org">Source</A><DD>More information about these man pages.}
sl@0:     puts $manual(short-toc-fp) "</DL><HR><PRE>"
sl@0:     # insert merged copyrights
sl@0:     foreach copyright $manual(merge-copyrights) {
sl@0: 	puts $manual(short-toc-fp) "<A HREF=\"copyright.htm\">Copyright</A> &#169; [lrange $copyright 2 end]"
sl@0:     }
sl@0:     puts $manual(short-toc-fp) "<A HREF=\"copyright.htm\">Copyright</A> &#169; 1995-1997 Roger E. Critchlow Jr."
sl@0:     puts $manual(short-toc-fp) "</PRE></BODY></HTML>"
sl@0:     close $manual(short-toc-fp)
sl@0: 
sl@0:     ##
sl@0:     ## output man pages
sl@0:     ##
sl@0:     unset manual(section)
sl@0:     foreach path $manual(all-pages) {
sl@0: 	set manual(wing-file) [file dirname $path]
sl@0: 	set manual(tail) [file tail $path]
sl@0: 	set manual(name) [file root $manual(tail)]
sl@0: 	set text $manual(output-$manual(wing-file)-$manual(name))
sl@0: 	set ntext 0
sl@0: 	foreach item $text {
sl@0: 	    incr ntext [llength [split $item \n]]
sl@0: 	    incr ntext
sl@0: 	}
sl@0: 	set toc $manual(toc-$manual(wing-file)-$manual(name))
sl@0: 	set ntoc 0
sl@0: 	foreach item $toc {
sl@0: 	    incr ntoc [llength [split $item \n]]
sl@0: 	    incr ntoc
sl@0: 	}
sl@0: 	puts stderr "rescanning page $manual(name) $ntoc/$ntext"
sl@0: 	set manual(outfp) [open $html/$manual(wing-file)/$manual(name).htm w]
sl@0: 	puts $manual(outfp) "<HTML><HEAD><TITLE>$manual($manual(name)-title)</TITLE></HEAD><BODY>"
sl@0: 	if {($ntext > 60) && ($ntoc > 32) || [lsearch {
sl@0: 	    Hash LinkVar SetVar TraceVar ConfigWidg CrtImgType CrtItemType
sl@0: 	    CrtPhImgFmt DoOneEvent GetBitmap GetColor GetCursor GetDash
sl@0: 	    GetJustify GetPixels GetVisual ParseArgv QueueEvent
sl@0: 	} $manual(tail)] >= 0} {
sl@0: 	    foreach item $toc {
sl@0: 		puts $manual(outfp) $item
sl@0: 	    }
sl@0: 	}
sl@0: 	foreach item $text {
sl@0: 	    puts $manual(outfp) [insert-cross-references $item]
sl@0: 	}
sl@0: 	puts $manual(outfp) </BODY></HTML>
sl@0: 	close $manual(outfp)
sl@0:     }
sl@0:     return {}
sl@0: }
sl@0: 
sl@0: parse_command_line
sl@0: 
sl@0: set tcltkdesc ""; set cmdesc ""; set appdir ""
sl@0: if {$build_tcl} {append tcltkdesc "Tcl"; append cmdesc "Tcl"; append appdir "$tcldir"}
sl@0: if {$build_tcl && $build_tk} {append tcltkdesc "/"; append cmdesc " and "; append appdir ","}
sl@0: if {$build_tk} {append tcltkdesc "Tk"; append cmdesc "Tk"; append appdir "$tkdir"}
sl@0: 
sl@0: set usercmddesc "The interpreters which implement $cmdesc."
sl@0: set tclcmddesc {The commands which the <B>tclsh</B> interpreter implements.}
sl@0: set tkcmddesc {The additional commands which the <B>wish</B> interpreter implements.}
sl@0: set tcllibdesc {The C functions which a Tcl extended C program may use.}
sl@0: set tklibdesc {The additional C functions which a Tk extended C program may use.}
sl@0: 		
sl@0: if {1} {
sl@0:     if {[catch {
sl@0: 	make-man-pages $webdir \
sl@0: 	    "$tcltkdir/{$appdir}/doc/*.1 \"$tcltkdesc Applications\" UserCmd {$usercmddesc}" \
sl@0: 	    [expr {$build_tcl ? "$tcltkdir/$tcldir/doc/*.n {Tcl Commands} TclCmd {$tclcmddesc}" : ""}] \
sl@0: 	    [expr {$build_tk ? "$tcltkdir/$tkdir/doc/*.n {Tk Commands} TkCmd {$tkcmddesc}" : ""}] \
sl@0: 	    [expr {$build_tcl ? "$tcltkdir/$tcldir/doc/*.3 {Tcl Library} TclLib {$tcllibdesc}" : ""}] \
sl@0: 	    [expr {$build_tk ? "$tcltkdir/$tkdir/doc/*.3 {Tk Library} TkLib {$tklibdesc}" : ""}]
sl@0:     } error]} {
sl@0: 	puts $error\n$errorInfo
sl@0:     }
sl@0: }