Subject: Re: Embedding Lisp in arbitrary text files (or: "Lisp server pages")
From: rpw3@rpw3.org (Rob Warnock)
Date: Fri, 09 Jan 2009 22:37:57 -0600
Newsgroups: comp.lang.lisp
Message-ID: <RvidnWxn9MW4u_XUnZ2dnUVZ_j2dnZ2d@speakeasy.net>
WalterGR  <waltergr@gmail.com> wrote:
+---------------
| Lars Rune N�stdal <larsnost...@gmail.com> wrote:
| > I don't know if you care for opinions a bit to the side of what you're
| > asking about here, but I think templating; something like HTML-TEMPLATE,
| > is a better idea in general:
| > http://weitz.de/html-template/
| >
| > ..and I think something like CL-WHO is an even better idea yet:
| > http://weitz.de/cl-who/
| >
| > I guess; "embedding data in Lisp is nicer than embedding Lisp in
| > data" .. IMHO - when possible.
| 
| Actually, please permit me to simply say - I understand the benefits
| of each approach.  I find the high "turtle-factor" [1] of approaches
| like CL-WHO especially appealing.  [1] "...it's Lisp all the way down!"
+---------------

Yes, CL-WHO & HTOUT & HTMLGEN (and others shown on this page
<http://www.cliki.net/Lisp%20Markup%20Languages>) are *extremely*
nice to use, IMHO, mainly because you can nest HTML templates inside
Lisp code inside HTML templates inside Lisp code... as far as you like.

What they lack (of course) is an infrastructure that makes them
easy to use as more-or-less standalone web page source files.
But it's actually very easy to wrap a trivial "defsystem"-like
thing around a LOAD, so that if you haven't LOAD-ed a page before
then do so and "auto-register" it, and if there is a compiled
version then you check to see if the source is newer and if so
recompile/reload that, etc. That's what I did back circa 2002
[as part of *my* first major production use of CL], and came up
with my LHP ("Lisp-Handled Pages") format, of which you can see
samples here:

    http://rpw3.org/hacks/lisp/minimal.lhp
    http://rpw3.org/hacks/lisp/appsrv-demo.lhp

[LHP currently uses HTOUT, though it could easily be converted
to CL-WHO or others.]

+---------------
| The Lisp-in-data would be only one of the tools in my toolbox -
| albeit a necessary one.
+---------------

Well, "necessary" might be a bit strong, since even if using CL-WHO
(or something like it) one can add an extended string readmacro
(typically #"..."#) to allow large quantities of text or HTML to
be included, including unescaped double-quotes.

But if you absolutely insist on having a "raw text" format that uses
angle brackets the way HTML/XML do, like ASP or PHP, well, people have
done that, too. Possibly the simplest version is the one I first heard
of from Erik Naggum, who called it Enamel or NML, which was later
refined by Tim Bradshaw into TML (Trivial Markup Language) and then
DTML ("TML with macros", sayeth Tim). See the following for more
details than I mention below:

    Newsgroups: comp.lang.lisp
    From: Tim Bradshaw <tfb@cley.com>
    Subject: Re: Difference between LISP and C++
    Date: 24 Oct 2002 13:47:12 +0100
    Message-ID: <ey3elagc8bz.fsf@cley.com>

Basically, all of {N,T,DT}ML use angle brackets *as* sexp parentheses --
and thus there is no separate closing tag, only a matching right angle
bracket -- but differs from {HT,X}ML in using a lexical marker (the "|"
char, in NML/TML/DTML) separating the tag and attributes (if any) from
the body of the element. In the [D]TML case, the attribute section is
a plist of naked Lisp sexps which *are* evaluated (as in HTOUT & CL-WHO),
and the body section is unevaluated plain text (thus double quotes need
not be escaped) terminated by the matching right angle. E.g., whereas
in CL-WHO or HTOUT (etc.) one might write this:

      (:html
	(:head (:title () title))
	((:body :bgcolor "#ffffff")
	 "Here is some body text, with a quoted \"foo\","
	 " and here is the value of FOO: " foo))

in TML it might be written this way:

      <html |
	<head | <title | <lisp :val title |>>>
	<body :bgcolor "#ffffff" |
	 Here is some body text, with a quoted "foo",
	 and here is the value of FOO: <lisp :val foo |>>>

<aside|At various times, Erik used [...] or {...} to escape back into
  Lisp. I don't actually know what Tim currently uses for that these
  days in [D]TML, but at least the above is clearly feasible.>

One can unambiguously shortcut that into this (and Tim does, IIRC):

      <html<head<title<lisp :var title>>>
	<body :bgcolor "#ffffff" Here is some body text, with a
	  quoted "foo", and here is the value of FOO: <lisp :var foo>>>

Parsing {N,T,DT}ML into HTOUT/CL-WHO should be trivial, and is left
as an exercise for the reader...  ;-}


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607