# $Id: xodoc.xotcl,v 1.7 2000/11/29 22:20:15 neumann Exp $ package provide xoDoc 0.82 #package require trace @ @File { description { XOTcl documentation tool. Overloads the command @, which is used as a documentation token. } } Class DocToken -parameter { {name ""} {docProperties ""} } DocToken proc sortTokenList l { foreach t $l { set names([$t set name]) $t } set sortedName [lsort [array names names]] set sortedList "" foreach n $sortedName { lappend sortedList [set names($n)] } return $sortedList } DocToken instproc evaluateDoc doc { foreach {p v} $doc { [self] set $p $v [self] lappend docProperties $p } } DocToken instproc capitalize string { if {$::tcl_version >= 8.3} { string toupper $string 0 0 } else { return "[string toupper [string range $string 0 0]][string range $string 1 end]" } } @ DocToken instproc getDocPropertiesHTML {} { description { Returns list of properties as HTML. } } DocToken instproc getDocPropertiesHTML {} { set c "" foreach p [[self] set docProperties] { if {[[self] exists $p]} { append c "

" [[self] capitalize $p] ":" if {[string equal $p "errorCodes"]} { # Build table with list of error codes. append c "

" foreach {code desc} [[self] set $p] { set code [string map [list < <\; > >\;] $code] set desc [string map [list < <\; > >\;] $desc] append c "
$code$desc" } append c "
" } else { append c [[self] reflowHTML " " [[self] set $p]] \n\n } } } return $c } DocToken instproc reflowHTML {left paragraph} { #set result "" #foreach line [split $paragraph \n] { # if {![regexp {^ *$} $line]} { # append result "$left$line
\n" # } #} #return $result return $paragraph } Class DocFile -superclass DocToken DocFile instproc printHTML {} { set c "
Filename: [[self] set name]

\n" append c "[[self] getDocPropertiesHTML]
\n" return $c } Class DocPackage -superclass DocToken -parameter { {version ""} {type ""} } Class DocObj -superclass DocToken -parameter { {procList ""} cl } DocObj instproc getProcsHTML {} { set c "" set pl [DocToken sortTokenList [[self] procList]] if {[[self] istype DocCl]} { set pl [concat [DocToken sortTokenList [[self] instprocList]] $pl] } foreach p $pl { set pn [$p set name] set label($pn) "$pn" } foreach l [lsort [array names label]] { if {$c != ""} {append c ", "} append c $label($l) } if {$c != ""} {append c "."} return $c } DocObj instproc printHTML {} { set c "

Object: [[self] set name]

\n" if {[[self] exists cl]} { append c "Class: [[self] set cl]
\n" } if {[[self] exists heritage]} { append c "Heritage: [[self] set heritage]
\n" } set head " Procs " if {[[self] istype DocCl]} { set head " Procs/Instprocs: " } append c "$head \n [[self] getProcsHTML]" \ "

\n" \ [[self] getDocPropertiesHTML] return $c } Class DocCl -superclass DocObj -parameter { {instprocList ""} } DocCl instproc init args { [self] set obj [[self class] autoname clobj] next } DocCl instproc printHTML {} { regsub "

Object:" [next] "

Class:" r return $r } Class DocMetaCl DocMetaCl instproc printHTML {} { regsub "

Class:" [next] "

Meta-Class:" r return $r } Class DocMethod -superclass DocToken -parameter { arguments returnValue obj } # Prints out method information as HTML. DocMethod instproc printHTML {} { #[self] showVars set argText "\n" set a "Arguments: " set anchor "[[self] set obj]-[[self] set name]" set c "\n
  • [[self] set name] " if {[[self] exists arguments]} { foreach {arg argD} [[self] set arguments] { if {[llength $arg] > 1} { # A default value was given to the argument. append c " ?[lindex $arg 0]?" append argText "$a" append argText "?[lindex $arg 0]?:" \ [[self] reflowHTML " " \ "$argD Default: \"[lindex $arg 1]\"."] \ "\n" } else { append c " $arg" append argText "$a$arg: " \ "[[self] reflowHTML " " $argD]\n" } set a "" } } append c "
    \n\n" \ $argText [[self] getDocPropertiesHTML] \n \
    \n return $c } Class DocProc -superclass DocMethod Class DocInstproc -superclass DocMethod @ Class XODoc { description "Handler class for building a documentation database" } Class XODoc -parameter { {objList ""} {packageList ""} {knownMetaclasses "Class"} {ns ""} fileToken } XODoc instproc init args { next } @ XODoc proc documentFileAsHTML {file "filename of the xotcl file to be documented" docdir "directory to which the html file is written"} { description "Uses the xoDoc package to produce an HTML documentation of a specified file ***.xotcl. The file is written to ***.html in docdir" return "file basename without suffix" } XODoc proc documentFileAsHTML {file docdir} { set docdb [XODoc [XODoc autoname docdb]] ::@ set xoDocObj $docdb $docdb readFile $file set fb $file regexp {([^/]*)\.[^.]*$} $fb _ fb $docdb writeFile ${docdir}/$fb.html $fb [$docdb printHTML] $docdb destroy return $fb } XODoc instproc handleMethod {obj type name {argList ""} {doc ""}} { #puts stderr "+++Method $type $name $argList $doc" set procClass DocProc; set objCl DocObj if {$type == "instproc"} {set procCl DocInstproc; set objCl DocCl} set t [$procClass create [[self] autoname t]] set n [$t set name [string trimleft $name :]] $t set obj $obj set objFound 0 foreach o [[self] set objList] { if {[$o set name] == $obj} { set objFound 1 if {$type == "instproc" && ![$o istype DocCl]} { $o class DocCl } break } } if {$objFound == 0} { set o [$objCl create [[self] autoname t]] $o set name $obj [self] lappend objList $o } $o lappend ${type}List $t $t set arguments $argList $t evaluateDoc $doc } XODoc instproc handleObj {class name args} { [self] instvar knownMetaclasses objList extensions set objCl DocObj if {[lsearch $class $knownMetaclasses] != -1} { set objCl DocCl } # if an instproc/proc has created an entry for this obj/class # -> use it and overwrite it with new info if {[set idx [lsearch $name $objList]] != -1} { set t [lindex $objList $idx] $t class $objCl } else { set t [$objCl create [[self] autoname t]] [self] lappend objList $t } $t set name $name set la [llength $args] # evaluate -superclass argument if {($la == 3 || $la == 2) && [lindex $args 0] == "-superclass"} { set heritage [$t set heritage [lindex $args 1]] foreach h $heritage { if {[lsearch $h $knownMetaclasses] != -1} { # A new metaclass was defined lappend knownMetaclasses $name $t class DocMetaCl } } } # evaluate documentation set doc "" if {$la == 1} { set doc [lindex $args 0] } elseif {$la == 3} { set doc [lindex $args 2] } $t evaluateDoc $doc $t set cl $class #puts stderr "+++Obj $name $args" } XODoc instproc handleFile doc { if {[[self] exists fileToken]} { [[self] set fileToken] evaluateDoc $doc } } XODoc instproc handlePackage args { #puts "$args" if {[llength $args] > 2} { set type [lindex $args 1] if {$type == "provide" || $type == "require"} { set t [DocPackage create [[self] autoname t]] [self] lappend packageList $t $t set name [lindex $args 2] $t set type $type if {[llength $args] > 3} { $t set version [lindex $args 3] } } } } XODoc instproc printHTML {} { [self] instvar extensions set c "

    Package/File Information

    " [self] instvar packageList if {[llength $packageList] > 0} { foreach t $packageList { if {[$t type] == "provide"} { append c " Package provided: [$t name] [$t version]
    \n" } elseif {[$t type] == "require"} { append c " Package required: [$t name] [$t version]
    \n" } } } else { append c " No package provided/required
    \n" } if {[info exists extensions]} { # Add list of extensions. foreach extension $extensions { append c "
    " append c "

    Document extension: [$extension name]

    " append c "Description: [$extension description]" } } set objList [DocToken sortTokenList [[self] objList]] if {[llength $objList]>0} { append c "
    Defined Objects/Classes: \n\n" } if {[[self] exists fileToken]} { append c "[[[self] set fileToken] printHTML]
    " } else { append c " No file information.
    \n" } foreach t $objList { append c "


    \n" [$t printHTML] set pl [$t set procList] if {[$t istype DocCl]} { set ipl [$t set instprocList] if {[llength $ipl] > 0} { append c "

    Instprocs

    \n\n" } } if {[llength $pl] > 0} { append c "

    Procs

    \n\n" } #append c "
    \n" } return $c } XODoc instproc getCommand {content} { upvar $content c [self] instvar cmd if {[set line [string first "\n" $c]] != -1} { append cmd [string range $c 0 $line] \n set c [string range $c [expr $line + 1] end] if {[info complete $cmd]} { set r $cmd; set cmd "" return $r } } else { return "" } [self] getCommand c } XODoc instproc evaluateCommands {c} { while 1 { set command [[self] getCommand c] if {$command == ""} { break } #puts stderr "$command===========================" if {[regexp "^ *:*@ " $command]} { #puts stderr "$command===========================" eval $command } elseif {[regexp "^ *package " $command]} { #puts stderr "$command===========================" eval [self] handlePackage $command } elseif {[regexp "^ *namespace *eval *(\[^\{\]*) *\{(.*)\}\[^\}\]*$" $command _ namespace nsc]} { #puts stderr "$command===========================" [self] evaluateCommands $nsc } } } XODoc instproc readFile name { [self] set cmd "" set t [DocFile create [[self] autoname t]] $t set name $name [self] set fileToken $t set f [open $name r] set c [read $f] close $f [self] evaluateCommands $c } XODoc instproc replaceFormatTags {fc} { regsub -all <@ $fc < fc regsub -all XOTcl - Documentation -- $name

    $name


    $filecontent


    Back to index page.

    } set content [subst -nobackslashes -nocommands $content] #puts $content set f [open $filename w] puts $f $content close $f } Class XODocCmd -parameter { {xoDocObj ""} } XODocCmd instproc unknown args { [self] instvar xoDocObj if {[llength $args] > 1} { switch [lindex $args 1] { proc - instproc { return [eval $xoDocObj handleMethod $args] } default { switch [lindex $args 0] { @File { return [$xoDocObj handleFile [lindex $args 1]] } default { return [eval $xoDocObj handleObj $args] } } } } } puts stderr "Unknown documentation: '$args'" } XODocCmd @