[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