Version 1 of docextract

Updated 2010-01-30 14:16:58 by jnc

docextract

jnc Jan 30, 2010 - A more recent copy of doctools is now in my "Misc TCL" code fossil repo, it can be had at http://jeremy.cowgar.com/misctcl

jnc likes keeping documentation and source in one file. Why? Ease of editing and maintaining both the source and documentation for that source. You are more likely to update the docs when a proc changes if they are staring you in the face. Thus, I wrote this simple utility I call docextract.tcl. You can include doctools comments inline with your source code and docextract will extract the comments making a .man page suitable for processing by the doctools family of utilities.

You need to use a special syntax for the comments you wish to be extracted. Simply start the comment block with a # and one or more * characters. For example:

 #****
 # [para]
 # this will be extracted and placed into the .man file
 if {1==2} {
   # this will not
 }

Once a doctools block comment is started, all content will be placed into the man file until the first character in a line does not begin with a # character. Thus, if you wish to include a doctools comment back to back with a programmers comment, you must do something such as:

 #****
 # doctools comment
 # more comments for doctools

 # this is not a doctools comment and will not be extracted
 # to the resulting .man page.

 puts "Hello World!"

Now for the source

 #!/bin/sh
 # -*- tcl -*-
 # The next line is executed by /bin/sh, but not tcl \
 exec tclsh "$0" ${1+"$@"}

 package require cmdline

 set options {
   {o.arg "./" "set the output directory"}
   {all        "output all .man files even when no valid comments where found"}
 }
 set usage ": docextract \[options] filename ...\noptions:"
 if {[catch {array set params [::cmdline::getoptions argv $options $usage]} msg]} {
   puts $msg
   exit 0
 }

 file mkdir $params(o)

 foreach fname $argv {
   set ofname [file join $params(o) [file rootname $fname].man]
   set fh [open $fname r]
   set comments ""

   set inDocComment 0

   while {[gets $fh line] >=0} {
      set line [string trim $line]
     if {$inDocComment && [string index $line 0] != "#"} {
       set inDocComment 0
     } elseif {[string range $line 0 1]=="#*"} {
       set inDocComment 1
     } elseif {$inDocComment} {
       append comments "[string range $line 2 end]\n"
     }
   }

   close $fh

   if {$params(all) || [string length $comments] > 0} {
     set ofh [open $ofname w]
     puts $ofh $comments
     close $ofh
   }
 }