Version 3 of A Minimal Hypertext Help System

Updated 2005-11-14 15:46:02 by jcw

D. McC: For those who want super-simple hypertext help with extremely little overhead, here's something that will do the job. It requires:

  • Tk 8.4 or greater, to hide link markup tags with the "-elide" flag in the text widget.
  • A plain-text help file with uniquely named section titles (or other section identifiers), plus minimal markup for links with names that exactly replicate the section titles, like this:
 <link "Run Programs:">Run Programs</link>

Here's a proc to create the text box:

 proc userhelp {} {
        toplevel .uhelp
        grid [text .uhelp.tx -width 65 -height 25 -bg white \
                -yscrollcommand ".uhelp.roll set" \
                -font "times 14" -wrap word -cursor top_left_arrow] \
                -row 0 -column 0 -sticky news
        grid [scrollbar .uhelp.roll -width 12 \
                -command ".uhelp.tx yview"] -row 0 -column 1 -sticky news
        grid [button .uhelp.close -text "Close" -borderwidth 6 \
                -command {destroy .uhelp}] -row 1 -column 0 \
                -columnspan 2 -sticky news
        grid rowconfigure .uhelp 0 -weight 1
        grid columnconfigure .uhelp 0 -weight 1
 }

Here's one to get the text widget to display links and let the user see the uniquely named sections when the links are clicked (anybody who can make this one even simpler than it is, please let me know):

 proc getlinks {} {

        # Find beginnings and ends of all links:
        set linkstars [.uhelp.tx search -regexp -all \
                -count cti "<link .+?>" 1.0 end]
        set linkends [.uhelp.tx search -regexp -all "</link>" 1.0 end]

        # Fix the links up to work:
        for {set i 0} {$i < [llength $linkstars]} {incr i} {
                set star [lindex $linkstars $i] ; # Begin link-start tag
                set starleng [lindex $cti $i] ; # Length of link-start tag
                set starsplit [split $star "."]
                set starline [lindex $starsplit 0] ; # Line number in text
                set starchar [lindex $starsplit end] ; # Position in line

                # End of link-start tag:
                set starend $starline.[expr {$starchar + $starleng}]
                # Content of link-start tag:
                set linkstar [.uhelp.tx get $star $starend]
                set linkname [string trim $linkstar "<>"] ; # Link name

                # Tag to hide link tags:
                .uhelp.tx tag configure hide -elide 1
                .uhelp.tx tag add hide $star $starend

                # Add tag for clickable link between link-start and link-end tags:
                set finis [lindex $linkends $i]
                .uhelp.tx tag add $linkname $starend $finis
                # And one to hide the link-end tag:
                .uhelp.tx tag add hide $finis "$finis +7c"

                # Get clickable tag to look right and do things:
                .uhelp.tx tag configure $linkname -foreground blue -underline 1
                .uhelp.tx tag bind $linkname <ButtonRelease-1> {
                        # See where clicked link is:
                        set clickpos [.uhelp.tx index insert]
                        # Verify that it's really a link:
                        set tagnames [.uhelp.tx tag names $clickpos]
                        set tagplace [lsearch $tagnames "link *"]
                        if {$tagplace > -1} {
                                # If so, strip off everything but its name:
                                set tagname [lindex $tagnames $tagplace]
                                set tagend [lindex [.uhelp.tx tag range "$tagname"] end]
                                set searchname [string map "{link } {} {\"} {}" $tagname]
                                # And find where the name appears in the help-file text:
                                set target [.uhelp.tx search "$searchname" $tagend \
                                         end]
                                if {$target ne ""} {
                                        .uhelp.tx see $target
                                }
                        }
                }
        }
 }

And here's an example of a proc for getting an application to invoke the help system:

 proc comhelp {} {
        userhelp
        wm title .uhelp "WISH Command Center - User Help"
        set helpfile [open /home/david/9.com/wish/suite/comhelp_link.txt r]
        set helpcontents [read $helpfile]
        close $helpfile
        .uhelp.tx insert 1.0 $helpcontents
        getlinks
 }

Category Deployment | Category Documentation