BrowseX  Documentation

[%pragma<-sendtml=1>]
[title TML 2.0 Documentation]
[%source<nocomplain=1> Master.tmpl]
[?
     if {[info commands Trailer] == {}} {
       set nomaster 1
       proc Trailer args { global b
         return "</TD></TR></TABLE> <CENTER ALIGN=right><P><IMG SRC=http://browsex.com/browsex.gif> \
            <I>Copyright &copy; 1999-2001 &nbsp; <a href=\"mailto:peter@browsex.com\">Peter MacDonald</a> &nbsp; \
            <a href=\"http://BrowseX.com\">http://BrowseX.com</a></I></CENTER><P>&nbsp;<P>"}
         proc BRX args { return <B>BrowseX</B> }
     }
     if {[info exists nomaster]} {
       tml puts "<body bgcolor=white>"
     }
?]

[%define Tml <FONT color=steelblue>TML</FONT>]
[%define Hr <p><hr><p>]
[%define Cmd <p><hr><a name=$1>]
[%define Out <p><b>Output:</b><p>]
[%define Ex <p><b>Example:</b><p>]
[define Bi <font color=red>*</font>]

[name top]
[H1 TML Version 2.0: [sp 2] Generic Embedded Web Script]
[i copyright &copy; 2000-2001 - [a mailto:peter@browsex.com Peter MacDonald]] [a http://www.browsex.com][p]
[# [%iref<title="Table of Contents" goto=top>
[%tmltoc 2]
] #]

[a #TOC Table Of Contents]

[h2 Introduction]
[Tml] is a [a #copyright Free]  [b Tcl] extension that provides an
embedded [i Web Scripting]
interface to [a #tutorial Tcl], [a #langperl Perl] and 
[a #langpython Python].
It parses web pages, using square bracket escapes 
[b "[lb]"] and [b "[rb]"] to call procedures.
Values returned from a procedure call are inserted inline into the page.
[Tml] comes as a stand-alone and [a #cgi CGI] [i and is also
built-in to [a http://browsex.com Browsex]].
[Tml] is vaguely like [a http://www.php.net PHP], except that
it doesn't use  &lt;&gt; HTML tag delimiters.
More importantly, [Tml] itself [b 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 
[a #ifcmd if], [a #whilecmd while], and [a #foreachcmd foreach] to direct the parse.
There are also some cool extensions 
such as [a #irefcmd inline refs] and [a #tmltoccmd table of contents]
and even a way to [a #replace wrap HTML entirely].
[Tml] pages can also execute natively in [a http://browsex.com Browsex], ie.
without webserver or CGI.  
[p]
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 [a #installation Installation] to get started.

[h= A [Tml] PRIMER]
A [Tml] call is made from a web page when a square bracket [b [lb]] 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 [tt "Four-score and seven years ago"] 
up to the matching end bracket and passes it as
a single string argument to the [a #definesect user defined] procedure [b 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.

[name definesect]
[h2 Defining Procedures]
A user of [Tml] does not require [b Tcl] or programming knowledge.
The [a definecmd %define] command lets you define your own macro-like
procedures.
[=

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

=]
The [b $1] gets substituted with your data ([b $2] is for attributes).
Applied to the first example this produces:[p]
[sp 2] 
  [%define Bg <B><FONT COLOR=green>$1</FONT></B>]
  [Bg Four-score and seven years ago] our <I>forefathers</I> ...
[p]

Programmers may place code or other text inline
using a [a #iinlinecmd Block Eval ] escape: [b [lb]?][br]
Here is the Tcl definition for the above %define:
[=
  [?
     proc Bg {1} {
        return "<B><FONT COLOR=green>$1</FONT></B>"
     }
  ?]
=]

[h= Attributes]
Attributes contain information that somehow describe or parameterize the data.
An example of an attributes is the [b "color=red"] part in the 
HTML [b "&lt;FONT color=red&gt;"].
Interworking with HTML requires an effective way of dealing with attributes.
The next example is 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 [i (string)] argument to a procedure, or as $2 in
a [a #definecmd %define].  [Tml] attributes may contain
Tcl variables and procedure calls.  These are resolved with a call to Tcl's
[b subst].
The attributed syntax may seem a little odd at first, but it is
useful in an number of cases, including [a #replace supplanting HTML].
Here is an example:
[pre [-

  [%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:
  [? set size 5; proc color args { return blue } ?]
  [%define Bg <FONT $2>$1</FONT>]
  [Bg<size=$size color=[color]> A call with parameters.]
[p]
Don't try to use a $size anywhere else in the document, as only function
calls, not variables work.  Use [b [lb]set size[rb]] 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.

[p]
That in a nutshell covers the basics of using [Tml].
Here are some additional things to consider.
[ul
  [li For existing HTML, [a #tools Convert] or [a #iprecmd Block Protect] all square brackets.]
  [li You can use simple [b Tcl] variables and calls inside attributes &lt;&gt; only.]
  [li To use Perl or Python for [Tml] calls, see [a #altlang Alternate Languages].]
]
If your new to [b Tcl], you might want to see the [a #tutorial Tcl Tutorial and
References] section.

[Hr]
[name tools]
[h2 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 [b tml -quote] to translate all [b [lb]] and [b [rb]] 
in an HTML file into the [Tml] escapes: [b [- [lb] and [rb] -]].
Subsequent processing by [Tml] will produce the original 
document (+ a comment).  It will also insert a [a #pragmacmd %pragma] 
on line one of the output to indicate that even script/embeds have been
converted.[p]

[b Example:]
[=
    tml -quote foo.html > foo.tml
=]


[p][hr]
[h2 [Tml] BUILTINS]

Following are the builtins available in [Tml].  
Any marked with a [font<color=red> *] are intrinsics, not [b Tcl] commands.
All others are just [b Tcl] procedures defined in [b Tcl] in [a htmlrule.tcl],
which means you are free to use them from Tcl or override them.

[h3 Block Escapes]
It is sometimes necessary to handle a block of text in a
special way, the following special block delimiters are available:

[%tmldef
[tdi [a #ihashcmd [lb]# ... #[rb]],     Block Comment[Bi]]
[tdi [a #iprecmd [lb]= ... =[rb]],      Block Protect[Bi]]
[tdi [a #iinlinecmd [lb]? ... ?[rb]],   Block Eval. Optionally with a command: [lb]?&lt;command&gt; ... ?[rb][Bi]]
[#
[tdi [a #ipasscmd [lb]= ... =[rb]],      Passthru text: ie ignore all [lb] and [rb][Bi]]
[tdi [a #ifiltcmd [lb]+[ch <]func> ... +[rb]], Pass text as first arg to filter proc [b func][Bi]]
#]
]

[Tml] commands are invoked by an open square bracket: [b [lb]].
Note that by [a #percent convention], builtin commands start with
a percent char (%) to avoid colliding with [b Tcl] commands.[p]
[name builtin]

[p]
[h3 Character Commands]
[tmldef
[tdi [a #lbcmd %lb]  , output a left bracket: [lb]]
[tdi [a #rbcmd %rb]   , output a right bracket: [rb]]
[tdi [a #chcmd %ch], output special chars, eg:  ?, &, copy, nbsp. +opt count]
[tdi [a #spcmd %sp], output a space, with optional repeat count]
[tdi [a #vspcmd %vsp], output a vertical space, with optional repeat count]
]

[h3 Control Constructs]
[tmldef
[tdi [a #sourcecmd %source]  , include a local file and interpret as tml[Bi]]
[tdi [a #includecmd %include]  , include a local file (no tml interpretation)[Bi]]
[tdi [a #ifcmd %if&lt;cond>], if statement[ch ,] cond is a Tcl expression[Bi]]
[tdi [a #ifcmd %elseif&lt;cond>], elseif statement[ch ,] follows %if or %elseif[Bi]]
[tdi [a #ifcmd %else], else statement[ch ,] follows [b [rb]] of %if or %elseif[Bi]]
[tdi [a #whilecmd %while&lt;expr>], while loop[Bi]]
[tdi [a #forcmd %for&lt;init expr incr>], for loop[Bi]]
[tdi [a #foreachcmd %foreach&lt;var list ...>], foreach loop[Bi]]
[tdi [a #breakcmd %break], break out of innermost [b for, foreach or while] loops[Bi]]
[tdi [a #continuecmd %continue], continue at top of inner loop[Bi]]
[tdi [a #exitcmd %exit], exit processing[Bi]]
[tdi [a #errorcmd %error], exit processing with given error message[Bi]]
[tdi [a #limitcmd %limit], limit the maximum loop iterations: default 1000[Bi]]
[tdi [a #tmlevalcmd %parse], parse a string containing [Tml][Bi]]
[# [tdi [a #langcmd %language], setup the secondary language. eg. perl[Bi]] #]
[tdi [a #pragmacmd %pragma], force options: see [a #cgi CGI][Bi]]
]

[p]
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 [b %eval] or one of the
following predefined convenience functions:
[tmldef
[tdi [a #evalcmd %eval]  ,Tcl eval[ch ,] no output]
[tdi [a #setcmd %set]  ,set value of a variable[ch ,] no output]
[tdi [a #incrcmd %incr]  ,incr value of a variable[ch ,] no output]
[tdi [a #nullcmd %null]  , does nothing[ch ,] no output]
]

[h3 Defining commands]
These following are for defining/redefining other commands.
[%tmldef
[tdi [a #definecmd %define name ...], define a tag [i name].]
[tdi [a #predefinecmd %predefine name pre], pre is a tcl proc that preprocess input to name]
[tdi [a #postdefinecmd %postdefine name post], post is a tcl proc that postprocess output from name]
]

[h3 Miscellaneous Commands]

[%tmldef
  [tdi [a #perlcmd %perl], evals perl code]
  [tdi [a #pythoncmd %python], evals python code]
  [tdi [a #querycmd %query], return the query args given the url]
  [tdi [a #namecmd %name], shortcut for &lt;A NAME=.., ie. defining a label ]
  [tdi [a #aecmd %ae], like &lt;A HREF=.., but derefs .tml if file exists]
  [tdi [a #htmlcmd %html], generate HTML encodings for all &lt; and &gt;.]
  [tdi [a #echocmd %echo], just returns block of text unchanged.]
  [tdi [a #precmd %pre], same as %html, plus wraps output in a pair of PRE tags.]
  [tdi [a #setcookiecmd %setcookie], set a cookie value in a CGI]
  [tdi [a #getcookiecmd %getcookie], get a cookie value in a CGI]
]

[P] [hr][h3 [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.

[p]
[name %iref]
[tmldef
[tdi [a #trdcmd %trd], specify a whole table row where all the &lt;td>'s are between ,] 
[tdi [a #tmltoccmd %tmltoc], generates a table of contents for page  headings.]
[tdi [a #tmlbordercdm %tmlborder], a table with a nice solid border/header (table in a table)]
[tdi [a #tmldefcmd %tmldef], a definition table, consisting of a bolded term and a Def.]
[tdi [a #tdicmd %tdi], a [b tmldef] item.  Separate Term and Def with a ,] 
[tdi [a #footnotecmd %footnote], adds text to end of file, and inserts
a link image to it.]
[tdi [a #irefcmd %iref], an inline reference]
]

[p][hr]
[name tmlpass]
[h2 [Tml] Widget Commands]

The [b tml] command is created in the target interpreter, and has a number of
subcommands.  Obviously, these are available only from [b Tcl]:
[tmldef
[tdi tml debug ?N?, get/set the current debug level]
[tdi [a #tmlerrcmd tml errorcmd cmd], setup a command as an error handler]
[tdi [a #inputscmd tml inputs ?-includes?], get [Tml] page source ?with includes?]
[tdi [a #tmlcmd tml maxpass ?N?], get/set the maximum number of passes]
[tdi [a #tmlcmd tml pass], returns current [b pass] number.  1 is the first pass]
[tdi [a #tmlparsecmd tml parse], actually performs the parse]
[tdi [a #output tml puts STR], send a string directly to page output (no newline)]
[tdi [a #append tml append STR], append string to end-buffer (footnotes, etc)]
[tdi tml language STR, sets the default alternate language]
]
[p]
The script [b tml.tcl] sets up the proper environment and
handles the parse for you.   This includes sourcing [i htmlrule.tcl]
to create all the other commands needed in the environment. 
[Tml] can run in either a [b safe] interpreter or a normal one.
Please refer to [b tml.tcl] for details.


[p][hr]
[name replace]
[h2 HTML Commands]
[i htmlrule.tcl] defines [b Tcl] procedures for
the standard HTML tags (upper and lower case) so that
[Tml] equivalents are available for all common tags. eg:
[b B, b, I, FONT,] etc   Most work the same as their counterparts,
but the [b 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.
[p]
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 &gt; is required.

[=
  
 HTML:   <FONT COLOR=RED SIZE=1>Hello World</FONT>
 TML:    [FONT<COLOR=RED SIZE=1> Hello World]

=]
The proc [b 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.
[p]
The file [i 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:
[PRE

  TT B I U S STRIKE BIG SMALL SUB SUP EM STRONG DFN CODE SAMP KBD IMG
  VAR CITE LI TITLE CENTER OL UL DL DD DT FORM BLOCKQUOTE TABLE TR TD 
  BR HR FORM SELECT INPUT TEXTAREA MAP FONT
  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.
[p]
[name widget]
[p][hr]
[H2 Defining Procedures]
The most important thing to know about [Tml] is that the evaluation
is non-recursive. ie.
returning "[lb]B[sp]xyz[rb]" from a proc will not result in proc "B" being called.
The only exception  to this are the [B %source] and [b %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 

=]

[p]

For simple tags, [Tml] syntax is straightforward, but
the need to handle attributes complicates things a bit. 
[=
  <TAG ATTRIBUTES> DATA </TAG>
=]
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 
[I attr] argument and "Some stuff" would be assigned to [I data].
If there are never any attributes, the second parameter can be
omitted, or defined as [b {attr {}}] or even [b 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

=]
[p]
It was said that by convention, attrs are passed in the second argument.
A procedure is free to interpret the [B data] any way it likes.
For example, the [B [lb]A[rb]] tag is implemented with shortcuts
to allow the href to be the first string in the data.
See htmlrule.tml and [BRX] docs for examples.
[p][hr]
[h2 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 [B 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 [b Tcl] procedures.
The later, XML, is aided by the hierarchical nesting of tags
that [Tml] enforces.
[p]
While HTML [I &lt;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 [i (CGI et al)] to output HTML,
but programming syntax is somewhat awkward and cumbersome to use, and read.
[P]

There are two implications to embedding Tml inside [BRX].  The
first is that .tml files can be viewed directly by
[BRX] 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.
[P]
The second implication is that it is possible for Web servers to
return documents of type text/tml and have the [BRX] browser
process the document tags correctly.  This will however work only
with [BRX], 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.

[PRE [-

  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.
[BRX] 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:
[p]

[PRE
  .tml    text/tml        # HTML Tcl Macro Language
]

[Hr]
[name installation]
[h2 Installation]
The source code for [Tml] is available 
[a http://browsex.com/download/v1.5/tml2.0.tgz here].  
You must already have [b Tcl] installed on your system.  [Tml] was
developed using [i Tcl 8.4a2] under [i Linux Redhat 7.0].  It has also
been tested and used under Windows and Solaris 7/8.[p]

Edit the [i 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.[p]

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

In any case, see [a #tools 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
[b htmlrules_init], [b tml] and [b _tml].[p]

The source for
[Tml] is very small: comprised of just the following source files:
[tmldef
[tdi tml.c, The tml widget]
[tdi tml.tcl, Command and CGI front end]
[tdi htmlrule.tcl, Implements the Tcl procs sourced into the widget]
]

[p][hr]
[name cgi]
[h2 CGI [b Tml]]

[Tml] can run as a CGI, and even has a safe mode when run in just [b Tcl].
To setup [Tml] for [b Apache], [a #installation install] [Tml], then
copy [b 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.
[b 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:
[tmldef
[tdi  -sendtml n,Set to 0 to not allow sending raw TML to [BRX] (default 0)]
[tdi  -safe n,Set to 0 to not use Safe interp (default 1)]
]
Using [b -sendtml] will sense when [BRX] is the connecting browser and 
will then send raw [b tml] 
for local interpretation  ([b %include/%source] directives are done first).
This make the dynamic use
of [Tml] conditional directives like [a #%iref %iref] 
without invoking network traffic the default 
[i (requires version 1.5+ of [BRX])].
As the could interfere with server CGI's the better way is to put
[b [lb]%pragma<-sendtml=1>[rb] ] on the
first line of such documents.
[p]
The [b -safe] option forces [Tml] to always be run in a safe
interpreter.   By default, this is off but
[BRX] uses [b -safe] for [Tml] that are not file:/ URLs.
ie. sent by CGI's using the [b -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 [a #pragmacmd %pragma] option on the first
line of the Html file to force -safe on or -sendtml off.

[p][hr]
[h2 Using A Database]

[b Tcl] has several database options.  
[ul
[li [a http://sourceforge.net/projects/mysql/ MySql] claims to be the most common
freeware one. Use the [a http://www.velocigen.com/~tdarugar/tcl-sql/download/
Tcl-Sql] package with it.]
[li [a http://postgresql.org Postgresql] comes with a Tcl interface.]
[li For [b Oracle], there is [a http://sourceforge.net/projects/oratcl/ OraTcl].]
[li For [b Sybase], there is [a http://sourceforge.net/projects/sybtcl/ SybTcl].]
[li For [b ODBC], there is [a http://www.neosoft.com/tcl/ftparchive/sorted/databases/odbcisql/1.0/odbcisql-1.0.tar.gz odbcisql-1.0.tar.gz]]
[li or there is [a http://www.hwaci.com/sw/sqlite/index.html Sqllite]
which gives GDBM a SQL interface]
]
As with any [b Tcl] extension package, you download and install it.
Then include the approriate [i package require] and your off.
Here is an example from the [a DB/tcl-sql.tar.gz Tcl-SQL] package 
for [b 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
=]


[p][hr]
[h2 Some Advantages of [Tml]]
The advantages of [Tml] include:
[UL
[li [Tml] is not a language, and so should be relatively static]
[li [Tml] is small (around 1200 lines of C) and should stay small]
[li [Tml] is server and/or client side. CGI and embedded work the same]
[li The [BRX] client means you can run even DB scripts without a Web Server]
[li Bracket matching [I (ala VI)] can be used to check nesting.]
[li Web pages are fully programmable and parameterizable.]
[li Less tags means pages are more human readable]
[LI Redefine any or all tags: eg. retarget output, say to LaTeX.]
[li Most of the
standard HTML 3.2 tags have also been defined as [b 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.]
[li If it doesn't do what you want, or the way you want, you have the (small) source!]
]
[p]
[b Note 1:] All the [BRX] Web pages are written in [Tml].
[p]
[name percent]
[b 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.
[p][hr]

[name tutorial]
[h2 Tcl Tutorial and References]

[h+ 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 [a #tclrefs Tcl References]
at the end of this tutorial.
[p]
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.

[h+ 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:
[ul
[li variable declarations aren't required in Tcl.]
[li all variables in a procedure are local by default.]
[li Tcl uses the [b set] command to assign values to variables,
rather than an [b =].]
[li it uses [b $] to get the value of a variable, but not during a [b set].]
[li curly braces are always required for blocks (unless it's a single word).]
[li use square brackets to call a proc and get it's return value.]
[li the Tcl comment is like a command: [b "#"] is after [b ";"] or is first word in line.]
[li and braces in comments must be balanced, if present.]
]
[h= Example 2: Loop constructs]

A crude comparison with [b '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=' ';
  }                                     }
=] 


[h= 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
=] 


[h= 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);                 
=]

[h- Tcl Syntax]
One might rightly wonder why
[b Tcl] doesn't give shorthands like [b "x=y++;"]
rather than the more cumbersome [b "set x [lb]incr y[rb]"]?
The answer is: [i it can't!].  Here's why:
[p]
[b Tcl] is really just a command processor, with all
commands in the form of a list:
[=
  cmd arg arg arg ...
=]
For instance, the [b 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 
[b while] command in [b Tcl].
[p]
The point is that [b Tcl] doesn't really have a syntax.  There are quoting rules,
commands and [b [lb]proc calls[rb]], but little else.
Even the lowly comment in [b 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.
[p][hr]

[%name tclrefs]
[h= Tcl References]
[ul
  [li Another slightly longer [a tcl_tut.html Tcl tutorial].]
  [li Other Tcl [a http://tcl.activestate.com:8002/resource/doc/start/
tutorials].]
  [li [a http://tcl.activestate.com/man/tcl8.4/ Online Manual Pages]]
  [li [a  http://tcl.activestate.com/software/tclpro/eval/1.4.html  TclPro]: a Tcl debugger.]
  [li [a http://tcl.activestate.com The Tcl Main Site]]
]
[p][hr]


[name altlang]
[h- 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 [a #perlcmd %perl] or [a #pythoncmd %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 [a #cgi CGI] option as this relies on SafeTcl.
[name langperl]
[h+ Using Perl]

You can configure for the perl [a #altlang Language] as follows.
First you need to install Jean-Luc Fontaine's great tclperl package.
Source is in the tclperl directory.  Just type [i make install] there,
or see [a http://jfontain.free.fr/] for RPMs/DLLs and details.
[p]
Now you can use the [a #perlcmd %perl] command to evaluate blocks of perl code.

[=
    <H1>Test of Perl</H1>
    [?<%perl>
       sub Bold {
	 my($a)=@_;
         return "<b>".$a."</b>";
       }
       return "Perl code: "
    ?]
    [Bold Here is some text bolded by perl]
=]

Note: the explicit [b 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 ?]
    [?<%perl>
       sub Bold {
	   my($a)=@_;
           return "<b>".$a."</b>";
       }
    ?]
    [Bold Here it is perl]
=]

[p][hr]
[name langpython]
[h= Using Python]

You can configure for the python [a #altlang Language] as follows.
First you need to install Jean-Luc Fontaine's great tclpython package.
Source is in the tclpython directory. [b NOTE:] the INSTALL advises
that a patch is required to compile.  An easier way is to get
precompiled RPMs/DLLs from [a http://jfontain.free.fr/].
[p]
Now you can use the 
[a #pythoncmd %python] command to evaluate blocks of python code.
Due to the finicky indenting requirements
of python, blocks are stripped of leading [i whitespace] and trailing [i spaces].

[=
    [?<%python>
      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 [b _=] statement is required if you wish to have
see output from a Block Eval.

[p][hr][hr]
[h- [Tml] COMMAND REFERENCE]

[%define star <font color=red>*</font>]
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
[b [ch <]Attr1=Val1 Attr2=Val2 ...[ch >]].
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.
[br]


[Cmd aecmd][h+ %ae  [i - like &lt;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.
[p]
The [i %ae] command is like the hyperlink reference [i &lt;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, [i %ae] appends [b .tml] to the filename
and uses that as the link.  However, if the source is preprocessed
to HTML, [b .html] is appended to make it look for preprocessed links.
The following example presumes [i Foo.tml] exists.
[Ex]
[=
    [%ae Foo Link to foo]
=]

[Cmd breakcmd ]
[h= %break [i - break out of innermost [b for, foreach or while] loops]]
For use in the [i %for, %foreach and %while] commands, [i %break]
directs the parse to exit the loop and continue at the statement
after the loop end bracket.
[Ex]
[=
    [%while<$y>0>
        [%if<$x<9>
            [%break]
        ]
    ]

=]

[Cmd chcmd] [h= %ch [i - output special chars, eg:  ?, &, copy, nbsp. +opt count]]
The [i %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 [b &] and [b ;].  This is useful to prevent
interpretation like the [a #tdicmd %tdi] command.
[Ex]
[=
    [%ch ,]
    [%ch copy 5]
=]
[Out]
    [%ch ,]
    [%ch copy 5]

[Cmd continuecmd ]
[h= %continue [i - continue at top of inner loop]]
For use in the [i %for, %foreach and %while] commands, [i %continue]
directs the parse to continue at the top of the loop.

[Ex]
[=
    [%while<$y>0>
        [%if<$x<9>
	    [%continue]
        ]
    ]
=]


[Cmd definecmd]
[h= %define - define a macro]

The [B %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 [b [lb]ch "[rb]] 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.
[Ex]
[=

  [%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>"  }
  ?]

=]


[Cmd echocmd]
[h= %echo, - returns input unchanged.]

[p][hr]

[h= %else - conditional]
See [a #ifcmd %if].

[p][hr][h= %elseif - conditional]
See [a #ifcmd %if].


[Cmd evalcmd ]
[h= %eval [i - Tcl eval but discard output]]
A convenience function, [i %eval] does the same as [i eval] but
discards output.
[Ex]
[=
    [%eval set x 99]
=]

[Cmd errorcmd ]
[h= %error [i - exit processing with given error message]]
The [i %error] directive causes the parse to terminate immediately
 and generates an error with the provided string argument.
[Ex]
[=
  [%if<$x>10>
    [%error Value [set x] is out of range]
  ]
=]


[Cmd exitcmd ]
[h= %exit [i - exit processing]]
The [i %exit] directive causes the parse to terminate immediately
as though it had reached the end of the page.
[Ex]
[=
  [%if<$x>10>
    [%exit]
  ]
=]


[Cmd forcmd]
[h= %for&lt;init expr incr> [i - a for loop]]
Implements a for loop for the parse.
[p][b Attributes:][p]
The attribute of %for contains an list of three items
which are interpreted/evaluated by [b Tcl]: the initializer, the exit condition,
and the increment.  Behavior is the same as Tcl for.
[Ex]
[=
    [%for<{set i 1} {$i<5} {incr i}>
       Here is the output for line [set i]<br>
    ]
=]
[Out]
    [%for<{set i 1} {$i<5} {incr i}>
       Here is the output for line [set i]<br>
    ]

[Cmd foreachcmd]
[h= %foreach&lt;var list ?var list ...?> [i - foreach loop]]
Implements a foreach command to iterate variable(s) over 
list(s) of values.
[p][b Attributes:][p]
The attribute of %foreach contains an even numbered list of two or more items
which are interpreted/evaluated by [b Tcl].  Each pair is a variable
and its list of values.  Behavior is the same as Tcl foreach.
[Ex]
[=
    [%foreach<i {Tic Tac Toe}>
       Iterate over [set i]<br>
    ]
=]
    [%foreach<i {Tic Tac Toe}>
       Iterate over [set i]<br>
    ]
[p][b and ...]
[Ex]
[=
    [%foreach<r {{Bob Ganes} Tom Bill} p {First Second Third}>
       [set r] was [set i]<br>
    ]
=]
[Out]
    [%foreach<r {{Bob Ganes} Tom Bill} p {First Second Third}>
       [set r] was [set p]<br>
    ]


[Cmd getcookiecmd]
[h= %getcookie, - get a cookie value in a CGI]
This command, which is useful only in CGI,
gets a cookie(s) for the given name.
[Ex]
[=
  [%getcookie state]
=]

[Cmd htmlcmd]
[h= %html, - generate HTML encodings for all &lt; and &gt;.]

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



[Cmd ifcmd]
[h= %if/%else/%elseif - conditional]
The [i %if] command lets you control the conditional flow of the parse.
It may be followed by the [i %elseif] and [i %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 [b $i > 3] rather
than [b $i>3] would have
accidentally matched the end of attribute and caused an error.

[p][b Attributes:][p]
The attributes for %if and %elseif contain an expression which is passed to 
[b Tcl] for evaluation.
[Ex]
[=
  I think that I will
  [%if<$i>3>
     take a <b>walk</b>
     in the park.
  ]
  [%else
     go for a <i>run</i>
     on the beach.
  ]
=]
A more convoluted example can be seen here:
[%iref
[=
  [%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]]
=]

[Out]

[pre
  [%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]]
]
]

[Cmd includecmd]
[h= %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 
[b FileRead] inside the interpreter.
[p]
[b Attributes:]
[tmldef
  [tdi nocomplain, - silently fail if file does not exist]
]
[Ex]
[p]
[=
  [%include myincs.txt]
  [%include<nocomplain=1> maybeincs.txt]
=]


[Cmd incrcmd ]
[h= %incr  [i - incr value of a variable[ch ,] discard output]]
A convenience function, [i %incr] does the same as [i eval incr] but
discards output.
[Ex]
[=
    [%incr x -1]
=]


[Cmd lbcmd] [h= %lb   [i - output a left bracket: [lb]]]
The [i %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 [b %] can be omitted.
[Ex]
[=
    Assign A[lb]99[rb] = 19
=]

[Cmd limitcmd ]
[h= %limit [i - 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.
[Ex]
[=
    [%limit 100]
=]


[Cmd namecmd][h= %name  [i - shortcut for &lt;A NAME=.., ie. defining a label ]]
Outputs a label anchor: [i &lt;A NAME=].
[Ex]
[=
    [%name foo]
=]

[#
[Cmd langcmd]
[h= %language -  define the secondary language]
This command defines the secondary language
to invoke when the Tcl command is not found upon a [b [lb][rb]] call.
See the section on [a #langperl Perl Setup] on what to install for [b perl],
or the section on [a #langpython Python Setup] on what to install
for [b python].
You need use the %language directive only once per document.
[Ex]
[=
    [%language perl]
    [?<perl>
       sub Bold {
	 my($a)=@_;
         return "<b>".$a."</b>";
       }
    ?]
    [Bold Here is some bold text]
=]
#]

[Cmd tmlevalcmd]
[h= %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.
[Ex]
[=
    [?
        set x {[b Bold moves] are required}
    ?]
    [%parse<$x>]
=]
[Out]

  [?
      set x {[b Bold moves] are required}
  ?]
  [%parse<$x>]


[Cmd perlcmd]
[h= %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 [a #langperl Block Eval] and requires the
installation of [a #langpython TclPerl].
[=
  [%perl $x=99]
=]

As a side effect, perl now becomes the default [a #altlang alternate language].
Therefore it is reasonable to use the following:
[=
  [%perl]
=]

[Cmd postdefinecmd]
[h= %postdefine - postmodify a define]
See [a #predefinecmd %predefine].

[Cmd pragmacmd ]
[h= %pragma [i - request override options]]
The [i %pragma] directive must be on the first line of the .tml file.
Typically [i %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.

[p][b Attributes:]
[tmldef
[tdi -safe, run in safe interpreter]
[tdi -sendtml, send raw [Tml] to BrowseX]
[tdi 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.]
]
[Ex]
[=
    [%pragma<-safe=1,-sendtml=1>]
=]

[Cmd precmd]
[h= %pre, - output translated and  PRE protected text]
Does the same thing as [a #htmlcmd %html], 
plus it wraps output in a pair of PRE tags.

[Cmd predefinecmd]
[h= %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
[i (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.
[Ex]
[=
  [%define myh2 <A href=#toc>$1</A>]
  [%predefine h2 myh2a]
=]

[Cmd pythoncmd]
[h= %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 [a #langpython Block Eval] and requires the
installation of [a #langpython TclPython].
[=
  [%python x=99]
=]
As a side effect, python now becomes the default [a #altlang alternate language].
Therefore it is reasonable to use the following:
[=
  [%python]
=]

[Cmd querycmd]
[h= %query - return the query part of the url]

The [b %query] command returns the query part of the url
as a list suitable for assigning with [i array set].
This is useful within CGI's to obtain form parameters.
It is also available within [BRX], 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 [b ?toc=0]
is appended to the .tml filename in the location bar:

[Ex]
[=
  [?
    array set qargs {toc 1}
    array set qargs [%query]
  ?]
  [%if<$qargs(toc)>
    [%tmltoc 2]
  ]
=]

[Cmd rbcmd] [h= %rb   [i - , output a right bracket: [rb]]]
The [i %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 [b %] can be omitted.
[Ex]
[=
    Assign A[lb]99[rb] = 19
=]



[Cmd setcmd ]
[h= %set  [i - set value of a variable[ch ,] discard output]]
A convenience function, [i %set] does the same as [i eval set] but
discards output.
[Ex]
[=
    [%set x 99]
=]

[Cmd setcookiecmd]
[h= %setcookie, - set a cookie value in a CGI]
This command, which is useful only in CGI,
sets a cookie for name/value.
[Ex]
[=
  [%setcookie state 12345]
=]


[Cmd sourcecmd]
[h= %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 
[b FileRead] inside the interpreter so that safe-tcl is honored.
[p]
[b Attributes:]
[tmldef
  [tdi nocomplain, - silently fail if file does not exist]
]
[Ex]
[=
    [%source mysrc.tml]
=]


[Cmd spcmd] [h= %sp [i - output a space, with optional repeat count]]
This command outputs one or more spaces in HTML encoding. ie.
&amp;nbsp;
[Ex]
[=
    A [%sp 20] Gap
=]
[Out]
    A [%sp 20] Gap



[Cmd vspcmd] [h= %vsp [i -output a vertical space, with optional repeat count]]
This command outputs one or more vertical spaces in HTML encoding.
ie. &amp;nbsp&lt;br>
[Ex]
[=
    A [%vsp 3] Gap
=]
[Out]
    A [%vsp 3] Gap


[Cmd whilecmd]
[h=  %while&lt;expr> [i - a while loop]]
The [i %while] command lets you iterate a parse repeatedly over
as section of output.

[p][b Attributes:][p]
The attributes for %while contain an expression which is passed to 
[b Tcl] for evaluation.
[Ex]
[=
    [%set i 5]
    [%while<$i>0>
        Output for line [set i]<br>
	[%incr i -1]
    ]
=]
[Out]
    [%set i 5]
    [%while<$i>0>
        Output for line [set i]<br>
	[%incr i -1]
    ]


[Cmd iinlinecmd] [h= [lb]? ... ?[rb] [i - Block Eval.  Optionally with command: [lb]?&lt;command&gt; ... ?[rb]]]
A Block Eval lets you put a block of code or processable text inline
into a document.   An optional attribute can follow the [b ?]
and if present is interpreted as a Tcl [i command] to process the raw block.
A value returned from [i command] is output to the page.
With no attribute/command, the default is to evaluate the block
in [i Tcl], and discard the result.  But you can use [b "tml puts"] to output
text directly. eg.

[p]
[b Examples:]
[=
   [?
        # Some Tcl code
        set i 99
	proc Foo {x} { return [incr x] }
	tml puts "Foo<br>"
   ?]
=]

[define Ba <p><font color=red>$1</font>]
[Ba ==>]  Foo<br>
[p]
The above is equivalent to using the eval command. Note that in Tcl the
result of the last expression becomes it's return value:
[=
   [?<eval>
	set x "Foo<br>"
   ?]
=]
[Ba ==>]  Foo<br>
[p]
Commands may also take preceding arguments.

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

[Ba ==>]    [?<string toupper> 
        here is a bunch of upper case text.
   ?]
[p]

And the empty attribute just echos output unchanged.

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

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

[Cmd iprecmd] [h= [b [lb]= ... =[rb]]  [i - 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 [b PRE] tag to preserve formatting.
You can do almost the same thing with a %pre attribute in an 
[a #iinlinecmd Block Eval].
[Ex]
<pre>
    [lb]=
	Here is an example<>:
            A[lb]99[rb]=19.
    =[rb]
</pre>
    
[Out]
[=
     Here is an example<>:
        A[99]=19.
=]



[Cmd ihashcmd] [h= [lb]# ... #[rb] [i - 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.
[Ex]
[=
   [# This is a comment
      [%if<$i<1>  # Something going on here...
      ]
   #]
=]

[#


[Cmd ipasscmd] [h= [lb]= ... =[rb] [i - Passthru text: ie ignore all [lb] and [rb]]]
The Block Passthru delimiters prevent the square bracket escapes
from being interpreted.  This lets you protect blocks containing
square brackets.
[Ex]
[=
   [=
      The value was A[99].
   =]
=]

[#
[Cmd itranscmd] [h= [lb]- ... -[rb] [i - Passthru text but translates html < and &]]
Like [a #ipasscmd [lb]= ... =[rb]],
the Block Passthru/translate delimiters prevent the square bracket escapes
from being interpreted, 
but it also translates angle brackets.
This not often used, as the  [a #ipasscmd [lb]= ... =[rb]] block
delimiters are more generally useful.  It may at some point be discontinued
in favor of block filtering.
[Ex]
[=
    [-
        Tags are <TAG> and brackets are []
    -]
=]


[Cmd ifiltcmd] [h= [lb]+[ch <]func> ... +[rb] [i - Pass text as first arg to filter proc [b func]]]
The Block Filter delimiters provide a way to have an entire block
of text passed to a function for special processing.
[Ex]
[=
    [? proc Foo 1 { 
	 regsub -all S $1 s 1
	 return $1
       }
    ?]
    [+<Foo>
       Silly Sally Sent Someone South.
    +]
=]
[Out]
    [? proc Foo 1 { 
	 regsub -all S $1 s 1
	 return $1
       }
    ?]
    [+<Foo>
       Silly Sally Sent Someone South.
    +]
#]



[p][hr][hr][p]
[h- 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.

[Cmd irefcmd]
[h+ %iref - Inline Reference Link]

[Tml] enables the composition of
very sophisticated tags: [b %iref] is one such.
It implements a so-called
[b inline reference] to allow displaying additional
information inserted into the current context.
%irefs shows up as a little orange book: eg [%iref<goto=irefcmd> 
[p]
Here is an example inline ref.[br]
When you clicked it opened. Here is the code.[p]
[=
[%iref<goto=irefcmd> 
[p]
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 [i (if you've setup the
[a #cgi [Tml] CGI])] by downloading the document again.
[BRX] has the ability to view [b %iref]s 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 [i Alt text balloon]. [BRX] will display
multiline [i Alt text balloons], so often you don't even need to click.
Following is an example of an
[name ttop]
[%iref<title="Tree list">
[ul
[li [%iref<title="Nested list 1" goto=ttop>
[ul
[li [%iref<title="OptionA" goto=ttop> [p]Stuff 1 ]]
[li [%iref<title="OptionB" goto=ttop> [p]Stuff 3 ]]
[li [%iref<title="OptionC" goto=ttop> [p]Stuff 3 ]]
]]]
[li [%iref<title="Nested list 2" goto=ttop>
[ul
[li [%iref<title="Option1" goto=ttop> [p]Stuff 1 ]]
[li [%iref<title="Option2" goto=ttop> [p][a http://www.yahoo.com Stuff 3] ]]
[li [%iref<title="Option3" goto=ttop> [p]Stuff 3 ]]
]]]
]
]

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

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

[Cmd footnotecmd]
[h= %footnote - Footnote]
Adds text to end of file, and inserts a link image to it at the current
postion.

[Ex]
[=
  [%footnote Note: footnote from demo.]
=]
  [%footnote Note: footnote from demo.]

[Cmd tdicmd][h= %tdi  [i - a [b %tmldef] item.  Comma separated Term and Def]]
[i %tdi] is used within [i %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 [a #tmldefcmd %tmldef] for an example.


[Cmd tmltoccmd][h= %tmltoc  [i - generates a table of contents for page  headings.]]

[i %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.
[b %tmltoc] optionally takes two
arguments, the min and max header levels to include in the index.

[p]
[b Attributes:]
[%tmldef
  [%tdi twopass, do two passes so we can put TOC at top or anywhere.]
]

[Ex]
[=
  [? 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.  
  [%tmltoc]
=] 


[Cmd tmlbordercdm][h= %tmlborder  [i - 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 [BRX] web site.

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


[Cmd tmldefcmd][h= %tmldef  [i - a definition table, consisting of a bolded term and a Def.]]
A convienience function to avoid having to specify all those TD tags.
[Ex]
[=
    [tmldef
	[tdi One:, first definition]
	[tdi Two:, second definition]
    ]
=]
[Out]
    [tmldef
	[tdi One:, first definition]
	[tdi Two:, second definition]
    ]

[Cmd trdcmd][h= %trd  [i - specify a whole table row where all the &lt;td>'s are comma separated] ]
A convienience function to avoid having to specify all those
TD tags
[Ex]
[=
    [table<border=1>
	[trd one, two, three]
	[trd A , B, C]
    ]
=]
[Out]
    [table<border=1>
	[trd one, two, three]
	[trd A , B, C]
    ]


[p][hr][hr][p]
[h- [Tml] Widget Subcommands]

[Cmd inputscmd][h+ tml inputs [i - get [Tml] page source]]
[b 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, [b inputs] will return the expanded text
after all file includes.
See the bottom of the page to see it in action.

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

[Cmd output][h= tml puts [i - send a string directly to page output]]
[b Used from Tcl], [i output] sends a string to the output stream
so that it appears on the page.
[Ex]
[=
   [?
	tml puts "The total is: $ttl"
   ?]
=]

[Cmd append][h= tml append [i - append string to end-buffer (footnotes, etc)]]
[b Used from Tcl], [i 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.
[Ex]
[=
   [?
	tml append "note: see references"
   ?]
=]

[Cmd tmlcmd ][h= tml pass/maxpass [i -access and sets variables [b pass] and [b maxpass]]]
[b 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<twopass>):
[tmldef
[tdi pass, the current pass number in a multipass parse (readonly)]
[tdi maxpass, the maximum number of parse passes]
]

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

[Cmd tmlerrcmd ][h= tml errorcmd CMD [i - 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.

[Ex]
[=
   [?
	tml errorcmd MyError
   ?]
=]

[Cmd tmlparsecmd ][h= tml parse [i - actually performs the parse]]
Used internally by [b tml.tcl].  Usually not useful by the end user.

[p][hr][p]
[name copyright]
[H2 Copyright]
[=
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.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS.

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.

=]

[p][hr][p]
[%name TOC] [H2 Table of Contents]
[%tmltoc 2]

[Trailer]

[p][hr][p]
[A TML.tml TML Source Code For This Page]
[p]