Jeff Cunningham jeffrey@cunningham.net writes:
Edi Weitz wrote:
On Sat, 2 Feb 2008 15:18:09 -0600, "Eli Naeher" enaeher@gmail.com wrote:
It seems like it would be nice to expand any macros detected while walking the tree of the w-h-o body. This would allow users to define their own pseudo-tags a little more flexibly than is possible with convert-tag-to-string-list. In particular, it would allow the user to create a tag which modifies its body (as a tree) even when that body contains the expansion of another user-defined tag. I don't believe this is currently possible, as this hypothetical outer tag would have access only to the HTML strings returned by the convert-tag-to-string-list specialized on the inner tag and not to the relevant s-expressions.
Modifying CL-WHO's internals to allow this is on my todo list, but there are a lot more things on this list, so the chances of me doing this myself in the near future are not very big. So, if someone wants to do this, I'm all for it. Please read this first, though:
In the case of CL-WHO I'd think that backwards compatibility would be pretty important.
Edi.
I also like the idea. And as I have tens of thousands of lines of cl-who code in operation, I emphatically vote for backwards compatibility.
Below is my attempt to implement macroexpansion capability in with-html-output body. Before sending it formally as a patch I want to get your feedback on the implementation and also ask for some testing.
The idea is simple: we define new special variable *MACRO-TO-EXPAND* which stores names of all the macros that should be expanded before with-html-output comes into play. Notice that specail forms 'htm', 'esc', 'str' and 'fmt' are no exception here, and may be defined as similar macros. That simplifies code of TREE-TO-TEMPLATE, TREE-TO-COMMANDS-AUX and TREE-TO-COMMANDS significantly.
Below[1] is an example of how we're using this functionality. def-syntax-macro is a syntactic sugar that defines a normal macro and also adds its name to *MACRO-TO-EXPAND*
(defpackage :cl-who-example (:use :cl :cl-who))
(in-package :cl-who-example)
(cl-who::def-syntax-macro html-list (&body body) `(:ul ,@(loop for elem in body collect `(:li ,elem))))
(with-html-output-to-string (s) (:html (:title "Title")) (:body (:h1 "H1 header") (:p "A small list" (html-list "First" "Second" (:a :href "/link" "Third")))))
=> "<html><title>Title</title></html><body><h1>H1 header</h1><p>A small list<ul><li>First</li><li>Second</li><li><a href='/link'>Third</a></li></ul></p></body>"
To test new functionality, simply load the code in who1.lisp[2] after you load CL-WHO - that will allow you to keep the original CL-WHO intact.
I'm also attaching very simple test to check that we haven't braken things at least for the three examples advertised on CL-WHO web page.
Please let me know your feedback,
Victor.
--