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)) ,@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