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 "} 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"} }