**Description** The engine works by converting a template (which is a string, or a file) into a Tcl script, and then running it. Each line of text encountered will be returned as is. Exception is text between '''<%''' ... '''%>''' which is treated as [Tcl] code (the [eval] happens in a regular [interp]). ***Why not [expand]?*** [expand] is a simple and snugly for Tcl language, be mounted in [tcllib]. You can use it as quick as flash. But, that library has a problem, when to really use. We cannot write easily following signs [ ] { } [DDG] No! We can easily write [ ] { } with [expand] if we use alternative brackets for expansion: (Tclkit) 24 % package require textutil::expander 1.3.1 (Tclkit) 25 % textutil::expander exp ::exp (Tclkit) 26 % set string {[] {} <% set x %> } [] {} <% set x %> (Tclkit) 27 % set x 65 65 (Tclkit) 28 % exp expand $string {<% %>} [] {} 65 [kanryu] Oh, I didn't know to be able to change brackets with textutil::expander. Then, there are restricted cases to use this library, maybe. ***Why not [TemplaTcl]?*** [TemplaTcl] is a powerful and cool template engine. But now, we cannot use it on Tcl8.4 :( **tmpl_parser is** a simple and fast template engine. That still not have function to read a file, create a parser object. But we can use it instant, only write a command '''require''' or '''source'''. Simple variable substitution is done with "<%= $''variable'' %>" (e.g., Thanks <%=$count%> accesses!). Simple expression substitution is done with "<%:''Tcl expression''%>" (e.g., <%:$i+2000%>). **Usage** First, let's create a template file (templtest.tmpl): ====== <% for {set i 0} {$i < 4} {incr i} { %> <% } %>
<%= $i %>
====== The above template (in [HTML] language) generates a 4-row table and an unordered list, taking values from a ''$cityList'' variable that we're going to define. First let's load the code: ====== source tmpl_parser.tcl ====== reading template file. ====== set fd [open templtest.tmpl r] set tmpl [read $fd] close $fd ====== now create a parser instance: ====== set parser [::tmpl_parser::tmpl_parser $tmpl] ====== set the variables used in our template: set cityList {Ragusa Ravenna Rieti Rimini Rome Rovigo} and render the template: puts [eval $parser] Here's the output that gets produced: ======
1
2
3
4
====== **tmpl_parser code** ====== # tmpl_parser.tcl # # Tcl embeddedd script parser(a template engine) # # This module comverts Tcl embedded scripts into a Tcl normal script(parser), # after you just have to do eval command for the generated parser. # # Copyright (c) 2007 by Kanryu KATO # licensed on Tcl License. package require Tcl 8.3 package provide tmpl_parser 0.1 namespace eval ::tmpl_parser { namespace export tmpl_parser } proc ::tmpl_parser::tmpl_parser {tmpl} { # Tcl enbedded tags # [[outer <%...inner...%> outer]] <-$tmpl # [ = ] <-$token # cd ef hi j <-indexes set parser { {set _o {}} } while {[set i [string first %> $tmpl]] != -1} { set h [expr {$i-1}] set j [expr {$i+2}] set token [string range $tmpl 0 $h] set d [string first <% $token] set c [expr {$d-1}] set e [expr {$d+2}] set f [expr {$d+3}] # outer lappend parser [escaped_parse [string range $token 0 $c]] switch [string index $token $e] { "=" { # normal expression (e.g., Thanks <%=$count%> accesses!) lappend parser [normal_parse [string range $token $f end]] } ":" { # numeric expression (e.g., <%:$i+2000%>) lappend parser [numeric_parse [string range $token $f end]] } default { # embedded Tcl command is passed through listing lappend parser [string range $token $e end] } } # after "%>" set tmpl [string range $tmpl $j end] } #last outer lappend parser [escaped_parse $tmpl] lappend parser {join $_o ""} return [join $parser "\n"] } proc ::tmpl_parser::escaped_parse {str} { set str [string map {\" \\\" \{ \\\{ \} \\\} \\ \\\\} $str] return "lappend _o \"$str\"" } proc ::tmpl_parser::normal_parse {str} { return "lappend _o $str" } proc ::tmpl_parser::numeric_parse {str} { return "lappend _o [expr $str]" } ====== ---- '''[milarepa] - 2014-07-20 17:26:11''' I been using tmpl_parser to parse a configuration file. So far it works fine. My problem now is that when I insert a variable like this: ====== <%= $variable_name %> ====== Inside that `$variable_name` there is a plain text that containes another tag to process another variable: ====== <%= $variable_inside_a_variable %> ====== I understand when the parser processes `$variable_name` will print `$variable_inside_a_variable` literally without doing the variable substitution. Is there a way to do exactly that? ---- !!!!!! %|[Category Application] |[Category Template]|% !!!!!!