[cl-who-devel] Re: Macroexpansion of with-html-output body?
Jeff Cunningham
jeffrey at cunningham.net
Wed Feb 13 05:58:48 UTC 2008
Wow - talk about fast! Victor, I'm impressed.
Victor Kryukov wrote:
> 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 use all of them, so it's 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.
>
Okay, I'll do that.
> 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!
>
It should - it is a remnant of my simplification (belonged to a
preceding row). I was trying to hack out everything not pertinent to the
example.
> 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.
>
>
Excellent.
>> 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.
>
>
I'm not at all sure, and you're probably right that its a bad idea.
Still, I'd like to understand it.
Interesting... I just tried to write down what led me to it and in the
process thought of a much simpler way.
> 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.
>
Its a fascinating piece of code. I'm going to play with it. Thanks!
Regards,
Jeff
More information about the Cl-who-devel
mailing list