== Extending tcl to generate html == [CMcC] Following from [jenglish]'s comment: why learn to use a monster HTML-template library when you can, with a few lines of code, extend the base language so you can write things like [[ href "/home.html" { ! "Home" }]] ... I wrote the following to do just that using the techniques in [let unknown know]. package require know know {[string match <*> [lindex $args 0]]} { set tag [string trim [lindex $args 0] "<>"] ::proc ::<$tag> {args} [string map [list @T $tag] { set result {} foreach {n v} [lrange $args 0 end-1] { lappend result "$n='[armour $v]'" } return "<@T [join ${result}]>[lindex $args end]" }] return [eval $args] } This will generate a proc for any command like [[
  • ]] which will do pretty much what you'd expect it to. ---- == Armouring HTML == Prevent output from containing html-significant characters interp alias {} armour {} string map {& & < < > > \" " ' '} ... fairly clearly ''that'' needs some work :) ---- == Functional HTML generation == Often what you want isn't to iterate, but to convert a list into something else. One generic technique I've found helpful is the use of [join], as follows: Which will convert a tcl list into an HTML unordered list. Similar techniques are possible with s The technique can be readily made generic: == Subst-if == Here's a variant of [if] which evaluates its conditional using [subst] and not [eval] proc If {args} { while {[llength $args] && ![uplevel expr [lindex $args 0]]} { set args [lrange $args 2 end] ;# lose the cond and positive-cond if {[lindex $args 0] eq "elseif"} { set args [lrange $args 1 end] continue ;# continue to evaluate conditionals } elseif {[lindex $args 0] eq "else"} { break } } return [uplevel subst [list [lindex $args 1]]] ;# return with neg-consequence } set a 1; set b 2 puts [If {$a} {a is true} else {a is false}] puts [If {$a == $b} {a == b} elseif {$b == 1} {b is 1} else {b is not 1 it is $b}]