[cl-who-devel] Re: Macroexpansion of with-html-output body?

Victor Kryukov victor.kryukov at gmail.com
Wed Feb 13 05:11:27 UTC 2008


Jeff Cunningham <jeffrey at cunningham.net> writes:

> Victor,
>
> I'm not sure anything I'm doing really exercises your changes, but I
> now have it running on three servers without any sign of trouble (or
> difference in output, for that matter).

Well, if you code ever uses special symbols str, esc, fmt or htm -
that's a good sign - it means that macroexpansion is working.

> I sat down this evening to try to understand it better, and for awhile
> I thought I might be able to use it to solve a macro expansion problem
> that's been bothering me. I don't think it can be applied, but I'm not
> sure. Here's a simplified version of a macro I use :

I highly recommend readign cl-who code. It's an easy read - the code
is short, very well written and has just the right amount of comments.

> (defmacro section (title &rest body)
>  `(with-html-output (*standard-output* nil :indent t)
>     (:table
>      (:a :name ,title)
>      (:tr
>       (:td
>        (:h2 (str ,title))
>        , at body)))))

With the new macro def-syntax-macro, you can achieve the same with the
following code:

(cl-who::def-syntax-macro section (title &rest body)
  `(:table
     (:a :name ,title)
     (:tr (:td (:h2 (str ,title)) , at body))))

BTW - your (:a :name ,title) inside a table looks really suspicious!

Now whenever you use section macro inside your with-html-output, it
will expanded _before_ with-html-output comes into play. Note
cl-who:: qualifier before the def-syntax-macro name - I haven't
touched original cl-who files for the purpose - it's much easier to
try the changes this way - and therefore def-syntax-macro is not
exported by default, hence the cl-who:: package specification. 
          

> Here is a trivial example showing how I use it:
>
> (section "A Title"
>           (:p "A cl-who formatted form")
>           (:p "The body could be any collection of cl-who code"))

If you define section with the def-syntax-macro as above, you can
legally use this inside your with-html-output macro.

> What I'd like to be able to do is feed it unexpanded cl-who code like this:
>
> (let ((code1 '("A Title"
>               (:p "A cl-who formatted form")
>               (:p "The body could be any collection of cl-who code")))
>      (code2 '("Another title"
>               (:h2 "Different code here"))))
>  (section* code1)
>  (section* code2))

Well - are you _sure_ you really need that? Currently, cl-who doesn't
provide any interface for producing code out of sexps, and if you read
who.lisp or cl-who documentation - esp. paying attention to "Syntax
and Semantics" section - you'll understand why.

In most cases, you just don't need that. If you _really_ insist, try
this one:

(defpackage :cl-who-sexp
  (:use :cl :cl-who))

(in-package :cl-who-sexp)

(defun sexp-with-html-output (sexp)
  "Generates string out of SEXP according to CL-WHO rules"
  (with-output-to-string (s)
    (eval (cl-who::tree-to-commands sexp s))))

CL-WHO-SEXP> (sexp-with-html-output '(:html (:title "title")))
"<html></html><title>title</title>"
    
This is either a very clever or very ugly hack. It would be better to
re-write tree-to-commands-aux to provide such functionality instead.

Regards,

Victor
--
http://macrodefinition.blogspot.com/




More information about the Cl-who-devel mailing list