#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"


# 
#  this is a quick and dirty script to convert a text description of
#  the gnocl commands to html man pages
# 
#  Copyright (c) 2001 P.G. Baum
# 
#  See the file "license.terms" for information on usage and redistribution
#  of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 

#  History
#  2001-06: Begin of developement
# 

set HEAD \
{<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="Author" content="Peter G. Baum (peter@dr-baum.net)">
   <meta name="keywords" content="gnocl, Tcl, gtk, gnome">
   <title>TITLE</title>
</head>}

set COPYRIGHT \
   "Copyright &copy; 2001 - 2002 <a href=\"http://www.dr-baum.net\">P. G. Baum</a>"

set fp [open manpages.txt]
set fpAllWithLinks [open allwithlinks.html w]
set fpAllNoLinks [open allnolinks.html w]

puts $fpAllWithLinks [string map {TITLE "gnocl commands"} $HEAD]
puts $fpAllWithLinks "<body>\n<h1>gnocl commands</h1>\n<table>"

puts $fpAllNoLinks [string map {TITLE "gnocl commands"} $HEAD]
puts $fpAllNoLinks "<body>\n<h1>gnocl commands</h1>\n<table>"

proc getLine { fp line {skipEmpty 0} } {
   upvar $line ll
   # skip comments with "#" as first character
   while { [set ret [gets $fp ll]] >= 0 \
         && ( [string index $ll 0] == "#" \
            || ( $skipEmpty && \
                  [string length [set ll [string trim $ll]]] == 0 ) ) } {
      ; # do nothing
   }
   if { !$skipEmpty } {
      set ll [string trim $ll]
   }

   # puts "in getLine: $ll"
   return $ret
}

proc handleShortDescr { fp ll command } {
   upvar $ll line
   upvar $command cmd
   # .SHORTDESCR:
   set cmd(shortDescr) [string trim [string range $line 13 end]]
   return [getLine $fp line 1]
}

proc handleSynopsis { fp ll command } {
   upvar $ll line
   upvar $command cmd
   # .SYNOPSIS:
   set cmd(synopsis) [string trim [string range $line 10 end]]
   return [getLine $fp line 1]
}

proc handleOptions { fp ll command } {
   upvar $ll line
   upvar $command cmd

   # new section start with an "."
   while { [set ret [getLine $fp line 1]] > 0 \
         && [string index $line 0] != "." } {
      set opt $line
      # after the options comes the description til the first empty line
      set descr ""
      while { [set ret [getLine $fp line 0]] > 0 && \
            [string length $line] > 0 } {
         append descr $line "\n"
      }
      # options are separated by "; "
      set q [split [string map {"; " "\n"} $opt] "\n"] 
      lappend q $descr
      lappend cmd(options) $q
   }
   return $ret
}
proc handleDescription { fp ll command } {
   upvar $ll line
   upvar $command cmd

   # .DESCRIPTION:
   set cmd(descr) [string trim [string range $line 14 end]]
   while { [set ret [getLine $fp line 0]] > 0 \
         && [string length $line] > 0 } {
      append cmd(descr) "\n" $line
   }
   if { $ret >= 0 } {
      # skip last empty line
      set ret [getLine $fp line 0]
   }
   return $ret
}
proc handleCommands { fp ll command } {
   upvar $ll line
   upvar $command cmd

   while { [set ret [getLine $fp line 1]] > 0 \
         && [string index $line 0] != "." } {
      set opt $line
      # after the command comes the description til the first empty line
      set descr ""
      while { [set ret [getLine $fp line 0]] > 0 && \
            [string length $line] > 0 } {
         append descr "\n" $line
      }
      lappend cmd(commands) [list $opt $descr]
   }
   return $ret
}
proc handleKeywords { fp ll command } {
   upvar $ll line
   upvar $command cmd
   return [getLine $fp line 1]
}

proc handleHeading { fp ll } {
   upvar $ll line
   # upvar $command cmd
   # .HEADING:

   set txt [string trim [string range $line 9 end]]
   puts $::fpAllNoLinks "\n</table><h2>$txt</h2>\n<table>"
   puts $::fpAllWithLinks "\n</table><h2>$txt</h2>\n<table>"

   return [getLine $fp line 1]
}

proc printCmd { command } {
   upvar $command cmd

   set fileName [string tolower $cmd(name)].html 

   puts $::fpAllNoLinks "<tr><th align=left>$cmd(name)</th>"
   puts $::fpAllNoLinks "   <td>$cmd(shortDescr)</td></tr>"

   puts $::fpAllWithLinks "<tr><th align=left>"
   puts $::fpAllWithLinks "   <a href=\"$fileName\">$cmd(name)</a></th>"
   puts $::fpAllWithLinks "   <td>$cmd(shortDescr)</td></tr>"

   set fp [open $fileName w]
   puts $fp [string map [list TITLE $cmd(name)] $::HEAD]
   puts $fp "<body>\n<h2>NAME</h2>\n$cmd(name) - $cmd(shortDescr)\n"

   puts $fp "<h2>SYNOPSIS</h2>"
   set txt ""
   foreach el [split $cmd(synopsis)] {
      if { [string equal $el $cmd(name)] } {
         append txt "<b>$el</b> "
      } elseif { [string equal $el VAROPTS] } {
         append txt "<i>?-option optionVal ...?</i> " 
      } else {
         append txt "<i>$el</i> "
      }
   }
   puts $fp "<dl><dt>$txt</dt></dl>"


   puts $fp "\n<h2>OPTIONS</h2>"
   foreach el $cmd(options) {
      foreach {name type def descr} $el break
      set def [string map { "\"" "&quot;"} $def]
      puts $fp "   <dl>\n   <dt><b>$name</b></dt>"
      puts $fp "      <dd>$descr"
      puts $fp "      <br>type: <b>$type</b>"
      puts $fp "      <br>default: <b>$def</b></dd></dl>\n"

   }

   puts $fp "\n<h2>DESCRIPTION</h2>"
   puts $fp $cmd(descr)

   puts $fp "\n<h2>WIDGET COMMANDS</h2>"
   if { [llength $cmd(commands)] > 0 } {
      puts $fp "The <b>$cmd(name)</b> command creates a new Tcl command 
whose name is an ID returned on widget creation. This command may be 
used to invoke various operations on the widget. It has the following 
general form: 
<br><br>
<i>ID </i>option ?arg arg ...?
<br><br>
<i>option</i> and <i>arg</i> determine the exact behavior of the 
command. The following commands are possible for $cmd(name) widgets:
<br>"

      foreach el $cmd(commands) {
         foreach {cc descr} $el break
         set txt "   <dl>\n   <dt><i>ID</i>"
         set cc [split $cc]
         append txt " <b>" [lindex $cc 0] "</b> "
         foreach el [lrange $cc 1 end] {
            if { [string equal $el VAROPTS] } {
               append txt " <i>?-option optionVal ...?</i>" 
            } else {
               append txt " <i>$el</i>"
            }
         }
         append txt "</dt>"
         puts $fp $txt
         puts $fp "       <dd>$descr</dd></dl>\n"
      }
   }

   puts $fp "\n<h2>KEYWORDS</h2>"

   puts $fp "<hr>"
   puts $fp $::COPYRIGHT
   puts $fp "</body>\n</html>"
   close $fp
}

proc handleCommand { fp ll } {
   upvar $ll line

   array set cmd [list name [string trim [string range $line 6 end]] \
         shortDescr "" synopsis "" options {} descr "" commands "" \
         keywords "" ]

   set ret [getLine $fp line 1]
   while { $ret > 0 } {
      set idx [string first ":" $line]
      if { $idx < 0 || [string index $line 0] != "." } {
         error "handleCommand: unknown sequence: \"$line\""
      }
      switch -exact -- [string range $line 1 $idx] {
         SHORTDESCR:    { set ret [handleShortDescr $fp line cmd] }
         SYNOPSIS:      { set ret [handleSynopsis $fp line cmd] }
         OPTIONS:       { set ret [handleOptions $fp line cmd] }
         DESCRIPTION:   { set ret [handleDescription $fp line cmd] }
         COMMANDS:      { set ret [handleCommands $fp line cmd] }
         KEYWORDS:      { set ret [handleKeywords $fp line cmd] }
         # NAME:          { break }
         # default        { error "unknown sequence \"$line\"" }
         default        { break }
      }
   }

   parray cmd
   printCmd cmd

   return $ret
}

# skip empty lines
set line ""
set ret [getLine $fp line 1]

while { $ret >= 0 } {
   set idx [string first ":" $line]
   if { $idx < 0 || [string index $line 0] != "." } {
      error "handleCommand: unknown sequence: \"$line\""
   }
   switch -exact -- [string range $line 1 $idx] {
      NAME:    { set ret [handleCommand $fp line] }
      HEADING: { set ret [handleHeading $fp line] }
      default  { error "unknown sequence: \"$line\"" }
   }
}

close $fp

puts $fpAllWithLinks "</table>\n</body>"
puts $fpAllWithLinks "
<hr>
<div align=left>$COPYRIGHT</div>
<div align=center>Back to the gnocl <a href=\"index.html\">main page</a></div>
</body>"

puts $fpAllNoLinks "</table>\n</body>"
puts $fpAllNoLinks "
<hr>
<div align=left>$COPYRIGHT</div>
<div align=center>Back to the gnocl <a href=\"index.html\">main page</a></div>
</body>"

close $fpAllWithLinks
close $fpAllNoLinks

