Section Intro:
Macro Commands
Macro CommandsSynopsis:
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. Commands:
More Information:
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! <define-container NAME &optional [NAMED-PARAMETERS] &key [PACKAGE=PACKNAME] [WHITESPACE=DELETE] body </define-container> | Complex |
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. <define-function NAME &optional [NAMED-PARAMETERS] &key [PACKAGE=PACKNAME] [WHITESPACE=DELETE] body </define-function> | Complex |
Define NAME as a simple tag.
The only differences between define-function
and define-tag are:
- The whitespace=delete option is assumed.
- The NAMED-PARAMETERs are evaluated in the context of the
caller, not of the definition of the defun.
- 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<define-tag NAME &optional [NAMED-PARAMETERS] &key [PACKAGE=PACKNAME] [WHITESPACE=DELETE] body </define-tag> | Complex |
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.
Returns "true" if NAME is defined as a Meta-HTML primitive or
a user-defined function, or the empty string otherwise.
<defmacro NAME &optional [NAMED-PARAMETERS] &key [PACKAGE=PACKNAME] [WHITESPACE=DELETE] body </defmacro> | Complex |
<defsubst NAME &optional [NAMED-PARAMETERS] &key [PACKAGE=PACKNAME] [WHITESPACE=DELETE] body </defsubst> | Complex |
<defun NAME &optional [NAMED-PARAMETERS] &key [PACKAGE=PACKNAME] [WHITESPACE=DELETE] body </defun> | Complex |
<defweakmacro NAME &optional [NAMED-PARAMETERS] &key [PACKAGE=PACKNAME] [WHITESPACE=DELETE] body </defweakmacro> | Complex |
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>
Returns "true" if NAME is defined as a Meta-HTML primitive, or
the empty string otherwise.
<undef &optional [NAME...] | Simple |
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. <user-function? NAME | Simple |
Returns "true" if NAME is defined as a user function, or
the empty string otherwise.
Edit Section
Function Index
Variable Index

The
META-HTML
Reference Manual V2.0
Copyright © 1995, 1998,
Brian J. Fox
Found a bug? Send mail to
bug-manual@metahtml.org
|