the tclsh spot
by Clif Flynt
Clif Flynt has been a professional programmer for almost twenty
years, and a Tcl advocate for the past four. He consults on Tcl/Tk and
Internet applications.
Except HTML. HTML was developed well after metamail, and while there are simple hooks in the mailcap file to invoke Netscape, I don't want to start up a full browser just to read one email message with an HTML attachment. So, after grousing about this enough times, I put together a simple little HTML text viewer. The program is pretty simple: a text widget, a scrollbar, a quit button, and a call to the HTML-rendering package. #!/usr/local/bin/wish source "htmllib.tcl" # build and display the button, text widget, and scrollbar
set b [button .b -text "quit" -command "exit"]
grid $t -row 0 -column 0
# Read from a file if there's one on the command line, else stdin
if {$argc >= 1} {
# Read the input, and display it.
Rather obviously, the main functionality in this program is in htmllib.tcl. The command source "htmllib.tcl" merges the HTML library into the HTML viewer at runtime. The source command loads a script into a Tcl program and evaluates the commands in that script before evaluating the next line of the original script. Syntax: source fileName This is similar to the C language #include or the C-Shell source command. The source command is the easiest way to split your package into multiple source-code modules. (There are other ways, and I'll get to them in future articles.) Steve Uhler wrote the htmllib.tcl package while he was with the Tcl group at Sun Labs. Since then, Steve Ball and others have used and modified it. This package shows some tricks you can play with the proc and eval commands, and demonstrates the power of the Tcl text widget. Like most programming languages, Tcl allows programmers to split pieces of functionality into subroutines to create modular code. The Tcl subroutine is sometimes called a procedure and sometimes referred to by the name of the Tcl command that creates a procedure, proc. The syntax for the proc command is: Syntax: proc name args body The args and body parameters are generally grouped with braces when you create a procedure in your application:
proc mySubroutine {arg1 arg2} {
In Tcl every line starts with a command. So, Tcl doesn't declare procedures the way we're used to with C or FORTRAN. The word proc is a command, not a declaration. Despite the fact that it looks a lot like a declaration that mySubroutine is a procedure, what's actually happening is that the proc command is creating a new procedure and adding it to the procedure hash table. The Tcl interpreter will not only evaluate scripts you've created with an editor; it will also evaluate lines that are created at runtime by the program being evaluated. The command that will evaluate a line of text is eval. Syntax: eval string The string is any valid Tcl command. The eval command is the trick that makes the HTML parsing code in htmllib.tcl elegantly simple. The htmllib.tcl package uses a set of regular expressions to convert an HTML page from a list of tags and strings into a set of Tcl commands. The htmllib package uses eval to evaluate the Tcl procedures that render the HTML page into displayed text. Tcl regular-expression commands are rich enough to fill more than a single "Tclsh Spot" article. In the htmllib.tcl package, they are used to convert this text: This is <B>bold</B> and <I>italics</I>. to these Tcl commands:
HMrender .t {P} {} {} {This is }
Within the HMrender procedure, the HTML tag information is massaged into new procedure names such as HMtag_b and HMtag_\b. These procedures are then evaluated to insert strings into the text widget with the appropriate formatting which finally brings us to the text widget and some of the things you can do with it. My previous article (;login:, June 1999) showed how to create a text widget and insert text. Now, let's look at what we can do to control the appearance of that text. The contents of a text widget are addressed by their index. An index is a line and character position in the format line.character. To match other UNIX utilities, the line numbers start at 1, and the character positions start at 0. The index 1.0 represents the first character in a text widget, and the index 2.3 is the fourth character on the second line. The text widget allows scripts to tag areas of text and then define how to display text within that area. A tag consists of a reference name for the tag, and the start and end indices of the area associated with that tag. A tag is added to a text widget with the textName tag add command. Syntax: textName tag add tagName startIndex1 ?end1? ?start2? ... ?endN?
Text within a tagged area is manipulated with the textName tag configure command. Syntax: textName tag configure tagName -parameter value
As a simple example, this short script generates this display:
text .t -height 2 -width 20 -font {times 16 normal}
The text and canvas widgets support a bind command that lets you bind a script to an event. Whenever an event (a button press or RESIZE event, for instance) occurs, the defined script will be evaluated. The script may be multiple lines of commands, or a single call to a Tcl procedure. The text widget supports binding actions to events that happen to tagged areas. Syntax: textName tag bind tagName ?eventType? ?script?
Adding this line to the previous example would turn the word "bold" red when a user clicks on it. .t tag bind loud {.t tag configure loud -foreground red} In the TclTutor package, I use this technique to bring up TkMan (or the Windows help viewer) when a user clicks on a word. In the htmllib.tcl package, the bind command is used to invoke a procedure to handle hypertext references. Finally, the HTML viewer uses a scrollbar to shift the displayed section of the text widget. The Tcl scrollbar widget sends commands to a target widget requesting that widget to modify its state to match the scrollbar. The scrollbar receives commands from the target widget to modify its appearance when the target's state changes. Using the Tcl scrollbar to control a text or canvas widget is fairly simple:
After those steps are complete, everything else is automatic. Syntax: scrollbar scrollbarName ?options?
In the HTML viewer, the code -command "$t yview" tells the scrollbar to invoke the text widget's yview subcommand with new parameters when a user modifies the scrollbar. The text widget option -yscrollcommand ".sy set" causes the text widget to send information to the scrollbar whenever its state changes. That describes some of the details hiding inside the trivial little 20-line HTML viewing script. All you need to do is copy that file into your /usr/local/bin directory and add the following line to your mailcap file and you can view HTML messages from elm, pine, or your favorite curses-based mail reader (assuming you run your curses-based mail reader from an X-Term window). text/html; /usr/local/bin/htmlview.tcl
Steve Uhler's original html_library.tcl file is available at
<ftp://ftp.scriptics.com/pub/tcl/
|
|
Last changed: 18 Nov. 1999 mc |
|