global L lm1 lm2 in TS
set L(C0) 0 ;# Current margin for lists.
set L(I0) 0 ;# Indent margin for lists.
set L(M0) 0 ;# List margin for lists.
set L(S0) {} ;# Style (COMPACT or null)
set L(T0) {} ;# Type (tag) for lists.
set TS(0) 0 ;# Tab string for lists.
set lm1 0 ;# Current lmargin1.
set lm2 0 ;# Current lmargin2.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Process one HTML tag. We get the tag with the <> and white stuff trimmed
# away. We first divide the tag into its initial keyword and its args. The
# big switch then takes care of the primary actions for the tag.
proc Tag {w tag} {
global V me in ll lm1 lm2 Lnum Mtab in Lang wantNL Script scripts curD title \
Trow Trows Tcol Tcols Txt opt N Finfo Fsize Fcolor Ftag Link L TS link
set id "$me/Tag"
regexp {^(/?)(.*)$} $tag {} s tag
if ![regexp -nocase {^([a-z]*)([ :])(.*)} $tag {} t d a] {
set t $tag ;# Tag, in mixed case.
set a {} ;# Attributes, if any.
}
set TAG $s[set T [string toupper $t]]
#
# Now we should have:
# s = "/" if there was one, or null.
# t = tag, mixed case, without initial slash.
# T = tag, upper case, without initial slash.
# a = attribute list.
# tag = original tag minus initial slash.
# TAG = uppercase slash+tag.
#
if {$V>4} {puts "$id: $curD s=\"$s\" T=\"$T\" TAG=\"$TAG\" attributes=\"$a\""}
switch -- $TAG {
A {tagA $curD $a}
/A {endA $curD $a}
FONT {tagFONT $w $curD $a}
/FONT {endFONT $w $curD $a}
STRONG -
BIG -
EM -
B {incT B; PushFont {} {} {} b}
/STRONG -
/BIG -
/EM -
/B {if {$in(B)} {decT B; PopFont}}
I {incT I; PushFont {} {} i {}}
/I {if {$in(I)} {decT I; PopFont}}
TT {tagTT $T $a}
/TT {endTT}
H6 {incT H6; BR $curD; PushFont 3 v r m}
H5 {incT H5; BR $curD; PushFont 3 v r b}
H4 {incT H4; BR $curD; PushFont 4 v r b}
H3 {incT H3; BR $curD; PushFont 5 v r b}
H2 {incT H2; BR $curD; PushFont 6 v r b}
H1 {incT H1; BR $curD; PushFont 7 v r b}
/H1 - /H2 - /H3 - /H4 - /H5 -
/H6 {if {$in($T)} {decT $T; PopFont; BR $curD}}
HR {tagHR $curD $a}
BL {BR $curD; ListEnter $curD $TAG $a}
OL {BR $curD; ListEnter $curD $TAG $a}
BLOCKQUOTE -
UL {BR $curD; ListEnter $curD $TAG $a; litab $curD}
DL {BR $curD; ListEnter $curD $TAG $a}
LI {tagLI $curD $TAG $a}
/BL -
/OL -
/BLOCKQUOTE -
/UL -
/DL {ListExit $curD $TAG; BR $curD}
DT {BR $curD; lltab $curD}
DD {if {$L(S$ll) == {COMPACT}} {Htxt \t} else {BR $curD}; litab $curD}
TABLE {tagTABLE $curD $TAG $a}
/TABLE {endTABLE $curD $TAG $a}
TD {tagTD $curD $a}
TR {tagTR $curD $a}
/TD {endTD $curD $a}
/TR {endTR $curD $a}
CENTER - /CENTER -
BR {BR $curD}
P {Hnl 2}
/P {}
BODY {Section $TAG; BR $curD}
/BODY {Section {}}
FORM {tagFORM $curD $t $a}
/FORM {incr N(FORM) -1}
HTML {incT HTML}
/HTML {decT HTML; BR $curD}
PLAINTEXT {tagPLAINTEXT $curD $TAG $a}
/PLAINTEXT {endPLAINTEXT $curD $TAG}
PRE {tagPRE $curD $TAG $a}
/PRE {endPRE $curD $TAG}
IMG {tagIMG $curD $TAG $a}
/IMG {}
HEAD {Section $TAG}
/HEAD {Section {}}
INPUT {tagINPUT $curD $TAG $a}
/INPUT {}
OPTION {tagOPTION $curD $TAG $a}
SCRIPT {
set Script([incr scripts]) {}
incT except
incT SCRIPT
if {$V>1} {puts "$id: SCRIPT $scripts in(SCRIPT)=$in(SCRIPT)"}
if [regexp -nocase {language="*(.+)"*} $a {} l] {
set Lang($scripts) $l
} else {
set Lang($scripts) {???}
}
}
/SCRIPT {
decT except
decT SCRIPT
if {$V>1} {puts "$id:/SCRIPT $scripts in(SCRIPT)=$in(SCRIPT)"}
}
SELECT {tagSELECT $curD $TAG $a}
/SELECT {endSELECT $curD}
TITLE {set title {}; incT TITLE; set wantNL(TITLE) 0}
/TITLE {decT TITLE}
TCL {incr in(TCL)}
/TCL {incr in(TCL) -1; if {$in(TCL) < 0} {set in(TCL) 0}}
URL {tagURL $curD $t $d $a}
CAPTION {tagCAPTION $curD $TAG $a}
/CAPTION {endCAPTION $curD $TAG $a}
/OPTION -
ABBR - /ABBR -
ACRONYM - /ACRONYM -
ADDRESS - /ADDRESS -
APPLET - /APPLET -
AREA - /AREA -
BASE -
BGSOUND - /BGSOUND -
BLINK - /BLINK -
CITE - /CITE -
CODE - /CODE -
COMMENT - /COMMENT -
DFN - /DFN -
DIR - /DIR -
DIV - /DIV -
EM - /EM -
FRAMESET - /FRAMESET -
HN - /HN -
ISINDEX - /ISINDEX -
KBD - /KBD -
LINK - /LINK -
LISTING - /LISTING -
MAP - /MAP -
MARQUEE - /MARQUEE -
META - /META -
NETXID - /NETXID -
NOBR - /NOBR -
SAMP - /SAMP -
SMALL - /SMALL -
STRIKE - /STRIKE -
SUB - /SUB -
SUP - /SUP -
TEXTAREA - /TEXTAREA -
TH - /TH -
VAR - /VAR -
WBR - /WBR -
XMP - /XMP -
default {if {$V>1} {puts "$id: Tag <$TAG> ignored."}}
}
if {$V>4} {puts "$id: $TAG in(PRE)=$in(PRE) (final)"}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
proc incT args {
global V me in
set v 0
foreach t $args {
if ![info exists in($t)] {set in($t) 1} else {incr in($t)}
if {$V>2} {puts "$me/incT: in($t)=$in($t)."}
set v $in($t)
}
return $v
}
proc decT args {
global V me in
set v 0
foreach t $args {
if {![info exists in($t)] || $in($t)<2} {set in($t) 0} else {incr in($t) -1}
if {$V>2} {puts "$me/decT: in($t)=$in($t)."}
set v $in($t)
}
return $v
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Handle an
tag. We may be in any sort of list. We break to the next #
# line, figure out what sort of item id symbol to produce, then tab to the #
# list's indent position. #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
proc tagLI {w TAG a} {
global V me ll lm1 lm2 L TS
set id "$me/tagLI"
BR $w
if {$V>4} {puts "$id: $TAG ll=$ll lm1=$lm1 lm2=$lm2 (init)"}
lltab $w
switch $L(T$ll) {
OL {set TS(li$ll) "[incr L(n$ll)] "}
DL {set TS(li$ll) {}}
UL {set TS(li$ll) {* }}
TR {set TS(li$ll) {- }}
default {set TS(li$ll) {+ }}
}
if {$V>4} {puts "$id: $TAG ll=$ll lm1=$lm1 lm2=$lm2 L(M$ll)=$L(M$ll)"}
Htxt $TS(li$ll)
litab $w
if {$V>4} {puts "$id: $TAG ll=$ll lm1=$lm1 lm2=$lm2 L(M$ll)=$L(M$ll)"}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Not much needs to be done for PRE tags, just set a few global variables to #
# tip off the formatting code that it shouldn't do its job. We do assume that #
# PRE tags can be nested, and try to handle this appropriately. #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
proc tagPRE {w T a} {
global in Sep
incr in(PRE)
set Sep "\n"
PushFont {} f {} {}
BR $w
}
proc endPRE {w T} {
global in Sep
if {[incr in(PRE) -1] < 1} {
set in(PRE) 0
set Sep "\n"
PopFont
}
# Hnl 0
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# This is called when we start a new list tag of any sort. We bump the list #
# level, ll, and set up a number of variables in the L() array to handle the #
# indentation for this list level. #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
proc ListEnter {w TAG a} {
global V me in ll Listype L
set id "$me/ListEnter"
if {$V>4} {puts "$id: LIST tag $TAG ll=$ll a={$a} (init)"}
incr in($TAG); # Note nesting of list tags.
if {$V>2} {puts "$id: $ll $TAG LM=$L(M$ll) LI=$L(I$ll) LC=$L(C$ll) (init)"}
incr ll
set L(M$ll) [expr $ll-1]
set L(I$ll) $ll
set L(C$ll) $L(M$ll)
set L(T$ll) $TAG ;# List type.
set L(n$ll) 0 ;# List item counter.
set L(S$ll) {} ;# List style (COMPACT or null)
if [regexp -nocase compact $a] {
set L(S$ll) COMPACT
}
if {$V>2} {puts "$id: $ll $TAG LM=$L(M$ll) LI=$L(I$ll) LC=$L(C$ll) (final)"}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# This handles exit from a list tag. We only give a warning if the wrong type #
# of list was terminated. We then pop the list level by one and reset various #
# globals dealing with the indentation. #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
proc ListExit {w TAG} {
global V me in ll Listype L
set id "$me/ListExit"
regsub {^/+} $TAG {} TAG
if {$V>2} {puts "$id: LIST type $TAG level $ll done."}
if {[incr in($TAG) -1] < 0} {
if {$V>0} {puts "$id: Unmatched $TAG>"}
set in($TAG) 0
}
if {$TAG != "/$L(T$ll)"} {
if {$V>1} {puts "$id: L(T$ll)=$L(T$ll) ended by $TAG."}
}
if {[incr ll -1] < 0} {
if {$V>0} {puts "$id: ### Tried to decrement list level past 0 ###"}
set ll 0
}
if {$V>2} {puts "$id: List $ll $TAG L(M$ll)=$L(M$ll) L(I$ll)=$L(I$ll) L(C$ll)=$L(C$ll)"}
lctab $w
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Set the tab position to the current list level indent.
proc lltab {w} {
global V L ll lm1 lm2 me Mtab ts
set id "$me/lltab"
if {$V>4} {puts "$id: ll=$ll lm1=$lm1 lm2=$lm2 Mtab=$Mtab (init)"}
set L(C$ll) [set il $L(M$ll)]
set Mtab Mtab$il
if {$V>4} {puts "$id: ll=$ll lm1=$lm1 lm2=$lm2 Mtab=$Mtab il=$il (new)"}
set i [expr $il*$ts]
if {$V>4} {puts "$id: i=\"$i\" il=\"$il\" ts=\"$ts\""}
$w tag config $Mtab -lmargin1 $i -lmargin2 $i -tabs $ts
if {$V>4} {puts "$id: $w tag config $Mtab -lmargin1 $i -lmargin2 $i -tabs $ts"}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Set the tab position to the current list item indent.
proc litab {w} {
global V ll lm1 lm2 me L Mtab ts
set id "$me/litab"
if {$V>4} {puts "$id: ll=$ll lm1=$lm1 lm2=$lm2 Mtab=$Mtab (init)"}
set lm1 $L(M$ll)
set lm2 $L(I$ll)
set L(C$ll) [set il $L(I$ll)]
if {$V>4} {puts "$id: ll=$ll lm1=$lm1 lm2=$lm2 il=$il (set)"}
if ![info exists L(i$lm1)] {set L(i$lm1) 0}
set L(i$lm2) [expr $L(i$lm1)+$ts]
if {$V>4} {puts "$id: ll=$ll lm1=$lm1 lm2=$lm2 il=$il (incr)"}
set Mtab Mtab$il
if {$V>4} {puts "$id: ll=$ll lm1=$lm1 lm2=$lm2 Mtab=$Mtab (new)"}
set i [expr $il*$ts]
if {$V>4} {puts "$id: i=\"$i\" il=\"$il\" ts=\"$ts\""}
$w tag config $Mtab -lmargin1 $i -lmargin2 $i -tabs $ts
if {$V>4} {puts "$id: $w tag config $Mtab -lmargin1 $i -lmargin2 $i -tabs $ts"}
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Set the tab position to the current list indent (list level or item level).
proc lctab {w} {
global V ll lm1 lm2 me L TS Mtab ts
set id "$me/lctab"
if {$V>4} {puts "$id: TS ll=$ll L(C$ll)=$L(C$ll) Mtab=$Mtab (init)"}
set lci $L(C$ll)
if {$V>4} {puts "$id: TS ll=$ll lci=$lci Mtab=$Mtab (set)"}
set Mtab Mtab$lci
if {$V>4} {puts "$id: TS ll=$ll lci=$lci Mtab=$Mtab (new)"}
set i [expr $lci*$ts]
$w tag config $Mtab -lmargin1 $i -lmargin2 $i -tabs $ts
if {$V>4} {puts "$id: TS $w tag config $Mtab -lmargin1 $i -lmargin2 $i -tabs $ts"}
}