TTP - the Tcl Template Parser

Program documentation
Georg Lehner, 09/2007

1. Table of Contents

2. TTP - the Tcl Template Parser

TTP is yet another template engine, with, guess it, a Tcl touch. Each template line is processed with the Tcl subst command.

TTP is a small and simple yet powerful utility. I use it in places, where lots of configuration file with lots of little variations have to be created.

On the other hand, TTP is a general purpose application launcher with commandline and configfile parser. I use it to wrap my tcl applications without need to reinvent the wheel over and over again.

TTP is written in Tcl, comprises only two small files and does not require any additional libraries.

You can get the latest TTP at http://www.magma.com.ni/sw/ttp/ttp.tgz

3. Notation conventions

variable
name of a variable

expr
either
  1. text without whitespaces (a token), Note that this can also be a number
  2. "text within double quotes"
  3. {text within braces}
  4. tcl script within

$variable
a variable which is expanded by prepending a $ sign to the variable name.

[variable]
a variable which is expanded by enclosing the variable name with brackets.

tcl script
a whitespace separated list of expresions of which the first expands (hopefully) to a valid tcl command.

4. Quickref

4.1. Usage

  Usage: ttp [options] [arguments]
  
    -l file       .. source in a library
    -o path       .. output to file instead of stdout
    -d value      .. set debuging level, default: INFO
    -D varName value      .. define a variable
    -e value      .. break after count parsing errors, default: 200
    -h    .. usage information
    -I path       .. set include path
  
  loglevels: DEVEL INFO WARN FATAL ERROR DEBUG
  

4.2. Expansion

some text
is passed through to the output unchanged

$variable
is substituted with the value of the $variable named variable. If not defined a parsing error occurs.

[variable]
is substituted with the value of the [variable] name variable. If not defined a parsing error occurs.

[tcl script]
is substituted with the result of the tcl script. If an error occurs, e.g. the first token is not a valid tcl command, a parsing error occurs.

If a parsing error occurs, the line is passed through unchanged, but prefixed with `>>>`.

The error is logged to stderr.

4.3. Commands

--
comment

literal
insert text literally

tcl
interpret text as tcl script

cmd expr
parse each line with a command

set: variable expr
set the value of $variable named variable to the result of the expresion

default: variable expr
if variable is not defined, define and set it to the result of the expresion

let: variable expr
set the [variable] named variable to the result of the expresion

existsElseValue variable expr
returns the value of the variable, if the variable does not exist, it returns the value of the expr instead.

stamp
generates three line of output: `` # ttp: timestamp `` # user@host:pwd `` # commandline

skipline
skip the current line

out
outputs text

parse file [mode] [tcl script]
inserts other files in the output. Start parsing with mode.

5. Variables

The following variables are available in a template

rc
"return code", if positive, number of parse errors until now, if negative, internal error

libs
list of "library" name given with the -l commandline switch

loglevel
textual string, loglevel, invoke ttp -h -d DEBUG to see them all

loglevels
array holding loglevels and their priority

root
include directory, from where libs are imported

defs
(possibly empty) list of definition files

template
template file name

6. Log levels

The following are recommendations for use of the ''log loglevel msg'' command in scripts and templates. These recomendations are (hopefully) followed in the TTP core.

DEVEL
for messages used during development of templates and scripts. Used by developers.

DEBUG
for debugging of your application or template, i.e. messages which show the progress of TTP while processing its input. Used by developers.

VERBOSE
for detailed information about the content of the definition and template files. Used by advanced users of the finished application/template system.

INFO
for important information gathered during processing of the definition and template files. Thinks that you want the user know. Used by standard users of the finished application/template system.

WARN
non critical warnings: information that affect the quality of the output, put does not stop the template/application processing.

ERROR
critical warnings: information that invalidates the output of the templates or make the application do the wrong thing.

FATAL
aborts TTP, and tells the user why.

7. Utility functions

7.1. For definition files

This functions are primarily used in the definition files, e.g. default.tcl.

include path onerror msg
path filename to include
onerror can have the following values:
continueWhenMissing
if file does not exist, silently go on

abortOnError
exit TTP if an error is generated while sourcing the file

continueOnError (default)
continue with TTP if an error is generated while sourcing the file
msg
additional message to log, default "Exiting..."

library patch onerror msg
is the same is include with two differences:
  1. instead of a path, a filename is to be given, the file is then sourced in from the include directory

  2. by default onerror is set to `abortOnError`

follow path
if path is a symlink, follow it until we get to a real file. This is a very blueyed version of follow. It will break on dangling and circular symlinks.

log level msg
log msg if level is equal or higher then loglevel. logging goes to stderr

fatal msg exitcode
log msg with level FATAL increment the errorcount and exit

exitcode is optional. if it is not zero don't leave (yet) and set the the variable rc to the value of exitcode. this is an obscure feature used with negative exitcodes on startup. Don't use exitcode at all.

8. How TTP works

You can view TTP (at least) from two different points.

8.1. Template Parser

8.2. Application Launcher

TTP inspects the name as which it is called. This means you can either rename the file ttp or symlink to it, and TTP will change its "identity" to the new name. The main idea is to install TTP in some place, say /usr/share/ttp, and then create a symlink for each TTP-ified application you want to launch, e.g.:

```ln -s /usr/share/ttp/ttp /usr/local/bin/myapp

Then when:

9. Examples

9.1. Just a template file

example.tpl:

  [-- This is an example template]
  You, $name, will be fired.

Invocation:

  ttp -D name Fred example.tpl

Will give:

  You, Fred, will be fired.

9.2. Template file and default library

example.tpl:

  [-- This is an example template]
  You, $name, will [fired reason] be fired.

`default.tcl`:

  proc fired_p {num} {
        switch $num {
    	0 {return surely}
    	1 {return certainly}
    	2 {return "of course not"}
    	default {return never}
        }
  }

Invocation:

  ttp -D name Fred -d reason 2 example.tpl
  ttp -D name Bill -D reason 4 example.tpl

Will give:

  You, Fred, will of course not be fired.
  You, Bill, will never be fired.

9.3. Using a definition file

`names.def`:

  set t [clock scan now]
  set reason [expr {int(srand($t)*4)}]
  set names {Mike Bill Frank George}
  set i [expr {int(rand()*4)}]
  set name [lindex $names $i]

Invocation:

  ttp example.tpl names.def

will output a random combination of name and reason to be fired each time ttp is invoked

10. Command Reference

10.1. Preliminaries

The commands:

  1. -- (comment)
  2. literal
  3. tcl

    can be used on a line by themselfes to start/end a region with the respective function, or they can be used with arguments, in which case they are "embedded" in the current line.

    The literal command just takes (zero or) one single argument, while --- and tcl can take an arbitrary long list of arguments.

    The commands:

  4. set:
  5. default:
  6. let:

    by default take two arguments: name and value. However if you want to use them on a line by themselfes whithout showing any output you can add an arbitrary text (comment) after the value. Good style is e.g. using a single dash:
      [default: count 12 -]
    

10.2. ''--'' comment

Allows to insert comments, i.e. text that is not displayed in the ouput. The following variations are possible:

[--] on a line by itself: start comment region

Starting from this line, up to the next line where [--] occurs no output is produced

[-- some text] sourrounded by text: insert comment

the sorrounding text is output, everything between [-- and ] disappears from the output

[-- some text] on a single line: skip line

if the comment is not surrounded by text, the whole commentline is skipped. Parsing continues normally on the next line

10.3. literal

Allows to insert text literally, i.e. without substitutions. The following variations are possible:

[literal] on a line itself: start literal text region

Starting from this line, up to the next line where [literal] occurs each line is output literally.

Note however, that all [commands] occuring on a line are still evaluated. While any errors are ignored silently, some commands might confuse ttp, [exit] is such an example

[literal {some text}] insert: text literally

The text inside the brace is reproduced literally in the output. Note that this syntax is slightly different. Consider omitting the braces, like in the following example, suppose that variable is set to 'VAR':

[literal $variable some text]

The resulting output will be: VAR some text, since whitespace is substituted by single blanks, and each token is evaluated with command and variable expansion ([], $).

By putting the text inside {braces}, the parameter expansion just eliminates the {} braces themselves and leaves the text intact.

10.4. parse

The complete syntax of parse is:

parse path [type] [tcl script]

path
the file to be parsed

type
the parsing type to use initially, can be:
tcl script
this is only used when the parse type is cmd. It is the script to parse each line.

10.5. cmd

This allows to parse each line of a file with some user defined command. TTP first checks

11. Commands YetToBeExplained

11.1. tcl

11.2. set:

11.3. default:

11.4. let:

11.5. exitsElseValue

11.6. stamp

11.7. skipline

11.8. out

12. Bugs and Todo