The programmatic interface is a collection of Common Lisp macros designed to make embedding HTML in lisp code easy. It was created with the following goals in mind:
- The code for creating HTML should look and act like regular lisp code.
- Given what we know about HTML and the ratio of static to dynamic text in a typical web page it's important to constant fold as much as possible.
- Tags should be easily definable and should be able to perform arbitrary computations at both run time and compile time.
You use YACLML tags just like regular macros, any attributes are passed in like keyword arguments. YACLML examines its args (at compile time) and distinguishes between the keyword arguments which become attributes and everything else, which becomes the tag's body. Tags all have the following syntax:
( tag-name [ :keyword value ] * . body )
The name of the attribute will be the result of string-downcase'ing the symbol-name specified in the macro. Depending on the runtime value returned executing the value specified in the macro call three things can happen:
NIL - The attribute will be ignored
T - The attribute will be printed with (string-downcase name) as the value.
anything else - The result of evaluating the value will be printed (via PRINC) as the value of the attribute.
If the need ever arises to have an HTML attribute whose value is T or NIL it is necessary to return the string \"T\" or \"NIL\" and not the symbol T or NIL.
Every element of the tag body is processed in order: if it is a form it is executed at runtime and must explicitly print to the stream *yaclml-stream* if it needs to generate output, if it is a string its value will be printed to *yaclml-stream* at run time.
;; Assuming *yaclml-stream* is bound to *standard-output*
(<:a :href \"http://foo.com\" \"foo.com\") => <a href=\"http://foo.com\">foo.com</a>
(<:br) => <br/>
(<:td \"whatever\") => <td>whatever</td>
Variable *YACLML-STREAM* The stream to which tags are printed.
Variable *YACLML-INDENT* When T (must be set while compiling yaclml code) the generated HTML is indented.
Macro WITH-YACLML-STREAM Evaluate BODY with *yaclml-stream* bound to STREAM.
Macro WITH-YACLML-OUTPUT-TO-STRING Evaluate BODY with *yaclml-stream* bound to a string stream, return the string.
Variable %YACLML-CODE% The list of currently collected code this yaclml macro should expand into.
Variable *EXPANDERS* Hash table mapping expanders to the expander function.
Variable *EXPANDER-MACROS* Hash table mapping expander macros to theri macre functions.
Function YACLML-CONSTANT-P Returns T if THING is, as far as yaclml is concerned, a run time constant.
Function EMIT-PRINC Emit to the current yaclml-code a form which will, at runtime, princ ITEM.
Function EMIT-HTML Like EMIT-PRINC but escapes html chars in item.
Function EMIT-CODE Emit to the current yaclml-code CODE.
Function EMIT-PRINC-ATTRIBUTES Assuming attributes is a list of (name1 value1 name2 value2 .
Function EMIT-OPEN-TAG Emit the code required to print an open tag whose name is NAME and with the attributes ATTRIBUTES.
Function EMIT-CLOSE-TAG Emit the code required to print a close tag whose name is NAME.
Function EMIT-EMPTY-TAG Emit the code required to print an empty tag with name NAME and a attributes ATTRIBUTES.
Function EMIT-BODY Traverse body and emit the corresponding code.
Function EMIT-FORM Emits the code to print FORM.
Macro DEFTAG Define a new tag.
Macro DEFTAG-MACRO Define a new YACLML tag macro.
Macro DEF-SIMPLE-XTAG Convience macro for defing tags which accept any kind of attribute and just wrap the body in an xml tag.
Macro ENABLE-XML-SYNTAX Enable xml reader syntax for the file being compiled or loaded.
Function XML-READER-OPEN Emit XML elements into *yaclml-stream*, use keyword parameters for attributes and rest parameters for nested XML elements or normal lisp code.