Subject: Re: How can this macro be improved?
From: rpw3@rpw3.org (Rob Warnock)
Date: Sun, 22 May 2005 21:56:44 -0500
Newsgroups: comp.lang.lisp
Message-ID: <B7qdnQ5S0NDx2wzfRVn-rA@speakeasy.net>
Jeff Cunningham  <jeffrey@cunningham.net> wrote:
+---------------
| I (a neophyte at macros) wrote this as an exercise. The idea was to have
| it write an html link with or without attributes. That is, one of the two
| following ways:
|   <a href="somelink.html">Some text</a>
|   <a href="somelink.html" someproperty="123">Some text</a>
+---------------

In addition to the excellent advice others have given you on macro
style, let me add just this: "Don't invent when you can steal."
[...or re-use, whatever.]  This applies to "style" as well as
to actual "code". The more different styles you can study before
freezing your own style the better off your code will be in the
long run.

As for the present topic, using macros to create a small embedded
language for convenient writing of HTML is a much-explored topic in
the Common Lisp community. Besides what you saw in Paul Graham's
book, there are two whole chapters on the topic in Peter Seibel's
"Practical Common Lisp" [Ch.30-31], as well as a plethora of
HTML-generating libraries available. See <http://www.cliki.net/Web>
for a few of them [and some other useful web tools].

Personally, I like HTOUT and CL-WHO, which let you write things
like this:

    > (let ((title "Simple Page") 
            (links '("foo" "bar" "baz")) 
            (link-url "http://gorp.com/"))
        (with-output-to-string (some-stream)
          (with-html-output (s some-stream)
            (:html
              (:head (:title title))
              (lfd) 
              (:body
                (:h1 title) (lfd)
                (loop for link in links 
                      for url = (concatenate 'string link-url link)
                  do (htm ((:a :href url) link)
                          :br (lfd))))))))

    "<HTML><HEAD><TITLE>Simple Page</TITLE></HEAD>
    <BODY><H1>Simple Page</H1>
    <A HREF='http://gorp.com/foo'>foo</A><BR>
    <A HREF='http://gorp.com/bar'>bar</A><BR>
    <A HREF='http://gorp.com/baz'>baz</A><BR>
    </BODY></HTML>"
    >

Notice how the embedded sub-language [s-exprs starting with keywords or,
for attributes, starting with lists starting with keywords] lets you
concentrate on the *shape* of the resulting page as a whole, rather
than on the mechanics of generating the individual HTML elements.

If you study HTOUT and CL-WHO plus Peter's chapters you'll get a
good set of alternate styles on the HTML-generating problem. Peter's
FOO in particular addresses the issue of nicely-formatting the
resulting HTML (or not), which HTOUT doesn't help much with, hence
the occasional explicit LFD (linefeed) calls in the above example.  ;-}

[Though looking at how the HTM, LFD, FMT, etc., macrolets get
defined in HTOUT is quite useful for pedagogical purposes...]


-Rob

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