SourceForge Logo



TML Version 2.0:    Generic Embedded Web Script

copyright © 2000-2001 - Peter MacDonald

Table Of Contents


TML is a Free Tcl extension that provides an embedded Web Scripting interface to Tcl, Perl and Python. TML can be used to develop hybrid Tcl/HTML applications. It parses web pages, using square bracket escapes "[" and "]" to call procedures. Values returned from a procedure call are inserted inline into the page. TML comes as a stand-alone and CGI and is also built-in to Browsex. TML is vaguely like PHP, except that it doesn't use <> HTML tag delimiters. More importantly, TML itself is not a language. TML handles inline-code for the three most popular scripting languages and then adds conditional and loop control constructs such as if, while, and foreach to direct the parse. There are also some cool extensions such as inline refs and table of contents and even a way to wrap HTML entirely. TML pages can also execute natively in Browsex, ie. without webserver or CGI.

For a sizable example of a TML document, see the link to the source for this document at the bottom of this page. For the impatient, see Installation to get started.


A TML call is made from a web page when a square bracket [ is encountered. As TML calls do not require quotes, usage seem more natural than program generated pages. eg.
  [Bg Four-score and seven years ago] our <I>forefathers</I> ...
TML collects the text "Four-score and seven years ago" up to the matching end bracket and passes it as a single string argument to the user defined procedure Bg. Text may span multiple lines and if another open brace is encountered along the way, that command gets processed first, and it's output added to the collection. TML calls can be nested to any depth.

Here is a longer sample, with the HTML translation side by side.

[H1 Some Sample TML]
[B Here] is some demonstration
[A TML.html TML]].
  [li List item 1]
  [li List item 2]
  [li List item 3]

<H1>Some Sample TML</H1>
<B>Here</B> is some demonstration
<A HREF="TML.html">TML</A>.
  <LI>List item 1</LI>
  <LI>List item 2</LI>
  <LI>List item 3</LI>

Defining Procedures

So far, using TML doesn't seem like much of a savings over HTML. However, TML lets you do something that HTML does not: define your own tags/procedures. The user does not require Tcl or programming knowledge for this as the %define command lets you define your own macro-like procedures.

  [%define Bg <B><FONT COLOR=green>$1</FONT></B>]

The $1 gets substituted with your data ($2 is for attributes). Applied to the first example this produces:

   Four-score and seven years ago our forefathers ...

Alternatively, programmers can place code or other text inline using a Block Eval escape: [?
Here is the Tcl definition for the above %define:

     proc Bg {1} {
        return "<B><FONT COLOR=green>$1</FONT></B>"


HTML tags make extensive use of attributes, which contain information that somehow describe or parameterize text. An example of an attributes is the "color=red" part in the HTML "<FONT color=red>". Interworking with HTML requires an effective way of dealing with attributes. Thus, this next example demonstrates an attributed TML call:
  [Bg<attr1=a attr2=b> Four-score and twenty years ago]
In a TML call, the attributes get passed as the second (string) argument to a procedure, or as $2 in a %define. TML attributes may contain Tcl variables and procedure calls. These are resolved with a call to Tcl's subst. The attributed syntax may seem a little odd at first, but it is useful in an number of cases, including supplanting HTML. Here is an example:
  [%define Bg <FONT $2>$1</FONT>]
      set size 5;
      proc color args {
        return blue
  [Bg<size=$size color=[color]> A call with parameters.]
Which produces: A call with parameters.

Don't try to use a $size anywhere else in the document, as only function calls, not variables work. Use [set size] instead. Also note that the arguments to procedures within attributes are processed according to Tcl rules, not TML rules, and so may require quoting/bracketing.

Default attributes to many of the predefined HTML TML tags may be defined as in the following for the INPUT tag:

  [? set _input_ " color=white " ?]

Moreover, the following attributes are recognized by BrowseX.
target=new open hyperlink A in a new window
onevent="..." event handler ala javascript
tclevent="event cmd ..." bind event to a form element
tclopts="..." pass tcl options to form element tcl widget
tktable="VAR" NOT IMPLEMENTED: for a TABLE, use a tktable with Variable VAR
Also, the _tml array contains the following elements:
eventinfo contains information about an event
browser set to name of browser
islocal set to 1 if tml is local (ie. file:)
iscgi set to 1 if tml is begin executed in a cgi
url url of current page
query query string of current page

That covers the basics of TML. Here are some additional things to consider.

  • For existing HTML, Convert or Block Protect all square brackets.
  • You can use simple Tcl variables and calls inside attributes <> only.
  • To use Perl or Python for TML calls, see Alternate Languages.
If your new to Tcl, you might want to see the Tcl Tutorial and References section.

Escaping Square Brackets In HTML

Square brackets are fairly common characters in documents, and as such you'll probably need to convert an existing HTML document before using it as TML. You can do it manually, or you can use tml -quote to translate all [ and ] in an HTML file into the TML escapes: [lb] and [rb] . Subsequent processing by TML will produce the original document (+ a comment). It will also insert a %pragma on line one of the output to indicate that even script/embeds have been converted.


    tml -quote foo.html > foo.tml


Following are the builtins available in TML. Any marked with a * are intrinsics, not Tcl commands. All others are just Tcl procedures defined in Tcl in htmlrule.tcl, which means you are free to use them from Tcl or override them.

Block Escapes

It is sometimes necessary to handle a block of text in a special way, the following special block delimiters are available:
[# ... #] Block Comment *
[= ... =] Block Protect *
[? ... ?] Block Eval. Optionally with a command: [?<command> ... ?] *
TML commands are invoked by an open square bracket: [. Note that by convention, builtin commands start with a percent char (%) to avoid colliding with Tcl commands.

Character Commands

%lb output a left bracket: [
%rb output a right bracket: ]
%ch output special chars, eg: ?, &, copy, nbsp. +opt count
%sp output a space, with optional repeat count
%vsp output a vertical space, with optional repeat count

Control Constructs

%source include a local file and interpret as tml *
%include include a local file (no tml interpretation) *
%if<cond> if statement, cond is a Tcl expression *
%elseif<cond> elseif statement, follows %if or %elseif *
%else else statement, follows ] of %if or %elseif *
%while<expr> while loop *
%for<init expr incr> for loop *
%foreach<var list ...> foreach loop *
%break break out of innermost for, foreach or while loops *
%continue continue at top of inner loop *
%exit exit processing *
%error exit processing with given error message *
%limit limit the maximum loop iterations: default 1000 *
%parse parse a string containing TML *
%pragma force options: see CGI *

Tcl commands can of course be accessed directly. Commands that take two or more arguments can be called with eval. For example:

     [eval set x 9]  
     [set x]  
Remember, anything returned by commands will be inserted directly into the output. The previous example inserts "9 9". To avoid this you would use %eval or one of the following predefined convenience functions:
%eval Tcl eval, no output
%set set value of a variable, no output
%incr incr value of a variable, no output
%null does nothing, no output

Defining commands

These following are for defining/redefining other commands.
%define name ... define a tag name.
%predefine name pre pre is a tcl proc that preprocess input to name
%postdefine name post post is a tcl proc that postprocess output from name

Miscellaneous Commands

%perl evals perl code
%python evals python code
%query return the query args given the url
%name shortcut for <A NAME=.., ie. defining a label
%ae like <A HREF=.., but derefs .tml if file exists
%html generate HTML encodings for all < and >.
%echo just returns block of text unchanged.
%pre same as %html, plus wraps output in a pair of PRE tags.
%setcookie set a cookie value in a CGI
%getcookie get a cookie value in a CGI
%accessdata get/set data from storage
%alert popup a message dialog box
%widgetcmd execute a formatted command with a widget
%formwidget execute subcommand for a form widget
%formvalue get/set value for a form widget
%sqlite access sqlite database
%urlget get a url
%urlgetrel get a url relative to current
%urlview get a url in a new view
%viewconf change view configuration

TML Composite Procedures

Included are several additional utility macros, As a hint at what's possible. This is the part of TML that will likely grow.

%trd specify a whole table row where all the <td>'s are between ,
%tmltoc generates a table of contents for page headings.
%tmlborder a table with a nice solid border/header (table in a table)
%tmldef a definition table, consisting of a bolded term and a Def.
%tdi a tmldef item. Separate Term and Def with a ,
%footnote adds text to end of file, and inserts a link image to it.
%iref an inline reference

TML Widget Commands

The tml command is created in the target interpreter, and has a number of subcommands. Obviously, these are available only from Tcl:
tml debug ?N? get/set the current debug level
tml errorcmd cmd setup a command as an error handler
tml inputs ?-includes? get TML page source ?with includes?
tml maxpass ?N? get/set the maximum number of passes
tml pass returns current pass number. 1 is the first pass
tml parse actually performs the parse
tml puts STR send a string directly to page output (no newline)
tml append STR append string to end-buffer (footnotes, etc)
tml language STR sets the default alternate language

The script tml.tcl sets up the proper environment and handles the parse for you. This includes sourcing htmlrule.tcl to create all the other commands needed in the environment. TML can run in either a safe interpreter or a normal one. Please refer to tml.tcl for details.

HTML Commands

htmlrule.tcl defines Tcl procedures for the standard HTML tags (upper and lower case) so that TML equivalents are available for all common tags. eg: B, b, I, FONT, etc Most work the same as their counterparts, but the A tag has been overloaded so that if you provide just a single argument, it becomes the href. With more than one, the href plus the viewable contents.

Here is a brief usage comparison of TML and HTML:

 HTML:   <B>Brave <I>New World</I></B>
 TML:    [B Brave [I New World]]

As some HTML tags possess attributes, TML supports attributes enclosed in angle braces immediately following the tag (no space). A space after the > is required.
 TML:    [FONT<COLOR=RED SIZE=1> Hello World]

The proc FONT ends up getting called with exactly two parameters.
  FONT "Hello World" "COLOR=RED SIZE=1"
You are free of course to redefine any of these procs.

The file htmlrule.tcl contains the macros that encapsulate html tags. At a minimum, the following tags (upper and lower case) are defined in the current htmlrule.tcl:

  H1 H2 H3 H4 H5 H6 H+ H= H-

The last three tags are for relative heading levels at the next/current/previous level respectively.

Defining Procedures

The most important thing to know about TML is that the evaluation is non-recursive. ie. returning "[B xyz]" from a proc will not result in proc "B" being called. The only exception to this are the %source and %parse commands which do recursively interpret its results. Conversely, if a Tcl procedure calls a TML proc, it must pass all data as the first argument, and attributes as the second. eg.
  proc foo {v args} { return [B some text bolded] };            # WRONG!!
  proc foo {v args} { return "<B>some text bolded</B>" } ;      # OK
  proc foo {v args} { return [B "some text bolded"] };          # OK
  proc foo {v args} { return [FONT "color text" COLOR=WHITE] }; # OK 

For simple tags, TML syntax is straightforward, but the need to handle attributes complicates things a bit.

Information between an HTML begin and end tag normally contain two things: tag attributes and data. The attributes are the part contained within the angle braces of the start tag, and the data is the part between the begin and end tags. And these are passed as two separate arguments. TML procs take up to 2 arguments, and TML encodes the data in the first argument and the attributes, if any as the second.

  [? proc CENTER {data attr} { return <CENTER$attr>$data</CENTER> } ?]
  [CENTER<align=left color=white>
    Some stuff.
In the above, the "align=left color=white" would be passed via the attr argument and "Some stuff" would be assigned to data. If there are never any attributes, the second parameter can be omitted, or defined as {attr {}} or even args. There are so many ways of defining a Tcl procedure that accept zero - two arguments, it is confusing. The simplest universal declaration is:
  proc foo {data args} {
In case anyone cares, here are the various permutations.
  proc foo {}                 { return <B>FOO</B> };# 0 args: NOT IN TML
  proc foo {d}                { return <B>$d</B> }; # 1 arg
  proc foo {d attr}           { return <B>$d</B> }; # 2 args
  proc foo {d {attr {}}}      { return <B>$d</B> }; # 1 or 2 args
  proc foo {{d {}} {attr {}}} { return <B>$d</B> }; # 0, 1, or 2
  proc foo {d args}           { return <B>$d</B> }; # 1 or 2 args
  proc foo {args}             { return <B>$args</B> }; # 0 or more

It was said that by convention, attrs are passed in the second argument. A procedure is free to interpret the data any way it likes. For example, the [A] tag is implemented with shortcuts to allow the href to be the first string in the data. See htmlrule.tml and BrowseX  docs for examples.

How Is It Useful

TML has a small number of intrinsic functions (lb, rb, source, etc), but HTML tags and the rest of the functions are defined in Tcl in the file lib/tml/htmlrule.tcl. The inline nature of TML can be more naturally readable because it eliminates the need for end tags and reduces the number of markup tags in a document by half. It is possible that the document could be retargetable to say manpages, latex or even XML just by redefining the Tcl procedures. The later, XML, is aided by the hierarchical nesting of tags that TML enforces.

While HTML <script> areas allows for programmable documents on the client side, it comes up short in several respects. Foremost, it is not reasonably useful on the server side. Conversely, languages such as Perl and Tcl are often used server side (CGI et al) to output HTML, but programming syntax is somewhat awkward and cumbersome to use, and read.

There are two implications to embedding Tml inside BrowseX . The first is that .tml files can be viewed directly by BrowseX  without manually preprocessing the files. This works only because the source file is local (a file:) and therefore Safe-Tcl is not by default used (or when it is, safe-read is enabled) in the embedded Tml-Tcl. Thus file source, includes, etc should work fine.

The second implication is that it is possible for Web servers to return documents of type text/tml and have the BrowseX  browser process the document tags correctly. This will however work only with BrowseX , so caution should be exercised with this practice and/or the Browser type should be checked by the web server. In addition, site specific include files would need to be embedded in an eval statement at top.

  set title {Hello World}
  puts "<B>$title</B><BR>"

Schemes to use variable substitution and procedure calls get ever more snarled in quoting issues and programming indirection. TML, on the other hand, is designed to make markup more readable, primarily because there is less of it. BrowseX  runs TML within Safe-Tcl inside the browser to provide on the fly macro processing and in so doing, creates a new document type/extension:

  .tml    text/tml        # HTML Tcl Macro Language


The source code for TML is available here. You must already have Tcl installed on your system. TML was developed using Tcl 8.4a2 under Linux Redhat 7.0. It has also been tested and used under Windows and Solaris 7/8.

Edit the Makefile to change the target install destination, if desired. Edit tml.tcl to change the tclsh line at top if you are not using tclsh8.4.

Type make install. This installs the TML library and puts a tml in your bin directory. If using the CGI, see CGI TML. For Perl, see the Perl section. You may want to get BrowseX  so that you can view tml files directly. If using neither CGI nor BrowseX , you can run the tml command to convert .tml files to HTML for local viewing under a standard browser.

In any case, see Escaping Square Brackets In HTML before working with existing html documents. Also, when defining variables or procedures remember that using % as the first character is reserved for TML. Also reserved are htmlrules_init, tml and _tml.

The source for TML is very small: comprised of just the following source files:

tml.c The tml widget
tml.tcl Command and CGI front end
htmlrule.tcl Implements the Tcl procs sourced into the widget


TML can run as a CGI, and even has a safe mode when run in just Tcl. To setup TML for Apache, install TML, then copy tml.tcl to your cgi directory and add something like the following to your httpd.conf file:
  AddType application/x-httpd-tml .tml
  Action application/x-httpd-tml "/cgi-bin/tml.tcl"
You will also want to add the gifs from the icons directory to your icons directory. Tml.tcl has several options the defaults which can either be passed as arguments or set at the top of tml.tcl. The two most important are:
-sendtml nSet to 0 to not allow sending raw TML to BrowseX  (default 0)
-safe nSet to 0 to not use Safe interp (default 1)
Using -sendtml will sense when BrowseX  is the connecting browser and will then send raw tml for local interpretation (%include/%source directives are done first). This make the dynamic use of TML conditional directives like %iref without invoking network traffic the default (requires version 1.5+ of BrowseX ). As the could interfere with server CGI's the better way is to put [%pragma<-sendtml=1>] on the first line of such documents.

The -safe option forces TML to always be run in a safe interpreter. By default, this is off but BrowseX  uses -safe for TML that are not file:/ URLs. ie. sent by CGI's using the -sendtml option. Note: setting this to 1 in CGI will limit operations (ie. no or restricted read/write/exec), and you will not be able to use a alternate language (Perl and Python). You can use the %pragma option on the first line of the Html file to force -safe on or -sendtml off.

Using A Database

Tcl has several database options. As with any Tcl extension package, you download and install it. Then include the approriate package require and your off. Here is an example from the Tcl-SQL package for MySql.
    package require sql
    set conn1 [sql connect mypass]
    sql selectdb $conn1 test
    catch {sql exec $conn1 "drop table foofoo"}
    sql exec $conn1 "create table foofoo (i integer, r real, s char(10))"
    for {set i 0} {$i < 10} {incr i} {
            sql exec $conn1 "insert into foofoo values ($i, $i.01, 'xx $i xx')"
    sql query $conn1 "select * from foofoo"
    puts "Printing results:"
    while {1} {
            set row [sql fetchrow $conn1]
            if {$row == ""} break
            puts "##row = $row"
    sql endquery $conn1
    sql disconnect $conn1

Some Advantages of TML

The advantages of TML include:
  • TML is not a language, and so should be relatively static
  • TML is small (around 1200 lines of C) and should stay small
  • TML is server and/or client side. CGI and embedded work the same
  • The BrowseX  client means you can run even DB scripts without a Web Server
  • Bracket matching (ala VI) can be used to check nesting.
  • Web pages are fully programmable and parameterizable.
  • Less tags means pages are more human readable
  • Redefine any or all tags: eg. retarget output, say to LaTeX.
  • Most of the standard HTML 3.2 tags have also been defined as Tcl procs. So you can supplant HTML entirely, if desired. Using square brackets rather than angle braces means your not constantly hitting the shift key. And end tags are redundant.
  • If it doesn't do what you want, or the way you want, you have the (small) source!

Note 1: All the BrowseX  Web pages are written in TML.

Note 2: For backward compatibility, commands that were in Version 1 of TML (eg. source, define, etc), will also work without the leading percent (%), but will be discontinued in future.

Tcl Tutorial and References

A Tcl Tutorial

If your thinking of trying Tcl for the first time, perhaps this tutorial can help get you going. It's a learn-by-example, comparing Tcl, with C and Perl. If you're not already a seasoned programmer, see the other Tcl References at the end of this tutorial.

Tcl has really only one data type: string. If spaces or special characters are within the string, it should be enclosed in quotes (ie. double quotes or curly braces). Double quotes let variables and calls inside the string be evaluated, curly braces don't. Strings can also be treated as a list: Whitespace is the list separator. Curly braces enclose sublists and need to be balanced or be escaped.

Example 1: The Basics

  # TCL {}               # Perl                   /* C */                
  set s1 {Hello World}   $s1="Hello World";       char *s1="Hello World";
  set s2 "Foo Bar"       $s2="Foo Bar";           char *s2="Foo Bar";
  set s3 Fantasy         $s3="Fantasy";           char *s3="Fantasy";
  set y 7                y=7;                     int x, y=7, K;
  proc max {x1 x2} {     sub max {                int max(int x1, int x2) {
    global K               my($x1,$x2) = @_;
    if {$x1>$x2} {         if ($x1>$x2)             if (x1>x2)
       return $x1            return $x1;               return x1;
    } else {               else                     else
       return $x2            return $x2;               return x2;
    }                      $K=1;                    K=1;
    K=1                  }                        }
  set x [max $y 9]        $x=&max($y,9);          x=max(y,9);                
  unset x
The above shows:
  • variable declarations aren't required in Tcl.
  • all variables in a procedure are local by default.
  • Tcl uses the set command to assign values to variables, rather than an =.
  • it uses $ to get the value of a variable, but not during a set.
  • curly braces are always required for blocks (unless it's a single word).
  • use square brackets to call a proc and get it's return value.
  • the Tcl comment is like a command: "#" is after ";" or is first word in line.
  • and braces in comments must be balanced, if present.

Example 2: Loop constructs

A crude comparison with 'C'. No real surprises.
  # TCL                                 /* C */
  set s 0                               int s=0;
  for {set i 0} {$i<10} {incr i} {      for (i=0; i<10; i++)
    incr s $i                             s+=i;
  set s 0                               s=0;
  set i 0                               i=0;
  while {$i<10} {                       while (s<10) 
    incr s $i                             s+=i;
  foreach i {A B C} {                   char *lst[] = {"A","B","C",0}, *cp=lst;
    append str $i                       while (*cp) strcat(buf,cp++);
  switch $i {                           switch (i) {
    A { set l a}                           case 'A': l='a'; break;
    B { set l b}                           case 'B': l='b'; break;
    C { set l c}                           case 'C': l='c'; break;
    default { set l " " }                  default: l=' ';
  }                                     }

Example 3: Expressions and Arrays

  set x 1;                      # there are no integer types
  set y [expr {$x*1.25}];       # i all numeric operations are done by expr
  if {[expr {($y+1)*5}] > 19} { # round braces really only used in expr
     puts "Got it"
  set ar(0) A
  set ar($x) B
  set ar({Hello World}) -1;     # Tcl arrays are always associative.
  array set ar {3 C 4 D 5 E};   # assign array from list: ar(3)=C, ar(4)=D, ...
  set lst [array get ar];       # assign list from array contents
  foreach i {[array names ar]} {
    append str $ar($i)
  unset ar

Example 4: Pass by reference

Here is the same function as in example 1, but passing x by reference (using upvar).
  # TCL                   /* C */
  set y 7                 int x, y=7;
  proc max {xx x1 x2} {   int max(int *x, int x1, int x2) {
    upvar $xx x            
    if {$x1>$x2} {          if (x1>x2)
       set x $x1              *x=x1;
    } else {                else
       set x $x2              *x=x2;
    }                     }
  max x $y 9              max(&x,$y,9);                 

Tcl Syntax

One might rightly wonder why Tcl doesn't give shorthands like "x=y++;" rather than the more cumbersome "set x [incr y]"? The answer is: it can't!. Here's why:

Tcl is really just a command processor, with all commands in the form of a list:

  cmd arg arg arg ...
For instance, the while statement above is just a command with two string arguments. It is called during execution, with two arguments. The first it evaluates as an expression and the second as a block of code. This means, for example, that you can easily write your own while command in Tcl.

The point is that Tcl doesn't really have a syntax. There are quoting rules, commands and [proc calls], but little else. Even the lowly comment in Tcl can be considered as a sort of NULL command. There is no complicated grammar. In fact, the structure of the language could not be simpler.

Tcl References

Alternate Languages

When TML processes a square bracket command, it looks for a Tcl procedure by that name to call. Normally, if the named command does not exist, an error is raised. However, if %perl or %python has been used, procedures may have been defined in those languages as well. In this case, the missed command is issued as a call to the alternate language. If both %perl and %python have been used in the document, the alternate language is defined to be the last one to call it's access function: %perl or %python. Alternate languages works only for TML function calls. But within attributes any variables or function calls, will be evaluated only in Tcl. Also alternate languages can not be accessed while using the -safe CGI option as this relies on SafeTcl.

Using Perl

You can configure for the perl Language as follows. First you need to install Jean-Luc Fontaine's great tclperl package. Source is in the tclperl directory. Just type make install there, or see for RPMs/DLLs and details.

Now you can use the %perl command to evaluate blocks of perl code.

    <H1>Test of Perl</H1>
       sub Bold {
         return "<b>".$a."</b>";
       return "Perl code: "
    [Bold Here is some text bolded by perl]
Note: the explicit return statement is required if you wish to see output from the Block Eval. The above works fine as long as there is not already a Tcl function called Bold. If there is, you can still override the Tcl command with a perl command by renaming the Tcl command. eg.
    <H1>Test of Perl</H1>
    [? rename Bold OldBold ?]
       sub Bold {
           return "<b>".$a."</b>";
    [Bold Here it is perl]

Using Python

You can configure for the python Language as follows. First you need to install Jean-Luc Fontaine's great tclpython package. Source is in the tclpython directory. NOTE: the INSTALL advises that a patch is required to compile. An easier way is to get precompiled RPMs/DLLs from

Now you can use the %python command to evaluate blocks of python code. Due to the finicky indenting requirements of python, blocks are stripped of leading whitespace and trailing spaces.

      def bold(n): # return bolded string
         "Return a bolded string"
         return "<b>" + n + "</b>"

_="Python code: "
    [bold here is some text bolded by python]
Note: the explicit _= statement is required if you wish to have see output from a Block Eval.


Following is an exhastive list of all TML commands, with examples and attributes. Attributes for commands are just text. However, often they are used as AVP's, attribute-value pairs in the form <Attr1=Val1 Attr2=Val2 ...>. RHS values are typically either strings or integers with 1/0 meaning true/false. Some commands will pass parameters in the data argument as positional arguments.

%ae - like <A HREF=.., but derefs .tml if file exists

The AE tag provides a mechanism to use .tml links when using the browser, that references the .html file instead when preprocessed on the server side.

The %ae command is like the hyperlink reference <a href= tag. It takes a file name minus extension as the first argument. The remaining arguments are used as the link description. When viewed as a TML file, %ae appends .tml to the filename and uses that as the link. However, if the source is preprocessed to HTML, .html is appended to make it look for preprocessed links. The following example presumes Foo.tml exists.


    [%ae Foo Link to foo]

%break - break out of innermost for, foreach or while loops

For use in the %for, %foreach and %while commands, %break directs the parse to exit the loop and continue at the statement after the loop end bracket.



%ch - output special chars, eg: ?, &, copy, nbsp. +opt count

The %ch command encodes a character to HTML encoding. If it is a single characters it is converted to the numerical encoding, otherwise it is placed in between & and ;. This is useful to prevent interpretation like the %tdi command.


    [%ch ,]
    [%ch copy 5]


, ©©©©©

%continue - continue at top of inner loop

For use in the %for, %foreach and %while commands, %continue directs the parse to continue at the top of the loop.



%define - define a macro

The %define macro is really just a shortcut for defining a procedure, and as such you should avoid special chars like quote, braces, etc, or use [ch "] to get the html encoding. You may also want to use mixed case names or some other convention to avoid colliding with possible future HTML tags.


  [%define FOO <b>FOO</b>]
  [%define BAR <b>BAR $1</b>]

which is more or less equivalent to

     proc FOO {}  { return "<b>FOO</b>"  }
     proc BAR arg { return "<b>BAR $arg</b>"  }

%echo, - returns input unchanged.

%else - conditional

See %if.

%elseif - conditional

See %if.

%eval - Tcl eval but discard output

A convenience function, %eval does the same as eval but discards output.


    [%eval set x 99]

%error - exit processing with given error message

The %error directive causes the parse to terminate immediately and generates an error with the provided string argument.


    [%error Value [set x] is out of range]

%exit - exit processing

The %exit directive causes the parse to terminate immediately as though it had reached the end of the page.



%for<init expr incr> - a for loop

Implements a for loop for the parse.


The attribute of %for contains an list of three items which are interpreted/evaluated by Tcl: the initializer, the exit condition, and the increment. Behavior is the same as Tcl for.


    [%for<{set i 1} {$i<5} {incr i}>
       Here is the output for line [set i]<br>


Here is the output for line 1
Here is the output for line 2
Here is the output for line 3
Here is the output for line 4

%foreach<var list ?var list ...?> - foreach loop

Implements a foreach command to iterate variable(s) over list(s) of values.


The attribute of %foreach contains an even numbered list of two or more items which are interpreted/evaluated by Tcl. Each pair is a variable and its list of values. Behavior is the same as Tcl foreach.


    [%foreach<i {Tic Tac Toe}>
       Iterate over [set i]<br>
Iterate over Tic
Iterate over Tac
Iterate over Toe

and ...


    [%foreach<r {{Bob Ganes} Tom Bill} p {First Second Third}>
       [set r] was [set i]<br>


Bob Ganes was First
Tom was Second
Bill was Third

%getcookie, - get a cookie value in a CGI

This command, which is useful only in CGI, gets a cookie(s) for the given name.


  [%getcookie state]

%html, - generate HTML encodings for all < and >.

This command is used to translate all angle brackets in the input text so that it does not get eaten by the browser.

%if/%else/%elseif - conditional

The %if command lets you control the conditional flow of the parse. It may be followed by the %elseif and %else commands, with intervening whitespace or newlines, which is discarded. All other space goes to ouput. One gotcha to be aware of: the extra space in writing $i > 3 rather than $i>3 would have inadvertantly matched the end of attribute and caused an error.


The attributes for %if and %elseif contain an expression which is passed to Tcl for evaluation.


  I think that I will
     take a <b>walk</b>
     in the park.
     go for a <i>run</i>
     on the beach.
A more convoluted example can be seen here: 
  [%set i 0]
  [%while<$i<4> Loop[incr i] ]
  [%for<{set i 0} {$i<10} {incr i}>
    [%if<$i==0> My Heading [%continue]]
    [%else Data[set i]]
    [%if<$i>3> [%break]]
  [%foreach<i {a b c}> [set i]]


  Loop1 Loop2 Loop3 Loop4 
      My Heading      Data1

%include - data file inclusion

Bring a data file into output. No interpretation is done. For security reasons, the actual file read is done by the Tcl procedure FileRead inside the interpreter.


nocomplain - silently fail if file does not exist


  [%include myincs.txt]
  [%include<nocomplain=1> maybeincs.txt]

%incr - incr value of a variable, discard output

A convenience function, %incr does the same as eval incr but discards output.


    [%incr x -1]

%lb - output a left bracket: [

The %rb command outputs a single square left bracket. This is to avoid having it be interpreted as a TML escape. Because this command is so common, the % can be omitted.


    Assign A[lb]99[rb] = 19

%limit - limit the maximum loop iterations

This directive is to prevent %for and %while loops from going into infinite loops. It the maximum is exceeded an error is generated.


    [%limit 100]

%name - shortcut for <A NAME=.., ie. defining a label

Outputs a label anchor: <A NAME=.


    [%name foo]

%parse - evaluate tml in current context

This command lets you build up a TML string inside TCL and then have it evaluated in the current context. The results are inserted into the output.


        set x {[b Bold moves] are required}


Bold moves are required

%perl - evaluate a string containing perl code

The %perl command evaluates perl code. Although it can be used directly as in the following example, it is more commonly used in an Block Eval and requires the installation of TclPerl.
  [%perl $x=99]
As a side effect, perl now becomes the default alternate language. Therefore it is reasonable to use the following:

%postdefine - postmodify a define

See %predefine.

%pragma - request override options

The %pragma directive must be on the first line of the .tml file. Typically %pragma is used to change the way TML processing is done. For example, you could ask to be run in -safe, when unsafe is the default, but not the other way around. Attributes with a leading dash are commandline options as well.


-safe run in safe interpreter
-sendtml send raw TML to remote BrowseX
-cgidata cgi send data file in _tml(cgidata:0), multiple sends ok.
-cgilist cgi send list items from data file in _tml(cgilist:0), multiple sends ok.
inscripts look for escape chars even inside script/embed tags. Normally TML will try to avoid what is inside of a SCRIPT or EMBED tag.



%pre, - output translated and PRE protected text

Does the same thing as %html, plus it wraps output in a pair of PRE tags.

%predefine - premodify a define

There is a limited facility for modifying existing tag definitions. The %predefine (%postdefine) command lets a user defined Tcl proc, process arguments to to a tag before (after) the original does it's work. You may use pre/postdefine at most once each for any given tag (however, as predefined tags are both upper and lower case you could define each with different pre/post defines). Future releases may extend this to multiple levels and add preundef/postundef. The following example shows how to modify the definition of H2 to also have it make it a link to the TOC.


  [%define myh2 <A href=#toc>$1</A>]
  [%predefine h2 myh2a]

%python - evaluate a string containing python code

The %python command evaluates python code. Although it can be used directly as in the following example, it is more commonly used in an Block Eval and requires the installation of TclPython.
  [%python x=99]
As a side effect, python now becomes the default alternate language. Therefore it is reasonable to use the following:

%query - return the query part of the url

The %query command returns the query part of the url as a list suitable for assigning with array set. This is useful within CGI's to obtain form parameters. It is also available within BrowseX , ie. without a CGI or a web server. Following is a snippet of code that shows how to turn off the Table of Contents when ?toc=0 is appended to the .tml filename in the location bar:


    array set qargs {toc 1}
    array set qargs [%query]
    [%tmltoc 2]

%rb - , output a right bracket: ]

The %rb command outputs a single square right bracket. This is to avoid having it be interpreted as the end of a TML escape. Because this command is so common, the % can be omitted.


    Assign A[lb]99[rb] = 19

%set - set value of a variable, discard output

A convenience function, %set does the same as eval set but discards output.


    [%set x 99]

%setcookie, - set a cookie value in a CGI

This command, which is useful only in CGI, sets a cookie for name/value.


  [%setcookie state 12345]

%source - tml source file inclusion

The %source command brings a file inline into the parse and interprets any TML inside it. There is one restriction. Although you may use %source inside of a %if/%elseif/%else, you must not use it inside of a %while/%for/%foreach loop. Doing so will generate an error. For security reasons, the actual file read is done by the Tcl procedure FileRead inside the interpreter so that safe-tcl is honored.


nocomplain - silently fail if file does not exist


    [%source mysrc.tml]

%sp - output a space, with optional repeat count

This command outputs one or more spaces in HTML encoding. ie. &nbsp;


    A [%sp 20] Gap


A                      Gap

%vsp -output a vertical space, with optional repeat count

This command outputs one or more vertical spaces in HTML encoding. ie. &nbsp<br>


    A [%vsp 3] Gap



%while<expr> - a while loop

The %while command lets you iterate a parse repeatedly over as section of output.


The attributes for %while contain an expression which is passed to Tcl for evaluation.


    [%set i 5]
        Output for line [set i]<br>
	[%incr i -1]


Output for line 5
Output for line 4
Output for line 3
Output for line 2
Output for line 1

[? ... ?] - Block Eval. Optionally with command: [?<command> ... ?]

A Block Eval lets you put a block of code or processable text inline into a document. An optional attribute can follow the ? and if present is interpreted as a Tcl command to process the raw block. A value returned from command is output to the page. With no attribute/command, the default is to evaluate the block in Tcl, and discard the result. But you can use "tml puts" to output text directly. eg.


        # Some Tcl code
        set i 99
	proc Foo {x} { return [incr x] }
	tml puts "Foo<br>"

==> Foo

The above is equivalent to using the eval command. Note that in Tcl the result of the last expression becomes it's return value:

	set x "Foo<br>"

==> Foo

Commands may also take preceding arguments.

   [?<string toupper>
	here is a bunch of upper case text.


And the empty attribute just echos output unchanged.

     This is the same as using <%echo> and passes []

==> This is the same as using <%echo> and passes []

[= ... =] - Block Protect

A Block Protect is a shorthand way to pass through text so that it appears as typed on the web page. In addition to preventing square bracket escapes from being interpreted, it translates angle brackets into HTML escapes and wraps the result in a PRE tag to preserve formatting. You can do almost the same thing with a %pre attribute in an Block Eval.


	Here is an example<>:


     Here is an example<>:

[# ... #] - A Block Comment

A TML block comment delimits data that is to be discarded from the parse. It is useful for commenting out blocks of code.


   [# This is a comment
      [%if<$i<1>  # Something going on here...

Composite Procedures

TML Includes several additional utility macros, As a hint at what's possible. This is the part of TML that will likely grow.

%iref - Inline Reference Link

TML enables the composition of very sophisticated tags: %iref is one such. It implements a so-called inline reference to allow displaying additional information inserted into the current context. %irefs shows up as a little orange book: eg 

Here is an example inline ref.
When you clicked it opened. Here is the code.

Here is an example inline ref.[br]
When you clicked it opened to show this.[p]

. Clicking on this changes the icon to an open book image and displays the text arguments to the tag. Click again and it collapses. This works with Netscape and other browsers (if you've setup the TML CGI) by downloading the document again. BrowseX  has the ability to view %irefs directly without a redownload over the network, because it can parse TML locally. When closed, inline references will normally display the text body of the reference as a the image Alt text balloon. BrowseX  will display multiline Alt text balloons, so often you don't even need to click. Following is an example of an 
Nested list 1

Nested list 2

Tree list


usealt Show ref text as image alt balloon (default 1)
maxalt Max alt lines to display (default 500)
closealt alt string to display when open
imgdir Directory to obtain images from
title Title string to display before book image
boldtitle Bold title when reference open (default 1)
goto label to goto when click occurs
imgopened minbook1.gif
imgclosed minbook2.gif


    [%iref<title="Open Orders">
	Some lines shown upon click
	Some lines shown upon click
    %Open Orders

%footnote - Footnote

Adds text to end of file, and inserts a link image to it at the current postion.


  [%footnote Note: footnote from demo.]

%tdi - a %tmldef item. Comma separated Term and Def

%tdi is used within %tmldef to list definitions. Essentially, it puts everything before the first comma into the first row of the table and bolds it. Everything else goes in the second row unbolded. See %tmldef for an example.

%tmltoc - generates a table of contents for page headings.

%tmltoc, provides support for the auto-generation of a TOC (Table Of Contents) from the heading levels H1, H2, ... H6, for all the headings seen so far. %tmltoc optionally takes two arguments, the min and max header levels to include in the index.


twopass do two passes so we can put TOC at top or anywhere.


  [? proc mytitle {v args} { return "Hello $v World" } ?]
  [H1 My First TML Doc]
  [H2 A First Crack]
  [B [mytitle Brave New]][BR]
  Here is <I>some</I> text.  

%tmlborder - a table with a nice solid border/header

Creates a bordered table (table within a table). This gives the solid bordered table as seen on the BrowseX  web site.


    [tmlborder<title="Hello There">
	[trd Here is a bunch of stuff[br]to fill the table]


Hello There
Here is a bunch of stuff
to fill the table

%tmldef - a definition table, consisting of a bolded term and a Def.

A convienience function to avoid having to specify all those TD tags.


	[tdi One:, first definition]
	[tdi Two:, second definition]


One: first definition
Two: second definition

%trd - specify a whole table row where all the <td>'s are comma separated

A convienience function to avoid having to specify all those TD tags


	[trd one, two, three]
	[trd A , B, C]


one two three

TML Widget Subcommands

tml inputs - get TML page source

Used from Tcl, this gets the TML page source as a string. Mostly this is used to display the page source to the user. If given an argument, inputs will return the expanded text after all file includes. See the bottom of the page to see it in action.


    [%iref<title="TML Source Code For This Page">
      set dat [tml inputs]
      regsub -all {<} $dat {\&lt;} dat
      tml puts <pre>$dat</pre>

tml puts - send a string directly to page output

Used from Tcl, output sends a string to the output stream so that it appears on the page.


	tml puts "The total is: $ttl"

tml append - append string to end-buffer (footnotes, etc)

Used from Tcl, append adds the string argument to the end-buffer such that at the end of the parse, the end-buffer is concatenated to the output.


	tml append "note: see references"

tml pass/maxpass -access and sets variables pass and maxpass

Used from Tcl, gets or sets the value of TML internal variables. Mostly this is used to control or query the following variables for multiple passes (eg. %tmltoc):
pass the current pass number in a multipass parse (readonly)
maxpass the maximum number of parse passes


       proc Foo args {
          tml maxpass 2
          if {[tml pass] != [tml maxpass]} return

tml errorcmd CMD - set an error handler command

Lets you provide an Tcl error handler command that gets called when there is an error. The error message string is appended as an argument.


	tml errorcmd MyError

tml parse - actually performs the parse

Used internally by tml.tcl. Usually not useful by the end user.


This software is copyrighted Peter MacDonald and BrowseX Systems Inc.
The following terms apply to all files associated
with the software unless explicitly disclaimed in individual files.

The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors
and need not follow the licensing terms described here, provided that
the new terms are clearly indicated on the first page of each file where
they apply.



GOVERNMENT USE: If you are acquiring this software on behalf of the
U.S. government, the Government shall have only "Restricted Rights"
in the software and related documentation as defined in the Federal
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
are acquiring the software on behalf of the Department of Defense, the
software shall be classified as "Commercial Computer Software" and the
Government shall have only "Restricted Rights" as defined in Clause
252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the
authors grant the U.S. Government and others acting in its behalf
permission to use and distribute the software in accordance with the
terms specified in this license.

Table of Contents

Copyright © 1999-2001   Browsex Systems Inc


TML Source Code For This Page

Note: footnote from demo.