This is a rough manual/tutorial thing for "html.ss".

Contents:

  1. General
  2. Scheme extensions
  2.1. Lisp-like self-evaluating keywords
  2.2. Extended function arguments
  2.3. Convenient list syntax
  2.4. General functions and macros
  3. HTML generation
  3.1. General value producing
  3.2. Quoting -- Scheme and HTML output
  3.3. Global variables
  3.4. Text processing
  3.5. Output and formatting tags
  3.6. Tags, wrappers, and attributes
  3.7. Predefined tags and wrappers
  4. Making it work
  4.1. General Scripting
  4.2. Script setup for "html.ss"
  4.3. Creating HTML files


========================================================================
1. General

This is the documentation for "html.ss", a module I wrote to produce
HTML code using Scheme (specific to MzScheme).  This project was born as
a quick hack to create my home page files, and grew into a much larger
system, which was later incorporated into my Scheme Web Server as well.
Its goals are to produce HTML easily and elegantly, so that even the
HTML code generated is readable.

You should use this thing if you want to produce a lot of HTML output in
a uniform way, and have a relatively easy time maintaining it.  However,
the price which is paid to achieve this goal, is that you should know
how to program well.  This means that if you want a quick HTML page, or
if you don't know/want/like programming, then this is probably the wrong
solution.  One thing to bear in mind is that a project can begin its
life using this and at some point, it can continue by editing the HTML
output (and suffer the usual price this implies).  The goal of having
readable HTML output is not only for having an elegant output, but for
making such a conversion easy since this output is human-readable.

I'm assuming general knowledge of Scheme, MzScheme and HTML.
Documentations can be found on the PLT sites (http://www.drscheme.org/),

* The Revised Scheme Report:
  http://download.plt-scheme.org/doc/mzscheme/

* MzScheme: http://www.plt-scheme.org/

Also, good HTML reference can be found at:
  http://www.idocs.com/tags/

To use this thing, all you need to do is download and install the PLT
file at http://www.barzilay.org/Swindle/, and load the module with:
  (require (lib "html.ss" "swindle"))
This document is not complete, nor does it attempts to be -- the
ultimate documentation is, as usually with all open-source projects, the
code itself.  But there are more convenient ways to write scripts as
explained below.

If you have any more comments, questions, suggestions or bug reports,
mail eli@barzilay.org.


========================================================================
2. Scheme extensions

There are several extensions to Scheme that "html.ss" provides and uses.
Again, this comes on top of MzScheme which has its own extensions on top
of the Scheme standard.  Note also, that "html.ss" does a
`(read-case-sensitive #t)', so all Scheme code which uses it is
case-sensitive.


------------------------------------------------------------------------
2.1. Lisp-like self-evaluating keywords

As in Lisp, symbols that begin with a `:' evaluate to themselves.  This
is used for keyword function arguments, including functions that
generate HTML tags, where arbitrary keyword/values can be specified and
will be used as attributes and values for the HTML tag.


------------------------------------------------------------------------
2.2. Extended function arguments

Function arguments (both for `define' and `lambda' expressions (named
and anonymous functions)) are extended considerably:

* A function can have nested parens to indicate currying.  This is
  useful for functions that will swallow some arguments and output a
  function to be used later.
   +----------
   |> (define ((plus x) y) (+ x y))
   |> (plus 1)
   |#<procedure:plus:1>
   |> ((plus 1) 2)
   |3
   +----------

* `&optional' indicates optional arguments, as in Lisp.  They can also
  contain default values:
   +----------
   |> (define (foo x &optional y) (list 'x= x 'y= y))
   |> (foo 1)
   |(x= 1 y= #f)
   |> ((lambda (x &optional y) (list 'x= x 'y= y)) 1)
   |(x= 1 y= #f)
   |> (foo 1 2)
   |(x= 1 y= 2)
   |> (define (foo x &optional (y 3)) (list 'x= x 'y= y))
   |> (foo 1)
   |(x= 1 y= 3)
   |> (foo 1 2)
   |(x= 1 y= 2)
   |> (define (foo x &optional (y (* x 2))) (list 'x= x 'y= y))
   |> (foo 12)
   |(x= 12 y= 24)
   +----------

* `&keys' behaves like Lisp's `&key' (for compatibility, `&key' does the
  same), and is used to define arguments that are assigned by labeled
  keywords.  Default values and different names are possible too.  Note
  that no extensive error checking is done (like checking that the
  keyword list is balanced, or that it uses only keywords), so watch for
  sneaky bugs.
   +----------
   |> (define (foo x &keys y z) (list 'x= x 'y= y 'z= z))
   |> (foo 1)
   |(x= 1 y= #f z= #f)
   |> (foo 1 :z 2)
   |(x= 1 y= #f z= 2)
   |> (foo 1 :z 2 :y 1)
   |(x= 1 y= 1 z= 2)
   |> (foo 1 :y 1 :y 2 :y 3)
   |(x= 1 y= 1 z= #f)
   |> (define (foo x &keys (y 'yyy)) (list 'x= x 'y= y))
   |> (foo 1)
   |(x= 1 y= yyy)
   |> (foo 1 :y 2)
   |(x= 1 y= 2)
   |> (define (foo x &keys (y :foo 'yyy)) (list 'x= x 'y= y))
   |> (foo 1 :foo 2)
   |(x= 1 y= 2)
   |> ((lambda (&keys x y) (list x y)) :y 1 :x 2)
   |(2 1)
   +----------
  Keywords are an important feature for this system, since it allows
  modifying a function so it is more generalized without affecting
  previous places that use it.

* `&rest' indicates an argument that holds unprocessed values for the
  function call.  This is mainly for completeness with Lisp's syntax,
  since it is the same as using Scheme's dot notation.
   +----------
   |> (define (foo x &optional y &rest r) (list 'x= x 'y= y 'r= r))
   |> (foo 1)
   |(x= 1 y= #f r= ())
   |> (foo 1 2)
   |(x= 1 y= 2 r= ())
   |> (foo 1 2 3)
   |(x= 1 y= 2 r= (3))
   |> (foo 1 2 3 4)
   |(x= 1 y= 2 r= (3 4))
   +----------

* There are two additional options that are related to `&rest':
  - `&body' is like `&rest' without all keyword/values;
  - `&rest-keys' is like `&rest' without all keyword/values for the
    specified `&keys'.
   +----------
   |> ((lambda (&keys x y &rest r &rest-keys r1 &body r2)
   |     (list x y r r1 r2))
   |   :x 2 :z 2 3)
   |(2 #f (:x 2 :z 2 3) (:z 2 3) (3))
   +----------
  Note that this is different than Lisp, where `&body' is the same as
  `&rest'.


------------------------------------------------------------------------
2.3. Convenient list and strings syntax

Since lists are useful as a way to concatenate output elements (see
below), there is a convenient notation for them -- just use an infix
`:'.  It can also be used inside quotes and quasiquotes.  Note that it
cannot touch an identifier because it will get parsed as part of that
identifier.
   +----------
   |> (begin 1 : 2)
   |(1 2)
   |> (let ((x 12)) "var foo = "(+ x 1))
   |13
   |> (let ((x 12)) "var foo = ":(+ x 1))
   |("var foo = " 13)
   |> (let ((x 12)) "var foo = ":x)
   |:x
   |> (let ((x 12)) '("var foo = ":(+ x 1):"z"))
   |(("var foo = " (+ x 1) "z"))
   |> (let ((x 12)) '("{" "var foo = ":(+ x 1):"z" "}"))
   |("{" ("var foo = " (+ x 1) "z") "}")
   +----------
Notes: I have wrapped examples in a form since if you enter "1 : 2" then
MzScheme's evaluator will read the input item by item instead of using
the colon preprocessor.  Also note that the last form returned `:x'
because the colon was attached to the identifier, making it a keyword
which is the result of the whole form.

Also, strings as arguments are common, so there is another shortcut
syntax: if a string has a `_' on both sides, its contents is split on
newlines and the result substitutes the original.
   +----------
   |> (list _""_)
   |("")
   |> (list _"eli"_)
   |("eli")
   |> (list _"eli
   |          barzilay"_)
   |("eli" "barzilay")
   |> (list _"
   |          eli
   |          
   |          barzilay
   |          "_)
   |("eli" "" "barzilay")
   |> '(big: _"
   |          eli
   |          
   |          barzilay
   |          "_)
   |(big: "eli" "" "barzilay")
   |> (output-html (big: _"
   |                       eli
   |                       
   |                       barzilay
   |                       "_))
   |<big>eli  barzilay</big>
   +----------
The same notes above apply here too.

------------------------------------------------------------------------
2.4. General functions and macros

(getarg plist key [default])
  Given a keyword/value list (a Lisp "plist"), and a key, it returns the
  value associated with that key (or, if not found, it returns its third
  argument supplied as a default value, or #f if omitted)
   +----------
   |> (getarg '(1 11 2 22 3 33 444) 2)
   |22
   |> (getarg '(1 11 2 22 3 33 444) 4)
   |#f
   |> (getarg '(1 11 2 22 3 33 444) 4 "FOO")
   |"FOO"
   |> (getarg '(1 11 2 22 3 33 444) 4 (delay "FOO"))
   |"FOO"
   |> (getarg '(1 11 2 22 3 33 444) 4 (thunk "FOO"))
   |"FOO"
   +----------
  This is not something that should be used frequently, since usually
  you would use `&keys' to pull out keyword arguments.

(eprintf format-str args...)
  A function that can be used like MzScheme's `printf', except it
  outputs stuff on the standard error port, so you can use this for
  debugging.  This is useful because during HTML generation, standard
  output is post-processed (and probably going away to a file).

(defmacro (foo ...) ...)
  Is a macro that generates macro bindings in a simple Lisp-like way.
  The difference from Lisp is that the argument list contains the
  identifier as in Scheme functions, unlike Lisp's definitions.

(maptree func tree)
  Similar to `map', but descends down into lists and pairs.

(mappend func list...)
  Performs a normal `map' and appends the results.

(mapply func list)
  Performs a `map' by applying the given function over argument lists in
  the given list.

(thunk ...)
  A macro that has some forms in its body like Scheme's `begin', and
  will generate an argument-less function that evaluates the body when
  called.  This can be used to defer evaluation, but note that Scheme
  promises are handled as well (using `delay' and `force').


========================================================================
3. HTML generation

The `output-html' function outputs the HTML code generated by its
arguments.  To try things out, simply run mzscheme and type
  (require (lib "html.ss" "swindle"))
Do all this in Emacs for more convenience.  Another option is to write a
quick script that will do it, see below for ways to do this.

The main function to try things out is `output-html' which is the one
used to produce HTML output.  Another function that might be useful in
some cases is `output'.  This is the internal function that is used to
output text, except that it doesn't do HTML quoting etc (which the above
does).

Note that all this is either for internal usage, debugging or
experimenting.  Other functions should be used to generate HTML files,
such as `make-html' etc, more later.


------------------------------------------------------------------------
3.1. General value producing

HTML values are almost any Scheme values.

* Simple values will just get printed out.  This includes values that
  don't fall under one of the categories below.
   +----------
   |> (output-html 1)
   |1
   |> (output-html 'foo)
   |foo
   |> (output-html "foo")
   |foo
   |> (output-html 0.10)
   |0.1
   |> (output-html (/ 4 3))
   |4/3
   +----------

* Lists are iterated over, general pairs get recursed too.
   +----------
   |> (output-html (list 1 'foo "foo" 0.10 (/ 4 3)))
   |1foofoo0.14/3
   |> (output-html (list 'foo (list 1 (cons 2 3) 4)))
   |foo1234
   |> (let ((f (lambda (x) "{": x :"}"))) (output-html (f 1):" ":(f 2)))
   |{1} {2}
   +----------
  The last example demonstrates usage of both a scheme function, and the
  list infix notation.  An exception for this are lists that represent
  HTML tags, which are lists that begin with a symbol that ends with a
  colon:
   +----------
   |> (output-html (list 'foo: :bar 1 "x" '(foo: "y")))
   |<foo bar="1">x <foo>y</foo></foo>
   +----------
  This is explained below.

* Functions are applied on no arguments, which means that only thunks
  should be used.  One note here -- the function is called with no
  arguments and then the value it returns is again passed to the output
  function, so a function can either print stuff, return stuff, or even
  both.
   +----------
   |> (output-html (lambda () 'foo))
   |foo
   |> (output-html (lambda () (output 'foo)))
   |foo
   |> (output-html (lambda () (output 'foo) 'bar))
   |foobar
   |> (output-html (lambda () (output "<") 123))
   |&lt;123
   |> (output (lambda () (output "<") 123))
   |<123
   +----------
  Note that the third expression will output "foo" and return a symbol
  which is then printed as it is the result of the function call.  The
  last two expressions demonstrates that using `output' is fine within
  HTML generating code, but when used outside the HTML processing
  context, the result is normal.

* Promises are forced -- this is not the place to describe promises, but
  as a quick reminder, (delay ...) is similar to an argument-less
  function, and `force' will evaluate the body and return its value
  (caching it for further `force's, which is the difference between a
  promise and a thunk).
   +----------
   |> (let ((x (delay (begin (output "foo!") 'x))))
   |    (output-html (list x x x)))
   |foo!xxx
   +----------

* Parameters output their values.  (Parameters are MzScheme's solution
  against using global values -- they are procedures that when applied
  on no arguments return the stored value, and when applied on a value,
  they set the stored value to it.  They are safer than globals since
  they work properly even in a multithreaded environment.)

* #f and MzScheme's `void' produces no output, which is useful for
  conditional expressions.
   +----------
   |> (output-html (list 'a (and (< 3 2) 2) 'b))
   |ab
   |> (output-html (list 'a (when (< 3 2) 2) 'b))
   |ab
   +----------

Allowing general functions is especially useful: it allows you to
include functions that will generate output by printing things.  This
can be used to create arbitrary output (but see the "Quoting" section
below).

When writing code that generate HTML, remember that this is still
standard Scheme, so while a function like `html:' will process all of
its arguments, it is different than Scheme's `begin' (you can use lists
instead).  For example:
   +----------
   |> (output-html (html: 1 2 3))
   |<html>
   |1
   |2
   |3
   |</html>
   |> (output-html (html: (lambda () 1 2 3)))
   |<html>
   |3
   |</html>
   |> (output-html (html: (lambda () (list 1 2 3))))
   |<html>
   |123
   |</html>
   |> (output-html (html: (lambda () 1 : 2 : 3)))
   |<html>
   |123
   |</html>
   +----------


------------------------------------------------------------------------
3.2. Quoting -- Scheme and HTML output

One thing to keep in mind, which tends to make things seem a bit
complicated, is that in Scheme strings, the backslash and double-quote
characters have special meanings.  A double-quote terminates a string
and a backslash is used to add the following character literally,
including backslash itself (note that in future versions of MzScheme,
more C-like backslash sequences will be included).  So, for example, the
scheme string "\"\\\"" contains a double-quote, a backslash, and another
double-quote.  As you can see, when combining Scheme with another system
that uses backslash as a special character, you get a bunch of fun
backslashes to play with.  So, just be careful, it's not as complicated
as it seems to be.

HTML output is done with an output post-processing context, so printing
special characters produces the correct HTML output.  Backslash can be
used to include the actual character, and it can be used to include a
literal backslash characters as well.
   +----------
   |> (output-html "<foo> & \"bar\"")
   |&lt;foo&gt; &amp; &quot;bar&quot;
   |> (output-html "\\<\\&\\>\\\\")
   |<&>\
   +----------
Character conversions are controlled by the value of the `html-quotes'
variable.

There are also some special characters that produce some special HTML
symbol as a result.  Currently, this list has space which generates an
HTML non-breakable space symbol, `C' (copywrite), `R'(trademark), `-'
(mdash), `<' and `>' (left and right angle quotes), `1', `2' and `3'
(superscript 1, 2 and 3), `*' (bullet).  Remember that you can always
quote the ampersand to insert any other element:
   +----------
   |> (output-html "\\ \\C\\R\\T\\*\\&foo;")
   |&nbsp;&copy;&reg;&trade;&bull;&foo;
   +----------
These are stored in the `html-specials' variables.  The default list is
likely to be augmented and changed.

Finally, there are two special strings that make a context where this
processing is disabled -- they are a NUL character (ASCII 0) followed by
a "{" to open the context and a "}" to close it.  In such a context,
which can be nested, HTML processing is disabled.  The choice of a NUL
character makes it impossible to have conflicts with input files and
user strings.  This construct can be made automatically with the
`::literal?' meta-keyword or the `literal:' function (see below).  In
(very) rare cases where the context should be controlled, you should use
the variables `literal-begin' and `literal-end' have these strings as
their values.

These constructs are used internally to make output of attributes and
their values, scripts and styles unprocessed.  There are some other
cases where they can be useful, like outputting raw HTML as part of
other code or from an external file, avoiding the standard
post-processing, as in the last line of the example below.

Examples:
   +----------
   |> (output-html literal-begin :"<foo>": literal-end)
   |<foo>
   |> (output-html literal-begin :"<": literal-begin :"&":
   |               literal-end :">": literal-end)
   |<&>
   |> (output-html literal-begin :"<": literal-begin :"&":
   |                literal-end :">")
   |<&>
   |quote-html: Unmatched open-literal.
   |> (output-html literal-begin :"x\\&y": literal-end)
   |x\&y
   |> (output-html literal-begin :"\\ \\C": literal-end)
   |\ \C
   |> (output-html
   |   literal-begin :(thunk (printf "<b>foo</b>")): literal-end)
   |<b>foo</b>
   |> (output-html (meta-content~ 'description "\"<meta>\" example"))
   |<meta name="description" content=""<meta>" example">
   |> (output-html (meta-content~ 'description
   |                              literal-end :"\"<meta>\" example":
   |                              literal-begin))
   |<meta name="description" content="&quot;&lt;meta&gt;&quot; example">
   +----------
Again, this is just to know what's going on, the `literal:' function and
`::literal?' keywords are preferable.

As another example, note that in:
   +----------
   |> (output-html (b: (thunk (output-html (i: "foo")))))
   |<b>&lt;i&gt;foo&lt;/i&gt;
   |</b>
   |> (output-html (b: (literal: (thunk (output-html (i: "foo"))))))
   |<b><i>foo</i>
   |</b>
   +----------
The internal thunk outputs raw HTML so `::literal?' should be #t, but it
is important for that thunk's formatting that `::verbatim?' is left as
the default #f because it uses the same values.  (The reason for the
unnecessary newline is that `output-html' always tries to terminate
output with a newline.)

The post-processing mechanism is general and applies to any output
generated when HTML is produced.  This simplifies including HTML
content by just printing stuff on the standard output.  A useful
function for this is `display-file' which gets a file name and prints
it.  So, you can use something like
   +----------
   |> (output-html (literal: (thunk (display-file "foo"))))
   |<b>foo</b>
   +----------
to display the contents of a file that contains raw HTML.  More on
`display-file' (and `display-mixed-file') below.


------------------------------------------------------------------------
3.3. Global parameters

The behavior of the HTML generator can be customized by modifying some
global parameters.  If these values are set, it should be done right
after loading "html.ss", it is not a wise thing to change these values
during HTML generation.  A parameter is a procedure that keeps a value:
to get the value you apply the procedure on no arguments and to change
its value, you apply it on the new value.  See the MzScheme manual for
more information on parameters.

*html-target-dir*
  a string which is the default directory to create HTML files in, or
  "", for using the current directory.  The default is "".  Can be set
  to #f: "" will be used in this case.  It always ends with a "/" unless
  it is "".

*html-suffix*
  a string which is used as a suffix for HTML files.  The default is
  ".html".  This string always begins with a ".".

*image-dir*
  a string which is the name of an images directory (similarly to
  `*html-target-dir*', it can be set to #f for no directory), used only
  for the `my-images~', `my-gif~', and `my-jpg~' functions.  The default
  is "images/".  It always ends with a "/" unless it is "".

*doc-type*
  a string that is inserted at the top of files generated by
  `make-html', and is intended for an initial "<!DOCTYPE...>" line.  It
  can be changed to #f to have no such line.  The default is: "HTML 4.0
  Transitional", the rest of this string is produced by `make-html'.
  (See the description of output values above for an explanation on
  parameters and how to change them.  In short, `(*doc-type*)' returns
  the value and `(*doc-type* x)' sets it to x.)

*charset-type*
  a string that is inserted in the header using `http-equiv~' and
  "Content-Type" and a default "text/html" value for the type.  The
  default is "ISO-8859-1".

*prefix*
  stuff that gets inserted by `html~:' into the header section.  Useful
  for adding things like `meta-content~'.  The default is #f.

*current-html-obj*
  when working on an HTML object (see below), this parameter will be set
  to this object.


------------------------------------------------------------------------
3.4. Text processing

Text processing is, obviously, a big thing for this application, and
there is therefore a lot of related functionality.

(concat str...)
  Is used to concatenate strings, shorthand for `string-append'.

(mapconcat func list separator)
  Similar to the Emacs Lisp `mapconcat' function, except that it works
  with lists: it gets a function, a sequence of objects and a returns a
  list of the function applied to all objects, with the separator
  between them.  The fact that it works with lists makes it suitable for
  HTML output.
   +----------
   |> (mapconcat add1 '(1 2 3) 'x)
   |(2 x 3 x 4)
   |> (output-html (mapconcat (lambda (x) "[": x :"]") '(1 2 3) " | "))
   |[1] | [2] | [3]
   +----------

(string-capital str)
  Capitalizes the first character in a given string (only the first).

(input->output)
  Copies (efficiently) the current input port to the current output
  port.

(with-output-filter filter-func output-thunk)
  The filter function is a function of no arguments that reads its input
  and write some accordingly processed output.  The output function is a
  function of no arguments that produces some output.  Applying
  filterize on both will run `output-thunk' piping its output into
  `filter-func' and its results are in turn printed on the standard
  output.  This is a low level function that is used to implement the
  HTML post-processing (and some more).

(with-input-filter filter-func input)
  Similar for `with-output-filter', but for input.

(display-file file)
  Gets a file name and simply spit its contents on the standard output.
  If you want to display HTML content using this, you should first wrap
  it in a thunk so the contents will appear as part of going over the
  HTML structure rather than when making the function call, and you also
  need to wrap it with a `literal:' to avoid processing of the HTML
  text.

(display-mixed-file file ...)
  Displays the file, filtered through a function that allows mixing raw
  text and Scheme code.  For example, if the file "x" contains:
   +----------
   |<#(define a "foo")#>
   |<a href="c:\{:a:}.htm"><#a#>&nbsp;?</a>
   |<#(b:#>FOO<#)#>
   +----------
  then you can get:
   +----------
   |> (output-html (big: (thunk (display-mixed-file "x"))))
   |<big>
   |<a href="c:\{:a:}.htm">foo&nbsp;?</a>
   |<b>FOO</b>
   |</big>
   +----------
  More arguments are keywords and values:
  * `:metas'         a list with two strings that are used as the open
                     and close markers.  (Default: "<#" and "#>").
  * `:scheme?'       if true, then the default initial mode for parsing
                     the file is Scheme -- note that in that case you'll
                     probably view the file as a Scheme file and the
                     meaning of the open/close will look like it is
                     reversed, so be careful.  (Default: #f).
  * `:string-quotes' if specified, either a string that will be inserted
                     for the Scheme reader for the begin/end of a meta
                     string, or a pair for different begin/end values.
  * `:split-lines?'  if true, then generated strings that span several
                     lines will be split so that each line is a separate
                     string in the result (and a a space prefix for
                     these lines is eliminated).  (Default: #f).
  If "y" contains:
   +----------
   |(define a "foo")
   |]<a href="c:\[a].htm">[a]&nbsp;?</a>[
   |(b: ]FOO[)
   +----------
  then:
   +----------
   |> (output-html
   |   (big: (thunk (display-mixed-file "y" :metas '("[" "]")
   |                                        :scheme? #t))))
   |<big><a href="c:\foo.htm">foo&nbsp;?</a><b>FOO</b></big>
   +----------
  Finally, if there is a sequence of two such meta-open tags, then a
  sequence of two closing ones is expected, all on one line with an even
  number of characters between them.  The two parts of the section
  between them are used as the new tokens.  If "z" contains:
   +----------
   |<#(define a "foo")#>
   |<#<#[]#>#>
   |<a href="c:\[a].htm">[a]&nbsp;?</a>
   |[(b: ]FOO[)]
   |[[{}]]{a}!
   |zzz
   +----------
  then (note the empty lines):
   +----------
   |> (output-html (thunk (display-mixed-file "z")))
   |
   |
   |<a href="c:\foo.htm">foo&nbsp;?</a>
   |<b>FOO</b>
   |foo!
   |zzz
   +----------

(relativize-path path)
  Attempt to relativize the given path according to the current path.
  This is used in case you want to create HTML objects in directories,
  refer to them according to their normal path and get it relative to
  the correct object.  For example, in the source for the `a/b' object,
  a reference to `c/d' will turn to "../d.html".  Search for this name
  below for more details.

(regexp-replacements replacements)
  This function gets a single argument which is a list of replacements,
  each one is a list of a regular expression an a replacement, which is
  either a fixed string, a string containing "\\N" instances (replaced
  using MzScheme's `regexp-replace'), or a function (applied on the
  result of `regexp-match').  The replacements list can hold a single
  replacement for convenience.  The return value is a function that will
  execute these replacements on a given input.  The result of applying
  the function is a string only as long as it is possible -- a
  replacement can put in non-string values and in this case the result
  will be a list of recursive calls (which makes it suitable for HTML
  output).
   +----------
   |> (regexp-replacements '(("a" "b")))
   |#<procedure:replacement>
   |> ((regexp-replacements '(("a" "b"))) "abcde")
   |"bbcde"
   |> ((regexp-replacements '(("[ae]" "\\0\\0"))) "abcde")
   |"aabcdee"
   |> ((regexp-replacements '(("[ae]" 12))) "abcde")
   |("" 12 ("bcd" 12 ""))
   |> (output-html ((regexp-replacements `(("[ae]" ,b:))) "abcde"))
   |<b>a</b>bcd<b>e</b>
   +----------
  Note that this function is not too optimized, and it is generally a
  quick hack which is supposed to do the right thing in simple cases.
  Also, replacement results are not rescanned again (or some of the
  above examples would loop infinitely).

(do-replacements replacements args...)
  This is a simple `maptree'ing of the generated replacements function,
  which makes it useful for general tree structures.  Note that there is
  it doesn't penetrate promises and thunks, and that it only works on
  the separate string elements so it can't recognize a regexp that
  starts at one place and ends at another string, for example, in the
  following:
   +----------
   |> (output-html
   |   (do-replacements (list "<([^<>]+)>" (lambda (_ x) (u: x)))
   |     (b: "FOO")))
   |<b>FOO</b>
   |> (output-html
   |   (do-replacements (list "<([^<>]+)>" (lambda (_ x) (u: x)))
   |     (b: "<FOO>")))
   |<b><u>FOO</u></b>
   +----------
  the "<b>"s and "</b>"s did not change since `tag~:' puts the "<" and
  the ">" in different elements of a list.  The replacements argument
  can be a function, expected to be the result of `regexp-replacements'.

(with-replacements replacements body...)
  Similar to the above, except the the body's output is post-processed
  using the specified replacements (using `with-output-filter').  This
  means that it covers any output, including HTML junk.  The output is
  pulled just before the normal HTML post-processing, so it'll have some
  "\\("s etc.  The output of `with-replacements' is actually a thunk, so
  its output is normally preprocessed getting the final HTML output.
  One more restriction is that it works on a line-by-line basis so no
  multi-line regexps can be used.
   +----------
   |> (output-html (u: (with-replacements `(("[ae]" ,b:)) "abcde")))
   |<u><b>a</b>bcd<b>e</b></u>
   |> (output-html (u: (with-replacements
   |                       `(("\\*([^*]*)\\*" ,(lambda (_ x) (b: x))))
   |                     "foo *bar* baz")))
   |<u>foo <b>bar</b> baz</u>
   +----------

text-replacements
  A variable holding a standard text replacements: "*...*" for bold,
  "_..._" underlines, "/.../" italicizes.
   +----------
   |> (output-html (with-replacements text-replacements
   |                                  "*foo* _bar_ _/baz/_"))
   |<b>foo</b> <u>bar</u> <u><i>baz</i></u>
   +----------

(regexp-case str clauses...)
  This is a macro that has a structure which is somewhat like a `case'
  expression.  Every clause has a test part which is a regexp, a list
  made of a regexp and some symbols following it or `else'.  If the
  given string matches the regexp of a clause, the body is evaluated,
  possibly binding given variable names to `regexp-match's results.  To
  access the complete result of `regexp-match', either use the `match'
  identifier that is bound to the whole match (when the form that binds
  variables is used), or use the `=>' syntax which applies a given
  function on all match results.
   +----------
   |> (regexp-case "foo"
   |    ["f" 1] [("(b)a(r*)" x y) (list x y)] [else '?])
   |1
   |> (regexp-case "barr"
   |    ["f" 1] [("(b)a(r*)" x y) (list x y)] [else '?])
   |("b" "rr")
   |> (regexp-case "bzzt"
   |    ["f" 1] [("(b)a(r*)" x y) (list x y)] [else '?])
   |?
   |> (regexp-case "bzzt" ["f" 1] [("b(z)" x) match])
   |"bz"
   |> (regexp-case "zbarrz"
   |    ["f" 1] ["(b)a(r*)" => (lambda x x)] [else '?])
   |("barr" "b" "rr")
   +----------


------------------------------------------------------------------------
3.5. Output and formatting tags

There are various functions that are used to format output.  These
functions are used by HTML-generating function to format the resulting
HTML so it is readable.  Despite being on a lower level, there are some
cases where they can be useful.

(display!: x)
  displays its argument like Scheme's `display', but it takes care of
  newline and indentation management.

(newline!:), (space!:)
  is used to stick newlines or spaces in the HTML code, in a way that
  respects the current indentation.

(newlines: ...), (spaces: ...)
  outputs its arguments, separated by `newline!:'s or `space!:'s.

(text: ...)
  is the same as `newlines:'.

(indent: ...)
  output its arguments in an indented environment.

(literal: ...)
  output its arguments in an environment that disables HTML post
  processing (for example, for including and external file, or code that
  outputs raw HTML).

(verbatim: ...)
  output its arguments in an environment that disables indentation etc
  temporarily (which is needed, for example, for `pre:').

(include-file: ...)
(include-mixed-file: ...)
  these are two wrappers for `display-file' and `display-mixed-file',
  described above.  Note that they don't use any meta keywords, and that
  `include-mixed-file:' can get normal keywords that are sent to
  `display-mixed-file'.


------------------------------------------------------------------------
3.6. HTML tags structures, wrappers, and attributes

There are several functions and macros that are used to produce HTML
tags and tag pairs, and for defining functions that produce them.  These
functions get keywords and values that are used for attributes and
values for the tags, and then some HTML content.  Note that if a keyword
appears more than once, the first value is the one used, but this is not
a feature that should be used often.  Boolean values for keywords are
special: #f drops the attribute, and #t will include it by itself.  The
HTML output has keyword values always surrounded by double quote (also,
remember that all this is in case-sensitive mode).

*** HTML list structures

First, there are some details to know.  The HTML tag functions create
list values that represent them, which are then converted to normal text
when output.  These list values are very simple -- they look just like
the function application, so they can be constructed using quotations or
any other way:
   +----------
   |> (b: 1 2)
   |(b: 1 2)
   |> (output-html (b: 1 2))
   |<b>1 2</b>
   |> (output-html '(b: 1 2))
   |<b>1 2</b>
   |> (output-html '(b: :x 1 1 2))
   |<b x="1">1 2</b>
   +----------

This is can be confusing for inexperienced Scheme programmers, for
example:
   +----------
   |> (define eli "Eli Barzilay")
   |> (output-html (b: eli))
   |<b>Eli Barzilay</b>
   |> (output-html '(b: eli))
   |<b>eli</b>
   +----------
what happened here is that the first `b:' form is a normal function
application which evaluated `eli' to its value.  The second form had a
literal quoted string that only has the symbol `eli' in it.  I could
resolve symbols by looking up their global value, but that wouldn't
work with local variables, which is the reason why these two
expression are different:
   +----------
   |> (let ((b: i:)) (output-html (b: "foo")))
   |<i>foo</i>
   |> (let ((b: i:)) (output-html '(b: "foo")))
   |<b>foo</b>
   +----------
The main thing to remember is that since the output of these tags is
readable, you can always inspect this value to see what's wrong.  For
example, here is the above values:
   +----------
   |> (b: eli)
   |(b: "Eli Barzilay")
   |> '(b: eli)
   |(b: eli)
   |> (let ((b: i:)) (b: "foo"))
   |(i: "foo")
   |> (let ((b: i:)) '(b: "foo"))
   |(b: "foo")
   +----------

For this reason, it is generally better to stick with the normal
function form rather than generate literal strings.  In the future, I
might make things better by making them return some non-list
structure, and doing some processing work, for example, an `itemize:'
function will return the appropriate `(ul: (li: ...) (li: ...))'
structure that matches exactly the HTML structure (sans formatting)...
The reason for this list structure is that I plan to reach the goal of
a better output for these HTML functions so you could inspect their
values as well, for example, use them with different packages like the
XML collection that comes with MzScheme.

Most HTML tags have such equivalent functions, so they can all be either
applied or stuck in lists manually.  Even symbols that end with a colon
that were not defined as functions can be used.
   +----------
   |> (output-html (x: :x 1 1 2))
   |reference to undefined identifier: x:
   |> (output-html '(x: :x 1 1 2))
   |<x x="1">1 2</x>
   +----------

There is a table that stores information about tags, including, in some
cases some processing functions:
   +----------
   |> (p: :x 1 1 2)
   |(p: :x 1 1 2)
   |> (output-html (p: :x 1 1 2))
   |<p x="1">
   |1
   |2
   |</p>
   +----------

Another confusing point about this is that the list structure matters:
if some `foo:' symbol doesn't appear at the beginning of a list, you
will not get the expected result -- normally, working with lists
(e.g., appending) does not modify the output, but if you modify the
list structure, you can get a mess:
   +----------
   |> (output-html (list "foo" (b: "bar")))
   |foo<b>bar</b>
   |> (output-html (cons "foo" (b: "bar")))
   |foob:bar
   +----------
The second result turned out wrong, because the `b:' symbol that the
`b:' function created is no long at the beginning of a list.  As said
above, remember that you can print these values to see what's wrong:
   +----------
   |> (list "foo" (b: "bar"))
   |("foo" (b: "bar"))
   |> (cons "foo" (b: "bar"))
   |("foo" b: "bar")
   +----------
The second expression's value shows why the output didn't come out
right.

There is a safety mechanism that can be used to prevent some of these
things -- making these HTML lists wrapped in an extra list level,
which will take care of most of these problem -- the
`make-safe-forms!' function can be used to turn it on (or off, given
an explicit #f argument):
   +----------
   |> (make-safe-forms!)
   |> (b: "bar")
   |((b: "bar"))
   |> (cons "foo" (b: "bar"))
   |("foo" (b: "bar"))
   |> (output-html (cons "foo" (b: "bar")))
   |foo<b>bar</b>
   |> (make-safe-forms! #f)
   |> (output-html (cons "foo" (b: "bar")))
   |foob:bar
   +----------
This is not on by default not only because it is less efficient (the
difference is negligible), but because it modifies the result structures
which means that code that must have it on should most likely be fixed
anyway.  Also, note that it doesn't change the result of manually
constructed lists (obviously).

*** Naming conventions

There are various identifier naming conventions that are used throughout
the system -- some are just conventions and some gets special treatment.

* As said above, symbols that begin with a ":" are keyword -- they
  evaluate to themselves.

* Keywords that begin with a ":" (= symbols that begin with a "::") are
  `meta-keywords' which are treated differently in HTML structures:
  normal keywords are used as tag attributes to display, but meta
  keywords are not displayed -- they are reserved for various tag
  processing functions, for output formatting and other information.
  For example:
   +----------
   |> (output-html '(foo: :bar 1 2 3))
   |<foo bar="1">2 3</foo>
   |> (output-html '(foo: ::bar 1 2 3))
   |<foo>2 3</foo>
   |> (output-html '(foo: ::spaces? #f ::bar 1 2 3))
   |<foo>23</foo>
   +----------
  (As usual in Scheme, a "?" is used for booleans.)

* Symbols that end with a ":" are used for HTML tags.  This is also for
  symbols that are bound to functions that produce HTML tags with the
  same symbol at its beginning.

* Names that end with a "~" are functions that generate HTML but do not
  get keyword/value arguments -- usually these create some HTML
  structure given some fixed arguments (e.g., `mailto~'), or HTML tags
  that have no end-tag (e.g., `meta-content~').  They are usually bound
  as the same type of functions (returning a value that looks like the
  function call), so they can be planted in lists, but only defined ones
  can be used.

* Names that end with a "~:" get some special argument and then more
  arguments that are used as usual, e.g., `color~:'.

* Names that end with a "::" (or "~::") are functions that generate
  functions that generate HTML output.  These are usually internal
  functions, and not defined as HTML tags (so you can't put these
  symbols in lists).

* Names that start with a "_" are normally used for global html-object
  bindings (see `defhtml' below).

* There are other standard Scheme conventions that I will not discuss.
  Just one thing that I use -- `*foo*' for parameter names, because
  they're somewhat equivalent to special globals in Common Lisp.

*** Some standard meta attributes

The following is a list of meta attributes that are common to all HTML
tags (there are others which are used by various functions).  Note that
some meta keywords are inherited to subforms, and some do not get passed
along -- in the descriptions, below, the default is that there is no
inheritance except when specified.

* `::args' -- This is a special meta argument that can have a list value
  which will be added to the argument list.  It is usually intended for
  keyword/value pairs, but can be used as a general mechanism (e.g., a
  substitute for apply).  For example:
   +----------
   |> (output-html
   |   (body: ::args '(:bgcolor "blue" :text "yellow") "foo"))
   |<body bgcolor="blue" text="yellow">
   |foo
   |</body>
   |> (output-html
   |   (body: :bgcolor "black" ::args '(:bgcolor "blue" :text "yellow")
   |     "foo"))
   |<body bgcolor="black" text="yellow">
   |foo
   |</body>
   |> (output-html ;; <- unreliable
   |   (body: ::args '(:bgcolor "blue" :text "yellow") :bgcolor "black"
   |     "foo"))
   |<body bgcolor="blue" text="yellow">
   |foo
   |</body>
   |> (output-html
   |   (body: ::args '(:bgcolor "blue" :text "yellow" "bar") "foo"))
   |<body bgcolor="blue" text="yellow">
   |bar
   |foo
   |</body>
   +----------
  Note that the place where these are stuck in is not something to rely
  on -- I have one version that sticks it in place, and another that
  puts it between the keywords and the body.  So don't rely on
  precedence with other keywords, and put normal arguments only if
  `::args' is the last keyword.

* `::func' -- A function that will be used to process the body.  The
  relation of this function and the assigned HTML tag string is complex
  so just don't use this.

* `::empty?' -- If #t, then this construct should not have any body and
  an error is raised if it gets any.  If it is #f, then when the body is
  empty you still get both open and close tags.  The default is neither,
  which makes the output have both tags only if there is some body
  present.

* `::1st-args' -- This should be a list of keywords.  This construct
  will pull an appropriate number of elements from the body and use them
  as values for these keywords, which makes it a mechanism to generate
  `foo~:' functions.  Mostly for internal usage.

* `::arg-funcs' -- The value of this keyword should be an association
  list of a keyword and a processing function.  If this keyword appears
  in an HTML function, the function will be applied on the HTML tag,
  keyword name (a string) and the given value, and it should return two
  values for the new name and value.  The default value is the value of
  the `*arg-funcs*' parameter which defaults to a list that will use
  `relativize-path' on `:src' and `:href' arguments.  To disable this
  processing, you can use `::arg-funcs #f', but that will disable all
  processing so it is better to disable processing only for one
  attribute, for example: `::arg-funcs (list* :href #f (*arg-funcs*))'.
  This keyword is inherited, so you can do this at any form to modify
  everything in it.

* `::literal?' -- If true, then HTML post-processing is disabled for the
  body (see above for more details).  Default: #f.  This meta-keyword is
  not inherited, but it is not needed since the context of the body is
  all literal.  Also, once it is used, it is impossible to disable it in
  nested forms by giving a #f value.

* `::verbatim?' -- If true, then spaces and newlines that are used for
  pretty printing are not used.  Default: #f.

* `::indent?' -- If true, make the body indented.  This meta keyword is
  inherited, default: #f

* `::newlines?' -- If true, put a `newline!:' between body elements.
  Note that `:newlines?' can be false, while `::indent?' true, because
  the contents can have things with newlines in them.  This meta keyword
  is inherited, default: same as `:indent?'.

* `::spaces?' -- Same for `space!:'s.  This meta keyword is inherited,
  default: the opposite of `::newlines?'.

*** Form functions and wrappers

(make-form ...)
  This is the function which is used to create HTML list structures.
  Usually `list*', but can be modified with `make-safe-forms!'.  See
  above.

(defform name: [string] ...)
  This macro defines `name:' (a ":" suffix is required) as an HTML
  structure generating function that outputs a "name" tag (or a
  different tag if a string follows `name:').  Such declared forms can
  be used as functions that will create a list that looks like the
  function application, so they can be used as symbols in lists too.  It
  can specify keywords (both normal and meta) to use with this construct
  -- but when the function is used, these keyword values can be
  overridden.  If the string is #f, then no tag gets printed, which is
  useful only for formatting and applying a sub `::func' field (this is
  how functions like `newlines:' are defined), and if it is a symbol it
  will use that form for output.  See the source for advanced usages.
   +----------
   |> (output-html '(foo: 1 2))
   |<foo>1 2</foo>
   |> (defform foo: :bar 1)
   |> (output-html '(foo: 1 2))
   |<foo bar="1">1 2</foo>
   |> (output-html (foo: 1 2))
   |<foo bar="1">1 2</foo>
   |> (output-html (foo:))
   |<foo bar="1">
   |> (output-html (foo: :bar 2))
   |<foo bar="2">
   |> (defform foo :bar 1)
   |defform: got a name that doesn't end with a colon at: foo in: [...]
   |> (defform foo: "foooo" :bar 1)
   |> (output-html (foo:))
   |<foooo bar="1">
   |> (output-html (foo: foo:))
   |<foooo bar="1"><foooo bar="1"></foooo>
   +----------
  Note that the resulting tag can be used with no arguments which means
  that it can be used as is (as shown in the last expression).

(defwrapper name: [string] ...)
(deftag name: [string] ...)
  These are versions of `defform' that set the ::empty? value:
   +----------
   |> (defwrapper foo: :bar 1)
   |> (output-html (foo: foo:))
   |<foo bar="1"><foo bar="1"></foo></foo>
   |> (deftag foo: :bar 1)
   |> (output-html (foo: foo:))
   |output-form: `foo' got a non-empty body: (#<procedure:foo:>).
   +----------

(form~:    tag ...)
(wrapper~: tag ...)
(tag~:     tag ...)
  These are special HTML functions that can be used to create arbitrary
  HTML tags, given a first string argument (must be first, and must be a
  string):
   +----------
   |> (output-html (wrapper~: "foo" :bar 1))
   |<foo bar="1"></foo>
   |> (output-html (tag~: "foo" :bar 1))
   |<foo bar="1">
   |> (output-html (form~: "foo" :bar 1))
   |<foo bar="1">
   |> (output-html (form~: "foo" :bar 1 1 2))
   |<foo bar="1">1 2</foo>
   |> (output-html (form~: "foo" :bar 1 ::indent? #t 1 2))
   |<foo bar="1">
   |  1
   |  2
   |</foo>
   |> (output-html '(form~: "foo" :bar 1 ::spaces? #f 1 2))
   |<foo bar="1">12</foo>
   |> (output-html '(form~: #f :bar 1 ::spaces? #f 1 2))
   |12
   +----------

(form:->:: foo:), (form~:->~:: foo~:),
  These are functions that gets a form function as its argument, and
  returns a different form function, the first returns a wrapper
  constructor with some default values.  The second works on functions
  that get a unique first argument.  (This is like currying, except that
  keywords given to the final result get precedence.)
   +----------
   |> (defwrapper foo: :bar 1)
   |> (defwrapper foo~: 'recform: ::tag 'foo: ::1st-args ::n)
   |> (define foo:: (form:->:: foo:))
   |> (define foo~:: (form~:->~:: foo~:))
   |> (output-html (foo: "zzz"))
   |<foo bar="1">zzz</foo>
   |> (output-html (foo~: 3 "zzz"))
   |<foo bar="1"><foo bar="1"><foo bar="1">zzz</foo></foo></foo>
   |> (output-html (foo~: 3 :bar 2 "zzz"))
   |<foo bar="2"><foo bar="2"><foo bar="2">zzz</foo></foo></foo>
   |> (output-html ((foo:: :x 1) :y 2 "bar"))
   |<foo y="2" x="1" bar="1">bar</foo>
   |> (output-html ((foo:: :x 1) :x 2 "bar"))
   |<foo x="2" bar="1">bar</foo>
   |> (output-html ((foo~:: 2 :x 1) :x 2 "bar"))
   |<foo x="2" bar="1"><foo x="2" bar="1">bar</foo></foo>
   +----------

(recform: foo:)
  This is a form function that expects `::tag' and `::n' arguments, and
  will repeat that tag the specified number of times, nesting it in
  itself or collecting a result list (depending on the `::empty?'
  property of its tag):
   +----------
   |> (output-html (recform: ::n 2 ::tag 'big:))
   |<big><big></big></big>
   |> (output-html (recform: ::n 2 ::tag 'big: "A"))
   |<big><big>A</big></big>
   |> (output-html (recform: ::n 2 ::tag 'br:))
   |<br><br>
   |> (output-html (recform: ::n 2 ::tag 'br: :foo 2))
   |<br foo="2"><br foo="2">
   |> (defwrapper foo~: 'recform: ::tag 'foo: ::1st-args ::n)
   |> (output-html (foo~: 2 "A"))
   |<foo><foo>A</foo></foo>
   |> (output-html (foo~: 2))
   |<foo><foo>
   +----------
  This is useful for HTML tags that can be `accumulated', like "<big>",
  and for defining many wrappers based on a more general one.


------------------------------------------------------------------------
3.7. Predefined tags and wrappers

This is a brief list of functions that generate HTML output.  For more
details, see the source.

br:, break:, break~:
  output an HTML line-break ("<br>").  `break~:' can be used to output a
  sequence of these.

hr: (hline:)
  outputs a horizontal line ("<hr>").

html:, head:, body:, title:, link:, base:, frameset:, frame:, noframes:,
iframe:, meta:, p:, b:, i:, u:, em:, strong:, blink:, strike:, tt:,
cite:, code:, samp:, kbd:, dfn:, var:, abbr:, acronym:, h1:, h2:, h3:,
h4:, h5:, h6:, sub:, sup:, ins:, del:, nobr:
  simple HTML wrappers and tags, each with some default formatting
  attributes (`::newlines?', `::indent?', `::spaces?').

(link-rel~ rel ref)
(link-rev~ rev ref)
  shorthand for (link: :rel rel :href ref), and the same for `:rev'.

(meta-content~ name content), (http-equiv~ name content)
  shorthand for (meta: :name name :content content) and for
  (meta: :http-equiv name :content content).

big:, big~:, small:, small~:
  simple and `recform:' versions of these tags.

font:, face~:, size~:, color~:, size-2:, ..., size+4:, black:, white:,
red:, green:, blue:, cyan:, magenta:, yellow:, purple:
  an HTML font tag, and shorthands for face, sizes, and colors
  specifications.

div:, left:, right:, center:, justify:
  a "div" tag, and shorthands for formatting text using the `:align'
  attribute.

ltr:, rtl:
  a "div" shorthand for using an "ltr" or an "rtl" direction using the
  `:dir' attribute.

span:, class~:
  a "span" tag, and shorthand for a "span" using a `:class' attribute.

address:, blockquote:, quote:, q:
  more simple tags (quote: is a `blockquote:' tag).

pre:
  a "pre" environment (with no automatic indentation).

img:, (image~ fname [alt] ...), (gif~ fname [alt] ...),
(jpg~ fname [alt] ...), (png~ fname [alt] ...)
  an "img" tag, shorthand for specifying the `alt:' attribute (with
  possibly more attributes), and shorthands for omitting common
  suffixes.

(my-image~ fname [alt]), (my-gif~ fname [alt] ...),
(my-jpg~ fname [alt] ...), (my-png~ fname alt ...)
  similar to the above, but automatically prepends `*image-dir*'.

map:, area:, spacer:
  some more image-related things.

a:, (ref~: ref ...), (name~: label ...)
  an html "a" wrapper, a reference link ("a" with an "href" attribute),
  and a named anchor ("a" with a "name" attribute).  The first argument
  to `ref~:' and `label~:' is the URL and the rest is the keyword/values
  and body expressions.
   +----------
   |> (output-html (html: (name~: "foo" "FOO") "foo..."
   |                      (ref~: "#foo" "Go to FOO")))
   |<html>
   |<a name="foo">FOO</a>
   |foo...
   |<a href="#foo">Go to FOO</a>
   |</html>
   +----------

http~:, ftp~:, telnet~:, mailto~:
  shorthands that prepends the corresponding URL element to a `ref~:'
  call.

(ref~ x), (http~ x), (ftp~ x), (telnet~ x), (mailto~ x)
  generate links that contain their own text in tt font.

(list~: tag ...)
  This generates a list of some kind, the given tag is the one used to
  construct the list.  There are some special keyword arguments that it
  handles -- a `::br' argument specifies some number of "<br>"s to stick
  after every item to make a list with more spaces, and a `::subtag'
  argument can be used to override the default "<li>" tag used for
  items.  The extra arguments for `list~:' are the items, each is a
  list that is passed to the item wrapper.  If the item list has a
  `item>' symbol, then it is split by that symbol to generate the real
  items (this is controlled by a `::split-by' argument).  Note that
  `item>' is bound to itself so it can be used unquoted and in manually
  constructed lists.
   +----------
   |> (output-html (list~: "ul" '("item #1") '("item #2")))
   |<ul>
   |  <li>item #1</li>
   |  <li>item #2</li>
   |</ul>
   |> (output-html (list~: "ul" ::br 2 '("item #1") '("item #2")))
   |<ul>
   |  <li>item #1 <br><br></li>
   |  <li>item #2 <br><br></li>
   |</ul>
   |> (output-html (list~: "ul" ::subtag "foo"
   |                        '("item #1") '("item #2")))
   |<ul>
   |  <foo>item #1</foo>
   |  <foo>item #2</foo>
   |</ul>
   |> (output-html (list~: "ul" :type 'disc
   |                        '("item" "#1") '(:foo 2 "item" "#2")))
   |<ul type="disc">
   |  <li>item #1</li>
   |  <li foo="2">item #2</li>
   |</ul>
   |> (output-html (list~: "ul" :type 'disc
   |                       item> "item" "#1"
   |                       item> :foo 2 "item" "#2"))
   |<ul type="disc">
   |  <li>item #1</li>
   |  <li foo="2">item #2</li>
   |</ul>
   +----------
  There is also an option of using a second `::subtag2' argument for
  things like description lists (below), and it is possible to put a
  list of tags in `::subtag' and a matching list of separators in
  `::split-by' (to change the token used to separate items) so a nested
  list can be generated (for example, for tables).  Finally, a
  `::subargs' argument can be used to supply default arguments
  (keywords) to sub items (see `table*:' below for an example).

enumerate:, itemize:, menu:, dir:
  These functions use the above (through `list~::'), for lists with
  "ol", "ul", "menu", and "dir" tags.

itemize-bullet:, itemize-circle:, itemize-square:
  These are versions of `itemize:' that use "disc", "circle", and
  "square" as the value of the "type" attribute to force a certain
  marker.

description:
   These are used for description lists ("dl").  Using them is similar
   to the above, except that in items a `!>' separates the header part
   ("dt") from the body part ("dd") (`!>', like `item>' is bound to
   itself).

table:, th:, tr:, td:
  "table" and related wrappers.

table*:
  This is an HTML function that uses the `list~:' function above, with
  `row>' and `col>' tokens, to create a table:
   +----------
   |> (output-html (table*: :width "100%"
   |                 row> :bgcolor "blue" col> "a" col> "b" "c"
   |                 row> col> "x" "y"
   |                 row> "1" "2" "3"))
   |<table width="100%">
   |  <tr bgcolor="blue">
   |    <td>a</td>
   |    <td>b c</td>
   |  </tr>
   |  <tr>
   |    <td>x y</td>
   |  </tr>
   |  <tr>
   |    <td>1</td>
   |    <td>2</td>
   |    <td>3</td>
   |  </tr>
   |</table>
   |> (output-html (table*: ::subargs '(:foo "bar")
   |                        row> col> "x1" col> "x2" row> "y1" "y2"))
   |<table>
   |  <tr foo="bar">
   |    <td>x1</td>
   |    <td>x2</td>
   |  </tr>
   |  <tr foo="bar">
   |    <td>y1</td>
   |    <td>y2</td>
   |  </tr>
   |</table>
   |> (output-html (table*: ::subargs '((:foo1 "bar") (:foo2 "baz"))
   |                        row> col> "x1" col> "x2" row> "y1" "y2"))
   |<table>
   |  <tr foo1="bar">
   |    <td foo2="baz">x1</td>
   |    <td foo2="baz">x2</td>
   |  </tr>
   |  <tr foo1="bar">
   |    <td foo2="baz">y1</td>
   |    <td foo2="baz">y2</td>
   |  </tr>
   |</table>
   +----------
  Note the last item in all examples, which doesn't have `col>' tokens
  so each element is made a separate item.  The `table*:' form is much
  easier to create `quick' tables, but when a program is used to create
  complex tables, `table:' (with `tr:' and `td:') can be more
  convenient, since it is not sensitive to the list structure of its
  arguments.

form:, input:, button:, submit-button:, text-input:, checkbox:,
radiobox:, password-input:, hidden-input:, select:, option:
  "form" wrapper and various form element tags, many are just `input:'
  with some value for `:type' (the last two are actually wrappers
  expecting a body).

(submit~: val ...)
  shorthand for `submit-button:' with the first argument being the label
  or the option value (the "value" attribute).

options:
  Similar to a list, but generates a `select' element with nested
  `options'.  Each item should have the value first:
   +----------
   |> (output-html (options: item> 1 "item #1" item> 2 "item #2"))
   |<select>
   |  <option value="1">item #1</option>
   |  <option value="2">item #2</option>
   |</select>
   +----------

(select-options: ...)
  shorthand for a `select:' with nested `option:'s -- the arguments are
  lists holding a value and a label, for example:
   +----------
   |> (output-html (select-options: '(1 label1) '(2 label2)))
   |<select>
   |  <option value="1">label1</option>
   |  <option value="2">label2</option>
   |</select>
   +----------

(button*: ...)
  this is the actual HTML "button" wrapper, unlike the above `button:'
  which is just a short for (input: :type 'button ...).

(label~: label ...)
  a "label" wrapper, with a value for the `:for' attribute.

(textarea: ...)
  a "textarea" form element, the contents has indentation disabled.

legend:, (fieldset: ...)
  a "legend" wrapper, and a "fieldset" wrapper -- if the `fieldset:'
  body contains a `!>', then the first part will be sent to `legend:'
  and the second used as the `fieldset:' body.

(comment: ...)
  formatted HTML comment (doesn't accept any attributes):
   +----------
   |> (output-html (comment: "foo"))
   |<!-- foo -->
   |> (output-html (comment: "foo" "bar"))
   |<!--
   |  foo
   |  bar
   |-->
   +----------

(script-src~ src), (style-src~ css-file)
  a "script" tag with its "src" attribute given and an empty body, and a
  "link" tag used for a css file specification.

script:, style:, noscript:
  comment-objects (objects that are placed in an HTML comment), and a
  matching "noscript" wrapper -- the contents is protected from HTML
  post-processing:
   +----------
   |> (output-html (script: "var i = 1;" "window.alert(\"foo\");"))
   |<script type="text/javascript" language="JavaScript"><!--
   |  var i = 1;
   |  window.alert("foo");
   |// --></script>
   +----------

applet:, object:, param:, param~:
  an "applet", and "object" wrappers, a "param" tag, and a function
  receiving the name and value of the parameter.

embed:, noembed:
  an "embed" tag and a "noembed" wrapper.

applet-params:, object-params:
  Uses `list:' for items that each has a name and a value.  Note that
  this is also useful if you give it arguments that are a two-element
  list each:
   +----------
   |> (output-html (applet-params: item> 'foo 1 item> 'bar 2))
   |<applet>
   |  <param name="foo" value="1">
   |  <param name="bar" value="2">
   |</applet>
   |> (output-html (object-params: '(foo 1) '(bar 2)))
   |<object>
   |  <param name="foo" value="1">
   |  <param name="bar" value="2">
   |</object>
   +----------

(html~: title head body [args...])
  This is a convenient HTML wrapper, getting a title, a head argument
  containing some list of stuff to put in the head section, and a body.
  It also uses `*prefix*' to add stuff to the header section (#f by
  default), and `*charset-type*' for adding the right meta-tag.  In
  addition, extra arguments can be used to override this behavior:
  `:prefix' and `:charset-type' can be used to override these defaults.
   +----------
   |> (*prefix* (meta-content~ 'author (concat "Eli Barzilay")))
   |> (output-html (html~: "Main Page" (list (script: "var foo = 1"))
   |                 (body: "blah blah blah")))
   |<html>
   |<head>
   |  <meta name="author" content="Eli Barzilay">
   |  <meta name="generator" content="Scheme!">
   |  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
   |  <title>Main Page</title>
   |  <script type="text/javascript" language="JavaScript"><!--
   |    var foo = 1
   |  // --></script>
   |</head>
   |<body>
   |blah blah blah
   |</body>
   |</html>
   +----------
  Note that the head argument must be in a list, see `make-safe-forms!'
  above.

(document: ...)
  This is a global wrapper, it does some minimal job like outputting the
  document type (if `*doc-type*' is set) and an optional comment to put
  at the top and bottom of the result (if a `::comment' keyword is
  given, or you can specify different ones with `::comment1' and
  `::comment2').


========================================================================
4. Making it work

Now that working with all the above should be clear, we reach the point
of putting it all together in a script.


------------------------------------------------------------------------
4.1. General scripting

The easiest way to run a script in Unix, is to make it executable (using
"chmod +x foo") and write some `magic' prefix that will allow it to run.
What I found most convenient is the following prefix:
   +----------
   |#!/bin/sh
   |#|
   |exec mzscheme -r "$0" "$@"
   ||#
   |... scheme code ...
   +----------
This will make it a /bin/sh script that will just execute mzscheme with
the correct command-line arguments: `-r' is for running a script: short
for `-fmv-' which stands for `-f' for loading an argument, `-m' for
suppressing the banner, `-v' for no interactive read-eval-print loop,
and `--' to specify that more arguments are passed to the script without
further processing.  The first "$0" argument is consumed by the `-f' --
this is the actual script (the double-quotes are to protect file name
with spaces from exploding to multiple arguments), and "$@" are other
arguments that are passed to the script because of the `--' (again "$@"
will send each argument, handling spaces in them correctly).  When
MzScheme starts, it ignores the /bin/sh stuff and will happily proceed
to execute the file.  Stick to this template and be safe.

On Windows, it should be possible to add an executable file type,
specifying how it should be run.  For example, making it executed by
  "C:\Program Files\PLT\MzScheme.exe" -r
should do the trick.  Note that spaces makes life a mess.


------------------------------------------------------------------------
4.2. Script setup for "html.ss"

The MzScheme executable accepts lots of useful flags that can be used to
automate a lot of work.  We've seen above how `-r' is used to run a
Scheme script, but HTML generation scripts will usually look roughly
like this:
   +----------
   |#!/bin/sh
   |#|
   |exec mzscheme -r "$0" "$@"
   ||#
   |(require (lib "html.ss" "swindle"))
   |...
   |... HTML-definitions scheme code  ...
   |...
   |(html-main argv)
   +----------
(See below for `html-main' usage.)

Now, we can further use the following command-line arguments:
* `-L' to specify a library file and collection names;
* `-C' to invoke `main' on the given script arguments as a list
  beginning with the script file name (it implies `-r').
Using these, we can write this equivalent script:
   +----------
   |#!/bin/sh
   |#|
   |exec mzscheme -LC "html.ss" "swindle" "$0" "$@"
   ||#
   |...
   |... HTML-definitions scheme code  ...
   |...
   |(define (main args) (html-main (cdr args)))
   +----------
Note that the "-LC" order specifies that the library and collection
names come first, then the script name and that `main' is invoked after
loading the file.

On Windows, the problem is that an extension can be used to specify that
a file is to be thrown as an argument on some binary with predefined
additional arguments.  So either use something like the first script
above, or create yet another extension for HTML scripts.


------------------------------------------------------------------------
4.3. Creating HTML files

Finally, this section describes how to produce HTML files.  This is
describing the level built on top of all of the above.

`*defined-htmls*' is a variable holding HTML objects.  To define an HTML
object, use the `(defhtml foo ...)' macro -- it gets a variable name
that will be bound to the HTML object, and push that object onto
`*defined-html*'.  The extra arguments are keyword/values, which are
expected to hold values for at least `:name' which holds the file name
(sans base directory and suffix, but possibly with sub directories), and
a `:contents' value that will be used to produce the HTML object.  The
`:contents' value can be any of the valid value that is shown as usual,
or a function of a variable number of arguments that will be applied to
the supplied list of keywords and values so it can inspect values for
more keywords (e.g., supplied by defaults as described below).  For
convenience, the `:name' argument can be dropped and the symbol name
will be used instead (dropping a "_" prefix of and adding "index" in
case it ends with a "/").  Also the `:contents' argument can be dropped
and its value should just be the last one -- in this case, its value
will be protected by a `delay' which makes it easier for it to reference
later defined values.  `defhtml' uses the `(html-obj!  ...)' macro,
which is similar to a simple `list', except that it handles the contents
value as described above, and the result is pushed on the
`*defined-htmls*' list (the `!' suffix doesn't mean that this is
especially exiting, just that it modifies a value rather than simply
returning one).
   +----------
   |> (html-obj! :a 1 :b 2 3)
   |(:a 1 :b 2 :contents #<struct:promise>)
   |> (defhtml x :a 1 :b 2 3)
   |> x
   |(:name "x" :a 1 :b 2 :contents #<struct:promise>)
   |> (getarg x :contents)
   |#<struct:promise>
   |> (force (getarg x :contents))
   |3
   |> *defined-htmls*
   |((:name "x" :a 1 :b 2 :contents #<struct:promise>)
   | (:a 1 :b 2 :contents #<struct:promise>))
   +----------
One note about `:name' -- possible file arguments (e.g., arguments for
`ref~:'s and `image~', can be relativized in case `:name' contains a
subdirectory name; to do this, use the `relativize-path' function
described above.  This means that to get it done properly, the actual
call should be done at HTML generation time (you can wrap them in a
`delay' or `thunk').

At this point you probably wonder why the whole keywords-values mess...

Well, one feature that is desired is to have access to information about
HTML objects from other pieces of code.  For example, code that
generates a menu that shows links to other pages with some information
about them, which is included in the appropriate `defhtml' form.  If an
HTML output object is used, there is no way to pull that information
out, so HTML objects are just keyword/value lists.  A good setup is to
have a function that creates the contents function and treats given
information in some uniform way -- see below for an example.  To pull
out keyword information from an HTML object, the utility function
`getarg' described above can be used.  Remember the option of using
`delay' (a Scheme promise) or a thunk (a function with no arguments)
above -- putting references to yet-undefined HTML objects is possible in
such constructs since they get evaluated when all HTML objects are
defined.

To actually produce HTML files from HTML objects, use the `make-html'
function -- it should be called with an HTML object and possibly more
keywords/values.  If keywords are provided, they will be used as default
values for HTML object keywords (so this can be used for invocation
specific values, like date).  The `make-htmls' is similar, except it
expects a list of HTML objects as its first arguments (and again,
optionally more keywords/values).  Finally, a convenient function is
`make-defined-htmls' -- when called (with no arguments or
keywords/values), it will go over all HTML objects in `*defined-htmls*',
collected by `defhtml' forms, and create their files.  Actually, it will
empty `*defined-htmls*', and recheck it once it is done, since more HTML
objects may be defined while creating pages.  `*all-html*' contains all
html object and is never emptied.

The following example is a complete script that will create three HTML
files in the directory you run it from.  (The evaluation delay trick
should be used in case the body of the `_main' object references later
ones.)

   +----------
   |#!/bin/sh
   |#|
   |exec mzscheme -LC "html.ss" "swindle" "$0" "$@"
   ||#
   |(define ((my-page: &rest body)
   |         &keys name (title (string-capital name)) info)
   |  (html: (title: title)
   |    (body: (h1: title) hr: body hr: (comment: "menu follows")
   |      (apply text: (map (lambda (html)
   |                          (ref~: (concat (getarg html :name)
   |                                         (*html-suffix*))
   |                                 "[":(getarg html :info):"]"))
   |                        (reverse *pages*))))))
   |(defhtml _main :name "index" :title "Main" :info "My main page"
   |  (my-page: "Yo!  Welcome to my main page!"))
   |(defhtml _professional :info "Career stuff"
   |  (my-page: "As CEO of Foo Corp, I blah blah blah..."))
   |(defhtml _hobbies :info "Personal hobbies"
   |  (my-page: "I like to shove dead bugs up my nose."))
   |(define *pages* *defined-htmls*)
   |(define (main args) (html-main (cdr args)))
   +----------

(Remember that `defhtml' can use symbol names that contain `/'s to put
the results in these subdirectories, but remember that these
subdirectories should exist.)

This is the standard approach that I prefer -- a single script that
creates multiple HTML files.  To create a single HTML file at a time,
different approaches can be used.  The first one, is to have the same
script, but create only a subset of the defined HTML objects.  For this,
use the function `html-main' instead of `make-defined-htmls'.  This
function gets a list as an argument and will make each HTML object on
the list or search for it by a defined name in case of a string.  It can
also accept more keyword/values to send to the html creation function.
If the input list is empty, it simply invokes `make-defined-htmls'.  To
search an HTML object by a string name, it looks for either a symbol
bound to an HTML object with the given argument name, or an HTML object
with a `:name' attribute equal to the given argument, or an HTML object
whose processed name (the `:name' value with `*html-target-dir*' and
`*html-suffix*') is equal to the given argument.  All this makes it
convenient to run on script inputs: with arguments it will generate only
the requested pages, and without it will create all defined pages.
Thing you should know if you use this approach:

* Make sure that the script header has that "$@" so additional command
  line arguments are passed to MzScheme.  On Windows you should make
  sure that whatever way you chose to invoke MzScheme programs, should
  be passing command line arguments to it.

* The variable MzScheme uses to bind command line arguments is `argv',
  it is bound to a vector of strings but `html-main' will convert a
  given vector to a list.

* MzScheme has a `-C' flag that will call the `main' function with the
  list of arguments, beginning with the script file name -- so you can
  bind `main' to `html-main' and get the above automatically.

* You should be aware of the fact that this approach might not evaluate
  all HTML bodies, so you should be careful not to rely on an HTML
  object evaluation to have a visible effect on evaluation of other
  objects.

Another option is to create separate scripts to create several pages.
For this, you can either use the above functions (just have a single
HTML object defined on each script) or resort to lower level functions
like `output-html'.  Another function that can be used for this purpose
is `(output-to-html "foo" html-object)' which will place the HTML output
of the given html-object in "foo.html" (or any other file, depending on
`*html-target-dir*' and `*html-suffix*'.  If these scripts rely on some
shared code, you should consult the MzScheme documentation to learn how
to load files.  Normally, you would just `load' the given shared code,
but you might want to invoke several scripts in a single execution --
for extra convenience you could use MzScheme's module mechanism.  For a
more ambitious project, you can even use MzScheme's `make' library and
much more.

In addition to all this, remember that the HTML generators can do
anything at all.  They can even read in external files and incorporate
them in the output -- remember that everything that is printed on the
standard output is included in the resulting HTML.  You can use
`display-mixed-file' as described above, or do anything you want, (and
remember to use `literal:' where necessary).


========================================================================
