
  The Meta-HTML Reference Manual
  Brian J. Fox, Universal Access Inc.

  Stripped down version for documenting just the 
  functionality used in WML pass 2 (wml_p2_mhc)
  Ralf S. Engelschall

  ---------------------------------------------------------------------------

  This document describes the Meta-HTML Programming Language, a language
  specifically designed for writing applications for the World Wide Web.

  Published by Universal Access Inc.
  129 El Paseo Court
  Santa Barbara, CA 93101 USA

  Permission is granted to make and distribute verbatim copies of this manual
  provided the copyright notice and this permission notice are preserved on
  all copies.

  Permission is granted to copy and distribute modified versions of this
  manual under the conditions for verbatim copying, provided that the entire
  resulting derived work is distributed under the terms of a permission
  notice identical to this one.

  Permission is granted to copy and distribute translations of this manual
  into another language, under the above conditions for modified versions,
  except that this permission notice may be stated in a translation approved
  by Universal Access Inc.

  Copyright (C) 1995, Brian J. Fox, Universal Access Inc.
  Copyright (C) 1996, Universal Access Inc.

  Welcome To Meta-HTML

  This document describes the Meta-HTML language, Version 5.0. It should not
  be considered a definitive reference manual by any means, as the target
  remains somewhat mobile. While the functions described in this manual will
  continue to operate as documented, there may be new functions or
  enhancements which supersede the functionality that the documented ones
  provide.

  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 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.

  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
  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 section of this manual documents those
  variables fully, while the Server Variables section contains more
  information on variables which control, or were specifically created by,
  the web server.

  Simple Tag: cgi-decode string [package]

       Decode string into package.

       If package is not specified the current package is used.

       STRING is a string that might have appeared in QUERY_STRING or the
       contents of the data that was posted to a document, such that it
       consists of name value pairs:

       FOO=bar&STRING=this+is+a+string%2C+other+chars

       PACKAGE is the name of a package to bind the variables in. So, given
       the above example as the text in a variable called STRING, here is
       what you get:

       <set-var string="FOO=bar&STRING=a+string%2C+other+chars">
       <cgi-decode <get-var string> mypack>
       <get-var mypack::string>

       produces

       a string, other chars

       Also see cgi-encode.

  Simple Tag: cgi-encode var1 [var2...]

       A CGI readable string is created from the names of var1 ... varn and
       the associated values of those variables. For example, if the variable
       FOO-VAR has the value "Foo & Value", then the invocation

       <cgi-encode FOO-VAR>

       produces

       FOO-VAR=Foo+%26+Value

  Simple Tag: coerce-var varname [type=(STRING|BINARY)]

       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.

       Just write it as a defmacro.

  Simple Tag: var-case [name=value] [consequent]

       For each "name=value" pair, the value of name is looked up in the
       current package, and compared with value of value. If they are equal,
       then consequent is evaluated, and no further cases are checked.

  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.

  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.

  Simple Tag: %%eval [expression]

       Internal function which performs evaluation.

       If you think that you need this in your program, you probably are
       doing something wrong.

  Simple Tag: %%read [expression]

       Internal function which performs Meta-HTML reading.

       If you think that you need this in your program, you probably are
       doing something wrong.

  Simple Tag: concat [arg1] [...] [argn]

       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: date [epoch-seconds]

       Returns the local date as a string of 24 characters.

       The output looks like Tue Feb 18 09:31:11 1997.

       Given the optional argument epoch-seconds, this number is treated as
       the number of seconds since 12 midnight, December 31st, 1969, and is
       converted into the current date.

       Also see the time function.

  Simple Tag: debugging-on [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.

  Simple Tag: DEBUGGING-OUTPUT

       By placing the <DEBUGGING-OUTPUT> tag somewhere in the page, you mark
       the location at which the Meta-HTML engine, server, or standalone
       processer should place any debugging statements which have been
       collected during the processing of the statements in the current page.

       Without the presence of this tag, no debugging information will be
       displayed as part of the final output.

       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 name

       Returns the Meta-HTML readable form of the function body stored in the
       user-defined function name.

       User-defined functions are made using defmacro,
       defsubst, or defun.

  Simple Tag: page-debug body

       Cause body to be inserted into the debugger output.

       This output shows up as the result of placing the special tag
       <DEBUGGING-OUTPUT> somewhere in the page.

  Simple Tag: pid

       Returns the current process ID on those systems which have process
       ID's.

  Simple Tag: prog code...

       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.

       For example:

       <if <eq this that>
          <prog <h2> This is equal to That </h2>>
         <prog <h2> This is not equal to That </h2>>>

       Although prog is a primitive in Meta-HTML, it could have been defined
       as:

       <defsubst prog>%body</defsubst>

  Simple Tag: symbol-info symbol

       Returns information about the symbol symbol.

       The information is two lines:

         1. The type of the symbol, either STRING, BINARY, or FUNCTION.
         2. 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: SYSTEM-ERROR-OUTPUT

       By placing the <SYSTEM-ERROR-OUTPUT> tag somewhere in the page, you
       mark the location at which the Meta-HTML engine, server, or standalone
       processer should place any error statements which have been collected
       during the processing of the statements in the current page.

       Without the presence of this tag, no system error information will be
       displayed as part of the final output.

       We recommend that you place this tag somewhere in the page while you
       are building and testing your application, or, if you are having
       confusing behavior from an existing application.

       Commands which manipulate files may place information about the
       underlying cause of the error condition here.

  Simple Tag: time

       Returns the current local time, as measured in seconds since the epoch
       (12 midnight, December 31, 1969).

       This is often useful as input to the date operator. Here is how
       one might find out the printable date for the time 10 hours from now.

          <date> ==> Wed Jul  3 17:14:53 1996
          <date <add <time> <mul 60 <mul 10 60>>>>
                 ==> Thu Jul  4 03:14:57 1996

  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: base64decode string

       Performs the translation operation commonly known as Base64 Decoding
       on STRING, and returns the results of that decoding.

       Base64 encoding is a common transfer encoding for binary data and for
       Basic Authorization values -- this function can be used to turn such
       strings into their original, pre-encoded state.

       <set-var the-data = "YmZveDpmcm9ibml0eg==">
       <base64decode <get-var the-data>>

       produces

       bfox:frobnitz

  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: 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

       Also see upcase, and capitalize.

  Simple Tag: match string regexp
  [action=(report|delete|extract|startpos|endpos|length)]

       Matches regexp against string and then performs action. The default
       action is report; when the expression matches the string match returns
       the text true.

       Here are some 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]*">             ==> ""

  Simple Tag: pad string total-size [align=(right|left|middle)] [truncate]

       Pads string to a length of total-size. align can be one of LEFT,
       MIDDLE, or RIGHT (the default).

       PAD inserts the correct number of spaces to make the input argument
       take the desired number of spaces (presumably for use in a <pre> ...
       </pre> statement).

       The optional arg TRUNCATE says to force the string to be the specified
       length.

       Before any padding is done, leading and trailing whitespace is removed
       from string.

       Examples:

         <pad "Hello" 10>              ==> "     Hello"
         <pad "Hello" 10 align=left>   ==> "Hello     "
         <pad "Hello" 10 align=middle> ==> "  Hello   "
         <pad "  Heckle  " 4 truncate> ==> "Heck"

  Complex Tag: plain-text [first-char=expr] [nobr=true]

       Performs the following steps:

            - Replace occurrences of pairs of newline characters with a
              single <P> tag. 
            - 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: small-caps [upper=size] [lower=size] [other=size]

       Modify the characters in body raising lower-case characters to
       upper-case, and changing the size of fonts as directed. For example,
       this is how "HELLO THERE" can be produced:

         <small-caps lower=-1>Hello There</small-caps>

  Simple Tag: string-eq string1 string2 [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: subst-in-string string regexp replacement [regexp]
  [replacement] [...]

       Replaces all occurrences of regexp with replacement in string.

       regexp can be any regular expression allowed by POSIX extended regular
       expression matching.

          <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: substring string 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.

  Simple Tag: upcase string

       Converts all of the lowercase characters in string to uppercase.

       <upcase "This is a list">

       produces

       THIS IS A LIST

       Also see downcase and capitalize.

  Simple Tag: word-wrap string [width=charwidth]

       Produce paragraphs of text from the string string with the text filled
       to a width of charwidth.

       This is provided for convenience only, and is of use when you need to
       present some free form text in pre-formatted fashion, such as when
       sending an E-mail message, or the like.

  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

       Returns the sum of arg1 and arg2.

  Simple Tag: decrement varname [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: div arg1 arg2

       Returns the quotient of arg1 and arg2.

           <div 12 2> ==> 6
           <div 10 3> ==> 3

  Simple Tag: increment varname [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: mod arg1 arg2

       Returns the remainder of arg1 and arg2.

           <mod 12 2> ==> 0
           <mod 10 3> ==> 1

  Simple Tag: mul arg1 arg2

       Returns the product of arg1 and arg2.

           <mul 12 2> ==> 24

  Simple Tag: random [arg]

       Returns a pseudo-random number between 0 and arg -1. The distribution
       is pretty good; calling <random 2> returns 0 50% of the time, and 1
       the other 50%.

       Also see randomize.

  Simple Tag: randomize [arg]

       Sets the pseudo-random number generator seed to arg. The next call to
       random uses this seed value to find the next pseudo-random number.
       There is no return value.

           <randomize 10>
           <random 100> ==> 28
           <random 100> ==> 15
           <randomize 10>
           <random 100> ==> 28

  Simple Tag: sub arg1 arg2

       Returns the difference of arg1 and arg2.

           <sub 12 2> ==> 10

  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
  Arithmetic Operators cover those in detail.

  Simple Tag: and expr [...]

       Evaluates the exprs until one of them results in the empty string, or
       they are all exhausted.

       The result of this expression is the last value evaluated.

  Simple Tag: eq arg1 arg2

       Returns the string "true" when the number value of arg1 is equal to
       the number value of arg2.

  Simple Tag: gt arg1 arg2

       Returns the string "true" when the numeric value of arg-1 is greater
       than the numeric value of arg-2.

  Simple Tag: lt arg1 arg2

       Returns the string "true" when the numeric value of arg-1 is less than
       the numeric value of arg-2.

  Simple Tag: not [body]

       body is evaluated. If the result is the empty string, then the string
       "true" is returned, otherwise, nothing is returned. The body is simply
       the entire contents of the simple tag, without the word "not" in it.
       Thus, in typical usage, one might write:

         <when <not <get-var foo>>>
            <comment> Complain that FOO is missing. </comment>
         </when>

  Simple Tag: or expr [...]

       Evaluates the exprs until one of them results in a non-empty value, or
       they are all exhausted.

       The result of this expression is the last value evaluated.

  Input and Output

  File Operators

  There are several types of commands in Meta-HTML for dealing with files.

  The functions allow you to include the contents of, open, create,
  read, or write various data sources, or to replace the contents of 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.

  Also see Stream Operators.

  Simple Tag: directory-contents path [package-name] [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 path, and the value of each variable is the
       association list for that file.

  Simple Tag: get-file-properties path

       Return an association-list containing operating system information
       about the file or directory named by path. path 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: Member Value
       Description

       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 get-file-properties.

       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 The date on which this file was created. The
       value is an array, with ordered values being: month, day, year, hours,
       minutes, and seconds.

       WRITTEN 6 29 96 10 3 24 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.

       READ 6 30 96 19 27 51 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.

       CREATOR bfox The system identifier of the user who created this file.

  Simple Tag: include filename [alt=code] [verbatim]

       Insert the contents of the file named by filename into the document at
       the point where the include form was read. If the positional argument
       verbatim is given, then the contents of the file are not executed,
       only inserted. Otherwise, execution resumes at the point where the
       file was inserted.

       filename can be given as an absolute pathname, or a relative pathname.
       If the path is relative, it is considered to be relative to the
       location of the document which contains the include form. If the path
       given is not relative, it is appended to the directory found in
       MHTML::INCLUDE-PREFIX.

       If the named file could not be found on the server, and an alt value
       is given, then that value is placed into the page instead.

  Simple Tag: require stem

       require tries hard to locate the source or library file specified by
       stem, and then loads that file if it hasn't already been loaded.

       If the variable mhtml::require-directories is present, then it is an
       array of directory names (without trailing slashes) relative to Web
       space that should be searched through, in the order that they appear
       in the array.

       require understands the following extensions:

          o .mhtml, or .src: A Meta-HTML source file.
          o .lib: A Meta-HTML library file.

       require loads the newest version of the file that it finds, and
       records the complete pathname of the loaded file in the array variable
       mhtml::require-loaded.

  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.

  Complex Tag: define-container name [named-parameter...]
  [package=package-name] [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 [named-parameter...] [package=packname]

       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 [named-parameter...] [package=package-name]
  [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 [named-parameter...] [package=package-name]
  [whitespace=delete]

       A synonym for define-container.

  Complex Tag: defsubst name [named-parameter...] [package=package-name]
  [whitespace=delete]

       A synonym for define-tag.

  Complex Tag: defun name [named-parameter...] [package=packname]

       A synonym for define-function.

  Simple Tag: undef 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.

  Managing the Page

  Page Operators

  Meta-HTML contains a few commands which operate on the entire page as it
  currently exists.

  You may find, modify, or delete text which has already been looked at by
  the interpreter, as well as text which hasn't yet been looked at.

  Most of the time, you won't need to use such commands. They can make it
  hard for other people to understand the sequence of code in your page, and
  they can sometimes produce unexpected results which are difficult to debug
  because much of the information has been modified.

  Simple Tag: page-insert offset content

       Insert content directly into the current page at the offset specified
       by offset.

       In most cases, there is never any need to do this. For some very
       strange situations involving direct communication with both the Web
       server, and the connecting client, it is conceivably possible that you
       would use this command.

       But I doubt it.

  Simple Tag: page-search start-offset regex [end]

       Returns a number representing the number of characters from the start
       of the current page that regex appears. If start-offset is not zero,
       then the search starts from that many characters from the beginning of
       the page.

       The optional argument end says to return the position of the last
       character which matched regex, instead of the first.

       Why would you use this?

  Simple Tag: replace-page filename [alt=code]

       Replace the entire contents of the current page with the contents of
       the file named by filename. You probably don't want to use this
       command, use redirect instead. In that way, the URLs give a
       consistent view to the user. The rules for which file is chosen are
       identical to those for include.

  Simple Tag: subst-in-page this with-that

       Replaces all occurrences of this with with-that in the current page.
       Both this and with-that are evaluated before the replacement is done.
       this can be any regular expression allowed by the POSIX extended
       regular expression matching.

       This command can be useful when included as part of a footer include
       file. For example, you could replace all occurrences of %name% with a
       the value of the variable FirstName by writing:

         <subst-in-page %name% <get-var forms::FirstName>>

  Block Commands

  The block commands operate on a specific area of the page, and tend to
  manipulate the interpreter pointer position as a result. These commands
  differ from the commands in the <section-ref pages> section of this manual
  because their scope is limited only to the block of statements that they
  surround.

  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.

  Complex Tag: verbatim [quote]

       Insert body verbatim, avoiding doing any processing on the contents.
       If the positional argument QUOTE is given, occurrences of characters
       with special meaning to HTML are replaced with the HTML code to
       produce that character in the output page.

       Contrast this with comment.


  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>
           9 / 3.0 = <div 9 3.0>
          10 / 3.0 = <div 10 3.0>
           9 / 3   = <div 9 3>
          10 / 3   = <div 10 3>
           <unset-var mhtml::decimal-places>
           9 / 3.0 = <div 9 3.0>
          10 / 3.0 = <div 10 3.0>
           9 / 3   = <div 9 3>
          10 / 3   = <div 10 3>

       produces

           9 / 3.0 = 3.0000000000
          10 / 3.0 = 3.3333333333
           9 / 3   = 3.0000000000
          10 / 3   = 3.3333333333

           9 / 3.0 = 3.00
          10 / 3.0 = 3.33
           9 / 3   = 3
          10 / 3   = 3

  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.02

