Académique Documents
Professionnel Documents
Culture Documents
com)
# Copyright (c) 1995 by Sun Microsystems
# Version 0.3 Fri Sep 1 10:47:17 PDT 1995
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# To use this package, create a text widget (say, .text)
# and set a variable full of html, (say $html), and issue:
# HMinit_win .text
# HMparse_html $html "HMrender .text"
# You also need to supply the routine:
# proc HMlink_callback {win href} { ...}
# win: The name of the text widget
# href The name of the link
# which will be called anytime the user "clicks" on a link.
# The supplied version just prints the link to stdout.
# In addition, if you wish to use embedded images, you will need to write
# proc HMset_image {handle src}
# handle an arbitrary handle (not really)
# src The name of the image
# Which calls
# HMgot_image $handle $image
# with the TK image.
#
# To return a "used" text widget to its initialized state, call:
# HMreset_win .text
# See "sample.tcl" for sample usage
##################################################################
############################################
# mapping of html tags to text tag properties
# properties beginning with "T" map directly to text tags
# initial values
set HMtag_map(hmstart) {
family times weight medium style r size 14
Tcenter "" Tlink "" Tnowrap "" Tunderline "" list list
fill 1 indent "" counter 0 adjust 0
}
HMinit_state $win
$win tag configure underline -underline 1
$win tag configure center -justify center
$win tag configure nowrap -wrap none
$win tag configure rindent -rmargin $var(S_tab)c
$win tag configure strike -overstrike 1
$win tag configure mark -foreground red ;# list markers
$win tag configure list -spacing1 3p -spacing3 3p ;# regular lists
$win tag configure compact -spacing1 0p ;# compact lists
$win tag configure link -borderwidth 2 -foreground blue ;# hypertext links
HMset_indent $win $var(S_tab)
$win configure -wrap word
# reset the state of window - get ready for the next page
# remove all but the font tags, and remove all form state
# A pair of pseudo tags are added automatically as the 1st and last html
# tags in the document. The default is <HMstart> and </HMstart>.
# Append enough blank space at the end of the text widget while
# rendering so HMgoto can place the target near the top of the page,
# then remove the extra space when done rendering.
# put the document title in the window banner, and remove the title text
# from the document
# a source
# a destination
# Inline Images
# This interface is subject to change
# Most of the work is getting around a limitation of TK that prevents
# setting the size of a label to a widthxheight in pixels
#
# Images have the following parameters:
# align: top,middle,bottom
# alt: alternate text
# ismap: A clickable image map
# src: The URL link
# Netscape supports (and so do we)
# width: A width hint (in pixels)
# height: A height hint (in pixels)
# border: The size of the window border
# get alignment
array set align_map {top top middle center bottom bottom}
set align bottom ;# The spec isn't clear what the default should be
HMextract_param $param align
catch {set align $align_map([string tolower $align])}
# When the image is available, the application should call back here.
# If we have the image, put it in the label, otherwise display the error
# message. If we don't get a callback, the "alt" text remains.
# if we have a clickable image, arrange for a callback
# We need to escape any %'s in the href tag name so the bind command
# doesn't try to substitute them.
# replace this!
# win: The name of the text widget to render into
# href: The HREF link for this <a> tag.
if {$val == ""} {
upvar $key result
} else {
upvar $val result
}
set ws " \n\r"
# look for name=value combinations. Either (') or (") are valid delimeters
if {
[regsub -nocase [format {.*%s[%s]*=[%s]*"([^"]*).*} $key $ws $ws] $param {\1}
value] ||
[regsub -nocase [format {.*%s[%s]*=[%s]*'([^']*).*} $key $ws $ws] $param {\1}
value] ||
[regsub -nocase [format {.*%s[%s]*=[%s]*([^%s]+).*} $key $ws $ws $ws] $param
{\1} value] } {
set result $value
return 1
}
# These next two routines manage the display state of the page.
proc HMoptimize {} {
regsub -all "\n\[ \]*#\[^\n\]*" [info body HMrender] {} body
regsub -all ";\[ \]*#\[^\n]*" $body {} body
regsub -all "\n\n+" $body \n body
proc HMrender {win tag not param text} $body
}
############################################
# Turn HTML into TCL commands
# html A string containing an html document
# cmd A command to run for each html tag found
# start The name of the dummy html start/stop tags
##########################################################
# html forms management commands
##########################################################
# html isindex tag. Although not strictly forms, they're close enough
# to be in this file
# is-index forms
# make a frame with a label, entry, and submit button
# initialize form state. All of the state for this form is kept
# in a global array whose name is stored in the form_id field of
# the main window array.
# Parameters: ACTION, METHOD, ENCTYPE
# Where we're done try to get all of the state into the widgets so
# we can free up the form structure here. Unfortunately, we can't!
###################################################################
# handle form input items
# each item type is handled in a separate procedure
# Each "type" procedure needs to:
# - create the window
# - initialize it
# - add the "submit" and "reset" commands onto the proper Q's
# "submit" is subst'd
# "reset" is eval'd
# input type=text
# parameters NAME (reqd), MAXLENGTH, SIZE, VALUE
# Set the global variable, don't use the "form" alias as it is not
# defined in the global scope of the button
set variable $var(form_id)(check_$var(tags))
set item $win.input_checkbutton,$var(tags)
checkbutton $item -variable $variable -off {} -on $value -text " "
if {[HMextract_param $param checked]} {
$item select
append form(reset) ";$item select"
} else {
append form(reset) ";$item deselect"
}
# radio buttons. These are like check buttons, but only one can be selected
# handle input images. The spec isn't very clear on these, so I'm not
# sure its quite right
# Use std image tag, only set up our own callbacks
# (e.g. make sure ismap isn't set)
# params: NAME, SRC (reqd) ALIGN
#########################################################################
# selection items
# They all go into a list box. We don't what to do with the listbox until
# we know how many items end up in it. Gather up the data for the "options"
# and finish up in the /select tag
# params: NAME (reqd), MULTIPLE, SIZE
# select options
# The values returned in the query may be different from those
# displayed in the listbox, so we need to keep a separate list of
# query values.
# form(select_default) - contains the default query value
# form(select_frame) - name of the listbox's containing frame
# form(select_values) - list of query values
# params: VALUE, SELECTED
# set up the submit button. This is the general case. For single
# selections we could be smarter
# This is a joke!
} else {
scrollbar $frame.scroll -command "$frame.list yview" \
-orient h -takefocus 0
$frame.list configure -height 1 \
-yscrollcommand "$frame.scroll set"
pack $frame.list $frame.scroll -side top -fill x
}
# cleanup
#####################################################################
# Assemble and submit the query
# each list element in "stuff" is a name/value pair
# - The names are the NAME parameters of the various fields
# - The values get run through "subst" to extract the values
# - We do the user callback with the list of name value pairs
if {[regexp % $data]} {
regsub -all {([][$\\])} $data {\\\1} data
regsub -all {%([0-9a-fA-F][0-9a-fA-F])} $data {[format %c 0x\1]} data
return [subst $data]
} else {
return $data
}
}
# There is a bug in the tcl library focus routines that prevents focus
# from every reaching an un-viewable window. Use our *own*
# version of the library routine, until the bug is fixed, make sure we
# over-ride the library version, and not the otherway around
auto_load tkFocusOK
proc tkFocusOK w {
set code [catch {$w cget -takefocus} value]
if {($code == 0) && ($value != "")} {
if {$value == 0} {
return 0
} elseif {$value == 1} {
return 1
} else {
set value [uplevel #0 $value $w]
if {$value != ""} {
return $value
}
}
}
set code [catch {$w cget -state} value]
if {($code == 0) && ($value == "disabled")} {
return 0
}
regexp Key|Focus "[bind $w] [bind [winfo class $w]]"
}