   This is the online manual for Le Sursis (Sane and Usable Response to
Scripting Internet Sites) Version 0.1.1

   Copyright (C) 2000 Tom Burdick

   Le Sursis is a system to aid in writing CGI scripts in Common Lisp.
This manual describes its use.

Distribution and Copying
************************

   This is Version 0.1.1 of Le Sursis by Tom Burdick.

   The latest version of Le Sursis can always be found on the Sursis
web site (http://sursis.sourceforge.net/) .

   Le Sursis is Free Software licensed to you, the user, under the
terms of the GNU General Public License , a copy of which should be in
the `COPYING' file included in the Le Sursis distribution.  Please read
it as it is designed to protect your rights as the user of this
software; it also places certain restrictions on the use of this
software so as to protect the rights of all users.

Introduction
************

   Le Sursis is an attempt to provide a good environment to write CGI
scripts in Common Lisp.  It consists of two packages: `sursis' and
`sursis-html'.  `sursis' contains the functions for retrieving CGI
queries, and `sursis-html' contains a set of utility functions to make
it easier to compose HTML.  Although they are meant to be
complimentary, each may be used independently of the other.

What does Le Sursis mean?
=========================

   Le Sursis nominally stands for "Sane and Usable Response to Scripting
Internet Sites."  However, "le sursis" is also French for "the
reprieve," meant here in the sense of "a reprieve from Perl."  And,
alas, while Le Sursis is indeed a reprieve from Perl, it is not a
solution.  If one has to work on a CGI script with others, it will
almost certainly be necessary to use a language other than Lisp.  But,
when you can use it, what a reprieve!

   Also, `Le Sursis' is a novel by Jean-Paul Sartre, the second in the
three-part series `Les Chemins de la Liberté' ("The Paths to Freedom").
It is a great book, M. Sartre was an amazing author and philosopher,
and I would encourage everyone to read his work.  The remainder of this
manual will consider only the software.

Basic Usage
===========

   All examples given here use the `.lsp' extension for lisp files.  In
most situations, you would want to compile the lisp files from this
distribution.  Any references to compiled files will use the `.fas'
extension used by CLISP (http://clisp.cons.org/) which is the Common
Lisp implementation used by the author.

   All lisp files intended to be used as CGI scripts are assumed to
begin with:
     #!/usr/local/bin/clisp

or the appropriate for the Lisp system being used, and are assumed to
have the appropriate executable permissions.

Basic `sursis' usage
--------------------

   The `sursis' package provides Le Sursis' interface to CGI queries.

   For the simplest scripts, the following should suffice:
     (load "sursis.lsp")
     (cgi:get-query)
       => (("name1" . "value1") ... ("nameN" . "valueN"))

   `get-query''s value is an association list; or, if no input was
given to the script, it's value is `nil'.

   The next most useful function exported is probably `format-query'.
`format-query' takes an a-list as an argument and its value is a
matching query string.  For example:
     (cgi:get-query)
       => (("greeting" . "Hello world!") ("tone" . "emphatic"))
     (cgi:format-query *)
       => "?greeting=Hello+world!&tone=emphatic"

This makes it easy to have a cgi script recur on itself.  In fact, it
was this behavior of the majority of my cgi scripts that lead me to
write this package.

   For more detail, see The sursis Package.

Basic `sursis-html' usage
-------------------------

   The `sursis-html' package provides utility functions to make it
easier to write HTML responses.  It exports functions with names
corresponding to most common HTML tags.  A simple example of its use is:
     (load "sursis-html.lsp")
     (use-package 's-html)
     (http-response
      (html
       (head
        (title "Test page"))
       (body nil
        (h1 "Section 1")
        (p "paragraph 1")
        (h2 "Subsection 1.1")
        (p (i "and so on...")))))
       => "Content-type: text/html

     <html>
     <!-- Generated with help from Le Sursis <http://sursis.sourceforge.net/> -->
     <head><title>Test page</title></head>
     <body>
     <h1>Section 1</h1>
     <p>paragraph 1</p>
     <h2>Subsection 1.1</h2>
     <p><i>and so on...</i></p>

     </body>
     </html>"

   The resulting html varies in readability, but the assumption is that
the user prefers easily readable lisp.  All the tag functions take
multiple arguments for their bodies and concatenate these to form the
text between the two tags (or after the tag in the case of `<p>',
`<li>', and some others).  A typical use could be as follows:
     (format t (http-response
                (html
                 (head
                  (title "Thank You!"))
                 (body
                  (h1 "Thank You!")
                  "Thank you for your response."))))

   Some tags, for example the `<img>' tag, take attribute values.  The
functions for these take a required a-list argument before any tag
contents.  Ex:
     (img '(("src" . "le-sursis.png")
            ("alt" . "The Le Sursis banner")))
       => "<img src=\"le-sursis.png\" alt=\"The Le Sursis banner\">"
     (table '(("border" . "on")) "...")
       => "<table border=\"on\">...</table>"

   Also note that some tag functions, like `img', do not accept any
arguments for their body, as they don't have one.

   For more detail, see The sursis-html Package.

The `sursis' Package
********************

   The `sursis' package (which is also available via the nickname
`cgi') is in `sursis.lsp'.  It exports functions for retrieving cgi
query data and for forming queries.  It currently supports only CLISP,
but it should be portable to any Common Lisp system with a one or two
line change (CL doesn't provide any mechanism for accessing
environmental variables).

   Currently (as of Version 0.1) the `sursis' package only supports GET
queries.  Version 0.2 will add support for POST queries.  Also, the
functions in this package have not been optimized to be tail-recursive.
Version 0.3--or possibly sooner--should see the re-writing of some
functions to be tail-recursive where efficiency or any potential stack
overflows could be a concern.

`sursis:get-query'
==================

   `get-query &OPTIONAL REGET'

`get-query''s value is an association list containing the key-value
pairs given to the cgi script, or `nil' if none were given.  Normally,
`get-query' reads the query data in once and returns the same list
every time it is called.  This improves efficiency and is necessary for
POST queries.  If a non-`nil' value is given for the optional argument
REGET, `get-query' will behave as if it has not yet been run.  This
behavior is almost never desired, except under the most pathological
circumstances.

Sample usage:
     (cgi:get-query)
       => (("message" . "Hello World!") ("tone" . "emphatic"))

`sursis:format-query'
=====================

   `format-query AL'

`format-query' takes an association list AL and returns an
appropriately encoded string to be used as a GET query.  Note that it
ignores repeats of keys, so it is safe to `acons' pairs onto the head
of the list returned by `get-query'.  Unless you care about order, in
which case you'll have to use a more awkward idiom.

Sample usage:
     (cgi:get-query)
       => (("message" . "Hello World!") ("tone" . "emphatic"))
     (acons "tone" "blasé" *)
       => (("tone" . "blasé") ("message" . "Hello World!") ("tone" . "emphatic"))
     (cgi:format-query *)
       => "?tone=blas%e9&message=Hello+World!"
     (format nil "http://path/to/self~A" *)
       => "http://path/to/self?tone=blas%e9&message=Hello+World!"

`sursis:get-environment'
========================

   `get-environment &OPTIONAL REGET TOGET'

`get-environment''s value is an association list of environmental
variables describing the CGI environment.  Under normal circumstances,
it reads from the environment once and returns the same list every time
it is called.  If the optional argument REGET is non-`nil', it will
return a newly-constructed list.  The optional variable TOGET, which
should be a list of strings, specifies the environmental variables to
include in the list.  As of this writing, TOGET defaults to
`("REQUEST_METHOD" "QUERY_STRING" "CONTENT_LENGTH")'.  This function
will eventually inspect all environmental variables in the CGI
specification; the user may wish to inspect the definition of
`get-environment' before passing it a custom list, in case the desired
variable has been added to the defaults.  When specifying a custom list
in TOGET, REGET should be set to non-`nil', or the behavior may be
other than what was desired.

   A note on the a-list returned by `get-environment':
  1. If an environmental variable is set, the `cdr' of its entry in the
     a-list will be its value: `( VARIABLE-NAME . VALUE )'.

  2. If it is not set, the `cdr' of its entry will be `nil': `(
     VARIABLE-NAME )'.

  3. If is is set to "", the `cdr' of its entry will be `""': `(
     VARIABLE-NAME . "" )'.
        Be careful not to mistake the second case for the third.

Sample usage:
     (cgi:get-environment)
       => (("REQUEST_METHOD" . "GET")
           ("QUERY_STRING" . "message=Hello+World!&tone=emphatic")
           ("CONTENT_LENGTH"))
     (cgi:get-environment nil '("SCI" "WWW_HOME" "USERNAME"))
       => (("REQUEST_METHOD" . "GET")
           ("QUERY_STRING" . "message=Hello+World!&tone=emphatic")
           ("CONTENT_LENGTH"))
     (cgi:get-environment t '("SCI" "WWW_HOME" "USERNAME"))
       => (("SCI" . "/usr/lib/scilab-2.4.1/")
           ("WWW_HOME" . "/home/noc/lynx_bookmarks.html")
           ("USERNAME" . ""))

   It is worth noting that `sursis' contains a definition for `getenv',
which is a thin wrapper around the current Lisp system's function to
retrieve a single environmental variable (this is not a part of Common
Lisp, so the function name varies from system to system).  It takes a
single string as an argument and returns a string, or `nil' if the
variable is not set.  It is not exported, but it may be useful to call
to retrieve a single variable from the environment.

The `sursis-html' Package
*************************

   The `sursis-html' package (which is also available via the nickname
`s-html') is in `sursis-html.lsp'.  It exports a large number of
utility functions to make it easier to form HTML responses to CGI
queries.  It is written entirely in Common Lisp, using no extensions.

   Unless one wishes to only use the `sursis-html' functions a few
times in a given script, one should import the functions provided by
`sursis-html'.  So long as one avoids the names of common html tags,
this name-space pollution should not be a problem, and the increased
readability of the Lisp code should more than make up for it.

   This package is optimized to be tail-recursive.

`sursis-html' Overview
======================

   Nearly every exported function is based on one of the two generic tag
functions: `sa-tag' and `tag'.  These functions are primitives for
creating a stand-alone tag, and a normal tag (with a `<name>' and a
`</name>' portion), respectively.  All tag functions except those for
purely stand-alone tags (i.e., tags like `<br>', as opposed to `<p>',
which may be viewed as having contents, even if it need not be closed)
have a `&rest' argument for the contents of the tag.  The tag functions
take the `~D' representations from `format' for all of their `&rest'
arguments and concatenate them together for the body of the tag:
     (html "The" " value of x is" 12)
       => "<html>The value of x is 12</html>"

This allows nesting of the tag functions, as in:
     (http-response
      (html
       (head
        (title "Example"))
       (body nil "Hi.")))
       => "Content-type: text/html

     <html>
     <!-- Generated with help from Le Sursis <http://sursis.sourceforge.net/> -->
     <head><title>Example</title></head>
     <body>
     Hi.
     </body>
     </html>"

The readability of the Lisp code given above is the point of this
package.

   Although the `http-response' function used in the example above does
not produce an HTML tag, it is provided to be consistent with the
philosophy of the package.

   Note that generation of the recognition comment above is controlled
by a constant set at the top of `sursis-html.lsp', and may be disabled.

Simple Tags
===========

   All these functions are of the form:
     name &REST SL

And produce output of the form: `<name>BODY</name>'.  The reader should
note that some of these functions insert line breaks for readability.
   * b

   * big

   * blockquote

   * dl

   * center

   * h1

   * h2

   * h3

   * h4

   * h5

   * h6

   * head

   * html

   * i

   * ol

   * p

   * pre

   * small

   * title

   * tt

   * ul

Un-closed Tags
==============

   All these functions are of the form:
     name &REST SL
   And produce output of the form: `<name>BODY'.  This is always
followed with a newline, except for `dt' which omits the newline to
increase readability:
     (dt "term" (dd "definition of term"))
       => "<dt>term<dd>definition of term
     "

   * dd

   * dt

   * li

Stand-alone Tags
================

   None of the functions in this section accept arguments for a body.
They do not have a general form, so they will be addressed one at a
time.
   * `anchor NAME'
          There is, of course, no `anchor' tag in HTML.  This function
          is meant for establishing anchors within a document, and is
          intended to be more readable than trying to do the same with
          the `a' function.
               (anchor "para1")
                 => "<a name=\"para1\"></a>

   * `br'
          `br' produces a `<br>' tag, with line breaks before and after
          the tag.

   * `hr &OPTIONAL ATRIB'
          `hr' works the same as `br', except that it accepts an
          optional list of attributes.

   * `img &OPTIONAL ATRIB'
          This produces a stand-alone `<img>' tag exactly how you would
          expect:
               (img '(("src" . "pic") ("alt" . "a pic")))
                 => "<img src=\"pic\" alt=\"a pic\">"

Tags with Attributes
====================

Simple
------

   These functions are of the form:
     name ATRIB &REST SL
   And produce output of the form: `<name a1="v1" ...>BODY</name>'.  As
with the simple tag functions, some insert line breaks for readability.
   * a

   * body

   * table

   * td

   * tr

Un-closed
---------

   No functions are currently in this section.

Miscellaneous Functions
=======================

   These functions do not have a general form, so they will be addressed
one at a time.
   * `comment &REST SL'
          This acts very much like a simple tag except that instead of
          `<name>BODY</name>', it produces `<!-- BODY -->'.

   * `http-response &REST SL'
          This functions simply prepends `"Content-type: text/html"'
          and two newlines to its body.

   * `sa-tag NAME ATRIB'
          `sa-tag' generates an unclosed (stand-alone) tag from the
          string given as NAME, and the a-list given as ATRIB:
               (sa-tag "name" nil)
                 => "<name>"
               (sa-tag "name" '(("a1" . "v1") ("a2" . "v2")))
                 => "<name a2=\"v2\" a1=\"v1\">"

   * `tag NAME ATRIB CONTENTS &OPTIONAL PRETTY1 PRETTY2'
          Most of the functions exported by `sursis-html' are built on
          `tag'.  Whereas `sa-tag' could be reasonable to use in one's
          code for tags not provided by `sursis-html', if one is going
          to use `tag' to produce a given tag more than once, it is
          probably worthwhile to define a new (inline) function to do
          this.  `tag' is build around `sa-tag'.  NAME and ATRIB are
          used as in `sa-tag', and CONTENTS provides the body.
          However, note that CONTENTS is a list, which makes `tag' very
          useful from functions with a &REST argument, but more
          difficult to use directly.  As an example, to create a `<b>'
          tag using `tag' directly, one could use:
               (p "Here's " (tag "b" nil '("some bold " "text")) ".")
                 => "<p>Here's <b>some bold text</b>.</p>"
          The `defun' for `b':
               (defun b (&rest sl) (tag "b" nil sl))
          makes this much less awkward:
               (p "Here's " (b "some bold " "text") ".")
          If PRETTY1 or PRETTY2 are non-`nil', they insert a newline
          after the `<name>' tag and before the `</name>' tag,
          respectively.  Both are optional, and both default to `nil'.

Index
*****