| 1 | #!/bin/sh | 
|---|
| 2 | # The next line is executed by /bin/sh, but not tcl \ | 
|---|
| 3 | exec tclsh8.4 "$0" ${1+"$@"} | 
|---|
| 4 |  | 
|---|
| 5 | package require Tcl 8.5 | 
|---|
| 6 |  | 
|---|
| 7 | # Convert Ousterhout format man pages into highly crosslinked hypertext. | 
|---|
| 8 | # | 
|---|
| 9 | # Along the way detect many unmatched font changes and other odd things. | 
|---|
| 10 | # | 
|---|
| 11 | # Note well, this program is a hack rather than a piece of software | 
|---|
| 12 | # engineering.  In that sense it's probably a good example of things | 
|---|
| 13 | # that a scripting language, like Tcl, can do well.  It is offered as | 
|---|
| 14 | # an example of how someone might convert a specific set of man pages | 
|---|
| 15 | # into hypertext, not as a general solution to the problem.  If you | 
|---|
| 16 | # try to use this, you'll be very much on your own. | 
|---|
| 17 | # | 
|---|
| 18 | # Copyright (c) 1995-1997 Roger E. Critchlow Jr | 
|---|
| 19 |  | 
|---|
| 20 | set Version "0.40" | 
|---|
| 21 |  | 
|---|
| 22 | set ::CSSFILE "docs.css" | 
|---|
| 23 |  | 
|---|
| 24 | proc parse_command_line {} { | 
|---|
| 25 |     global argv Version | 
|---|
| 26 |  | 
|---|
| 27 |     # These variables determine where the man pages come from and where | 
|---|
| 28 |     # the converted pages go to. | 
|---|
| 29 |     global tcltkdir tkdir tcldir webdir build_tcl build_tk | 
|---|
| 30 |  | 
|---|
| 31 |     # Set defaults based on original code. | 
|---|
| 32 |     set tcltkdir ../.. | 
|---|
| 33 |     set tkdir {} | 
|---|
| 34 |     set tcldir {} | 
|---|
| 35 |     set webdir ../html | 
|---|
| 36 |     set build_tcl 0 | 
|---|
| 37 |     set build_tk 0 | 
|---|
| 38 |     # Default search version is a glob pattern | 
|---|
| 39 |     set useversion {{,[8-9].[0-9]{,[.ab][0-9]{,[0-9]}}}} | 
|---|
| 40 |  | 
|---|
| 41 |     # Handle arguments a la GNU: | 
|---|
| 42 |     #   --version | 
|---|
| 43 |     #   --useversion=<version> | 
|---|
| 44 |     #   --help | 
|---|
| 45 |     #   --srcdir=/path | 
|---|
| 46 |     #   --htmldir=/path | 
|---|
| 47 |  | 
|---|
| 48 |     foreach option $argv { | 
|---|
| 49 |         switch -glob -- $option { | 
|---|
| 50 |             --version { | 
|---|
| 51 |                 puts "tcltk-man-html $Version" | 
|---|
| 52 |                 exit 0 | 
|---|
| 53 |             } | 
|---|
| 54 |  | 
|---|
| 55 |             --help { | 
|---|
| 56 |                 puts "usage: tcltk-man-html \[OPTION\] ...\n" | 
|---|
| 57 |                 puts "  --help              print this help, then exit" | 
|---|
| 58 |                 puts "  --version           print version number, then exit" | 
|---|
| 59 |                 puts "  --srcdir=DIR        find tcl and tk source below DIR" | 
|---|
| 60 |                 puts "  --htmldir=DIR       put generated HTML in DIR" | 
|---|
| 61 |                 puts "  --tcl               build tcl help" | 
|---|
| 62 |                 puts "  --tk                build tk help" | 
|---|
| 63 |                 puts "  --useversion        version of tcl/tk to search for" | 
|---|
| 64 |                 exit 0 | 
|---|
| 65 |             } | 
|---|
| 66 |  | 
|---|
| 67 |             --srcdir=* { | 
|---|
| 68 |                 # length of "--srcdir=" is 9. | 
|---|
| 69 |                 set tcltkdir [string range $option 9 end] | 
|---|
| 70 |             } | 
|---|
| 71 |  | 
|---|
| 72 |             --htmldir=* { | 
|---|
| 73 |                 # length of "--htmldir=" is 10 | 
|---|
| 74 |                 set webdir [string range $option 10 end] | 
|---|
| 75 |             } | 
|---|
| 76 |  | 
|---|
| 77 |             --useversion=* { | 
|---|
| 78 |                 # length of "--useversion=" is 13 | 
|---|
| 79 |                 set useversion [string range $option 13 end] | 
|---|
| 80 |             } | 
|---|
| 81 |  | 
|---|
| 82 |             --tcl { | 
|---|
| 83 |                 set build_tcl 1 | 
|---|
| 84 |             } | 
|---|
| 85 |  | 
|---|
| 86 |             --tk { | 
|---|
| 87 |                 set build_tk 1 | 
|---|
| 88 |             } | 
|---|
| 89 |  | 
|---|
| 90 |             default { | 
|---|
| 91 |                 puts stderr "tcltk-man-html: unrecognized option -- `$option'" | 
|---|
| 92 |                 exit 1 | 
|---|
| 93 |             } | 
|---|
| 94 |         } | 
|---|
| 95 |     } | 
|---|
| 96 |  | 
|---|
| 97 |     if {!$build_tcl && !$build_tk} { | 
|---|
| 98 |         set build_tcl 1; | 
|---|
| 99 |         set build_tk 1 | 
|---|
| 100 |     } | 
|---|
| 101 |  | 
|---|
| 102 |     if {$build_tcl} { | 
|---|
| 103 |         # Find Tcl. | 
|---|
| 104 |         set tcldir [lindex [lsort [glob -nocomplain -tails -type d \ | 
|---|
| 105 |                 -directory $tcltkdir tcl$useversion]] end] | 
|---|
| 106 |         if {$tcldir eq ""} { | 
|---|
| 107 |             puts stderr "tcltk-man-html: couldn't find Tcl below $tcltkdir" | 
|---|
| 108 |             exit 1 | 
|---|
| 109 |         } | 
|---|
| 110 |         puts "using Tcl source directory $tcldir" | 
|---|
| 111 |     } | 
|---|
| 112 |  | 
|---|
| 113 |     if {$build_tk} { | 
|---|
| 114 |         # Find Tk. | 
|---|
| 115 |         set tkdir [lindex [lsort [glob -nocomplain -tails -type d \ | 
|---|
| 116 |                                       -directory $tcltkdir tk$useversion]] end] | 
|---|
| 117 |         if {$tkdir eq ""} { | 
|---|
| 118 |             puts stderr "tcltk-man-html: couldn't find Tk below $tcltkdir" | 
|---|
| 119 |             exit 1 | 
|---|
| 120 |         } | 
|---|
| 121 |         puts "using Tk source directory $tkdir" | 
|---|
| 122 |     } | 
|---|
| 123 |  | 
|---|
| 124 |     # the title for the man pages overall | 
|---|
| 125 |     global overall_title | 
|---|
| 126 |     set overall_title "" | 
|---|
| 127 |     if {$build_tcl} { | 
|---|
| 128 |         append overall_title "[capitalize $tcldir]" | 
|---|
| 129 |     } | 
|---|
| 130 |     if {$build_tcl && $build_tk} { | 
|---|
| 131 |         append overall_title "/" | 
|---|
| 132 |     } | 
|---|
| 133 |     if {$build_tk} { | 
|---|
| 134 |         append overall_title "[capitalize $tkdir]" | 
|---|
| 135 |     } | 
|---|
| 136 |     append overall_title " Documentation" | 
|---|
| 137 | } | 
|---|
| 138 |  | 
|---|
| 139 | proc capitalize {string} { | 
|---|
| 140 |     return [string toupper $string 0] | 
|---|
| 141 | } | 
|---|
| 142 |  | 
|---|
| 143 | ## | 
|---|
| 144 | ## | 
|---|
| 145 | ## | 
|---|
| 146 | set manual(report-level) 1 | 
|---|
| 147 |  | 
|---|
| 148 | proc manerror {msg} { | 
|---|
| 149 |     global manual | 
|---|
| 150 |     set name {} | 
|---|
| 151 |     set subj {} | 
|---|
| 152 |     set procname [lindex [info level -1] 0] | 
|---|
| 153 |     if {[info exists manual(name)]} { | 
|---|
| 154 |         set name $manual(name) | 
|---|
| 155 |     } | 
|---|
| 156 |     if {[info exists manual(section)] && [string length $manual(section)]} { | 
|---|
| 157 |         puts stderr "$name: $manual(section): $procname: $msg" | 
|---|
| 158 |     } else { | 
|---|
| 159 |         puts stderr "$name: $procname: $msg" | 
|---|
| 160 |     } | 
|---|
| 161 | } | 
|---|
| 162 |  | 
|---|
| 163 | proc manreport {level msg} { | 
|---|
| 164 |     global manual | 
|---|
| 165 |     if {$level < $manual(report-level)} { | 
|---|
| 166 |         uplevel 1 [list manerror $msg] | 
|---|
| 167 |     } | 
|---|
| 168 | } | 
|---|
| 169 |  | 
|---|
| 170 | proc fatal {msg} { | 
|---|
| 171 |     global manual | 
|---|
| 172 |     uplevel 1 [list manerror $msg] | 
|---|
| 173 |     exit 1 | 
|---|
| 174 | } | 
|---|
| 175 |  | 
|---|
| 176 | ## | 
|---|
| 177 | ## templating | 
|---|
| 178 | ## | 
|---|
| 179 | proc indexfile {} { | 
|---|
| 180 |     if {[info exists ::TARGET] && $::TARGET eq "devsite"} { | 
|---|
| 181 |         return "index.tml" | 
|---|
| 182 |     } else { | 
|---|
| 183 |         return "contents.htm" | 
|---|
| 184 |     } | 
|---|
| 185 | } | 
|---|
| 186 | proc copyright {copyright {level {}}} { | 
|---|
| 187 |     # We don't actually generate a separate copyright page anymore | 
|---|
| 188 |     #set page "${level}copyright.htm" | 
|---|
| 189 |     #return "<A HREF=\"$page\">Copyright</A> © [htmlize-text [lrange $copyright 2 end]]" | 
|---|
| 190 |     # obfuscate any email addresses that may appear in name | 
|---|
| 191 |     set who [string map {@ (at)} [lrange $copyright 2 end]] | 
|---|
| 192 |     return "Copyright © [htmlize-text $who]" | 
|---|
| 193 | } | 
|---|
| 194 | proc copyout {copyrights {level {}}} { | 
|---|
| 195 |     set out "<div class=\"copy\">" | 
|---|
| 196 |     foreach c $copyrights { | 
|---|
| 197 |         append out "[copyright $c $level]\n" | 
|---|
| 198 |     } | 
|---|
| 199 |     append out "</div>" | 
|---|
| 200 |     return $out | 
|---|
| 201 | } | 
|---|
| 202 | proc CSS {{level ""}} { | 
|---|
| 203 |     return "<link rel=\"stylesheet\" href=\"${level}$::CSSFILE\" type=\"text/css\" media=\"all\">\n" | 
|---|
| 204 | } | 
|---|
| 205 | proc DOCTYPE {} { | 
|---|
| 206 |     return "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">" | 
|---|
| 207 | } | 
|---|
| 208 | proc htmlhead {title header args} { | 
|---|
| 209 |     set level "" | 
|---|
| 210 |     if {[lindex $args end] eq "../[indexfile]"} { | 
|---|
| 211 |         # XXX hack - assume same level for CSS file | 
|---|
| 212 |         set level "../" | 
|---|
| 213 |     } | 
|---|
| 214 |     set out "[DOCTYPE]\n<HTML>\n<HEAD><TITLE>$title</TITLE>\n[CSS $level]</HEAD>\n" | 
|---|
| 215 |     foreach {uptitle url} $args { | 
|---|
| 216 |         set header "<a href=\"$url\">$uptitle</a> <small>></small> $header" | 
|---|
| 217 |     } | 
|---|
| 218 |     append out "<BODY><H2>$header</H2>" | 
|---|
| 219 |     global manual | 
|---|
| 220 |     if {[info exists manual(subheader)]} { | 
|---|
| 221 |         set subs {} | 
|---|
| 222 |         foreach {name subdir} $manual(subheader) { | 
|---|
| 223 |             if {$name eq $title} { | 
|---|
| 224 |                 lappend subs $name | 
|---|
| 225 |             } else { | 
|---|
| 226 |                 lappend subs "<A HREF=\"${level}$subdir/[indexfile]\">$name</A>" | 
|---|
| 227 |             } | 
|---|
| 228 |         } | 
|---|
| 229 |         append out "\n<H3>[join $subs { | }]</H3>" | 
|---|
| 230 |     } | 
|---|
| 231 |     return $out | 
|---|
| 232 | } | 
|---|
| 233 | proc gencss {} { | 
|---|
| 234 |     set hBd "1px dotted #11577b" | 
|---|
| 235 |     return " | 
|---|
| 236 | body, div, p, th, td, li, dd, ul, ol, dl, dt, blockquote { | 
|---|
| 237 |     font-family: Verdana, sans-serif; | 
|---|
| 238 | } | 
|---|
| 239 |  | 
|---|
| 240 | pre, code { font-family: 'Courier New', Courier, monospace; } | 
|---|
| 241 |  | 
|---|
| 242 | pre { | 
|---|
| 243 |     background-color:  #f6fcec; | 
|---|
| 244 |     border-top:        1px solid #6A6A6A; | 
|---|
| 245 |     border-bottom:     1px solid #6A6A6A; | 
|---|
| 246 |     padding:           1em; | 
|---|
| 247 |     overflow:          auto; | 
|---|
| 248 | } | 
|---|
| 249 |  | 
|---|
| 250 | body { | 
|---|
| 251 |     background-color:  #FFFFFF; | 
|---|
| 252 |     font-size:         12px; | 
|---|
| 253 |     line-height:       1.25; | 
|---|
| 254 |     letter-spacing:    .2px; | 
|---|
| 255 |     padding-left:      .5em; | 
|---|
| 256 | } | 
|---|
| 257 |  | 
|---|
| 258 | h1, h2, h3, h4 { | 
|---|
| 259 |     font-family:       Georgia, serif; | 
|---|
| 260 |     padding-left:      1em; | 
|---|
| 261 |     margin-top:        1em; | 
|---|
| 262 | } | 
|---|
| 263 |  | 
|---|
| 264 | h1 { | 
|---|
| 265 |     font-size:         18px; | 
|---|
| 266 |     color:             #11577b; | 
|---|
| 267 |     border-bottom:     $hBd; | 
|---|
| 268 |     margin-top:        0px; | 
|---|
| 269 | } | 
|---|
| 270 |  | 
|---|
| 271 | h2 { | 
|---|
| 272 |     font-size:         14px; | 
|---|
| 273 |     color:             #11577b; | 
|---|
| 274 |     background-color:  #c5dce8; | 
|---|
| 275 |     padding-left:      1em; | 
|---|
| 276 |     border:            1px solid #6A6A6A; | 
|---|
| 277 | } | 
|---|
| 278 |  | 
|---|
| 279 | h3, h4 { | 
|---|
| 280 |     color:             #1674A4; | 
|---|
| 281 |     background-color:  #e8f2f6; | 
|---|
| 282 |     border-bottom:     $hBd; | 
|---|
| 283 |     border-top:        $hBd; | 
|---|
| 284 | } | 
|---|
| 285 |  | 
|---|
| 286 | h3 { font-size: 12px; } | 
|---|
| 287 | h4 { font-size: 11px; } | 
|---|
| 288 |  | 
|---|
| 289 | .keylist dt, .arguments dt { | 
|---|
| 290 |   width: 20em; | 
|---|
| 291 |   float: left; | 
|---|
| 292 |   padding: 2px; | 
|---|
| 293 |   border-top: 1px solid #999; | 
|---|
| 294 | } | 
|---|
| 295 |  | 
|---|
| 296 | .keylist dt { font-weight: bold; } | 
|---|
| 297 |  | 
|---|
| 298 | .keylist dd, .arguments dd { | 
|---|
| 299 |   margin-left: 20em; | 
|---|
| 300 |   padding: 2px; | 
|---|
| 301 |   border-top: 1px solid #999; | 
|---|
| 302 | } | 
|---|
| 303 |  | 
|---|
| 304 | .copy { | 
|---|
| 305 |     background-color:  #f6fcfc; | 
|---|
| 306 |     white-space:       pre; | 
|---|
| 307 |     font-size:         80%; | 
|---|
| 308 |     border-top:        1px solid #6A6A6A; | 
|---|
| 309 |     margin-top:        2em; | 
|---|
| 310 | } | 
|---|
| 311 | " | 
|---|
| 312 | } | 
|---|
| 313 |  | 
|---|
| 314 | ## | 
|---|
| 315 | ## parsing | 
|---|
| 316 | ## | 
|---|
| 317 | proc unquote arg { | 
|---|
| 318 |     return [string map [list \" {}] $arg] | 
|---|
| 319 | } | 
|---|
| 320 |  | 
|---|
| 321 | proc parse-directive {line codename restname} { | 
|---|
| 322 |     upvar 1 $codename code $restname rest | 
|---|
| 323 |     return [regexp {^(\.[.a-zA-Z0-9]*) *(.*)} $line all code rest] | 
|---|
| 324 | } | 
|---|
| 325 |  | 
|---|
| 326 | proc htmlize-text {text {charmap {}}} { | 
|---|
| 327 |     # contains some extras for use in nroff->html processing | 
|---|
| 328 |     # build on the list passed in, if any | 
|---|
| 329 |     lappend charmap \ | 
|---|
| 330 |         {&}     {&} \ | 
|---|
| 331 |         {\\}    "\" \ | 
|---|
| 332 |         {\e}    "\" \ | 
|---|
| 333 |         {\ }    { } \ | 
|---|
| 334 |         {\|}    { } \ | 
|---|
| 335 |         {\0}    { } \ | 
|---|
| 336 |         \"      {"} \ | 
|---|
| 337 |         {<}     {<} \ | 
|---|
| 338 |         {>}     {>} \ | 
|---|
| 339 |         \u201c "“" \ | 
|---|
| 340 |         \u201d "”" | 
|---|
| 341 |  | 
|---|
| 342 |     return [string map $charmap $text] | 
|---|
| 343 | } | 
|---|
| 344 |  | 
|---|
| 345 | proc process-text {text} { | 
|---|
| 346 |     global manual | 
|---|
| 347 |     # preprocess text | 
|---|
| 348 |     set charmap [list \ | 
|---|
| 349 |                      {\&}       "\t" \ | 
|---|
| 350 |                      {\%}       {} \ | 
|---|
| 351 |                      "\\\n"     "\n" \ | 
|---|
| 352 |                      {\(+-}     "±" \ | 
|---|
| 353 |                      {\(co}     "©" \ | 
|---|
| 354 |                      {\(em}     "—" \ | 
|---|
| 355 |                      {\(fm}     "′" \ | 
|---|
| 356 |                      {\(mu}     "×" \ | 
|---|
| 357 |                      {\(->}     "<font size=\"+1\">→</font>" \ | 
|---|
| 358 |                      {\fP}      {\fR} \ | 
|---|
| 359 |                      {\.}       . \ | 
|---|
| 360 |                      {\(bu}     "•" \ | 
|---|
| 361 |                     ] | 
|---|
| 362 |     lappend charmap {\o'o^'} {ô} ; # o-circumflex in re_syntax.n | 
|---|
| 363 |     lappend charmap {\-\|\-} --        ; # two hyphens | 
|---|
| 364 |     lappend charmap {\-} -             ; # a hyphen | 
|---|
| 365 |  | 
|---|
| 366 |     set text [htmlize-text $text $charmap] | 
|---|
| 367 |     # General quoted entity | 
|---|
| 368 |     regsub -all {\\N'(\d+)'} $text "\\&#\\1;" text | 
|---|
| 369 |     while {[string first "\\" $text] >= 0} { | 
|---|
| 370 |         # C R | 
|---|
| 371 |         if {[regsub {^([^\\]*)\\fC([^\\]*)\\fR(.*)$} $text \ | 
|---|
| 372 |                 {\1<TT>\2</TT>\3} text]} continue | 
|---|
| 373 |         # B R | 
|---|
| 374 |         if {[regsub {^([^\\]*)\\fB([^\\]*)\\fR(.*)$} $text \ | 
|---|
| 375 |                 {\1<B>\2</B>\3} text]} continue | 
|---|
| 376 |         # B I | 
|---|
| 377 |         if {[regsub {^([^\\]*)\\fB([^\\]*)\\fI(.*)$} $text \ | 
|---|
| 378 |                 {\1<B>\2</B>\\fI\3} text]} continue | 
|---|
| 379 |         # I R | 
|---|
| 380 |         if {[regsub {^([^\\]*)\\fI([^\\]*)\\fR(.*)$} $text \ | 
|---|
| 381 |                 {\1<I>\2</I>\3} text]} continue | 
|---|
| 382 |         # I B | 
|---|
| 383 |         if {[regsub {^([^\\]*)\\fI([^\\]*)\\fB(.*)$} $text \ | 
|---|
| 384 |                 {\1<I>\2</I>\\fB\3} text]} continue | 
|---|
| 385 |         # B B, I I, R R | 
|---|
| 386 |         if { | 
|---|
| 387 |             [regsub {^([^\\]*)\\fB([^\\]*)\\fB(.*)$} $text \ | 
|---|
| 388 |                 {\1\\fB\2\3} ntext] | 
|---|
| 389 |             || [regsub {^([^\\]*)\\fI([^\\]*)\\fI(.*)$} $text \ | 
|---|
| 390 |                     {\1\\fI\2\3} ntext] | 
|---|
| 391 |             || [regsub {^([^\\]*)\\fR([^\\]*)\\fR(.*)$} $text \ | 
|---|
| 392 |                     {\1\\fR\2\3} ntext] | 
|---|
| 393 |         } then { | 
|---|
| 394 |             manerror "impotent font change: $text" | 
|---|
| 395 |             set text $ntext | 
|---|
| 396 |             continue | 
|---|
| 397 |         } | 
|---|
| 398 |         # unrecognized | 
|---|
| 399 |         manerror "uncaught backslash: $text" | 
|---|
| 400 |         set text [string map [list "\\" "\"] $text] | 
|---|
| 401 |     } | 
|---|
| 402 |     return $text | 
|---|
| 403 | } | 
|---|
| 404 | ## | 
|---|
| 405 | ## pass 2 text input and matching | 
|---|
| 406 | ## | 
|---|
| 407 | proc open-text {} { | 
|---|
| 408 |     global manual | 
|---|
| 409 |     set manual(text-length) [llength $manual(text)] | 
|---|
| 410 |     set manual(text-pointer) 0 | 
|---|
| 411 | } | 
|---|
| 412 | proc more-text {} { | 
|---|
| 413 |     global manual | 
|---|
| 414 |     return [expr {$manual(text-pointer) < $manual(text-length)}] | 
|---|
| 415 | } | 
|---|
| 416 | proc next-text {} { | 
|---|
| 417 |     global manual | 
|---|
| 418 |     if {[more-text]} { | 
|---|
| 419 |         set text [lindex $manual(text) $manual(text-pointer)] | 
|---|
| 420 |         incr manual(text-pointer) | 
|---|
| 421 |         return $text | 
|---|
| 422 |     } | 
|---|
| 423 |     manerror "read past end of text" | 
|---|
| 424 |     error "fatal" | 
|---|
| 425 | } | 
|---|
| 426 | proc is-a-directive {line} { | 
|---|
| 427 |     return [string match .* $line] | 
|---|
| 428 | } | 
|---|
| 429 | proc split-directive {line opname restname} { | 
|---|
| 430 |     upvar 1 $opname op $restname rest | 
|---|
| 431 |     set op [string range $line 0 2] | 
|---|
| 432 |     set rest [string trim [string range $line 3 end]] | 
|---|
| 433 | } | 
|---|
| 434 | proc next-op-is {op restname} { | 
|---|
| 435 |     global manual | 
|---|
| 436 |     upvar 1 $restname rest | 
|---|
| 437 |     if {[more-text]} { | 
|---|
| 438 |         set text [lindex $manual(text) $manual(text-pointer)] | 
|---|
| 439 |         if {[string equal -length 3 $text $op]} { | 
|---|
| 440 |             set rest [string range $text 4 end] | 
|---|
| 441 |             incr manual(text-pointer) | 
|---|
| 442 |             return 1 | 
|---|
| 443 |         } | 
|---|
| 444 |     } | 
|---|
| 445 |     return 0 | 
|---|
| 446 | } | 
|---|
| 447 | proc backup-text {n} { | 
|---|
| 448 |     global manual | 
|---|
| 449 |     if {$manual(text-pointer)-$n >= 0} { | 
|---|
| 450 |         incr manual(text-pointer) -$n | 
|---|
| 451 |     } | 
|---|
| 452 | } | 
|---|
| 453 | proc match-text args { | 
|---|
| 454 |     global manual | 
|---|
| 455 |     set nargs [llength $args] | 
|---|
| 456 |     if {$manual(text-pointer) + $nargs > $manual(text-length)} { | 
|---|
| 457 |         return 0 | 
|---|
| 458 |     } | 
|---|
| 459 |     set nback 0 | 
|---|
| 460 |     foreach arg $args { | 
|---|
| 461 |         if {![more-text]} { | 
|---|
| 462 |             backup-text $nback | 
|---|
| 463 |             return 0 | 
|---|
| 464 |         } | 
|---|
| 465 |         set arg [string trim $arg] | 
|---|
| 466 |         set targ [string trim [lindex $manual(text) $manual(text-pointer)]] | 
|---|
| 467 |         if {$arg eq $targ} { | 
|---|
| 468 |             incr nback | 
|---|
| 469 |             incr manual(text-pointer) | 
|---|
| 470 |             continue | 
|---|
| 471 |         } | 
|---|
| 472 |         if {[regexp {^@(\w+)$} $arg all name]} { | 
|---|
| 473 |             upvar 1 $name var | 
|---|
| 474 |             set var $targ | 
|---|
| 475 |             incr nback | 
|---|
| 476 |             incr manual(text-pointer) | 
|---|
| 477 |             continue | 
|---|
| 478 |         } | 
|---|
| 479 |         if {[regexp -nocase {^(\.[A-Z][A-Z])@(\w+)$} $arg all op name]\ | 
|---|
| 480 |                 && [string equal $op [lindex $targ 0]]} { | 
|---|
| 481 |             upvar 1 $name var | 
|---|
| 482 |             set var [lrange $targ 1 end] | 
|---|
| 483 |             incr nback | 
|---|
| 484 |             incr manual(text-pointer) | 
|---|
| 485 |             continue | 
|---|
| 486 |         } | 
|---|
| 487 |         backup-text $nback | 
|---|
| 488 |         return 0 | 
|---|
| 489 |     } | 
|---|
| 490 |     return 1 | 
|---|
| 491 | } | 
|---|
| 492 | proc expand-next-text {n} { | 
|---|
| 493 |     global manual | 
|---|
| 494 |     return [join [lrange $manual(text) $manual(text-pointer) \ | 
|---|
| 495 |             [expr {$manual(text-pointer)+$n-1}]] \n\n] | 
|---|
| 496 | } | 
|---|
| 497 | ## | 
|---|
| 498 | ## pass 2 output | 
|---|
| 499 | ## | 
|---|
| 500 | proc man-puts {text} { | 
|---|
| 501 |     global manual | 
|---|
| 502 |     lappend manual(output-$manual(wing-file)-$manual(name)) $text | 
|---|
| 503 | } | 
|---|
| 504 |  | 
|---|
| 505 | ## | 
|---|
| 506 | ## build hypertext links to tables of contents | 
|---|
| 507 | ## | 
|---|
| 508 | proc long-toc {text} { | 
|---|
| 509 |     global manual | 
|---|
| 510 |     set here M[incr manual(section-toc-n)] | 
|---|
| 511 |     set there L[incr manual(long-toc-n)] | 
|---|
| 512 |     lappend manual(section-toc) \ | 
|---|
| 513 |             "<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$text</A>" | 
|---|
| 514 |     return "<A NAME=\"$here\">$text</A>" | 
|---|
| 515 | } | 
|---|
| 516 | proc option-toc {name class switch} { | 
|---|
| 517 |     global manual | 
|---|
| 518 |     if {[string match "*OPTIONS" $manual(section)]} { | 
|---|
| 519 |         if {$manual(name) ne "ttk_widget"} { | 
|---|
| 520 |             # link the defined option into the long table of contents | 
|---|
| 521 |             set link [long-toc "$switch, $name, $class"] | 
|---|
| 522 |             regsub -- "$switch, $name, $class" $link "$switch" link | 
|---|
| 523 |             return $link | 
|---|
| 524 |         } | 
|---|
| 525 |     } elseif {"$manual(name):$manual(section)" ne "options:DESCRIPTION"} { | 
|---|
| 526 |         error "option-toc in $manual(name) section $manual(section)" | 
|---|
| 527 |     } | 
|---|
| 528 |  | 
|---|
| 529 |     # link the defined standard option to the long table of contents and make | 
|---|
| 530 |     # a target for the standard option references from other man pages. | 
|---|
| 531 |  | 
|---|
| 532 |     set first [lindex $switch 0] | 
|---|
| 533 |     set here M$first | 
|---|
| 534 |     set there L[incr manual(long-toc-n)] | 
|---|
| 535 |     set manual(standard-option-$manual(name)-$first) \ | 
|---|
| 536 |         "<A HREF=\"$manual(name).htm#$here\">$switch, $name, $class</A>" | 
|---|
| 537 |     lappend manual(section-toc) \ | 
|---|
| 538 |         "<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$switch, $name, $class</A>" | 
|---|
| 539 |     return "<A NAME=\"$here\">$switch</A>" | 
|---|
| 540 | } | 
|---|
| 541 | proc std-option-toc {name page} { | 
|---|
| 542 |     global manual | 
|---|
| 543 |     if {[info exists manual(standard-option-$page-$name)]} { | 
|---|
| 544 |         lappend manual(section-toc) <DD>$manual(standard-option-$page-$name) | 
|---|
| 545 |         return $manual(standard-option-$page-$name) | 
|---|
| 546 |     } | 
|---|
| 547 |     manerror "missing reference to \"$name\" in $page.n" | 
|---|
| 548 |     set here M[incr manual(section-toc-n)] | 
|---|
| 549 |     set there L[incr manual(long-toc-n)] | 
|---|
| 550 |     set other M$name | 
|---|
| 551 |     lappend manual(section-toc) "<DD><A HREF=\"$page.htm#$other\">$name</A>" | 
|---|
| 552 |     return "<A HREF=\"$page.htm#$other\">$name</A>" | 
|---|
| 553 | } | 
|---|
| 554 | ## | 
|---|
| 555 | ## process the widget option section | 
|---|
| 556 | ## in widget and options man pages | 
|---|
| 557 | ## | 
|---|
| 558 | proc output-widget-options {rest} { | 
|---|
| 559 |     global manual | 
|---|
| 560 |     man-puts <DL> | 
|---|
| 561 |     lappend manual(section-toc) <DL> | 
|---|
| 562 |     backup-text 1 | 
|---|
| 563 |     set para {} | 
|---|
| 564 |     while {[next-op-is .OP rest]} { | 
|---|
| 565 |         switch -exact -- [llength $rest] { | 
|---|
| 566 |             3 { | 
|---|
| 567 |                 lassign $rest switch name class | 
|---|
| 568 |             } | 
|---|
| 569 |             5 { | 
|---|
| 570 |                 set switch [lrange $rest 0 2] | 
|---|
| 571 |                 set name [lindex $rest 3] | 
|---|
| 572 |                 set class [lindex $rest 4] | 
|---|
| 573 |             } | 
|---|
| 574 |             default { | 
|---|
| 575 |                 fatal "bad .OP $rest" | 
|---|
| 576 |             } | 
|---|
| 577 |         } | 
|---|
| 578 |         if {![regexp {^(<.>)([-\w ]+)(</.>)$} $switch \ | 
|---|
| 579 |                 all oswitch switch cswitch]} { | 
|---|
| 580 |             if {![regexp {^(<.>)([-\w ]+) or ([-\w ]+)(</.>)$} $switch \ | 
|---|
| 581 |                     all oswitch switch1 switch2 cswitch]} { | 
|---|
| 582 |                 error "not Switch: $switch" | 
|---|
| 583 |             } | 
|---|
| 584 |             set switch "$switch1$cswitch or $oswitch$switch2" | 
|---|
| 585 |         } | 
|---|
| 586 |         if {![regexp {^(<.>)([\w]*)(</.>)$} $name all oname name cname]} { | 
|---|
| 587 |             error "not Name: $name" | 
|---|
| 588 |         } | 
|---|
| 589 |         if {![regexp {^(<.>)([\w]*)(</.>)$} $class all oclass class cclass]} { | 
|---|
| 590 |             error "not Class: $class" | 
|---|
| 591 |         } | 
|---|
| 592 |         man-puts "$para<DT>Command-Line Name: $oswitch[option-toc $name $class $switch]$cswitch" | 
|---|
| 593 |         man-puts "<DT>Database Name: $oname$name$cname" | 
|---|
| 594 |         man-puts "<DT>Database Class: $oclass$class$cclass" | 
|---|
| 595 |         man-puts <DD>[next-text] | 
|---|
| 596 |         set para <P> | 
|---|
| 597 |  | 
|---|
| 598 |         if {[next-op-is .RS rest]} { | 
|---|
| 599 |             while {[more-text]} { | 
|---|
| 600 |                 set line [next-text] | 
|---|
| 601 |                 if {[is-a-directive $line]} { | 
|---|
| 602 |                     split-directive $line code rest | 
|---|
| 603 |                     switch -exact -- $code { | 
|---|
| 604 |                         .RE { | 
|---|
| 605 |                             break | 
|---|
| 606 |                         } | 
|---|
| 607 |                         .SH - .SS { | 
|---|
| 608 |                             manerror "unbalanced .RS at section end" | 
|---|
| 609 |                             backup-text 1 | 
|---|
| 610 |                             break | 
|---|
| 611 |                         } | 
|---|
| 612 |                         default { | 
|---|
| 613 |                             output-directive $line | 
|---|
| 614 |                         } | 
|---|
| 615 |                     } | 
|---|
| 616 |                 } else { | 
|---|
| 617 |                     man-puts $line | 
|---|
| 618 |                 } | 
|---|
| 619 |             } | 
|---|
| 620 |         } | 
|---|
| 621 |     } | 
|---|
| 622 |     man-puts </DL> | 
|---|
| 623 |     lappend manual(section-toc) </DL> | 
|---|
| 624 | } | 
|---|
| 625 |  | 
|---|
| 626 | ## | 
|---|
| 627 | ## process .RS lists | 
|---|
| 628 | ## | 
|---|
| 629 | proc output-RS-list {} { | 
|---|
| 630 |     global manual | 
|---|
| 631 |     if {[next-op-is .IP rest]} { | 
|---|
| 632 |         output-IP-list .RS .IP $rest | 
|---|
| 633 |         if {[match-text .RE .sp .RS @rest .IP @rest2]} { | 
|---|
| 634 |             man-puts <P>$rest | 
|---|
| 635 |             output-IP-list .RS .IP $rest2 | 
|---|
| 636 |         } | 
|---|
| 637 |         if {[match-text .RE .sp .RS @rest .RE]} { | 
|---|
| 638 |             man-puts <P>$rest | 
|---|
| 639 |             return | 
|---|
| 640 |         } | 
|---|
| 641 |         if {[next-op-is .RE rest]} { | 
|---|
| 642 |             return | 
|---|
| 643 |         } | 
|---|
| 644 |     } | 
|---|
| 645 |     man-puts <DL><DD> | 
|---|
| 646 |     while {[more-text]} { | 
|---|
| 647 |         set line [next-text] | 
|---|
| 648 |         if {[is-a-directive $line]} { | 
|---|
| 649 |             split-directive $line code rest | 
|---|
| 650 |             switch -exact -- $code { | 
|---|
| 651 |                 .RE { | 
|---|
| 652 |                     break | 
|---|
| 653 |                 } | 
|---|
| 654 |                 .SH - .SS { | 
|---|
| 655 |                     manerror "unbalanced .RS at section end" | 
|---|
| 656 |                     backup-text 1 | 
|---|
| 657 |                     break | 
|---|
| 658 |                 } | 
|---|
| 659 |                 default { | 
|---|
| 660 |                     output-directive $line | 
|---|
| 661 |                 } | 
|---|
| 662 |             } | 
|---|
| 663 |         } else { | 
|---|
| 664 |             man-puts $line | 
|---|
| 665 |         } | 
|---|
| 666 |     } | 
|---|
| 667 |     man-puts </DL> | 
|---|
| 668 | } | 
|---|
| 669 |  | 
|---|
| 670 | ## | 
|---|
| 671 | ## process .IP lists which may be plain indents, | 
|---|
| 672 | ## numeric lists, or definition lists | 
|---|
| 673 | ## | 
|---|
| 674 | proc output-IP-list {context code rest} { | 
|---|
| 675 |     global manual | 
|---|
| 676 |     if {![string length $rest]} { | 
|---|
| 677 |         # blank label, plain indent, no contents entry | 
|---|
| 678 |         man-puts <DL><DD> | 
|---|
| 679 |         while {[more-text]} { | 
|---|
| 680 |             set line [next-text] | 
|---|
| 681 |             if {[is-a-directive $line]} { | 
|---|
| 682 |                 split-directive $line code rest | 
|---|
| 683 |                 if {$code eq ".IP" && $rest eq {}} { | 
|---|
| 684 |                     man-puts "<P>" | 
|---|
| 685 |                     continue | 
|---|
| 686 |                 } | 
|---|
| 687 |                 if {$code in {.br .DS .RS}} { | 
|---|
| 688 |                     output-directive $line | 
|---|
| 689 |                 } else { | 
|---|
| 690 |                     backup-text 1 | 
|---|
| 691 |                     break | 
|---|
| 692 |                 } | 
|---|
| 693 |             } else { | 
|---|
| 694 |                 man-puts $line | 
|---|
| 695 |             } | 
|---|
| 696 |         } | 
|---|
| 697 |         man-puts </DL> | 
|---|
| 698 |     } else { | 
|---|
| 699 |         # labelled list, make contents | 
|---|
| 700 |         if {$context ne ".SH" && $context ne ".SS"} { | 
|---|
| 701 |             man-puts <P> | 
|---|
| 702 |         } | 
|---|
| 703 |         set dl "<DL class=\"[string tolower $manual(section)]\">" | 
|---|
| 704 |         man-puts $dl | 
|---|
| 705 |         lappend manual(section-toc) $dl | 
|---|
| 706 |         backup-text 1 | 
|---|
| 707 |         set accept_RE 0 | 
|---|
| 708 |         set para {} | 
|---|
| 709 |         while {[more-text]} { | 
|---|
| 710 |             set line [next-text] | 
|---|
| 711 |             if {[is-a-directive $line]} { | 
|---|
| 712 |                 split-directive $line code rest | 
|---|
| 713 |                 switch -exact -- $code { | 
|---|
| 714 |                     .IP { | 
|---|
| 715 |                         if {$accept_RE} { | 
|---|
| 716 |                             output-IP-list .IP $code $rest | 
|---|
| 717 |                             continue | 
|---|
| 718 |                         } | 
|---|
| 719 |                         if {$manual(section) eq "ARGUMENTS" || \ | 
|---|
| 720 |                                 [regexp {^\[\d+\]$} $rest]} { | 
|---|
| 721 |                             man-puts "$para<DT>$rest<DD>" | 
|---|
| 722 |                         } elseif {"•" eq $rest} { | 
|---|
| 723 |                             man-puts "$para<DT><DD>$rest " | 
|---|
| 724 |                         } else { | 
|---|
| 725 |                             man-puts "$para<DT>[long-toc $rest]<DD>" | 
|---|
| 726 |                         } | 
|---|
| 727 |                         if {"$manual(name):$manual(section)" eq \ | 
|---|
| 728 |                                 "selection:DESCRIPTION"} { | 
|---|
| 729 |                             if {[match-text .RE @rest .RS .RS]} { | 
|---|
| 730 |                                 man-puts <DT>[long-toc $rest]<DD> | 
|---|
| 731 |                             } | 
|---|
| 732 |                         } | 
|---|
| 733 |                     } | 
|---|
| 734 |                     .sp - .br - .DS - .CS { | 
|---|
| 735 |                         output-directive $line | 
|---|
| 736 |                     } | 
|---|
| 737 |                     .RS { | 
|---|
| 738 |                         if {[match-text .RS]} { | 
|---|
| 739 |                             output-directive $line | 
|---|
| 740 |                             incr accept_RE 1 | 
|---|
| 741 |                         } elseif {[match-text .CS]} { | 
|---|
| 742 |                             output-directive .CS | 
|---|
| 743 |                             incr accept_RE 1 | 
|---|
| 744 |                         } elseif {[match-text .PP]} { | 
|---|
| 745 |                             output-directive .PP | 
|---|
| 746 |                             incr accept_RE 1 | 
|---|
| 747 |                         } elseif {[match-text .DS]} { | 
|---|
| 748 |                             output-directive .DS | 
|---|
| 749 |                             incr accept_RE 1 | 
|---|
| 750 |                         } else { | 
|---|
| 751 |                             output-directive $line | 
|---|
| 752 |                         } | 
|---|
| 753 |                     } | 
|---|
| 754 |                     .PP { | 
|---|
| 755 |                         if {[match-text @rest1 .br @rest2 .RS]} { | 
|---|
| 756 |                             # yet another nroff kludge as above | 
|---|
| 757 |                             man-puts "$para<DT>[long-toc $rest1]" | 
|---|
| 758 |                             man-puts "<DT>[long-toc $rest2]<DD>" | 
|---|
| 759 |                             incr accept_RE 1 | 
|---|
| 760 |                         } elseif {[match-text @rest .RE]} { | 
|---|
| 761 |                             # gad, this is getting ridiculous | 
|---|
| 762 |                             if {!$accept_RE} { | 
|---|
| 763 |                                 man-puts "</DL><P>$rest<DL>" | 
|---|
| 764 |                                 backup-text 1 | 
|---|
| 765 |                                 set para {} | 
|---|
| 766 |                                 break | 
|---|
| 767 |                             } else { | 
|---|
| 768 |                                 man-puts "<P>$rest" | 
|---|
| 769 |                                 incr accept_RE -1 | 
|---|
| 770 |                             } | 
|---|
| 771 |                         } elseif {$accept_RE} { | 
|---|
| 772 |                             output-directive $line | 
|---|
| 773 |                         } else { | 
|---|
| 774 |                             backup-text 1 | 
|---|
| 775 |                             break | 
|---|
| 776 |                         } | 
|---|
| 777 |                     } | 
|---|
| 778 |                     .RE { | 
|---|
| 779 |                         if {!$accept_RE} { | 
|---|
| 780 |                             backup-text 1 | 
|---|
| 781 |                             break | 
|---|
| 782 |                         } | 
|---|
| 783 |                         incr accept_RE -1 | 
|---|
| 784 |                     } | 
|---|
| 785 |                     default { | 
|---|
| 786 |                         backup-text 1 | 
|---|
| 787 |                         break | 
|---|
| 788 |                     } | 
|---|
| 789 |                 } | 
|---|
| 790 |             } else { | 
|---|
| 791 |                 man-puts $line | 
|---|
| 792 |             } | 
|---|
| 793 |             set para <P> | 
|---|
| 794 |         } | 
|---|
| 795 |         man-puts "$para</DL>" | 
|---|
| 796 |         lappend manual(section-toc) </DL> | 
|---|
| 797 |         if {$accept_RE} { | 
|---|
| 798 |             manerror "missing .RE in output-IP-list" | 
|---|
| 799 |         } | 
|---|
| 800 |     } | 
|---|
| 801 | } | 
|---|
| 802 | ## | 
|---|
| 803 | ## handle the NAME section lines | 
|---|
| 804 | ## there's only one line in the NAME section, | 
|---|
| 805 | ## consisting of a comma separated list of names, | 
|---|
| 806 | ## followed by a hyphen and a short description. | 
|---|
| 807 | ## | 
|---|
| 808 | proc output-name {line} { | 
|---|
| 809 |     global manual | 
|---|
| 810 |     # split name line into pieces | 
|---|
| 811 |     regexp {^([^-]+) - (.*)$} $line all head tail | 
|---|
| 812 |     # output line to manual page untouched | 
|---|
| 813 |     man-puts $line | 
|---|
| 814 |     # output line to long table of contents | 
|---|
| 815 |     lappend manual(section-toc) <DL><DD>$line</DD></DL> | 
|---|
| 816 |     # separate out the names for future reference | 
|---|
| 817 |     foreach name [split $head ,] { | 
|---|
| 818 |         set name [string trim $name] | 
|---|
| 819 |         if {[llength $name] > 1} { | 
|---|
| 820 |             manerror "name has a space: {$name}\nfrom: $line" | 
|---|
| 821 |         } | 
|---|
| 822 |         lappend manual(wing-toc) $name | 
|---|
| 823 |         lappend manual(name-$name) $manual(wing-file)/$manual(name) | 
|---|
| 824 |     } | 
|---|
| 825 | } | 
|---|
| 826 | ## | 
|---|
| 827 | ## build a cross-reference link if appropriate | 
|---|
| 828 | ## | 
|---|
| 829 | proc cross-reference {ref} { | 
|---|
| 830 |     global manual | 
|---|
| 831 |     if {[string match "Tcl_*" $ref]} { | 
|---|
| 832 |         set lref $ref | 
|---|
| 833 |     } elseif {[string match "Tk_*" $ref]} { | 
|---|
| 834 |         set lref $ref | 
|---|
| 835 |     } elseif {$ref eq "Tcl"} { | 
|---|
| 836 |         set lref $ref | 
|---|
| 837 |     } else { | 
|---|
| 838 |         set lref [string tolower $ref] | 
|---|
| 839 |     } | 
|---|
| 840 |     ## | 
|---|
| 841 |     ## nothing to reference | 
|---|
| 842 |     ## | 
|---|
| 843 |     if {![info exists manual(name-$lref)]} { | 
|---|
| 844 |         foreach name { | 
|---|
| 845 |             array file history info interp string trace after clipboard grab | 
|---|
| 846 |             image option pack place selection tk tkwait update winfo wm | 
|---|
| 847 |         } { | 
|---|
| 848 |             if {[regexp "^$name \[a-z0-9]*\$" $lref] && \ | 
|---|
| 849 |                     [info exists manual(name-$name)] && \ | 
|---|
| 850 |                     $manual(tail) ne "$name.n"} { | 
|---|
| 851 |                 return "<A HREF=\"../$manual(name-$name).htm\">$ref</A>" | 
|---|
| 852 |             } | 
|---|
| 853 |         } | 
|---|
| 854 |         if {$lref in {stdin stdout stderr end}} { | 
|---|
| 855 |             # no good place to send these | 
|---|
| 856 |             # tcl tokens? | 
|---|
| 857 |             # also end | 
|---|
| 858 |         } | 
|---|
| 859 |         return $ref | 
|---|
| 860 |     } | 
|---|
| 861 |     ## | 
|---|
| 862 |     ## would be a self reference | 
|---|
| 863 |     ## | 
|---|
| 864 |     foreach name $manual(name-$lref) { | 
|---|
| 865 |         if {"$manual(wing-file)/$manual(name)" in $name} { | 
|---|
| 866 |             return $ref | 
|---|
| 867 |         } | 
|---|
| 868 |     } | 
|---|
| 869 |     ## | 
|---|
| 870 |     ## multiple choices for reference | 
|---|
| 871 |     ## | 
|---|
| 872 |     if {[llength $manual(name-$lref)] > 1} { | 
|---|
| 873 |         set tcl_i [lsearch -glob $manual(name-$lref) *TclCmd*] | 
|---|
| 874 |         set tcl_ref [lindex $manual(name-$lref) $tcl_i] | 
|---|
| 875 |         set tk_i [lsearch -glob $manual(name-$lref) *TkCmd*] | 
|---|
| 876 |         set tk_ref [lindex $manual(name-$lref) $tk_i] | 
|---|
| 877 |         if {$tcl_i >= 0 && $manual(wing-file) eq "TclCmd" | 
|---|
| 878 |                 || $manual(wing-file) eq "TclLib"} { | 
|---|
| 879 |             return "<A HREF=\"../$tcl_ref.htm\">$ref</A>" | 
|---|
| 880 |         } | 
|---|
| 881 |         if {$tk_i >= 0 && $manual(wing-file) eq "TkCmd" | 
|---|
| 882 |                 || $manual(wing-file) eq "TkLib"} { | 
|---|
| 883 |             return "<A HREF=\"../$tk_ref.htm\">$ref</A>" | 
|---|
| 884 |         } | 
|---|
| 885 |         if {$lref eq "exit" && $manual(tail) eq "tclsh.1" && $tcl_i >= 0} { | 
|---|
| 886 |             return "<A HREF=\"../$tcl_ref.htm\">$ref</A>" | 
|---|
| 887 |         } | 
|---|
| 888 |         puts stderr "multiple cross reference to $ref in $manual(name-$lref) from $manual(wing-file)/$manual(tail)" | 
|---|
| 889 |         return $ref | 
|---|
| 890 |     } | 
|---|
| 891 |     ## | 
|---|
| 892 |     ## exceptions, sigh, to the rule | 
|---|
| 893 |     ## | 
|---|
| 894 |     switch -exact -- $manual(tail) { | 
|---|
| 895 |         canvas.n { | 
|---|
| 896 |             if {$lref eq "focus"} { | 
|---|
| 897 |                 upvar 1 tail tail | 
|---|
| 898 |                 set clue [string first command $tail] | 
|---|
| 899 |                 if {$clue < 0 ||  $clue > 5} { | 
|---|
| 900 |                     return $ref | 
|---|
| 901 |                 } | 
|---|
| 902 |             } | 
|---|
| 903 |             if {$lref in {bitmap image text}} { | 
|---|
| 904 |                 return $ref | 
|---|
| 905 |             } | 
|---|
| 906 |         } | 
|---|
| 907 |         checkbutton.n - radiobutton.n { | 
|---|
| 908 |             if {$lref in {image}} { | 
|---|
| 909 |                 return $ref | 
|---|
| 910 |             } | 
|---|
| 911 |         } | 
|---|
| 912 |         menu.n { | 
|---|
| 913 |             if {$lref in {checkbutton radiobutton}} { | 
|---|
| 914 |                 return $ref | 
|---|
| 915 |             } | 
|---|
| 916 |         } | 
|---|
| 917 |         options.n { | 
|---|
| 918 |             if {$lref in {bitmap image set}} { | 
|---|
| 919 |                 return $ref | 
|---|
| 920 |             } | 
|---|
| 921 |         } | 
|---|
| 922 |         regexp.n { | 
|---|
| 923 |             if {$lref in {string}} { | 
|---|
| 924 |                 return $ref | 
|---|
| 925 |             } | 
|---|
| 926 |         } | 
|---|
| 927 |         source.n { | 
|---|
| 928 |             if {$lref in {text}} { | 
|---|
| 929 |                 return $ref | 
|---|
| 930 |             } | 
|---|
| 931 |         } | 
|---|
| 932 |         history.n { | 
|---|
| 933 |             if {$lref in {exec}} { | 
|---|
| 934 |                 return $ref | 
|---|
| 935 |             } | 
|---|
| 936 |         } | 
|---|
| 937 |         return.n { | 
|---|
| 938 |             if {$lref in {error continue break}} { | 
|---|
| 939 |                 return $ref | 
|---|
| 940 |             } | 
|---|
| 941 |         } | 
|---|
| 942 |         scrollbar.n { | 
|---|
| 943 |             if {$lref in {set}} { | 
|---|
| 944 |                 return $ref | 
|---|
| 945 |             } | 
|---|
| 946 |         } | 
|---|
| 947 |     } | 
|---|
| 948 |     ## | 
|---|
| 949 |     ## return the cross reference | 
|---|
| 950 |     ## | 
|---|
| 951 |     return "<A HREF=\"../$manual(name-$lref).htm\">$ref</A>" | 
|---|
| 952 | } | 
|---|
| 953 | ## | 
|---|
| 954 | ## reference generation errors | 
|---|
| 955 | ## | 
|---|
| 956 | proc reference-error {msg text} { | 
|---|
| 957 |     global manual | 
|---|
| 958 |     puts stderr "$manual(tail): $msg: {$text}" | 
|---|
| 959 |     return $text | 
|---|
| 960 | } | 
|---|
| 961 | ## | 
|---|
| 962 | ## insert as many cross references into this text string as are appropriate | 
|---|
| 963 | ## | 
|---|
| 964 | proc insert-cross-references {text} { | 
|---|
| 965 |     global manual | 
|---|
| 966 |     ## | 
|---|
| 967 |     ## we identify cross references by: | 
|---|
| 968 |     ##     ``quotation'' | 
|---|
| 969 |     ##    <B>emboldening</B> | 
|---|
| 970 |     ##    Tcl_ prefix | 
|---|
| 971 |     ##    Tk_ prefix | 
|---|
| 972 |     ##    [a-zA-Z0-9]+ manual entry | 
|---|
| 973 |     ## and we avoid messing with already anchored text | 
|---|
| 974 |     ## | 
|---|
| 975 |     ## | 
|---|
| 976 |     ## find where each item lives | 
|---|
| 977 |     ## | 
|---|
| 978 |     array set offset [list \ | 
|---|
| 979 |             anchor [string first {<A } $text] \ | 
|---|
| 980 |             end-anchor [string first {</A>} $text] \ | 
|---|
| 981 |             quote [string first {``} $text] \ | 
|---|
| 982 |             end-quote [string first {''} $text] \ | 
|---|
| 983 |             bold [string first {<B>} $text] \ | 
|---|
| 984 |             end-bold [string first {</B>} $text] \ | 
|---|
| 985 |             tcl [string first {Tcl_} $text] \ | 
|---|
| 986 |             tk [string first {Tk_} $text] \ | 
|---|
| 987 |             Tcl1 [string first {Tcl manual entry} $text] \ | 
|---|
| 988 |             Tcl2 [string first {Tcl overview manual entry} $text] \ | 
|---|
| 989 |             ] | 
|---|
| 990 |     ## | 
|---|
| 991 |     ## accumulate a list | 
|---|
| 992 |     ## | 
|---|
| 993 |     foreach name [array names offset] { | 
|---|
| 994 |         if {$offset($name) >= 0} { | 
|---|
| 995 |             set invert($offset($name)) $name | 
|---|
| 996 |             lappend offsets $offset($name) | 
|---|
| 997 |         } | 
|---|
| 998 |     } | 
|---|
| 999 |     ## | 
|---|
| 1000 |     ## if nothing, then we're done. | 
|---|
| 1001 |     ## | 
|---|
| 1002 |     if {![info exists offsets]} { | 
|---|
| 1003 |         return $text | 
|---|
| 1004 |     } | 
|---|
| 1005 |     ## | 
|---|
| 1006 |     ## sort the offsets | 
|---|
| 1007 |     ## | 
|---|
| 1008 |     set offsets [lsort -integer $offsets] | 
|---|
| 1009 |     ## | 
|---|
| 1010 |     ## see which we want to use | 
|---|
| 1011 |     ## | 
|---|
| 1012 |     switch -exact -- $invert([lindex $offsets 0]) { | 
|---|
| 1013 |         anchor { | 
|---|
| 1014 |             if {$offset(end-anchor) < 0} { | 
|---|
| 1015 |                 return [reference-error {Missing end anchor} $text] | 
|---|
| 1016 |             } | 
|---|
| 1017 |             set head [string range $text 0 $offset(end-anchor)] | 
|---|
| 1018 |             set tail [string range $text [expr {$offset(end-anchor)+1}] end] | 
|---|
| 1019 |             return $head[insert-cross-references $tail] | 
|---|
| 1020 |         } | 
|---|
| 1021 |         quote { | 
|---|
| 1022 |             if {$offset(end-quote) < 0} { | 
|---|
| 1023 |                 return [reference-error "Missing end quote" $text] | 
|---|
| 1024 |             } | 
|---|
| 1025 |             if {$invert([lindex $offsets 1]) eq "tk"} { | 
|---|
| 1026 |                 set offsets [lreplace $offsets 1 1] | 
|---|
| 1027 |             } | 
|---|
| 1028 |             if {$invert([lindex $offsets 1]) eq "tcl"} { | 
|---|
| 1029 |                 set offsets [lreplace $offsets 1 1] | 
|---|
| 1030 |             } | 
|---|
| 1031 |             switch -exact -- $invert([lindex $offsets 1]) { | 
|---|
| 1032 |                 end-quote { | 
|---|
| 1033 |                     set head [string range $text 0 [expr {$offset(quote)-1}]] | 
|---|
| 1034 |                     set body [string range $text [expr {$offset(quote)+2}] \ | 
|---|
| 1035 |                             [expr {$offset(end-quote)-1}]] | 
|---|
| 1036 |                     set tail [string range $text \ | 
|---|
| 1037 |                             [expr {$offset(end-quote)+2}] end] | 
|---|
| 1038 |                     return "$head``[cross-reference $body]''[insert-cross-references $tail]" | 
|---|
| 1039 |                 } | 
|---|
| 1040 |                 bold - | 
|---|
| 1041 |                 anchor { | 
|---|
| 1042 |                     set head [string range $text \ | 
|---|
| 1043 |                             0 [expr {$offset(end-quote)+1}]] | 
|---|
| 1044 |                     set tail [string range $text \ | 
|---|
| 1045 |                             [expr {$offset(end-quote)+2}] end] | 
|---|
| 1046 |                     return "$head[insert-cross-references $tail]" | 
|---|
| 1047 |                 } | 
|---|
| 1048 |             } | 
|---|
| 1049 |             return [reference-error "Uncaught quote case" $text] | 
|---|
| 1050 |         } | 
|---|
| 1051 |         bold { | 
|---|
| 1052 |             if {$offset(end-bold) < 0} { | 
|---|
| 1053 |                 return $text | 
|---|
| 1054 |             } | 
|---|
| 1055 |             if {$invert([lindex $offsets 1]) eq "tk"} { | 
|---|
| 1056 |                 set offsets [lreplace $offsets 1 1] | 
|---|
| 1057 |             } | 
|---|
| 1058 |             if {$invert([lindex $offsets 1]) eq "tcl"} { | 
|---|
| 1059 |                 set offsets [lreplace $offsets 1 1] | 
|---|
| 1060 |             } | 
|---|
| 1061 |             switch -exact -- $invert([lindex $offsets 1]) { | 
|---|
| 1062 |                 end-bold { | 
|---|
| 1063 |                     set head [string range $text 0 [expr {$offset(bold)-1}]] | 
|---|
| 1064 |                     set body [string range $text [expr {$offset(bold)+3}] \ | 
|---|
| 1065 |                             [expr {$offset(end-bold)-1}]] | 
|---|
| 1066 |                     set tail [string range $text \ | 
|---|
| 1067 |                             [expr {$offset(end-bold)+4}] end] | 
|---|
| 1068 |                     return "$head<B>[cross-reference $body]</B>[insert-cross-references $tail]" | 
|---|
| 1069 |                 } | 
|---|
| 1070 |                 anchor { | 
|---|
| 1071 |                     set head [string range $text \ | 
|---|
| 1072 |                             0 [expr {$offset(end-bold)+3}]] | 
|---|
| 1073 |                     set tail [string range $text \ | 
|---|
| 1074 |                             [expr {$offset(end-bold)+4}] end] | 
|---|
| 1075 |                     return "$head[insert-cross-references $tail]" | 
|---|
| 1076 |                 } | 
|---|
| 1077 |             } | 
|---|
| 1078 |             return [reference-error "Uncaught bold case" $text] | 
|---|
| 1079 |         } | 
|---|
| 1080 |         tk { | 
|---|
| 1081 |             set head [string range $text 0 [expr {$offset(tk)-1}]] | 
|---|
| 1082 |             set tail [string range $text $offset(tk) end] | 
|---|
| 1083 |             if {![regexp {^(Tk_\w+)(.*)$} $tail all body tail]} { | 
|---|
| 1084 |                 return [reference-error "Tk regexp failed" $text] | 
|---|
| 1085 |             } | 
|---|
| 1086 |             return $head[cross-reference $body][insert-cross-references $tail] | 
|---|
| 1087 |         } | 
|---|
| 1088 |         tcl { | 
|---|
| 1089 |             set head [string range $text 0 [expr {$offset(tcl)-1}]] | 
|---|
| 1090 |             set tail [string range $text $offset(tcl) end] | 
|---|
| 1091 |             if {![regexp {^(Tcl_\w+)(.*)$} $tail all body tail]} { | 
|---|
| 1092 |                 return [reference-error {Tcl regexp failed} $text] | 
|---|
| 1093 |             } | 
|---|
| 1094 |             return $head[cross-reference $body][insert-cross-references $tail] | 
|---|
| 1095 |         } | 
|---|
| 1096 |         Tcl1 - | 
|---|
| 1097 |         Tcl2 { | 
|---|
| 1098 |             set off [lindex $offsets 0] | 
|---|
| 1099 |             set head [string range $text 0 [expr {$off-1}]] | 
|---|
| 1100 |             set body Tcl | 
|---|
| 1101 |             set tail [string range $text [expr {$off+3}] end] | 
|---|
| 1102 |             return $head[cross-reference $body][insert-cross-references $tail] | 
|---|
| 1103 |         } | 
|---|
| 1104 |         end-anchor - | 
|---|
| 1105 |         end-bold - | 
|---|
| 1106 |         end-quote { | 
|---|
| 1107 |             return [reference-error "Out of place $invert([lindex $offsets 0])" $text] | 
|---|
| 1108 |         } | 
|---|
| 1109 |     } | 
|---|
| 1110 | } | 
|---|
| 1111 | ## | 
|---|
| 1112 | ## process formatting directives | 
|---|
| 1113 | ## | 
|---|
| 1114 | proc output-directive {line} { | 
|---|
| 1115 |     global manual | 
|---|
| 1116 |     # process format directive | 
|---|
| 1117 |     split-directive $line code rest | 
|---|
| 1118 |     switch -exact -- $code { | 
|---|
| 1119 |         .BS - .BE { | 
|---|
| 1120 |             # man-puts <HR> | 
|---|
| 1121 |         } | 
|---|
| 1122 |         .SH - .SS { | 
|---|
| 1123 |             # drain any open lists | 
|---|
| 1124 |             # announce the subject | 
|---|
| 1125 |             set manual(section) $rest | 
|---|
| 1126 |             # start our own stack of stuff | 
|---|
| 1127 |             set manual($manual(name)-$manual(section)) {} | 
|---|
| 1128 |             lappend manual(has-$manual(section)) $manual(name) | 
|---|
| 1129 |             if {$code ne ".SS"} { | 
|---|
| 1130 |                 man-puts "<H3>[long-toc $manual(section)]</H3>" | 
|---|
| 1131 |             } else { | 
|---|
| 1132 |                 man-puts "<H4>[long-toc $manual(section)]</H4>" | 
|---|
| 1133 |             } | 
|---|
| 1134 |             # some sections can simply free wheel their way through the text | 
|---|
| 1135 |             # some sections can be processed in their own loops | 
|---|
| 1136 |             switch -exact -- $manual(section) { | 
|---|
| 1137 |                 NAME { | 
|---|
| 1138 |                     if {$manual(tail) in {CrtImgType.3 CrtItemType.3 CrtPhImgFmt.3}} { | 
|---|
| 1139 |                         # these manual pages have two NAME sections | 
|---|
| 1140 |                         if {[info exists manual($manual(tail)-NAME)]} { | 
|---|
| 1141 |                             return | 
|---|
| 1142 |                         } | 
|---|
| 1143 |                         set manual($manual(tail)-NAME) 1 | 
|---|
| 1144 |                     } | 
|---|
| 1145 |                     set names {} | 
|---|
| 1146 |                     while {1} { | 
|---|
| 1147 |                         set line [next-text] | 
|---|
| 1148 |                         if {[is-a-directive $line]} { | 
|---|
| 1149 |                             backup-text 1 | 
|---|
| 1150 |                             output-name [join $names { }] | 
|---|
| 1151 |                             return | 
|---|
| 1152 |                         } else { | 
|---|
| 1153 |                             lappend names [string trim $line] | 
|---|
| 1154 |                         } | 
|---|
| 1155 |                     } | 
|---|
| 1156 |                 } | 
|---|
| 1157 |                 SYNOPSIS { | 
|---|
| 1158 |                     lappend manual(section-toc) <DL> | 
|---|
| 1159 |                     while {1} { | 
|---|
| 1160 |                         if { | 
|---|
| 1161 |                             [next-op-is .nf rest] | 
|---|
| 1162 |                             || [next-op-is .br rest] | 
|---|
| 1163 |                             || [next-op-is .fi rest] | 
|---|
| 1164 |                         } then { | 
|---|
| 1165 |                             continue | 
|---|
| 1166 |                         } | 
|---|
| 1167 |                         if { | 
|---|
| 1168 |                             [next-op-is .SH rest] | 
|---|
| 1169 |                             || [next-op-is .SS rest] | 
|---|
| 1170 |                             || [next-op-is .BE rest] | 
|---|
| 1171 |                             || [next-op-is .SO rest] | 
|---|
| 1172 |                         } then { | 
|---|
| 1173 |                             backup-text 1 | 
|---|
| 1174 |                             break | 
|---|
| 1175 |                         } | 
|---|
| 1176 |                         if {[next-op-is .sp rest]} { | 
|---|
| 1177 |                             #man-puts <P> | 
|---|
| 1178 |                             continue | 
|---|
| 1179 |                         } | 
|---|
| 1180 |                         set more [next-text] | 
|---|
| 1181 |                         if {[is-a-directive $more]} { | 
|---|
| 1182 |                             manerror "in SYNOPSIS found $more" | 
|---|
| 1183 |                             backup-text 1 | 
|---|
| 1184 |                             break | 
|---|
| 1185 |                         } | 
|---|
| 1186 |                         foreach more [split $more \n] { | 
|---|
| 1187 |                             man-puts $more<BR> | 
|---|
| 1188 |                             if {$manual(wing-file) in {TclLib TkLib}} { | 
|---|
| 1189 |                                 lappend manual(section-toc) <DD>$more | 
|---|
| 1190 |                             } | 
|---|
| 1191 |                         } | 
|---|
| 1192 |                     } | 
|---|
| 1193 |                     lappend manual(section-toc) </DL> | 
|---|
| 1194 |                     return | 
|---|
| 1195 |                 } | 
|---|
| 1196 |                 {SEE ALSO} { | 
|---|
| 1197 |                     while {[more-text]} { | 
|---|
| 1198 |                         if {[next-op-is .SH rest] || [next-op-is .SS rest]} { | 
|---|
| 1199 |                             backup-text 1 | 
|---|
| 1200 |                             return | 
|---|
| 1201 |                         } | 
|---|
| 1202 |                         set more [next-text] | 
|---|
| 1203 |                         if {[is-a-directive $more]} { | 
|---|
| 1204 |                             manerror "$more" | 
|---|
| 1205 |                             backup-text 1 | 
|---|
| 1206 |                             return | 
|---|
| 1207 |                         } | 
|---|
| 1208 |                         set nmore {} | 
|---|
| 1209 |                         foreach cr [split $more ,] { | 
|---|
| 1210 |                             set cr [string trim $cr] | 
|---|
| 1211 |                             if {![regexp {^<B>.*</B>$} $cr]} { | 
|---|
| 1212 |                                 set cr <B>$cr</B> | 
|---|
| 1213 |                             } | 
|---|
| 1214 |                             if {[regexp {^<B>(.*)\([13n]\)</B>$} $cr all name]} { | 
|---|
| 1215 |                                 set cr <B>$name</B> | 
|---|
| 1216 |                             } | 
|---|
| 1217 |                             lappend nmore $cr | 
|---|
| 1218 |                         } | 
|---|
| 1219 |                         man-puts [join $nmore {, }] | 
|---|
| 1220 |                     } | 
|---|
| 1221 |                     return | 
|---|
| 1222 |                 } | 
|---|
| 1223 |                 KEYWORDS { | 
|---|
| 1224 |                     while {[more-text]} { | 
|---|
| 1225 |                         if {[next-op-is .SH rest] || [next-op-is .SS rest]} { | 
|---|
| 1226 |                             backup-text 1 | 
|---|
| 1227 |                             return | 
|---|
| 1228 |                         } | 
|---|
| 1229 |                         set more [next-text] | 
|---|
| 1230 |                         if {[is-a-directive $more]} { | 
|---|
| 1231 |                             manerror "$more" | 
|---|
| 1232 |                             backup-text 1 | 
|---|
| 1233 |                             return | 
|---|
| 1234 |                         } | 
|---|
| 1235 |                         set keys {} | 
|---|
| 1236 |                         foreach key [split $more ,] { | 
|---|
| 1237 |                             set key [string trim $key] | 
|---|
| 1238 |                             lappend manual(keyword-$key) [list $manual(name) $manual(wing-file)/$manual(name).htm] | 
|---|
| 1239 |                             set initial [string toupper [string index $key 0]] | 
|---|
| 1240 |                             lappend keys "<A href=\"../Keywords/$initial.htm\#$key\">$key</A>" | 
|---|
| 1241 |                         } | 
|---|
| 1242 |                         man-puts [join $keys {, }] | 
|---|
| 1243 |                     } | 
|---|
| 1244 |                     return | 
|---|
| 1245 |                 } | 
|---|
| 1246 |             } | 
|---|
| 1247 |             if {[next-op-is .IP rest]} { | 
|---|
| 1248 |                 output-IP-list $code .IP $rest | 
|---|
| 1249 |                 return | 
|---|
| 1250 |             } | 
|---|
| 1251 |             if {[next-op-is .PP rest]} { | 
|---|
| 1252 |                 return | 
|---|
| 1253 |             } | 
|---|
| 1254 |             return | 
|---|
| 1255 |         } | 
|---|
| 1256 |         .SO { | 
|---|
| 1257 |             set targetPage $rest | 
|---|
| 1258 |             if {[match-text @stuff .SE]} { | 
|---|
| 1259 |                 output-directive {.SH STANDARD OPTIONS} | 
|---|
| 1260 |                 set opts [split $stuff \n\t] | 
|---|
| 1261 |                 man-puts <DL> | 
|---|
| 1262 |                 lappend manual(section-toc) <DL> | 
|---|
| 1263 |                 foreach option [lsort -dictionary $opts] { | 
|---|
| 1264 |                     man-puts "<DT><B>[std-option-toc $option $targetPage]</B>" | 
|---|
| 1265 |                 } | 
|---|
| 1266 |                 man-puts </DL> | 
|---|
| 1267 |                 lappend manual(section-toc) </DL> | 
|---|
| 1268 |             } else { | 
|---|
| 1269 |                 manerror "unexpected .SO format:\n[expand-next-text 2]" | 
|---|
| 1270 |             } | 
|---|
| 1271 |         } | 
|---|
| 1272 |         .OP { | 
|---|
| 1273 |             output-widget-options $rest | 
|---|
| 1274 |             return | 
|---|
| 1275 |         } | 
|---|
| 1276 |         .IP { | 
|---|
| 1277 |             output-IP-list .IP .IP $rest | 
|---|
| 1278 |             return | 
|---|
| 1279 |         } | 
|---|
| 1280 |         .PP { | 
|---|
| 1281 |             man-puts <P> | 
|---|
| 1282 |         } | 
|---|
| 1283 |         .RS { | 
|---|
| 1284 |             output-RS-list | 
|---|
| 1285 |             return | 
|---|
| 1286 |         } | 
|---|
| 1287 |         .RE { | 
|---|
| 1288 |             manerror "unexpected .RE" | 
|---|
| 1289 |             return | 
|---|
| 1290 |         } | 
|---|
| 1291 |         .br { | 
|---|
| 1292 |             man-puts <BR> | 
|---|
| 1293 |             return | 
|---|
| 1294 |         } | 
|---|
| 1295 |         .DE { | 
|---|
| 1296 |             manerror "unexpected .DE" | 
|---|
| 1297 |             return | 
|---|
| 1298 |         } | 
|---|
| 1299 |         .DS { | 
|---|
| 1300 |             if {[next-op-is .ta rest]} { | 
|---|
| 1301 |                 # skip the leading .ta directive if it is there | 
|---|
| 1302 |             } | 
|---|
| 1303 |             if {[match-text @stuff .DE]} { | 
|---|
| 1304 |                 set td "<td><p style=\"font-size:12px;padding-left:.5em;padding-right:.5em;\">" | 
|---|
| 1305 |                 set bodyText [string map [list \n <tr>$td \t $td] \n$stuff] | 
|---|
| 1306 |                 man-puts "<dl><dd><table border=\"0\">$bodyText</table></dl>" | 
|---|
| 1307 |                 #man-puts <PRE>$stuff</PRE> | 
|---|
| 1308 |             } elseif {[match-text .fi @ul1 @ul2 .nf @stuff .DE]} { | 
|---|
| 1309 |                 man-puts "<PRE>[lindex $ul1 1][lindex $ul2 1]\n$stuff</PRE>" | 
|---|
| 1310 |             } else { | 
|---|
| 1311 |                 manerror "unexpected .DS format:\n[expand-next-text 2]" | 
|---|
| 1312 |             } | 
|---|
| 1313 |             return | 
|---|
| 1314 |         } | 
|---|
| 1315 |         .CS { | 
|---|
| 1316 |             if {[next-op-is .ta rest]} { | 
|---|
| 1317 |                 # ??? | 
|---|
| 1318 |             } | 
|---|
| 1319 |             if {[match-text @stuff .CE]} { | 
|---|
| 1320 |                 man-puts <PRE>$stuff</PRE> | 
|---|
| 1321 |             } else { | 
|---|
| 1322 |                 manerror "unexpected .CS format:\n[expand-next-text 2]" | 
|---|
| 1323 |             } | 
|---|
| 1324 |             return | 
|---|
| 1325 |         } | 
|---|
| 1326 |         .CE { | 
|---|
| 1327 |             manerror "unexpected .CE" | 
|---|
| 1328 |             return | 
|---|
| 1329 |         } | 
|---|
| 1330 |         .sp { | 
|---|
| 1331 |             man-puts <P> | 
|---|
| 1332 |         } | 
|---|
| 1333 |         .ta { | 
|---|
| 1334 |             # these are tab stop settings for short tables | 
|---|
| 1335 |             switch -exact -- $manual(name):$manual(section) { | 
|---|
| 1336 |                 {bind:MODIFIERS} - | 
|---|
| 1337 |                 {bind:EVENT TYPES} - | 
|---|
| 1338 |                 {bind:BINDING SCRIPTS AND SUBSTITUTIONS} - | 
|---|
| 1339 |                 {expr:OPERANDS} - | 
|---|
| 1340 |                 {expr:MATH FUNCTIONS} - | 
|---|
| 1341 |                 {history:DESCRIPTION} - | 
|---|
| 1342 |                 {history:HISTORY REVISION} - | 
|---|
| 1343 |                 {switch:DESCRIPTION} - | 
|---|
| 1344 |                 {upvar:DESCRIPTION} { | 
|---|
| 1345 |                     return;                     # fix.me | 
|---|
| 1346 |                 } | 
|---|
| 1347 |                 default { | 
|---|
| 1348 |                     manerror "ignoring $line" | 
|---|
| 1349 |                 } | 
|---|
| 1350 |             } | 
|---|
| 1351 |         } | 
|---|
| 1352 |         .nf { | 
|---|
| 1353 |             if {[match-text @more .fi]} { | 
|---|
| 1354 |                 foreach more [split $more \n] { | 
|---|
| 1355 |                     man-puts $more<BR> | 
|---|
| 1356 |                 } | 
|---|
| 1357 |             } elseif {[match-text .RS @more .RE .fi]} { | 
|---|
| 1358 |                 man-puts <DL><DD> | 
|---|
| 1359 |                 foreach more [split $more \n] { | 
|---|
| 1360 |                     man-puts $more<BR> | 
|---|
| 1361 |                 } | 
|---|
| 1362 |                 man-puts </DL> | 
|---|
| 1363 |             } elseif {[match-text .RS @more .RS @more2 .RE .RE .fi]} { | 
|---|
| 1364 |                 man-puts <DL><DD> | 
|---|
| 1365 |                 foreach more [split $more \n] { | 
|---|
| 1366 |                     man-puts $more<BR> | 
|---|
| 1367 |                 } | 
|---|
| 1368 |                 man-puts <DL><DD> | 
|---|
| 1369 |                 foreach more2 [split $more2 \n] { | 
|---|
| 1370 |                     man-puts $more2<BR> | 
|---|
| 1371 |                 } | 
|---|
| 1372 |                 man-puts </DL></DL> | 
|---|
| 1373 |             } elseif {[match-text .RS @more .RS @more2 .RE @more3 .RE .fi]} { | 
|---|
| 1374 |                 man-puts <DL><DD> | 
|---|
| 1375 |                 foreach more [split $more \n] { | 
|---|
| 1376 |                     man-puts $more<BR> | 
|---|
| 1377 |                 } | 
|---|
| 1378 |                 man-puts <DL><DD> | 
|---|
| 1379 |                 foreach more2 [split $more2 \n] { | 
|---|
| 1380 |                     man-puts $more2<BR> | 
|---|
| 1381 |                 } | 
|---|
| 1382 |                 man-puts </DL><DD> | 
|---|
| 1383 |                 foreach more3 [split $more3 \n] { | 
|---|
| 1384 |                     man-puts $more3<BR> | 
|---|
| 1385 |                 } | 
|---|
| 1386 |                 man-puts </DL> | 
|---|
| 1387 |             } elseif {[match-text .sp .RS @more .RS @more2 .sp .RE .RE .fi]} { | 
|---|
| 1388 |                 man-puts <P><DL><DD> | 
|---|
| 1389 |                 foreach more [split $more \n] { | 
|---|
| 1390 |                     man-puts $more<BR> | 
|---|
| 1391 |                 } | 
|---|
| 1392 |                 man-puts <DL><DD> | 
|---|
| 1393 |                 foreach more2 [split $more2 \n] { | 
|---|
| 1394 |                     man-puts $more2<BR> | 
|---|
| 1395 |                 } | 
|---|
| 1396 |                 man-puts </DL></DL><P> | 
|---|
| 1397 |             } elseif {[match-text .RS .sp @more .sp .RE .fi]} { | 
|---|
| 1398 |                 man-puts <P><DL><DD> | 
|---|
| 1399 |                 foreach more [split $more \n] { | 
|---|
| 1400 |                     man-puts $more<BR> | 
|---|
| 1401 |                 } | 
|---|
| 1402 |                 man-puts </DL><P> | 
|---|
| 1403 |             } else { | 
|---|
| 1404 |                 manerror "ignoring $line" | 
|---|
| 1405 |             } | 
|---|
| 1406 |         } | 
|---|
| 1407 |         .fi { | 
|---|
| 1408 |             manerror "ignoring $line" | 
|---|
| 1409 |         } | 
|---|
| 1410 |         .na - | 
|---|
| 1411 |         .ad - | 
|---|
| 1412 |         .UL - | 
|---|
| 1413 |         .ne { | 
|---|
| 1414 |             manerror "ignoring $line" | 
|---|
| 1415 |         } | 
|---|
| 1416 |         default { | 
|---|
| 1417 |             manerror "unrecognized format directive: $line" | 
|---|
| 1418 |         } | 
|---|
| 1419 |     } | 
|---|
| 1420 | } | 
|---|
| 1421 | ## | 
|---|
| 1422 | ## merge copyright listings | 
|---|
| 1423 | ##  | 
|---|
| 1424 | proc merge-copyrights {l1 l2} { | 
|---|
| 1425 |     set merge {} | 
|---|
| 1426 |     set re1 {^Copyright +(?:\(c\)|\\\(co|©) +(\w.*?)(?:all rights reserved)?(?:\. )*$} | 
|---|
| 1427 |     set re2 {^(\d+) +(?:by +)?(\w.*)$}         ;# date who | 
|---|
| 1428 |     set re3 {^(\d+)-(\d+) +(?:by +)?(\w.*)$}   ;# from to who | 
|---|
| 1429 |     set re4 {^(\d+), *(\d+) +(?:by +)?(\w.*)$} ;# date1 date2 who | 
|---|
| 1430 |     foreach copyright [concat $l1 $l2] { | 
|---|
| 1431 |         if {[regexp -nocase -- $re1 $copyright -> info]} { | 
|---|
| 1432 |             set info [string trimright $info ". "] ; # remove extra period | 
|---|
| 1433 |             if {[regexp -- $re2 $info -> date who]} { | 
|---|
| 1434 |                 lappend dates($who) $date | 
|---|
| 1435 |                 continue | 
|---|
| 1436 |             } elseif {[regexp -- $re3 $info -> from to who]} { | 
|---|
| 1437 |                 for {set date $from} {$date <= $to} {incr date} { | 
|---|
| 1438 |                     lappend dates($who) $date | 
|---|
| 1439 |                 } | 
|---|
| 1440 |                 continue | 
|---|
| 1441 |             } elseif {[regexp -- $re3 $info -> date1 date2 who]} { | 
|---|
| 1442 |                 lappend dates($who) $date1 $date2 | 
|---|
| 1443 |                 continue | 
|---|
| 1444 |             } | 
|---|
| 1445 |         } | 
|---|
| 1446 |         puts "oops: $copyright" | 
|---|
| 1447 |     } | 
|---|
| 1448 |     foreach who [array names dates] { | 
|---|
| 1449 |         set list [lsort -dictionary $dates($who)] | 
|---|
| 1450 |         if {[llength $list] == 1 || [lindex $list 0] eq [lrange $list end end]} { | 
|---|
| 1451 |             lappend merge "Copyright © [lindex $list 0] $who" | 
|---|
| 1452 |         } else { | 
|---|
| 1453 |             lappend merge "Copyright © [lindex $list 0]-[lrange $list end end] $who" | 
|---|
| 1454 |         } | 
|---|
| 1455 |     } | 
|---|
| 1456 |     return [lsort -dictionary $merge] | 
|---|
| 1457 | } | 
|---|
| 1458 |  | 
|---|
| 1459 | proc makedirhier {dir} { | 
|---|
| 1460 |     if {![file isdirectory $dir] && \ | 
|---|
| 1461 |             [catch {file mkdir $dir} error]} { | 
|---|
| 1462 |         return -code error "cannot create directory $dir: $error" | 
|---|
| 1463 |     } | 
|---|
| 1464 | } | 
|---|
| 1465 |  | 
|---|
| 1466 | proc addbuffer {args} { | 
|---|
| 1467 |     global manual | 
|---|
| 1468 |     if {$manual(partial-text) ne ""} { | 
|---|
| 1469 |         append manual(partial-text) \n | 
|---|
| 1470 |     } | 
|---|
| 1471 |     append manual(partial-text) [join $args ""] | 
|---|
| 1472 | } | 
|---|
| 1473 | proc flushbuffer {} { | 
|---|
| 1474 |     global manual | 
|---|
| 1475 |     if {$manual(partial-text) ne ""} { | 
|---|
| 1476 |         lappend manual(text) [process-text $manual(partial-text)] | 
|---|
| 1477 |         set manual(partial-text) "" | 
|---|
| 1478 |     } | 
|---|
| 1479 | } | 
|---|
| 1480 |  | 
|---|
| 1481 | ## | 
|---|
| 1482 | ## foreach of the man directories specified by args | 
|---|
| 1483 | ## convert manpages into hypertext in the directory | 
|---|
| 1484 | ## specified by html. | 
|---|
| 1485 | ## | 
|---|
| 1486 | proc make-man-pages {html args} { | 
|---|
| 1487 |     global manual overall_title tcltkdesc | 
|---|
| 1488 |     makedirhier $html | 
|---|
| 1489 |     set cssfd [open $html/$::CSSFILE w] | 
|---|
| 1490 |     puts $cssfd [gencss] | 
|---|
| 1491 |     close $cssfd | 
|---|
| 1492 |     set manual(short-toc-n) 1 | 
|---|
| 1493 |     set manual(short-toc-fp) [open $html/[indexfile] w] | 
|---|
| 1494 |     puts $manual(short-toc-fp) [htmlhead $overall_title $overall_title] | 
|---|
| 1495 |     puts $manual(short-toc-fp) "<DL class=\"keylist\">" | 
|---|
| 1496 |     set manual(merge-copyrights) {} | 
|---|
| 1497 |     foreach arg $args { | 
|---|
| 1498 |         # preprocess to set up subheader for the rest of the files | 
|---|
| 1499 |         if {![llength $arg]} { | 
|---|
| 1500 |             continue | 
|---|
| 1501 |         } | 
|---|
| 1502 |         set name [lindex $arg 1] | 
|---|
| 1503 |         set file [lindex $arg 2] | 
|---|
| 1504 |         lappend manual(subheader) $name $file | 
|---|
| 1505 |     } | 
|---|
| 1506 |     foreach arg $args { | 
|---|
| 1507 |         if {![llength $arg]} { | 
|---|
| 1508 |             continue | 
|---|
| 1509 |         } | 
|---|
| 1510 |         set manual(wing-glob) [lindex $arg 0] | 
|---|
| 1511 |         set manual(wing-name) [lindex $arg 1] | 
|---|
| 1512 |         set manual(wing-file) [lindex $arg 2] | 
|---|
| 1513 |         set manual(wing-description) [lindex $arg 3] | 
|---|
| 1514 |         set manual(wing-copyrights) {} | 
|---|
| 1515 |         makedirhier $html/$manual(wing-file) | 
|---|
| 1516 |         set manual(wing-toc-fp) [open $html/$manual(wing-file)/[indexfile] w] | 
|---|
| 1517 |         # whistle | 
|---|
| 1518 |         puts stderr "scanning section $manual(wing-name)" | 
|---|
| 1519 |         # put the entry for this section into the short table of contents | 
|---|
| 1520 |         puts $manual(short-toc-fp) "<DT><A HREF=\"$manual(wing-file)/[indexfile]\">$manual(wing-name)</A></DT><DD>$manual(wing-description)</DD>" | 
|---|
| 1521 |         # initialize the wing table of contents | 
|---|
| 1522 |         puts $manual(wing-toc-fp) [htmlhead $manual(wing-name) \ | 
|---|
| 1523 |                 $manual(wing-name) $overall_title "../[indexfile]"] | 
|---|
| 1524 |         # initialize the short table of contents for this section | 
|---|
| 1525 |         set manual(wing-toc) {} | 
|---|
| 1526 |         # initialize the man directory for this section | 
|---|
| 1527 |         makedirhier $html/$manual(wing-file) | 
|---|
| 1528 |         # initialize the long table of contents for this section | 
|---|
| 1529 |         set manual(long-toc-n) 1 | 
|---|
| 1530 |         # get the manual pages for this section | 
|---|
| 1531 |         set manual(pages) [lsort -dictionary [glob $manual(wing-glob)]] | 
|---|
| 1532 |         set n [lsearch -glob $manual(pages) */ttk_widget.n] | 
|---|
| 1533 |         if {$n >= 0} { | 
|---|
| 1534 |             set manual(pages) "[lindex $manual(pages) $n] [lreplace $manual(pages) $n $n]" | 
|---|
| 1535 |         } | 
|---|
| 1536 |         set n [lsearch -glob $manual(pages) */options.n] | 
|---|
| 1537 |         if {$n >= 0} { | 
|---|
| 1538 |             set manual(pages) "[lindex $manual(pages) $n] [lreplace $manual(pages) $n $n]" | 
|---|
| 1539 |         } | 
|---|
| 1540 |         # set manual(pages) [lrange $manual(pages) 0 5] | 
|---|
| 1541 |         set LQ \u201c | 
|---|
| 1542 |         set RQ \u201d | 
|---|
| 1543 |         foreach manual_page $manual(pages) { | 
|---|
| 1544 |             set manual(page) $manual_page | 
|---|
| 1545 |             # whistle | 
|---|
| 1546 |             puts stderr "scanning page $manual(page)" | 
|---|
| 1547 |             set manual(tail) [file tail $manual(page)] | 
|---|
| 1548 |             set manual(name) [file root $manual(tail)] | 
|---|
| 1549 |             set manual(section) {} | 
|---|
| 1550 |             if {$manual(name) in {case pack-old menubar}} { | 
|---|
| 1551 |                 # obsolete | 
|---|
| 1552 |                 manerror "discarding $manual(name)" | 
|---|
| 1553 |                 continue | 
|---|
| 1554 |             } | 
|---|
| 1555 |             set manual(infp) [open $manual(page)] | 
|---|
| 1556 |             set manual(text) {} | 
|---|
| 1557 |             set manual(partial-text) {} | 
|---|
| 1558 |             foreach p {.RS .DS .CS .SO} { | 
|---|
| 1559 |                 set manual($p) 0 | 
|---|
| 1560 |             } | 
|---|
| 1561 |             set manual(stack) {} | 
|---|
| 1562 |             set manual(section) {} | 
|---|
| 1563 |             set manual(section-toc) {} | 
|---|
| 1564 |             set manual(section-toc-n) 1 | 
|---|
| 1565 |             set manual(copyrights) {} | 
|---|
| 1566 |             lappend manual(copyrights) "Copyright © 1995-1997 Roger E. Critchlow Jr." | 
|---|
| 1567 |             lappend manual(all-pages) $manual(wing-file)/$manual(tail) | 
|---|
| 1568 |             manreport 100 $manual(name) | 
|---|
| 1569 |             while {[gets $manual(infp) line] >= 0} { | 
|---|
| 1570 |                 manreport 100 $line | 
|---|
| 1571 |                 if {[regexp {^[`'][/\\]} $line]} { | 
|---|
| 1572 |                     if {[regexp {Copyright (?:\(c\)|\\\(co).*$} $line copyright]} { | 
|---|
| 1573 |                         lappend manual(copyrights) $copyright | 
|---|
| 1574 |                     } | 
|---|
| 1575 |                     # comment | 
|---|
| 1576 |                     continue | 
|---|
| 1577 |                 } | 
|---|
| 1578 |                 if {"$line" eq {'}} { | 
|---|
| 1579 |                     # comment | 
|---|
| 1580 |                     continue | 
|---|
| 1581 |                 } | 
|---|
| 1582 |                 if {![parse-directive $line code rest]} { | 
|---|
| 1583 |                     addbuffer $line | 
|---|
| 1584 |                     continue | 
|---|
| 1585 |                 } | 
|---|
| 1586 |                 switch -exact -- $code { | 
|---|
| 1587 |                     .ad - .na - .so - .ne - .AS - .VE - .VS - . { | 
|---|
| 1588 |                         # ignore | 
|---|
| 1589 |                         continue | 
|---|
| 1590 |                     } | 
|---|
| 1591 |                 } | 
|---|
| 1592 |                 switch -exact -- $code { | 
|---|
| 1593 |                     .SH - .SS { | 
|---|
| 1594 |                         flushbuffer | 
|---|
| 1595 |                         if {[llength $rest] == 0} { | 
|---|
| 1596 |                             gets $manual(infp) rest | 
|---|
| 1597 |                         } | 
|---|
| 1598 |                         lappend manual(text) "$code [unquote $rest]" | 
|---|
| 1599 |                     } | 
|---|
| 1600 |                     .TH { | 
|---|
| 1601 |                         flushbuffer | 
|---|
| 1602 |                         lappend manual(text) "$code [unquote $rest]" | 
|---|
| 1603 |                     } | 
|---|
| 1604 |                     .QW { | 
|---|
| 1605 |                         set rest [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest] | 
|---|
| 1606 |                         addbuffer $LQ [unquote [lindex $rest 0]] $RQ \ | 
|---|
| 1607 |                             [unquote [lindex $rest 1]] | 
|---|
| 1608 |                     } | 
|---|
| 1609 |                     .PQ { | 
|---|
| 1610 |                         set rest [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest] | 
|---|
| 1611 |                         addbuffer ( $LQ [unquote [lindex $rest 0]] $RQ \ | 
|---|
| 1612 |                             [unquote [lindex $rest 1]] ) \ | 
|---|
| 1613 |                             [unquote [lindex $rest 2]] | 
|---|
| 1614 |                     } | 
|---|
| 1615 |                     .QR { | 
|---|
| 1616 |                         set rest [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest] | 
|---|
| 1617 |                         addbuffer $LQ [unquote [lindex $rest 0]] - \ | 
|---|
| 1618 |                             [unquote [lindex $rest 1]] $RQ \ | 
|---|
| 1619 |                             [unquote [lindex $rest 2]] | 
|---|
| 1620 |                     } | 
|---|
| 1621 |                     .MT { | 
|---|
| 1622 |                         addbuffer $LQ$RQ | 
|---|
| 1623 |                     } | 
|---|
| 1624 |                     .HS - .UL - .ta { | 
|---|
| 1625 |                         flushbuffer | 
|---|
| 1626 |                         lappend manual(text) "$code [unquote $rest]" | 
|---|
| 1627 |                     } | 
|---|
| 1628 |                     .BS - .BE - .br - .fi - .sp - .nf { | 
|---|
| 1629 |                         flushbuffer | 
|---|
| 1630 |                         if {"$rest" ne {}} { | 
|---|
| 1631 |                             manerror "unexpected argument: $line" | 
|---|
| 1632 |                         } | 
|---|
| 1633 |                         lappend manual(text) $code | 
|---|
| 1634 |                     } | 
|---|
| 1635 |                     .AP { | 
|---|
| 1636 |                         flushbuffer | 
|---|
| 1637 |                         lappend manual(text) [concat .IP [process-text "[lindex $rest 0] \\fB[lindex $rest 1]\\fR ([lindex $rest 2])"]] | 
|---|
| 1638 |                     } | 
|---|
| 1639 |                     .IP { | 
|---|
| 1640 |                         flushbuffer | 
|---|
| 1641 |                         regexp {^(.*) +\d+$} $rest all rest | 
|---|
| 1642 |                         lappend manual(text) ".IP [process-text [unquote [string trim $rest]]]" | 
|---|
| 1643 |                     } | 
|---|
| 1644 |                     .TP { | 
|---|
| 1645 |                         flushbuffer | 
|---|
| 1646 |                         while {[is-a-directive [set next [gets $manual(infp)]]]} { | 
|---|
| 1647 |                             manerror "ignoring $next after .TP" | 
|---|
| 1648 |                         } | 
|---|
| 1649 |                         if {"$next" ne {'}} { | 
|---|
| 1650 |                             lappend manual(text) ".IP [process-text $next]" | 
|---|
| 1651 |                         } | 
|---|
| 1652 |                     } | 
|---|
| 1653 |                     .OP { | 
|---|
| 1654 |                         flushbuffer | 
|---|
| 1655 |                         lappend manual(text) [concat .OP [process-text \ | 
|---|
| 1656 |                                 "\\fB[lindex $rest 0]\\fR \\fB[lindex $rest 1]\\fR \\fB[lindex $rest 2]\\fR"]] | 
|---|
| 1657 |                     } | 
|---|
| 1658 |                     .PP - .LP { | 
|---|
| 1659 |                         flushbuffer | 
|---|
| 1660 |                         lappend manual(text) {.PP} | 
|---|
| 1661 |                     } | 
|---|
| 1662 |                     .RS { | 
|---|
| 1663 |                         flushbuffer | 
|---|
| 1664 |                         incr manual(.RS) | 
|---|
| 1665 |                         lappend manual(text) $code | 
|---|
| 1666 |                     } | 
|---|
| 1667 |                     .RE { | 
|---|
| 1668 |                         flushbuffer | 
|---|
| 1669 |                         incr manual(.RS) -1 | 
|---|
| 1670 |                         lappend manual(text) $code | 
|---|
| 1671 |                     } | 
|---|
| 1672 |                     .SO { | 
|---|
| 1673 |                         flushbuffer | 
|---|
| 1674 |                         incr manual(.SO) | 
|---|
| 1675 |                         if {[llength $rest] == 0} { | 
|---|
| 1676 |                             lappend manual(text) "$code options" | 
|---|
| 1677 |                         } else { | 
|---|
| 1678 |                             lappend manual(text) "$code [unquote $rest]" | 
|---|
| 1679 |                         } | 
|---|
| 1680 |                     } | 
|---|
| 1681 |                     .SE { | 
|---|
| 1682 |                         flushbuffer | 
|---|
| 1683 |                         incr manual(.SO) -1 | 
|---|
| 1684 |                         lappend manual(text) $code | 
|---|
| 1685 |                     } | 
|---|
| 1686 |                     .DS { | 
|---|
| 1687 |                         flushbuffer | 
|---|
| 1688 |                         incr manual(.DS) | 
|---|
| 1689 |                         lappend manual(text) $code | 
|---|
| 1690 |                     } | 
|---|
| 1691 |                     .DE { | 
|---|
| 1692 |                         flushbuffer | 
|---|
| 1693 |                         incr manual(.DS) -1 | 
|---|
| 1694 |                         lappend manual(text) $code | 
|---|
| 1695 |                     } | 
|---|
| 1696 |                     .CS { | 
|---|
| 1697 |                         flushbuffer | 
|---|
| 1698 |                         incr manual(.CS) | 
|---|
| 1699 |                         lappend manual(text) $code | 
|---|
| 1700 |                     } | 
|---|
| 1701 |                     .CE { | 
|---|
| 1702 |                         flushbuffer | 
|---|
| 1703 |                         incr manual(.CS) -1 | 
|---|
| 1704 |                         lappend manual(text) $code | 
|---|
| 1705 |                     } | 
|---|
| 1706 |                     .de { | 
|---|
| 1707 |                         while {[gets $manual(infp) line] >= 0} { | 
|---|
| 1708 |                             if {[string match "..*" $line]} { | 
|---|
| 1709 |                                 break | 
|---|
| 1710 |                             } | 
|---|
| 1711 |                         } | 
|---|
| 1712 |                     } | 
|---|
| 1713 |                     .. { | 
|---|
| 1714 |                         error "found .. outside of .de" | 
|---|
| 1715 |                     } | 
|---|
| 1716 |                     default { | 
|---|
| 1717 |                         flushbuffer | 
|---|
| 1718 |                         manerror "unrecognized format directive: $line" | 
|---|
| 1719 |                     } | 
|---|
| 1720 |                 } | 
|---|
| 1721 |             } | 
|---|
| 1722 |             flushbuffer | 
|---|
| 1723 |             close $manual(infp) | 
|---|
| 1724 |             # fixups | 
|---|
| 1725 |             if {$manual(.RS) != 0} { | 
|---|
| 1726 |                 puts "unbalanced .RS .RE" | 
|---|
| 1727 |             } | 
|---|
| 1728 |             if {$manual(.DS) != 0} { | 
|---|
| 1729 |                 puts "unbalanced .DS .DE" | 
|---|
| 1730 |             } | 
|---|
| 1731 |             if {$manual(.CS) != 0} { | 
|---|
| 1732 |                 puts "unbalanced .CS .CE" | 
|---|
| 1733 |             } | 
|---|
| 1734 |             if {$manual(.SO) != 0} { | 
|---|
| 1735 |                 puts "unbalanced .SO .SE" | 
|---|
| 1736 |             } | 
|---|
| 1737 |             # output conversion | 
|---|
| 1738 |             open-text | 
|---|
| 1739 |             set haserror 0 | 
|---|
| 1740 |             if {[next-op-is .HS rest]} { | 
|---|
| 1741 |                 set manual($manual(name)-title) \ | 
|---|
| 1742 |                         "[lrange $rest 1 end] [lindex $rest 0] manual page" | 
|---|
| 1743 |             } elseif {[next-op-is .TH rest]} { | 
|---|
| 1744 |                 set manual($manual(name)-title) "[lindex $rest 0] manual page - [lrange $rest 4 end]" | 
|---|
| 1745 |             } else { | 
|---|
| 1746 |                 set haserror 1 | 
|---|
| 1747 |                 manerror "no .HS or .TH record found" | 
|---|
| 1748 |             } | 
|---|
| 1749 |             if {!$haserror} { | 
|---|
| 1750 |                 while {[more-text]} { | 
|---|
| 1751 |                     set line [next-text] | 
|---|
| 1752 |                     if {[is-a-directive $line]} { | 
|---|
| 1753 |                         output-directive $line | 
|---|
| 1754 |                     } else { | 
|---|
| 1755 |                         man-puts $line | 
|---|
| 1756 |                     } | 
|---|
| 1757 |                 } | 
|---|
| 1758 |                 man-puts [copyout $manual(copyrights) "../"] | 
|---|
| 1759 |                 set manual(wing-copyrights) [merge-copyrights $manual(wing-copyrights) $manual(copyrights)] | 
|---|
| 1760 |             } | 
|---|
| 1761 |             # | 
|---|
| 1762 |             # make the long table of contents for this page | 
|---|
| 1763 |             # | 
|---|
| 1764 |             set manual(toc-$manual(wing-file)-$manual(name)) [concat <DL> $manual(section-toc) </DL>] | 
|---|
| 1765 |         } | 
|---|
| 1766 |  | 
|---|
| 1767 |         # | 
|---|
| 1768 |         # make the wing table of contents for the section | 
|---|
| 1769 |         # | 
|---|
| 1770 |         set width 0 | 
|---|
| 1771 |         foreach name $manual(wing-toc) { | 
|---|
| 1772 |             if {[string length $name] > $width} { | 
|---|
| 1773 |                 set width [string length $name] | 
|---|
| 1774 |             } | 
|---|
| 1775 |         } | 
|---|
| 1776 |         set perline [expr {120 / $width}] | 
|---|
| 1777 |         set nrows [expr {([llength $manual(wing-toc)]+$perline)/$perline}] | 
|---|
| 1778 |         set n 0 | 
|---|
| 1779 |         catch {unset rows} | 
|---|
| 1780 |         foreach name [lsort -dictionary $manual(wing-toc)] { | 
|---|
| 1781 |             set tail $manual(name-$name) | 
|---|
| 1782 |             if {[llength $tail] > 1} { | 
|---|
| 1783 |                 manerror "$name is defined in more than one file: $tail" | 
|---|
| 1784 |                 set tail [lindex $tail [expr {[llength $tail]-1}]] | 
|---|
| 1785 |             } | 
|---|
| 1786 |             set tail [file tail $tail] | 
|---|
| 1787 |             append rows([expr {$n%$nrows}]) \ | 
|---|
| 1788 |                     "<td> <a href=\"$tail.htm\">$name</a>" | 
|---|
| 1789 |             incr n | 
|---|
| 1790 |         } | 
|---|
| 1791 |         puts $manual(wing-toc-fp) <table> | 
|---|
| 1792 |         foreach row [lsort -integer [array names rows]] { | 
|---|
| 1793 |             puts $manual(wing-toc-fp) <tr>$rows($row)</tr> | 
|---|
| 1794 |         } | 
|---|
| 1795 |         puts $manual(wing-toc-fp) </table> | 
|---|
| 1796 |  | 
|---|
| 1797 |         # | 
|---|
| 1798 |         # insert wing copyrights | 
|---|
| 1799 |         # | 
|---|
| 1800 |         puts $manual(wing-toc-fp) [copyout $manual(wing-copyrights) "../"] | 
|---|
| 1801 |         puts $manual(wing-toc-fp) "</BODY></HTML>" | 
|---|
| 1802 |         close $manual(wing-toc-fp) | 
|---|
| 1803 |         set manual(merge-copyrights) [merge-copyrights $manual(merge-copyrights) $manual(wing-copyrights)] | 
|---|
| 1804 |     } | 
|---|
| 1805 |  | 
|---|
| 1806 |     ## | 
|---|
| 1807 |     ## build the keyword index. | 
|---|
| 1808 |     ## | 
|---|
| 1809 |     file delete -force -- $html/Keywords | 
|---|
| 1810 |     makedirhier $html/Keywords | 
|---|
| 1811 |     set keyfp [open $html/Keywords/[indexfile] w] | 
|---|
| 1812 |     puts $keyfp [htmlhead "$tcltkdesc Keywords" "$tcltkdesc Keywords" \ | 
|---|
| 1813 |                      $overall_title "../[indexfile]"] | 
|---|
| 1814 |     set letters {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} | 
|---|
| 1815 |     # Create header first | 
|---|
| 1816 |     set keyheader {} | 
|---|
| 1817 |     foreach a $letters { | 
|---|
| 1818 |         set keys [array names manual "keyword-\[[string totitle $a$a]\]*"] | 
|---|
| 1819 |         if {[llength $keys]} { | 
|---|
| 1820 |             lappend keyheader "<A HREF=\"$a.htm\">$a</A>" | 
|---|
| 1821 |         } else { | 
|---|
| 1822 |             # No keywords for this letter | 
|---|
| 1823 |             lappend keyheader $a | 
|---|
| 1824 |         } | 
|---|
| 1825 |     } | 
|---|
| 1826 |     set keyheader "<H3>[join $keyheader " |\n"]</H3>" | 
|---|
| 1827 |     puts $keyfp $keyheader | 
|---|
| 1828 |     foreach a $letters { | 
|---|
| 1829 |         set keys [array names manual "keyword-\[[string totitle $a$a]\]*"] | 
|---|
| 1830 |         if {![llength $keys]} { | 
|---|
| 1831 |             continue | 
|---|
| 1832 |         } | 
|---|
| 1833 |         # Per-keyword page | 
|---|
| 1834 |         set afp [open $html/Keywords/$a.htm w] | 
|---|
| 1835 |         puts $afp [htmlhead "$tcltkdesc Keywords - $a" \ | 
|---|
| 1836 |                        "$tcltkdesc Keywords - $a" \ | 
|---|
| 1837 |                        $overall_title "../[indexfile]"] | 
|---|
| 1838 |         puts $afp $keyheader | 
|---|
| 1839 |         puts $afp "<DL class=\"keylist\">" | 
|---|
| 1840 |         foreach k [lsort -dictionary $keys] { | 
|---|
| 1841 |             set k [string range $k 8 end] | 
|---|
| 1842 |             puts $afp "<DT><A NAME=\"$k\">$k</A></DT>" | 
|---|
| 1843 |             puts $afp "<DD>" | 
|---|
| 1844 |             set refs {} | 
|---|
| 1845 |             foreach man $manual(keyword-$k) { | 
|---|
| 1846 |                 set name [lindex $man 0] | 
|---|
| 1847 |                 set file [lindex $man 1] | 
|---|
| 1848 |                 lappend refs "<A HREF=\"../$file\">$name</A>" | 
|---|
| 1849 |             } | 
|---|
| 1850 |             puts $afp "[join $refs {, }]</DD>" | 
|---|
| 1851 |         } | 
|---|
| 1852 |         puts $afp "</DL>" | 
|---|
| 1853 |         # insert merged copyrights | 
|---|
| 1854 |         puts $afp [copyout $manual(merge-copyrights)] | 
|---|
| 1855 |         puts $afp "</BODY></HTML>" | 
|---|
| 1856 |         close $afp | 
|---|
| 1857 |     } | 
|---|
| 1858 |     # insert merged copyrights | 
|---|
| 1859 |     puts $keyfp [copyout $manual(merge-copyrights)] | 
|---|
| 1860 |     puts $keyfp "</BODY></HTML>" | 
|---|
| 1861 |     close $keyfp | 
|---|
| 1862 |  | 
|---|
| 1863 |     ## | 
|---|
| 1864 |     ## finish off short table of contents | 
|---|
| 1865 |     ## | 
|---|
| 1866 |     puts $manual(short-toc-fp) "<DT><A HREF=\"Keywords/[indexfile]\">Keywords</A><DD>The keywords from the $tcltkdesc man pages." | 
|---|
| 1867 |     puts $manual(short-toc-fp) "</DL>" | 
|---|
| 1868 |     # insert merged copyrights | 
|---|
| 1869 |     puts $manual(short-toc-fp) [copyout $manual(merge-copyrights)] | 
|---|
| 1870 |     puts $manual(short-toc-fp) "</BODY></HTML>" | 
|---|
| 1871 |     close $manual(short-toc-fp) | 
|---|
| 1872 |  | 
|---|
| 1873 |     ## | 
|---|
| 1874 |     ## output man pages | 
|---|
| 1875 |     ## | 
|---|
| 1876 |     unset manual(section) | 
|---|
| 1877 |     foreach path $manual(all-pages) { | 
|---|
| 1878 |         set manual(wing-file) [file dirname $path] | 
|---|
| 1879 |         set manual(tail) [file tail $path] | 
|---|
| 1880 |         set manual(name) [file root $manual(tail)] | 
|---|
| 1881 |         set text $manual(output-$manual(wing-file)-$manual(name)) | 
|---|
| 1882 |         set ntext 0 | 
|---|
| 1883 |         foreach item $text { | 
|---|
| 1884 |             incr ntext [llength [split $item \n]] | 
|---|
| 1885 |             incr ntext | 
|---|
| 1886 |         } | 
|---|
| 1887 |         set toc $manual(toc-$manual(wing-file)-$manual(name)) | 
|---|
| 1888 |         set ntoc 0 | 
|---|
| 1889 |         foreach item $toc { | 
|---|
| 1890 |             incr ntoc [llength [split $item \n]] | 
|---|
| 1891 |             incr ntoc | 
|---|
| 1892 |         } | 
|---|
| 1893 |         puts stderr "rescanning page $manual(name) $ntoc/$ntext" | 
|---|
| 1894 |         set outfd [open $html/$manual(wing-file)/$manual(name).htm w] | 
|---|
| 1895 |         puts $outfd [htmlhead "$manual($manual(name)-title)" \ | 
|---|
| 1896 |                 $manual(name) $manual(wing-file) "[indexfile]" \ | 
|---|
| 1897 |                 $overall_title "../[indexfile]"] | 
|---|
| 1898 |         if { | 
|---|
| 1899 |             (($ntext > 60) && ($ntoc > 32)) || $manual(tail) in { | 
|---|
| 1900 |                 Hash LinkVar SetVar TraceVar ConfigWidg CrtImgType CrtItemType | 
|---|
| 1901 |                 CrtPhImgFmt DoOneEvent GetBitmap GetColor GetCursor GetDash | 
|---|
| 1902 |                 GetJustify GetPixels GetVisual ParseArgv QueueEvent | 
|---|
| 1903 |             } | 
|---|
| 1904 |         } then { | 
|---|
| 1905 |             foreach item $toc { | 
|---|
| 1906 |                 puts $outfd $item | 
|---|
| 1907 |             } | 
|---|
| 1908 |         } | 
|---|
| 1909 |         foreach item $text { | 
|---|
| 1910 |             puts $outfd [insert-cross-references $item] | 
|---|
| 1911 |         } | 
|---|
| 1912 |         puts $outfd "</BODY></HTML>" | 
|---|
| 1913 |         close $outfd | 
|---|
| 1914 |     } | 
|---|
| 1915 |     return {} | 
|---|
| 1916 | } | 
|---|
| 1917 |  | 
|---|
| 1918 | parse_command_line | 
|---|
| 1919 |  | 
|---|
| 1920 | set tcltkdesc ""; set cmdesc ""; set appdir "" | 
|---|
| 1921 | if {$build_tcl} { | 
|---|
| 1922 |     append tcltkdesc "Tcl" | 
|---|
| 1923 |     append cmdesc "Tcl" | 
|---|
| 1924 |     append appdir "$tcldir" | 
|---|
| 1925 | } | 
|---|
| 1926 | if {$build_tcl && $build_tk} { | 
|---|
| 1927 |     append tcltkdesc "/" | 
|---|
| 1928 |     append cmdesc " and " | 
|---|
| 1929 |     append appdir "," | 
|---|
| 1930 | } | 
|---|
| 1931 | if {$build_tk} { | 
|---|
| 1932 |     append tcltkdesc "Tk" | 
|---|
| 1933 |     append cmdesc "Tk" | 
|---|
| 1934 |     append appdir "$tkdir" | 
|---|
| 1935 | } | 
|---|
| 1936 |  | 
|---|
| 1937 | set usercmddesc "The interpreters which implement $cmdesc." | 
|---|
| 1938 | set tclcmddesc {The commands which the <B>tclsh</B> interpreter implements.} | 
|---|
| 1939 | set tkcmddesc {The additional commands which the <B>wish</B> interpreter implements.} | 
|---|
| 1940 | set tcllibdesc {The C functions which a Tcl extended C program may use.} | 
|---|
| 1941 | set tklibdesc {The additional C functions which a Tk extended C program may use.} | 
|---|
| 1942 |  | 
|---|
| 1943 | if {1} { | 
|---|
| 1944 |     if {[catch { | 
|---|
| 1945 |         make-man-pages $webdir \ | 
|---|
| 1946 |             "$tcltkdir/{$appdir}/doc/*.1 \"$tcltkdesc Applications\" UserCmd {$usercmddesc}" \ | 
|---|
| 1947 |             [expr {$build_tcl ? "$tcltkdir/$tcldir/doc/*.n {Tcl Commands} TclCmd {$tclcmddesc}" : ""}] \ | 
|---|
| 1948 |             [expr {$build_tk ? "$tcltkdir/$tkdir/doc/*.n {Tk Commands} TkCmd {$tkcmddesc}" : ""}] \ | 
|---|
| 1949 |             [expr {$build_tcl ? "$tcltkdir/$tcldir/doc/*.3 {Tcl Library} TclLib {$tcllibdesc}" : ""}] \ | 
|---|
| 1950 |             [expr {$build_tk ? "$tcltkdir/$tkdir/doc/*.3 {Tk Library} TkLib {$tklibdesc}" : ""}] | 
|---|
| 1951 |     } error]} { | 
|---|
| 1952 |         puts $error\n$errorInfo | 
|---|
| 1953 |     } | 
|---|
| 1954 | } | 
|---|