
                        The Meta-HTML Reference Manual
                                       
   
    Brian J. Fox, Universal Access Inc.
     _________________________________________________________________
   
                             Warning for WML Users
                                       
   The wml_p2_mhc program is a stripped down version of the mhc program
   from Meta-HTML. Because lots of functionalities have been removed from
   the original Meta-HTML, this documentation may refer to non-existing
   features. Only variables and functions listed in index are relevant.
   
   By reading this guide, keep in mind it is a Meta-HTML reference
   manual. It may be used as a reference guide for wml_p2_mhc, and
   instructions on how to define new tags can be found into
   wml_tutorial(1) and wml_intro(1). 
   
   Denis Barbier
   
                             Welcome To Meta-HTML
                                       
   This document describes the Meta-HTML language, Version 6.05. It
   should be considered the definitive reference manual for this version
   of the language, but the language target itself remains somewhat
   mobile. While the functions described in this manual will continue to
   operate as documented, there may be new functions or enhancements
   appearing in future versions of the language which will supersede the
   functionality that the documented ones provide.
   
   If you are really impatient, or you fancy yourself a wizard, I suggest
   that you first look at the code examples at
   http://www.metahtml.com/examples.
   
   Comments and/or suggestions for improvement on this manual, the
   language definition, or writing style(!!) should be sent to
   bug-manual@metahtml.com.
   
   Although World Wide Web use of the Internet has been growing at a
   phenomenal rate over the past 3 years, there remains a dearth of
   interesting and useful client/server applications. Traditional
   programming languages do not provide an optimal environment for
   programming such applications because of the syntactical and
   paradigmatic distance between traditional languages and the target
   output, namely HTML.
   
   The stateless and dynamic nature of the WWW requires a level of
   support from traditional programming languages which they are hard
   pressed to provide. Must each application programmer write his or her
   own tool set to accomplish goals which are fundamentally similar
   across applications?
   
   Meta-HTML presents an alternative language choice for the design and
   implementation of Web applications, and supplies three methods of
   delivering the language.
   
The Purpose of Meta-HTML

   HTML is a description layout language. It describes in general the
   placement and visual style of elements in a page. These elements are
   generally sequences of text, with an occasional image thrown in for
   good measure.
   
   Meta-HTML<sup>TM</sup> is an interpreted computer language with
   dynamic variables and flow-control statements. Although it is not a
   complete general purpose computer language in the traditional sense
   (i.e., you cannot write a version of a Meta-HTML interpreter in
   Meta-HTML) it does perform processing and decision making of and on
   data elements.
   
   A quick example for the impatient is in order. The text:
   
   You are connected to "" and reading text written by .
   
   is produced in Meta-HTML by:
  <b>You are connected to "<get-var ENV::SERVER_NAME>" and
     reading text written by <get-var the-author>.</b>

   As the WWW grows, more and more document providers are realizing that
   stateless connections are only useful for retrieving documents full of
   static information, and that, at times, it can be very useful to
   remember state pertaining to the browser that is connecting.
   
   The problem of keeping state for a particular browser user has been
   resolved by various individuals; all of the solutions require
   information to be passed back and forth between the browser and the
   server. For example, to play a WWW Blackjack game could involve the
   passing back and forth of information including the current
   wins/losses of the user, which cards have been dealt from the deck so
   far, and so forth. This information is most often passed to and fro in
   the form of a "magic" URL. The problems with passing information in
   this way are two-fold:
    1. The information can be modified by the user before sending it
       back, which might allow a user to put more money in his or her
       bank account, for example, and, less importantly,
    2. The URL looks "ugly", since there is a large amount of information
       present which doesn't describe the essence of the location that
       the user is connecting to.
       
   Another mechanism can be taken advantage of when both the server and
   browser being used support HTTP Cookies. While this solves the problem
   of "ugly" URLs, (this mechanism does not place information in the URL)
   it generates a new problem: the user must be in possession of a
   compliant browser, and be communicating with a compliant server. In
   addition, the information can be changed by the user before sending it
   back.
   
   Meta-HTML solves the problem of keeping state for a particular
   session, and it does it in a server and browser independent manner.
   Our method requires no additional CGI programs to be written. You can
   read about the technical details in the Session Operators (not
   included in this document) section of this manual.
   
Implementation Design

   Initially, the vast majority of World Wide Web (WWW) documents
   consisted of static pages of text and images, which were described
   using HTML, and displayed using a browser which understood only the
   HTML language. The nature of a WWW connection is stateless by
   definition; each request for information is not associated in any way
   with any previous request for information, even when from the same
   source.
   
   Connections are made from a browser to a WWW server, in which the
   browser requests a particular item of data by specifying a Universal
   Resource Locator (URL). The server looks up the URL, and then returns
   the data contained within. While most URLs are static HTML documents,
   there exists a mechanism in which a program can be run. The output of
   such a program is an HTML document, and such programs are referred to
   as Common Gateway Interface, or CGI programs.
   
   Meta-HTML is currently implemented as a CGI program which can be
   executed every time the server is ready to retrieve a document. As
   before, the document to be retrieved can be a file of HTML, an image,
   or a CGI program to be executed. However, the document can also be a
   file of Meta-HTML code, in which case the benefits of dynamic
   variables and flow-control statements are fully realized.
   
   Although this implementation method is not server-specific, you still
   must make a couple of configuration changes to your HTTP server in
   order to hide the Meta-HTML program from the user. Details are in the
   Installation Guide.
   
Language Syntax

   A Meta-HTML document consists of plain text, HTML directives, and
   Meta-HTML statements.
   
   The syntax of the Meta-HTML language was designed to be as similar to
   HTML as possible, so as to not sacrifice readability of the total
   document. All of the Meta-HTML statements are delivered as a form of
   HTML tags. There are two types of Meta-HTML tags: simple and complex.
   
   A simple tag begins with an open angle bracket (<) and ends with a
   corresponding close angle bracket (>). The text enclosed within the
   brackets is called the body; it can contain assigned variables and
   positional arguments.
   
   A complex tag begins with what looks exactly like a simple tag,
   continues throughout the body of the text, and ends with the a
   matching closing tag. This is analogous to the use of tags within
   HTML. The body of a complex tag is all of the text which appears
   between the opening tag and the closing tag, exclusive of those tags
   themselves.
   
   Here is an example of using the simple tag set-var:
    <set-var foo=bar>

   Here is an example of using the complex tag when:
    <when <get-var foo>>
      The value of `foo' is <get-var foo>.
    </when>

   Note that both the set-var and when forms have opening tags which
   contain additional material. This material is used to supply
   information to the form.
   
   Additionally note that "simple" and "complex" do not refer to the
   complexity of the function performed; they simply refer to the syntax
   used to write the form in a document. For example, the simple tag
   var-case performs a complex operation based upon the arguments it is
   given.
   
   Variables assigned in the opening (or simple) tag have the form:
    name=value

   This gives the variable referred to as name a local value of value.
   Variable assignments such as these give the Meta-HTML writer a way to
   pass dynamic arguments to a function. For example, the
   with-open-database form can open the requested database in one of 3
   modes; you control which one by locally assigning the variable mode
   within the form:
    <with-open-database db "/phones.db" mode=<get-var db-mode>>
     ...
    </with-open-database>

    Quoting Syntax
    
   At times, you will need to quote the expressions that you pass to
   various Meta-HTML functions. You do this with double quotes (") and
   blackslashes (\). Here is a somewhat hairy example of quoting:
    <if <get-var "Space Name">
        <get-var "Space Name[space index]">
      <set-var space-name-present=false>>

   For most cases, quoting is unnecessary, because open braces are
   expected to match close braces, and doubles quotes are expected to
   come in pairs. This is the usual case. For example:
    <ifeq <get-var foo[index]> <get-var bar>
        <set-var array[index]=<get-var bar>-found>
      <set-var array[index]=<get-var bar>-missing>>

   In the above example, no quoting was required because the only
   whitespace which appeared in the expression was within a set of
   matched braces.
   
                          Essential Language Features
                                       
Variables

   Meta-HTML provides a simple mechanism for the storage and retrieval of
   variables during a single (possibly recursive) processing pass. In
   addition to this, functions are provided which test the value of a
   variable, and conditionally execute other code based upon the result.
   
   There is also a mechanism to group a set of variables using See
   section Packages.
   
   Variable Types and Information
   
   There are internal functions in Meta-HTML which create binary
   variables. Such variables cannot be used in the ordinary way, since
   the data contained within them may not retain integrity once printed
   out and read back in. You can check to see what the type of a
   particular variable is with the symbol-info function.
   
   Many variables are predefined by Meta-HTML, and made available to the
   page writer. The Page Variables (not included in this document)
   section of this manual documents those variables fully, while the
   Server Variables (not included in this document) section contains more
   information on variables which control, or were specifically created
   by, the web server.
   
   Simple Tag: alist? string
          Return "t" if string is a representation of an association
          list.
          
   Simple Tag: coerce-var varname &key [type=(STRING|BINARY|ARRAY)]
          Coerces varname's data to have the type specified by the
          argument to type. You can convert a binary object to a string
          object, and vice-versa.
          
          A binary variable might be created as the result of a call to
          stream-get-contents, for example. Once the data is read, you
          might wish to perform some substitutions on it, or otherwise
          get its value. To do so, you call coerce-var on the value:
          
<with-open-stream s /tmp/file mode=read>
  <stream-get-contents s foo>
</with-open-stream>

<coerce-var foo type=string>
<subst-in-string <get-var foo> "Hello" "Goodbye">
<get-var foo>

   Simple Tag: copy-var from-var &optional [to-var...]
          Copies the variable from-var to each of the named to-vars.
          
          Each to-var becomes the repository of a copy of the information
          already stored under from-var. This is a true copy; not an
          alias to the original variable.
          
<set-var foo=bar>
<get-var foo>      ==> bar
<get-var new>      ==>
<copy-var foo new> ==>
<get-var new>      ==> bar

<copy-var *meta-html*::get-var *meta-html*::foo>
<foo new>          ==> bar

   Simple Tag: decrement name &key [by=amount]
          Subtract amount (default 1) from the contents of the variable
          named by varname.
          
   <set-var foo=1>
   <get-var foo> ==> 1
   <decrement foo>
   <get-var foo> ==> 0

          Also see increment.
          
   Simple Tag: defvar name value
          DEFault the value of the VARiable named by name to value.
          
          defvar assigns value to name if, and only if, name has a
          non-empty value.
          
          defvar could have been defined in Meta-HTML using define-tag:
          
<define-tag defvar var val>
  <if <not <get-var var>> <set-var <get-var var>=<get-var val>>>
</define-tag>

   Simple Tag: get-var &optional [name...]
          Return the value of the names given. Each name is a variable
          name which has had a value assigned to it with set-var,
          set-var-readonly, or was created implicity via
          alist-to-package or coerce-var.
          
          The values are returned in the order in which the names appear.
          
          Examples:
          
<set-var foo=Var-1 bar=Var-2>
<get-var foo>, <get-var bar>

          produces
          
Var-1, Var-2

          When multiple names are given:
          
<get-var foo bar foo>

          produces
          
Var-1Var-2Var-1

   Simple Tag: get-var-once &optional [name...]
          Returns the current value of the variables named by the names
          given. The interpreter pointer is then moved to after the
          returned data, thus preventing further interpretation of the
          data.
          
          Example:
          
<set-var bar=HELLO>
<set-var-verbatim foo=<get-var bar>>
<get-var-once foo>   ==> <get-var bar>

          but...
          
<get-var foo>        ==> HELLO

   Simple Tag: increment name &key [by=amount]
          Add amount (default 1) to the contents of the variable named by
          varname.
          
<set-var foo=1>
<get-var foo> ==> 1
<increment foo>
<get-var foo> ==> 2

          Also see decrement.
          
   Simple Tag: set-var &optional [name=value...]
          Gives the variable name the value of value for the current
          processing run. Any number of name/value pairs may be given,
          and whitespace is not significant. Where =value is omitted, the
          value is the empty string.
          
<set-var foo=bar bar=baz>
<get-var foo>              ==> bar
<get-var bar>              ==> baz
<get-var <get-var foo>>    ==> baz

   Simple Tag: set-var-readonly &optional [name=value...]
          For each name specified, if that name is not already assigned a
          value with set-var-readonly, assigns the associated value to
          it, exactly in the way that set-var would.
          
          Once name has had a value assigned to it with set-var-readonly,
          then that variable is immutable, i.e., its value cannot be
          changed using any Meta-HTML commands.
          
          A useful construct for setting various site specific variables
          in your engine.conf or mhttpd.conf file, this allows one to
          create globally defined variables which cannot be changed by
          the execution of Meta-HTML statements in a page.
          
          Variables which can usefully benefit from this type of setting
          include mhtml::include-prefix and mhtml::relative-prefix among
          others.
          
   Simple Tag: set-var-verbatim &optional [name=value...]
          Gives the variable name the value of value for the current
          processing run. The difference between set-var-verbatim and
          set-var is that in set-var-verbatim the right-hand side of
          assignments are not evaluated.
          
          Example:
          
<set-var-verbatim foo=<get-var bar>>
<get-var-once foo>

          produces
          
Var-2

   Simple Tag: symbol-info symbol
          Returns information about the symbol symbol.
          
          The information is two lines:
          
          + The type of the symbol, which is one of:
              1. STRING,
              2. BINARY,
              3. USER DEFUN,
              4. USER SUBST,
              5. USER MACRO,
              6. PRIM DEFUN, or
              7. PRIM MACRO.
          + The "size" of the symbol.
            
          For STRING. variables, the size value is the number of elements
          in the array.
          For BINARY variables, the size value is the number of bytes of
          binary data stored within.
          
          The size value is zero for all other variable types.
          
   Simple Tag: unset-var &optional [name...]
          Make names be non-existent in the page environment.
          
          This is different than <set-var foo=""> because the variable
          actually ceases to exist, rather than is given no value.
          
          Example:
          
<set-var foo="">
<var-exists foo>      ==> true
<get-var foo>         ==>
<unset-var foo>
<var-exists foo>      ==>

   Simple Tag: var-exists name
          var-exists checks for the existence of the variable named by
          varname, and returns true if that variable exists.
          
          The existence of a variable has nothing to do with its value --
          a variable exists if it has been created with set-var, and
          doesn't exist after it has been unset with unset-var.
          
  <set-var foo=1 bar>
  <var-exists foo>       ==> true
  <var-exists bar>       ==> true
  <get-var bar>          ==>
  <unset-var foo>
  <var-exists foo>       ==>

Arrays

   Meta-HTML allows the use of array variables as well as single element
   variables. In fact, all string variables in Meta-HTML can be treated
   as array variables -- there is no special command for creating such
   variables. Array variable values are referenced by placing the array
   index directly after the variable name, enclosed in square brackets ([
   and ]). Thus, a reference to the 3rd element of the array foo looks
   like:
   
   foo[3]

   When an array reference is made without any containing index, the
   reference refers to the entire array. So, to get the value of the
   entire array stored in foo, you would write:
   
   <get-var foo[]>

   In order to ease the writing of array references which rely on a
   variable index, a variable name seen as an array reference index is
   automatically looked up as if you had written <get-var VAR>. Finally,
   multiple values may be given in a set-var command by separating those
   values with newline characters. The following sequence of commands
   illustrates the typical use of array variables.
<set-var array[] =
       "value-zero
        value-one
        value-two
        value-three">
    <set-var i=0>
    <while <get-var array[i]>>
      The value of array[<get-var i>] is `<get-var array[i]>'.<br>
      <increment i>
    </while>

   produces

          The value of array[0] is `value-zero'.


          The value of array[1] is `value-one'.


          The value of array[2] is `value-two'.


          The value of array[3] is `value-three'.



   Simple Tag: array-add-unique item arrayvar &key [caseless=true]
          Add item as the last array element of the contents of arrayvar
          if, and only if, item is not already a member of that array.
          
          The comparison is a direct string-wise compare. If CASELESS is
          non-empty, then a caseless string compare is done.
          
          See also array-append.
          
   Simple Tag: array-append item arrayvar
          Add item as the last array element of the contents of arrayvar.
          This is especially useful in conjunction with foreach as a
          collector:
          
<foreach name allnames>
  <if <satifies-criteria <get-var name>>
     <array-append <get-var name> useful-names>>
</foreach>

          See also array-add-unique.
          
   Simple Tag: array-concat receiver &optional [contributor...]
          Appends the contents of each contributor array to the end of
          receiver.
          
          Both receiver and each contributor are variable names whose
          values are treated as arrays.
          
          For a single contributor, array-concat could have been defined
          as:
          
<defsubst array-concat>
  <foreach item %1>
     <array-append <get-var item> %0>
  </foreach>
</defsubst>

   Simple Tag: array-member item arrayvar &key [caseless=true]
          Look up (and return) the index of item in the contents of the
          array referenced by arrayvar.
          
          If item is not found, then array-member returns the empty
          string.
          
          If caseless is non-empty, then the comparison is done without
          regard to character case. Otherwise, character case is
          significant in the location of the item.
          
<set-var array[] =
  <prog
     this
     another
     multi word
     thing>>
<array-member "multi word" array>

          produces
          
2

   Simple Tag: array-shift amount arrayvar &key [start]
          Shift the elements of arrayvar the indicated amount.
          
          If amount is negative, the elements are shifted down (i.e.
          towards zero), with the lowest number elements being lost.
          
          If amount is positive, the elements are shifted up, with no
          loss at all -- instead empty elements are used to fill the
          created space.
          
          If the keyword argument start is present, it indicates the
          zero-based offset from which to start shifting.
          
          Given the array:
          
<set-var array[] =
   <prog
       0
       1
       2>>

          then after executing <array-shift 2 array>, the array looks
          like:
          
   ""
   ""
   "0"
   "1"
   "2"

          and, a subsequent execution of <array-shift -3 array> leaves
          array:
          
   "1"
   "2"

   Simple Tag: array-size arrayvar
          Returns the number of elements in the array referenced by the
          variable arrayvar.
          
          Examples:
          
<set-var array[]="this">
<array-size array>

          produces
          
1

          and,
          
<array-shift 4 array>
<array-size array>

          produces
          
5

   Complex Tag: foreach elementvar arrayvar &key [start=x] [end=x]
          [step=x] [iter=var] [no-copy=true]
          Perform body with elementvar bound to successive memebers of
          arrayvar, starting with the element at start (default 0), and
          ending at end (default <array-size ARRAYVAR>), advancing by
          step (default 1). 
          
          The foreach command is the basic array looping device in
          Meta-HTML. It is guaranteed to iterate over each element that
          you specify, whether that element is the empty string or not.
          
          If no-copy=true is specified, the array is not copied before
          iteration, so that changes that you make to the array take
          place immediately, during the execution of the surrounding
          <foreach>.
          
          Starting with the simple array:
          
<set-var array[]="0\n1\n2\n3\n4\n5\n6\n7\n8\n9">

          we can print out the odd numbers of this array by using values
          for both start and step:
          
<foreach x array start=1 step=2> <get-var x>, </foreach>

          produces
          
 1,  3,  5,  7,  9,

          or, we can produce a "countdown" with a negative value for
          step:
          
<foreach x array step=-1> <get-var x>, </foreach> BOOM!

          produces
          
 9,  8,  7,  6,  5,  4,  3,  2,  1,  0,  BOOM!

   Simple Tag: sort arrayvar &optional [sort-fun] &key [caseless=true]
          [sortorder=[ascending|descending]] [number=true]
          Sort the contents of the array arrayvar.
          
          The elements are sorted in place -- this function has no return
          value.
          
          If caseless=true is given, then the comparison of the elements
          of the array is done without regards to case.
          
          If sortorder=reverse is given, then the results are returned in
          descending order, instead of ascending order. The default is to
          order the elements in ascending order.
          
          If numeric=true is given, then the elements of arrayvar are
          treated as numeric entities, whether they are or not. The
          default is to treat the elements as character strings, which
          can have unexpected results when sorting numeric quantities
          ("11" is less then "2" when sorting alphabetically!)
          
          Finally, you may supply a sorting function, whose name is
          passed as sort-fun. This function will be called on each
          element just before comparison, and the results of that
          function will be used for the comparison instead of the element
          itself. This allows you to create a collating sort, or to sort
          on complex weighting features, or anything else that you can
          conceive of.
          
          Examples:
          
          Given the array:
          
<set-var array[0] = 1
         array[1] = 2
         array[3] = 3
         array[4] = 4
         array[5] = 20>

          then,
          
<sort array>
<foreach x array> <get-var x> </foreach>

          produces
          
   1  2  20  3  4

          while
          
<sort array numeric=true>
<foreach x array> <get-var x> </foreach>

          produces
          
   1  2  3  4  20

          Sorting strings:
          
<set-var array[]="a\nb\nc\nd\ne\nf\nA\nB\nC\nD\nE\nF">
<sort array sortorder=descending>
<foreach x array> <get-var x> </foreach>

          produces
          
 f  e  d  c  b  a  F  E  D  C  B  A

          Without regards to case:
          
<sort array caseless=true>
<foreach x array> <get-var x> </foreach>

          produces
          
 a  A  b  B  c  C  d  D  e  E  f  F

          Finally, here is an example which sorts a list of words based
          upon the percentage of vowels present in each word, using a
          sort function which calculates that value for each string:
          
<defun vowel-percentage string>
  <set-var x =
    <subst-in-string <downcase <get-var string>> "([^aeiou])" "">>
  <percent <string-length <get-var x>>
           <string-length <get-var string>>>
</defun>

<set-var words[]=
  <prog
    Brian
    Fox
    sorts
    elegant
    strings
    beautifully>>

<sort words vowel-percentage numeric=true sortorder=descending>

<foreach word words>
  <get-var word> (<vowel-percentage <get-var word>>)<br>
</foreach>

          produces
          

  Brian (<percent 2
           5>)
  Fox (<percent 1
           3>)
  sorts (<percent 1
           5>)
  elegant (<percent 3
           7>)
  strings (<percent 1
           7>)
  beautifully (<percent 5
           11>)

Packages

   Packages are repositories which contain symbols and their values.
   
   Each time a symbol is referenced, a package must first be found, and
   then the symbol may be found within that package. You indicate which
   package to look the symbol up in by supplying a package prefix. When
   the prefix is not supplied, the symbol is looked up in the current
   package.For example, a full reference to the symbol bar stored in the
   foo package looks like:
   
   FOO::BAR

   There are very few commands specifically for dealing with packages,
   because most of the operations are performed implicitly, rather than
   explicitly. To create a package, simply give the package name as part
   of the symbol, in the place where the symbol is normally used.
   
   <set-var foo::bar = "Hello">

   This has the effect of creating the package foo if it didn't already
   exist.
   
   The majority of the functions documented here perform package
   maintenance, as opposed to variable manipulation. There are functions
   for querying a package about its contens, for deleting an entire
   package, for exporting and importing packages to and from sessions,
   for copying the contents of packages, and for converting packages from
   an internal representation to a printable representation, called an
   alist.
   
   Simple Tag: alist-defvar alistvar name value
          DEFault the value of the VARiable named by name to value, in
          the association list referenced by <alistvar>.
          
          defvar assigns value to name if, and only if, name has a
          non-empty value.
          
   Simple Tag: alist-get-var alistvar &optional [name...]
          Return the value of the names given from the association list
          specified by alistvar. Each name is a variable name which has
          had a value assigned to it with alist-set-var, or was created
          implicity via alist-to-package.
          
          The values are returned in the order in which the names appear.
          
   Simple Tag: alist-package-delete alistvar &rest packages[]
          For each variable in the association list within alistvar,
          remove the variable from the association list if it is prefixed
          with one of the specifed package names. For example, given that
          the variable alist contained the alist:
          
(("FOO::BAR" . "bar") ("FOO::BAZ" . "baz") ("BAR::X" . "val"))

          then calling:
          
<alist-package-delete alist foo>
<get-var-once alist>

          produces:
          
(("BAR::X" . "val"))

   Simple Tag: alist-package-names alistvar
          Return a newline separated list of all of the packages which
          are defined within the association list stored within alistvar.
          Because the list is newline separated, the result can easily be
          assigned to an array variable:
          
   Simple Tag: alist-set-var alistvar &optional [name=value...]
          Gives the variable name the value of value in the association
          list specified by alistvar. Any number of name/value pairs may
          be given, and whitespace is not significant. Where =value is
          omitted, the value is the empty string.
          
<alist-set-var myalist foo=bar bar=baz>
<alist-get-var myalist foo>    ==> bar
<alist-get-var myalist bar>    ==> baz
<alist-get-var myalist <alist-get-var myalist foo>>    ==> baz

   Simple Tag: alist-to-package alist &optional [package]
          Takes the textual list representation of a package, and creates
          (or modifies) the package named by package-name.
          
          alist-to-package is the inverse of the package-to-alist
          function -- given an "alist" (short for `association list') you
          can create a package, and vice-versa. The following expression
          is one way to copy all of the variables from the package FOO
          into the package BAR:
          
<alist-to-package <package-to-alist foo> bar>

   Simple Tag: alist-unset-var alistvar &rest names...
          Make names be non-existent in the association list specified by
          alistvar.
          
   Simple Tag: alist-var-exists alistvar name
          var-exists checks for the existence of the variable named by
          varname, in the association list specified by alistvar, and
          returns true if that variable does in fact exist.
          
          The existence of a variable has nothing to do with its value --
          a variable exists if it is present within the list, whether or
          not it has a value.
          
   Complex Tag: in-package package-name
          Evaluate body in an environment where variables which are not
          specifically prefixed with a package name are looked up and
          stored within package-name.
          
          The special package name "local" creates an anonymous package
          within which to work. The contents of local packages are only
          accessible within the expressions surrounded by the in-package
          operator.
          
   Simple Tag: package-delete package-name...
          Remove the definition of the packages named by package-names,
          and all of the variables defined within them.
          
   Simple Tag: package-names
          Return a newline separated list of all of the named packages
          which are currently defined. Because the list is newline
          separated, the result can easily be assigned to an array
          variable:
          
<set-var all-packages[]=<package-names>>

   Simple Tag: package-to-alist &optional [package]
          Returns a Lisp readable string containing the names and values
          of the variables in package. If strip=true is supplied, the
          package name is removed from the variables before placing them
          in the list. See the following code sequence:
          
<set-var
  foo::bar=baz
  foo::array[0]=Elt-0
  foo::array[1]=Elt-1>

  The contents of Foo: <package-to-alist foo>
The stripped contents: <package-to-alist foo strip=true>

          produces
          
  The contents of Foo: (("FOO::BAR" . "baz")("FOO::ARRAY" "Elt-0" "Elt-1"))
The stripped contents: (("BAR" . "baz")("ARRAY" "Elt-0" "Elt-1"))

   Simple Tag: package-vars &optional [package-name] &key [strip=true]
          Returns a newline separated list of the fully qualified
          variable names found in the package named by package-name, or
          in the current package if package-name is not given. When
          strip=true is supplied, the returned variable names have the
          package prefix stripped off, making them not fully qualified.
          The names are not returned in any significant order. Because
          the list is newline separated, the results can easily be
          assigned to an array variable:
          
<set-var foo::bar=baz>
<set-var foo::baz=bar>
<set-var names[]=<package-vars foo>>
<get-var names[1]>

          produces
          
FOO::ARRAY

   Complex Tag: with-local-package
          Shorthand for <in-package local> <i>body</i> </in-package> 
          
Flow Control

   Meta-HTML contains commands for controlling which of a set of
   statements will be executed, and for repetitive execution of a set of
   statements.
   
   Such commands constitute what is called flow control, since they tell
   the Meta-HTML interpreter where or what the next statement to
   interpret resides.
   
   All of the flow control operators in Meta-HTML take a test and some
   additional statements; the closest thing to a goto statement in
   Meta-HTML is the redirect command.
   
   Simple Tag: break
          Unconditionally and immediately stop the execution of the
          nearest surrounding while or foreach.
          
          Example usage:
          
<while true>

  <if <file-newer? <get-var foo.c> <get-var foo.o>>
    <break>>


  <process-chunk <get-var chunk-num>>
  <increment chunk-num>
</while>

   Simple Tag: concat &rest args
          Concatenate all of the arguments given, creating a single token
          with no intervening whitespace. This is quite useful for those
          situations where intervening whitespace would look bad in the
          output, but the input source would be unreadable without any.
          
          For example:
          
<concat <textarea name=label rows=10 cols=40>
        <get-var-once label>
        </textarea>>

   Simple Tag: group &rest args
          Combine all of the material passed into a single Meta-HTML
          statement. This is the primitive for grouping multiple
          statements where only a single statement is expected.
          Whitespace within the group is preserved, making this command
          useful for assigning to array variables.
          
          Some examples:
          
<set-var array[] =
  <group this is element 0
         this is element 1
         this is element 2>>

<if <eq this that>
    <group <h2> This is equal to That </h2>>
   <group <h2> This is NOT equal to That </h2>>>

          Although group is a primitive in Meta-HTML, it could have been
          defined as:
          
  <defsubst group>%body</defsubst>

   Simple Tag: if test &optional [then] [else]
          First test is evaluated. If the result does not contain only
          whitespace characters the then clause is evaluated, otherwise,
          the else clause is evaluated. Although Meta-HTML has the
          relational operator or, you can efficiently test for the
          presence of any of a group of variables with code similar to
          the following:
          
<if <get-var foo bar>
   "Either FOO or BAR is present"
  "Neither FOO nor BAR is present">

   Simple Tag: ifeq this that &optional [then] [else] &key
          [caseless=true]
          The this and that clauses are evaluated. If the results are
          text-wise identical, then the then clause is evaluated,
          otherwise, the else clause is evaluated. If caseless=true is
          given, the text-wise comparison of the values is done with no
          regard to upper and lower case distinctions.
          
   Simple Tag: ifneq this that &optional [then] [else] &key
          [caseless=true]
          The this and that clauses are evaluated. If the results are not
          text-wise identical, then the then clause is evaluated,
          otherwise, the else clause is evaluated. If caseless=true is
          given, the text-wise comparison of the values is done with no
          regard to upper and lower case distinctions.
          
   Variable: mhtml::iteration-limit
          The use of this variable has been deprecated. while loops last
          until either the test-clause is met, or a break statement is
          seen.
          
   Simple Tag: prog &rest args
          Synonym for group.
          
   Simple Tag: return &rest args
          Unconditionally and immediately stop the execution of the
          current function, macro, while or foreach statement, and return
          the evaluated args.
          
          Example usage:
          
<define-function countdown start stop>
  <if <eq start stop>
      <return BlastOff!>>
  <get-var start>,
  <countdown <sub start 1> <get-var stop>>
</define-function>
<countdown 10 4>

          produces
          
10, 9, 8, 7, 6, 5, BlastOff!

   Simple Tag: var-case &optional [name=value] [consequent...] [default]
          [default-consequent]
          For each name=value pair, the value of name is string-wise
          compared with value. If they are identical, then the
          corresponding consequent code is performed, and its value is
          the return value of the <var-case> form.
          
          If none of the clauses match, and there is a default clause,
          then the default-consequent is evaluated, and its return value
          is the return value of the <var-case> form.
          
          var-case is especially useful as a `traffic switch' to select
          one of several actions based on a user button press.
          
          For example:
          
<var-case
   action="Save Files"      <save-files <get-var posted::files[]>>
   action="Delete Files"    <delete-files <get-var posted::files[]>>
   action="Rename Files"    <redirect
                                 rename-files.mhtml?<cgi-encode files>>>

   Complex Tag: when test
          Evaluate test. If the result is a non-empty string, then
          execute the body statements. This is a cleaner way to handle
          optional multiple statement execution rather than dealing with
          quoting everything inside of an if form.
          
   Complex Tag: while test
          test is evaluated. If the result is a non-empty string, then
          the body statements are evaluated, and the process is repeated.
          
   Complex Tag: with &optional [var=val...]
          Execute body in an environment where var has the value val.
          Execution takes place in the current package. After execution,
          the value of var is restored to the value that it had before
          encountering the with macro.
          
<set-var x=hello>
<with x=1 z=<get-var foo>> <get-var x> </with>
<get-var x>

          produces
          
 1
hello

Convenience Primitives

   Meta-HTML provides various functions and variables which are used to
   operate on or within the language environment itself, rather than
   within the application environment.
   
   Such constructs make it possible to create self-modifying code, to
   change the way in which a builtin function operates, and other such
   language dependent features.
   
   Complex Tag: comment
          Simply discard the body. No processing is done, and no output
          is produced.
          
          A shorthand for commenting source on a single line exists; when
          the sequence of 3 semicolon character is seen (;;;), then the
          text from this sequence to the end of the line inclusive is
          discarded.
          
          Example:
          
<comment>
  This text is simply ignored.

  All of it.
</comment>

;; But NOT this line -- it only has two semi-colons on it.

   Variable: mhtml::inhibit-comment-parsing
          When this variable is set to a non-empty value, the triple
          semi-colon comment feature is disabled.
          
          You may need this for complex applications where you are
          deliberately shipping the source of a Meta-HTML document to the
          client.
          
   Variable: mhtml::version
          Contains the version identification of the currently running
          interpreter. This variable is available whereever the
          interpreter is running, including the Meta-HTML server, Engine,
          and in mdb.
          
<get-var mhtml::version>

          produces
          
5.09

                              Strings and Numbers
                                       
String Operators

   There is a single function in Meta-HTML which performs pattern
   matching, substring extraction, and substring deletion. For
   convenience, a blind substring extraction function is supplied as
   well. Three functions perform the three most common case changes.
   Finally, the pad function allows alignment of fixed-width text.
   
   Simple Tag: capitalize string
          Changes the case of each character in string to uppercase or
          lowercase depending on the surrounding characters.
          
<capitalize "This is a list">

          produces
          
This Is A List

          Also see downcase, and upcase.
          
   Simple Tag: char-offsets string ch &key [caseless]
          Return an array of numbers, each one representing the offset
          from the start of string of ch. This function is useful for
          finding candidate locations for word-wrapping, for example.
          Here is a complete example:
          
<char-offsets "This is a list" " ">

          produces
          
4
7
9

   Simple Tag: downcase string
          Converts all of the uppercase characters in string to
          lowercase.
          
<downcase "This is Written in Meta-HTML">

          produces
          
this is written in meta-html

   Simple Tag: match string regex &key
          [action=[delete|extract|report|startpos|endpos|length]]
          Matches regexp against string, and then performs the indicated
          action. The default for action is "report".
          
          When action is "report" (the default), returns "true" if regex
          matched.
          When action is "extract", returns the substring of string
          matching regex.
          When action is "delete", returns string with the matched
          substring removed.
          When action is "startpos", returns the numeric offset of the
          start of the matched substring.
          When action is "endpos", returns the numeric offset of the end
          of the matched substring.
          
          regexp is an extended Unix regular expression, the complete
          syntax of which is beyond the scope of this document. However,
          the essential basics are:
          
          + A period (.) matches any one character.
          + An asterisk (*) matches any number of occurrences of the
            preceding expression, including none.
          + A plus-sign matches one or more occurrences of the preceding
            expression.
          + Square brackets are used to enclose lists of characters which
            may match. For example, "[a-zA-Z]+" matches one or more
            occurrences of alphabetic characters.
          + The vertical bar is used to separate alternate expressions to
            match against. For example, "foo|bar" says to match either
            "foo" or "bar".
          + A dollar-sign ($) matches the end of STRING.
          + Parenthesis are used to group subexpressions.
            
          Here are a few examples:
          
  <match "foobar" ".*">                 ==> "true"
  <match "foobar" "foo">                ==> "true"
  <match "foobar" "foo" action=extract> ==> "foo"
  <match "foobar" "oob" action=delete>  ==> "far"
  <match "foobar" "oob" action=startpos>==> "1"
  <match "foobar" "oob" action=endpos>  ==> "4"
  <match "foobar" "oob" action=length>  ==> "3"
  <match "foobar" "[0-9]+">             ==> ""

   Complex Tag: plain-text &key [first-char=expr] [nobr=true]
          Performs the following steps:
          
    1. Replace occurrences of pairs of newline characters with a single
       <P> tag.
    2. Applies the function expr to the first character of every
       paragraph, and inserts the closing tag after that character.
       
   The output will start with a <P> tag, unless the optional argument
   nobr=true is given.
<plain-text first-char=<font size="+1"> nobr=true>
This is line 1.

This is line 2.
</plain-text>

   produces
This is line 1.

This is line 2.

   Simple Tag: string-compare string1 string2 &key [caseless]
          Compare the two strings string1 and string2, and return a
          string which specifies the relationship between them. The
          comparison is normall case-sensitive, unless the keyword
          argument caseless=true is given.
          
          The possible return values are:
          
    1. equal
       The two strings are exactly alike.
    2. greater
       string1 is lexically greater than string2.
    3. less
       string1 is lexically less than string2.
       
   Examples:
   
<string-compare "aaa" "aab">               ==> less
<string-compare "zzz" "aab">               ==> greater
<string-compare "zzz" "ZZZ">               ==> greater
<string-compare "zzz" "ZZZ" caseless=true> ==> equal

   Simple Tag: string-eq string-1 string-2 &key [caseless=true]
          Compare string1 to string2 and return the string "true" if they
          are character-wise identical.
          
          The optional keyword argument caseless=true indicates that no
          consideration should be given to the case of the characters
          during comparison.
          
<string-eq "foo" "FOO">               ==>
<string-eq "foo" "foo">               ==>true
<string-eq <upcase "foo"> "FOO">      ==>true
<string-eq "foo" "FOO" caseless=true> ==>true

   Simple Tag: string-length string
          Returns the number of characters present in string.
          
<string-length "This is an interesting string">

          produces
          
29

   Simple Tag: string-neq string-1 string-2 &key [caseless=true]
          Compare string1 to string2 and return the string "true" if they
          are NOT character-wise identical.
          
          The optional keyword argument caseless=true indicates that no
          consideration should be given to the case of the characters
          during comparison.
          
<string-neq "foo" "FOO">               ==>true
<string-neq "foo" "foo">               ==>
<string-neq <upcase "foo"> "FOO">      ==>
<string-neq "foo" "FOO" caseless=true> ==>

   Simple Tag: subst-in-string string &rest regexp replacement
          Replaces all occurrences of regexp with replacement in string.
          
          regexp can be any regular expression allowed by POSIX extended
          regular expression matching.
          
          In the replacement string, a backslash followed by a number n
          is replaced with the contents of the nth subexpression from
          regexp.
          
<set-var foo="This is a list">
<subst-in-string <get-var foo> "is" "HELLO">
     ==> "ThHELLO HELLO a lHELLOt"

<subst-in-string "abc" "([a-z])" "\\1 "> ==> "a b c "

   Simple Tag: subst-in-var varname &optional [this-string] [with-that]
          Replaces all occurrences of this-string with with-that in the
          contents of the variable named varname. Both this-string and
          with-that are evaluated before the replacement is done.
          this-string can be any regular expression allowed by the POSIX
          extended regular expression matching. This command can be
          useful when parsing the output of cgi-exec.
          
   Simple Tag: substring string &key [start] [end]
          Extracts the substring of string whose first character starts
          at offset start, and whose last character ends at offset end.
          The indexing is zero-based, so that:
          
  <substring "Hello" 1 2> ==> "e"

          This function is useful when you know in advance which part of
          the string you would like to extract, and do not need the
          pattern matching facilities of match.
          
          If you wish to index through each character of a string, the
          most direct way is to convert it to an array first using
          string-to-array, and then use the foreach function to iterate
          over the members.
          
<set-var s="This is a string.">
<string-to-array <get-var-once s> chars>
<foreach character chars><get-var character>-</foreach>

          produces
          
<string-to-array This is a string. chars>

   Simple Tag: upcase string
          Converts all of the lowercase characters in string to
          uppercase.
          
<upcase "This is Written in Meta-HTML">

          produces
          
THIS IS WRITTEN IN META-HTML

Arithmetic Operators

   Meta-HTML contains a small set of commands for operating on numerical
   quantities.
   
   All of the arithmetic operators described in this section can accept a
   number, or simply the name of a variable, which is then looked up as
   if it had been written with <get-var ...>.
   
   That is to say:
   
   <set-var total = <add <get-var subtotals[0]>
                         <get-var subtotals[current]>>>

   can be written as:
   
   <set-var total = <add subtotals[0] subtotals[current]>>

   The binary arithmetic operators always expect two arguments, and will
   produce a warning message in DEBUGGING-OUTPUT when given too few
   arguments.
   
   You can perform floating point arithmetic if one or both of the
   arguments is already a floating point number:
   
  <div 10 3>    ==> 3
  <div 10.0 3>  ==> 3.33

   Simple Tag: add arg1 arg2 &rest more-args
          Returns the summation of all of the arguments passed.
          
          Examples:
          
<add 1 2>        ==> 3
<add -1 2 2 1>   ==> 4

   Simple Tag: div arg1 arg2 &rest more-args
          Returns the quotient of all of the arguments passed.
          
          Examples:
          
<div 100 5>      ==> 20
<div 5 100>      ==> 0
<div 5.0 100.0>  ==> 0.05
<div 100 5 2>    ==> 10

   Simple Tag: eq arg1 arg2
          Returns "true" if the numeric value of arg1 is exactly equal to
          the numeric value of arg2. Just as with the arithmetic
          functions (See section Arithmetic Operators), the arguments may
          be the names of variables containing numeric values, and not
          just the values themselves. In that case, eq performs an
          implicit call to <get-var ...> in order to get the value to
          operate on.
          
          Examples:
          
<eq 3 4>              ==>
<eq 3 3>              ==> true
<eq 3.0 3>            ==> true
<set-var x=3.01>
<eq <get-var x> 3.01> ==> true

   Simple Tag: gt arg1 arg2 &rest more-args...
          Returns "true" if the numeric value of arg1 is greater than the
          numeric value of arg2 (which is greater than more-args. Just as
          with the arithmetic functions (See section Arithmetic
          Operators), the arguments may be the names of variables
          containing numeric values, and not just the values themselves.
          In that case, gt performs an implicit call to <get-var ...> in
          order to get the value to operate on.
          
          Examples:
          
<gt 4 3>            ==> true
<set-var x=3.4 y=3.5>
<gt x y>            ==>
<gt y x>            ==> true
<gt <get-var y> x>  ==> true

<defun between? item high low>
  <gt high item low>
</defun>

<between? 7 8 6>    ==> true

   Simple Tag: integer? string &key [base[=10]]
          Returns "true" if string is the string representation of an
          integer value in base base (default 10). This function is
          useful for checking the validity of user input to a form.
          
          You call this function with the actual value -- you may not
          pass the name of a variable instead.
          
          Some examples:
          
<set-var x=123>
<integer? -90>          ==> true
<integer? <get-var x>>  ==> true
<integer? 2.3>          ==>
<integer? FEFE base=16> ==> true
<integer? 874 base=8>   ==>

   Simple Tag: lt arg1 arg2 &rest more-args
          Returns "true" if the numeric value of arg1 is less than the
          numeric value of arg2 (which is less than more-args. Just as
          with the arithmetic functions (See section Arithmetic
          Operators), arg1 and arg2 may be the names of variables
          containing numeric values, and not just the values themselves.
          In that case, lt performs an implicit call to <get-var ...> in
          order to get the value to operate on.
          
          Examples:
          
<lt 3 4>            ==> true
<lt 4 3>            ==>
<set-var x=3.4 y=3.5>
<lt x y>            ==> true
<lt y x>            ==>
<lt x <get-var y>>  ==> true
<lt 4 5 6>          ==> true

   Simple Tag: max arg1 arg2 &rest more-args
          Returns the largets of all of the arguments passed.
          
          Examples:
          
<max 2 2>        ==> 2
<max 2.3 8 7>    ==> 8.00
<max 4 10 -4>    ==> 10

   Variable: mhtml::decimal-places
          Controls the number of decimal places which arithmetic
          functions produce. The default value of this variable is 2, but
          for times when you need greater resolution in your
          calculations, you may wish to set it higher.
          
<set-var mhtml::decimal-places = 10>
To 10 places: <div 1 .34567>
<unset-var mhtml::decimal-places>
To  2 places: <div 1 .34567>

          produces
          
To 10 places: 2.8929325657

To  2 places: 2.89

   Simple Tag: min arg1 arg2 &rest more-args
          Returns the smallest of all of the arguments passed.
          
          Examples:
          
<min 2 2>        ==> 2
<min 2.3 8 3>    ==> 2.30
<min 3 -4 10>    ==> -4

   Simple Tag: mod arg1 arg2 &rest more-args
          Returns the remainder of all of the arguments passed.
          
          Examples:
          
<mod 100 10>    ==> 0
<mod 101 10>    ==> 1
<mod 89 9 3>    ==> 2

   Simple Tag: mul arg1 arg2 &rest more-args
          Returns the product of all of the arguments passed.
          
          Examples:
          
<mul 2 2>        ==> 4
<mul 2.3 8 3>    ==> 55.20
<mul -4 10>      ==> -40

   Simple Tag: neq arg1 arg2
          Returns "true" if the numeric value of arg1 is NOT equal to the
          numeric value of arg2. Just as with the arithmetic functions
          (See section Arithmetic Operators), the arguments may be the
          names of variables containing numeric values, and not just the
          values themselves. In that case, eq performs an implicit call
          to <get-var ...> in order to get the value to operate on.
          
          Examples:
          
<neq 3 4>              ==> true
<neq 3 3>              ==>
<neq 3.0 3>            ==>
<set-var x=3.01>
<neq <get-var x> 3.00> ==> true

   Simple Tag: real? string
          Returns "true" if string is the string representation of a real
          number.Useful for checking the validity of user input to a
          form.
          
          You call this function with the actual value -- you may not
          pass the name of a variable instead.
          
          Some examples:
          
<set-var pi=3.141569>
<real? <get-var pi>>    ==> true
<real? 45>              ==>
<real? 2.3>             ==> true
<real? "This">          ==>
<real? -.087e4>         ==> true

   Simple Tag: set-output-radix new-radix
          Set the output radix for numbers produced by arithmetic
          operations to new-radix, which is specified in decimal. Returns
          the value of the previous output radix. Note that there is no
          corresponding function for setting the input radix. If the
          value of new-radix is a number between 2 and 32 decimal,
          inclusive, then the output radix is set to that value.
          new-radix can also be the name of a function of one argument,
          which should be called to produce the appropriate output.
          
          If the argument to does not fall between 2 and 32 inclusive,
          and is not the name of a defined function, then the output
          radix remains unchanged, and produces no output.
          
          Examples:
          
<set-output-radix 16>                ==> 10
<add 0x3e 1>                         ==> 0x3f
<set-output-radix 10>                ==> 16
<set-output-radix number-to-english> ==> 10
<add 23.4 32.32>                     ==> Fifty-Five point Seven Two

   Simple Tag: sub arg1 arg2 &rest more-args
          Returns the difference of all of the arguments passed.
          
          Examples:
          
<sub 2 1>        ==> 1
<sub 6 2 1>      ==> 3
<sub -1 -2>      ==> 1

Relational Operators

   Relational operators in Meta-HTML return information about the
   relationship between two items. There are three logical operators,
   and, or, and not.
   
   There are several other operators which compare numeric values; the
   section See section Arithmetic Operators cover those in detail.
   
   Simple Tag: and &rest expr...
          and evaluates each expr given until one of them evaluates to
          the empty string, or until they are all exhausted. The result
          is the result of the last evaluation. Evaluating just <and>
          returns "true".
          
          Examples:
          
<and>                    ==> true
<and this that>          ==> that
<unset-var foo>
<and <get-var foo> this> ==>
<and this <get-var foo>> ==>
<set-var foo=bar>
<and this long list <get-var foo>> ==> bar

          true could have been defined in Meta-HTML as follows:
          
<define-tag and &unevalled &rest expressions[] whitespace=delete>
  <set-var result=true>
  <foreach :expr expressions>
    <set-var result = <get-var :expr>>
    <if <not <get-var-once result>>
      <break>>
  </foreach>
  <get-var-once result>
</define-tag>

   Simple Tag: not &optional [body]
          body is evaluated. If the result is the empty string, then the
          string "true" is returned, otherwise nothing is returned. body
          is simply the entire contents of the simple tag, with the word
          "not" in it. Thus, in typical usage one might write:
          
<when <not <get-var foo>>>
  Hey!  You didn't set the variable FOO.
</when>

   Simple Tag: or &rest expr...
          or evaluates each expr given until one of them evaluates to a
          non-empty string, or until they are all exhausted. The result
          is the result of the last evaluation. Evaluating just <or>
          returns the empty string.
          
          Examples:
          
<or>                    ==>
<or this that>          ==> this
<unset-var foo>
<or <get-var foo> this> ==> this
<or this <get-var foo>> ==> this
<set-var foo=bar>
<or <get-var foo> this> ==> bar

          could have been defined in Meta-HTML as follows:
          
<define-tag or &unevalled &rest expressions[] whitespace=delete>
  <foreach :expr expressions>
    <set-var result = <get-var :expr>>
    <if <get-var-once result>
        <break>>
  </foreach>
  <get-var-once result>
</define-tag>

                               Input and Output
                                       
File Operators

   There are several types of commands in Meta-HTML for dealing with
   files.
   
   Some of these commands operate directly on an open files, while others
   operate on streams (see Stream Operators (not included in this
   document)), which may be connected to files or network data.
   
   The functions allow you to include the contents of, open
   (with-open-stream), create, read, or write various data sources, or to
   replace the contents of a page (replace-page) with another
   file.Commands such as get-file-properties may return additional
   information on some systems; this is documented with each function
   where that is the case.
   
   Simple Tag: directory-contents pathname &optional [package-name] &key
          [matching=pattern]
          Returns a newline separated list of association lists for the
          files matching pattern.
          
          When package-name is supplied, each variable in package-name is
          the name of a file in pathname, and the value of each variable
          is the association list for that file.
          
   Simple Tag: file-exists pathname
          Returns "true" if pathname is an existing file or directory.
          
          pathname is absolute, that is to say that it is looked up in
          absolute file system space, not in Web space. To find out if a
          file foo in the current directory exists, use:
          
<file-exists <thisdir>/foo>

   Simple Tag: get-file-properties pathname
          Return an association-list containing operating system
          information about the file or directory named by path. pathname
          must be given fully; it is not relative to Web space in any
          way.
          
          If the file exists and is accessible, the members of the
          returned association-list which are guaranteed to be present
          are:
          
          + NAME: welcome.mhtml
            The name of the file or directory, without any of the path
            information.
          + FULL-NAME: /www/site/docs/welcome.mhtml
            The name of the file or directory, with full path
            information. This should be identical to PATH as received by
            .
          + SIZE: 2188 
            The size of the file in bytes.
          + TYPE: FILE
            The type of the file. This will either be FILE or DIRECTORY.
            
          In addition to the above fields, the following fields appear on
          Unix based systems:
          
          + CREATED: 6 29 96 10 3 24 897595648
            The date on which this file was created. The value is an
            array, with ordered values being: month, day, year, hours,
            minutes, and seconds, and then the number of seconds since
            Jan 1st, 1970.
          + WRITTEN: 6 29 96 10 3 24 897595648
            The date on which this file was last written. The value is an
            array, with ordered values being: month, day, year, hours,
            minutes, and seconds, and then the number of seconds since
            Jan 1st, 1970.
          + READ: 6 30 96 19 27 51 897595648
            The date on which this file was last read. The value is an
            array, with ordered values being: month, day, year, hours,
            minutes, and seconds, and then the number of seconds since
            Jan 1st, 1970.
          + CREATOR: bfox
            The system identifier of the user who created this file.
            
          A example calling sequence:
          
<dump-alist <get-file-properties />>

                               Defining New Tags
                                       
Macro Commands

   Meta-HTML contains a powerful macro facility, which allows you to
   define your own commands. Such commands are first-class objects in
   Meta-HTML; they may even supersede the compiled in definitions.
   
   There are two types of macros that you can define. One type is a
   complex-tag; it consists of an opening tag, a body, and a closing
   tag. The other type is a simple-tag; it only has an opening tag.
   
   You create a macro by using one of the macro-defining commands. In the
   body of the definition, special keywords can be placed, which affect
   what is produced when the macro is invoked. As a macro writer, you
   have logical access to the arguments passed to the macro in the
   opening tag, and for complex-tags, you have access to the body which
   appears between the opening and closing tags. In the opening tag of
   the macro defining command, several special meta-arguments may be used
   to affect the binding method used at invocation time to bind the
   passed parameters to the formal arguments.
     * &optional
       Indicates that the following named parameter is optional, and does
       not have to be supplied. While at this time Meta-HTML does not
       complain if there are missing arguments at invocation time, it is
       likely that the byte-compiler will require function calls to match
       the formal parameters of the defined function.
<defun func x &optional y> <get-var x>, <get-var y> </defun>
     * &key
       Indicates that the following named parameters will be bound by the
       caller placing the name of the parameter followed by an equals
       sign, and the value of that parameter in the opening tag of the
       function call. Thus, keyword arguments may appear in any order in
       the calling function. Here is an example of defining a tag called
       <image> which will add the width and hieght if they are not
       already present:
<defun image &key src width height>
  <if <or <not <get-var width>>
          <not <get-var height>>>
      <find-image-xy <get-var src> width height>>
  <img src="<get-var src>" width=<get-var width> height=<get-var height>>
</defun>
     * &rest
       Gobbles up any remaining arguments to the function, collecting
       them in the named parameter which follows the &rest. The arguments
       may be gathered into a single string, or into an array, with one
       argument per slot. This is controlled by writing the formal
       parameter name either with or without sqaure braces: (i.e., foo[]
       or foo).
<defun func req-arg &rest rest-args[]>
  <ol>
    <foreach x rest-args>
      <li> <get-var x> </li>
    </foreach>
  </ol>
</defun>
     * &body
       Causes the following named parameter to be bound to the body of
       the invoked function or macro. For <defun> and <defsubst>, this is
       all of the material which appeared in the opening tag, while for
       <defmacro> and <defweakmacro>, this is all of the material that
       appeared between the opening and closing tags.
<defmacro with-debugging-output &body body>
  <with-open-stream debug-stream /tmp/debug-output mode=append>
    <stream-put debug-stream <get-var body>>
  </with-open-stream>
</defmacro>
     * &unevalled
       Modifies the binding rule of a formal parameter such that the
       material which is bound is not evaluated before the binding takes
       place. This is almost equivalent to using the %0 ... %9, or %body
       textual substitutions, but the arguments are bound to variables
       instead of pure textual substitution. Here is how one might write
       a function which takes an expression, and produces the expression
       and the evaluation of the expression as output:
<defun debug-expr &body &unevalled qbody &body body>
  <get-var-once qbody> EVALS TO: <get-var-once body>
</defun>
       Such an invocation might look like:
  <set-var x=4 y=5>
  <debug-expr <add x y>>
       which would produce:
  <add x y> EVALS TO: 9
       
   Here is a ridiculous function, which uses all of the special
   meta-parameters:
<defsubst func req &optional opt &key k1 &unevalled k2 &body b &rest args[]>
   REQ: <get-var-once req>,
   OPT: <get-var-once opt>
    K1: <get-var-once k1>
    K2: <get-var-once k2>
  BODY: <get-var-once b>
  REST: <foreach arg args><get-var-once arg> </foreach>
</defsubst>

   And, here are examples of calling that function:
   
   Example 1:
<set-var key-1-arg=key-1>
<func required k2="Unevalled" opt-arg k1=<get-var key-1-arg> rest0 rest1>
   REQ: required,
   OPT: opt-arg
    K1: key-1
    K2: Unevalled
  BODY: required k2="Unevalled" opt-arg k1=key-1 rest0 rest1
  REST: rest0 rest1

   Example 2:
<func k2=<get-var k1> required rest0 rest1>
   REQ: required,
   OPT: rest0
    K1:
    K2: <get-var k1>
  BODY: k2= required rest0 rest1
  REST: rest1

   Notice how in the second example, our optional parameter opt got bound
   to the second non-keyword argument rest0!
   
   Complex Tag: define-container name &optional [named-parameters] &key
          [package=packname] [whitespace=delete]
          Define name as a complex tag. At invocation time, various
          substitutions are made within body. Specifically, if the text
          string is:
          
          + %0,%1, and so on, upto %9 are replaced with the exact text of
            the positional arguments that were found in the opening tag
            of the invocation
          + %attributes is replaced by all of the arguments which
            appeared in the opening tag.
          + %body is replaced with the exact text of the material that
            appeared between the opening and closing tags
          + %qbody is similar to %body, but the string is first
            surrounded by double quotes, and double quote characters
            which appear in the string are escaped.
          + %xbody is replaced with the evaluation of the material that
            appeared between the opening and closing tags
            
          If any named-parameters are supplied, the values that were
          passed in the opening tag are evaluated and bound to the named
          parameters.
          
          A keyword argument of package-name wraps the entire body of the
          macro in an in-package statement.
          
          The keyword argument whitespace can be set to the string delete
          to remove whitespace from the starts and ends of lines in the
          macro definition before it is stored. This effectively
          concatenates all of the lines of the macro definition into a
          single long line.
          
   Complex Tag: define-function name &optional [named-parameters] &key
          [package=packname] [whitespace=delete]
          Define name as a simple tag.
          
          The only differences between define-function and define-tag
          are:
          
    1. The whitespace=delete option is assumed.
    2. The named-parameters are evaluated in the context of the caller,
       not of the definition of the defun.
    3. By default, a local package is wrapped around the invocation of
       the defined function. This can be changed by the use of the
       package=packname keyword.
       
<define-function factorial num>
   <if <lt num 2> 1
      <mul num <factorial <sub num 1>>>>
</define-function>

<factorial 5> ==> 120

   Complex Tag: define-tag name &optional [named-parameters] &key
          [package=packname] [whitespace=delete]
          Define name as a simple tag. Within body, the values of %0...%9
          are defined to be the positional arguments that were found in
          the opening tag of the invocation, and %body is all of that
          material in a single string.
          
          If any named-parameters are supplied, the values that were
          passed in the opening tag are evaluated and bound to the named
          parameters.
          
          A keyword argument of package-name wraps the entire body of the
          macro in an in-package statement.
          
          The keyword argument whitespace can be set to the string delete
          to remove whitespace from the starts and ends of lines in the
          subst definition before it is stored. This effectively
          concatenates all of the lines of the subst definition into a
          single long line.
          
          Also see define-function and define-container.
          
   Complex Tag: defmacro name &optional [named-parameters] &key
          [package=packname] [whitespace=delete]
          A synonym for define-container.
          
   Complex Tag: defsubst name &optional [named-parameters] &key
          [package=packname] [whitespace=delete]
          A synonym for define-tag.
          
   Complex Tag: defun name &optional [named-parameters] &key
          [package=packname] [whitespace=delete]
          A synonym for define-function.
          
   Complex Tag: defweakmacro name &optional [named-parameters] &key
          [package=packname] [whitespace=delete]
          defweakmacro is exactly like define-container, with one
          exception: at invocation time, the closing tag does not have to
          be present -- in that case, the invocation is treated as if the
          definition were a defsubst.
          
          This facility exists primarily to allow the redefinition of
          standard HTML constructs which allow the closing tag to be
          missing, and yet, still inexplicably operate correctly.
          
          For example, the <p> tag is often used without its closing
          counterpart of </p>. If you wished to redefine <p> to do
          something special when a closing tag was found, you might write
          the following definition:
          
<defweakmacro p>
  <verbatim><P></verbatim>
  <when %qbody> Look ma! %body See? </when>
  <verbatim></P></verbatim>
</defweakmacro>

          then, a simple <P> would produce <P></P>, while a complex
          invocation, such as:
          
<P> this is a list </P>

          produces
          
  <P> Look ma!  this is a list See? </P>

   Simple Tag: undef &optional [name...]
          Remove the definition of a user-defined defun, defmacro or
          defsubst. For every name that has been defined in this way,
          the definition is removed.
          
                            Debugging Your Programs
                                       
Debugging Commands

   Debugging a CGI application executing under a running Web server can
   be quite problematic. Meta-HTML provides the following functions,
   macros, and variables in an effort to alleviate the problems
   associated with this situation.In addition to the functions and
   variables above, Meta-HTML has a complete source language debugger
   called mdb, which can be used to interactively execute expressions, to
   place breakpoints in files and then run them examining local and
   global variables, and to single-step through source code that you have
   written in Meta-HTML. Instructions on the use of the debugger is
   beyong the scope of this manual -- please see MDB: A User's Guide to
   Debugging Meta-HTML Programs for more information specific to the
   debugger.
   
   Simple Tag: debugging-on &optional [function-name=level...]
          Turns on debugging for the function-names mentioned, setting
          the level of output to level. level is a number between 0 (the
          least amount of debugging info) and 10 (the maximum amount of
          debugging info).
          
          The output is placed into the Meta-HTML internal debugger
          buffer, and can be placed into an output page by simply placing
          the tag <DEBUGGING-OUTPUT> somewhere in the page, or can be
          explicity retrieved using <debugging-output retrieve>.
          
   Simple Tag: debugging-output &optional [action...]
          Meta-HTML stores debugging information in an internal buffer.
          You may directly place information into this buffer using the
          page-debug command, and you may retrieve or clear this buffer
          using <debugging-output>.
          
          Possible values for action are:
          
          + retrieve
            Inserts the current contents of the debugging buffer into the
            page at the current location.
          + clear
            Empties the debugging buffer of all stored information.
            
          If you place <debugging-output> into your page without passing
          any arguments, Meta-HTML treats this invocation specially; it
          marks the location at which any debugging statements which have
          been collected during the processing of the entire page should
          be placed.
          
          We recommend that you always place this tag somewhere in the
          output page, whenever that output is an HTML document, as
          opposed to a standalone script.
          
   Simple Tag: function-def function-name...
          Get the body of the macro, verbatim.
          
   Simple Tag: page-debug &rest body
          Cause body to be inserted into the debugger output.
          
          The output is placed into the Meta-HTML internal debugger
          buffer, and can be placed into an output page by simply placing
          the tag <DEBUGGING-OUTPUT> somewhere in the page, or can be
          explicity retrieved using <debugging-output retrieve>.
          
   Simple Tag: system-error-output &optional [action...]
          Meta-HTML stores system error information in an internal
          buffer. Such information may be the results of an error which
          occurred during the execution of an external command (such as
          with cgi-exec), or other information which is generated by the
          inability of Meta-HTML to access a particular file (such as
          with the require command).
          
          You may retrieve or clear this buffer using
          <system-error-output>.
          
          Possible values for action are:
          
          + retrieve
            Inserts the current contents of the system error buffer into
            the page at the current location.
          + clear
            Empties the system error buffer of all stored information.
            
          If you place <system-error-output> into your page without
          passing any arguments, Meta-HTML treats this invocation
          specially; it marks the location at which any system errors
          which have been collected during the processing of the entire
          page should be placed.
          
          We recommend that you always place this tag somewhere in the
          output page, whenever that output is an HTML document, as
          opposed to a standalone script.
          
Code Profiling

   The profiler module allows you to get a detailed listing of the number
   of times a particular function has executed, the amount of time spent
   within each function, and other information which can help you to tune
   your Meta-HTML application, and get it running as fast as possible.
   
   The use of this module is trivial. First, place
<set-var mhtml::profile-functions = true>

   at the top of the page that you would like to profile.
   
   At the bottom of the page, after the last normal instruction, place
<profiler::dump /tmp/meta.prof>

   After visiting the page in a browser, the file /tmp/meta.prog will
   contain a human readable dump of the profile information. Your page
   won't perceptibly slow down during loading -- the only indication that
   profiling is on is the creation of the output file that you specify.
   
   Simple Tag: profiler::dump filename &key [sort=[names|times|calls]]
          Write profiling information to filename. Unlike C profilers,
          the output is quite self-explanatory.
          
          Known bugs: The total time doesn't really correctly reflect the
          amount of time spent processing the entire page -- the time
          displayed is additive, so it is always orders of magnitude
          larger than it should be. However, the time displayed for each
          function call is correct.
          
                          Defined Meta-HTML Variables
                                       
   Variable: mhtml::decimal-places
          Controls the number of decimal places which arithmetic
          functions produce. The default value of this variable is 2, but
          for times when you need greater resolution in your
          calculations, you may wish to set it higher.
          
<set-var mhtml::decimal-places = 10>
To 10 places: <div 1 .34567>
<unset-var mhtml::decimal-places>
To  2 places: <div 1 .34567>

          produces
          
To 10 places: 2.8929325657

To  2 places: 2.89

   Variable: mhtml::inhibit-comment-parsing
          When this variable is set to a non-empty value, the triple
          semi-colon comment feature is disabled.
          
          You may need this for complex applications where you are
          deliberately shipping the source of a Meta-HTML document to the
          client.
          
   Variable: mhtml::iteration-limit
          The use of this variable has been deprecated. while loops last
          until either the test-clause is met, or a break statement is
          seen.
          
   Variable: mhtml::version
          Contains the version identification of the currently running
          interpreter. This variable is available whereever the
          interpreter is running, including the Meta-HTML server, Engine,
          and in mdb.
          
<get-var mhtml::version>

          produces
          
5.09

                                Function Index
                                       
a

     add
     alist-defvar
     alist-get-var
     alist-package-delete
     alist-package-names
     alist-set-var
     alist-to-package
     alist-unset-var
     alist-var-exists
     alist?
     and
     array-add-unique
     array-append
     array-concat
     array-member
     array-shift
     array-size
       
b

     break
       
c

     capitalize
     char-offsets
     coerce-var
     comment
     concat
     copy-var
       
d

     debugging-on
     debugging-output
     decrement
     define-container
     define-function
     define-tag
     defmacro
     defsubst
     defun
     defvar
     defweakmacro
     directory-contents
     div
     downcase
       
e

     eq
       
f

     file-exists
     foreach
     function-def
       
g

     get-file-properties
     get-var
     get-var-once
     group
     gt
       
i

     if
     ifeq
     ifneq
     in-package
     increment
     integer?
       
l

     lt
       
m

     match
     max
     min
     mod
     mul
       
n

     neq
     not
       
o

     or
       
p

     package-delete
     package-names
     package-to-alist
     package-vars
     page-debug
     plain-text
     profiler::dump
     prog
       
r

     real?
     return
       
s

     set-output-radix
     set-var
     set-var-readonly
     set-var-verbatim
     sort
     string-compare
     string-eq
     string-length
     string-neq
     sub
     subst-in-string
     subst-in-var
     substring
     symbol-info
     system-error-output
       
u

     undef
     unset-var
     upcase
       
v

     var-case
     var-exists
       
w

     when
     while
     with
     with-local-package
     _________________________________________________________________
   
   This document was generated on 5 July 1999 using the texi2html
   translator version 1.54.
