[cl-who-devel] Re: Macroexpansion of with-html-output body?
Victor Kryukov
victor.kryukov at gmail.com
Sun Feb 10 06:44:33 UTC 2008
Jeff Cunningham <jeffrey at cunningham.net> writes:
> Edi Weitz wrote:
>> On Sat, 2 Feb 2008 15:18:09 -0600, "Eli Naeher" <enaeher at 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:
>>
>> http://weitz.de/patches.html
>>
>> 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.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: who1.lisp
URL: <https://mailman.common-lisp.net/pipermail/cl-who-devel/attachments/20080210/7e485435/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: cl-who-example.lisp
URL: <https://mailman.common-lisp.net/pipermail/cl-who-devel/attachments/20080210/7e485435/attachment-0001.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: cl-who-test.lisp
URL: <https://mailman.common-lisp.net/pipermail/cl-who-devel/attachments/20080210/7e485435/attachment-0002.ksh>
-------------- next part --------------
;;; -*- mode: lisp; -*-
(with-html-output-to-string (http-stream)
(loop for (link . title) in '(("http://zappa.com/" . "Frank Zappa")
("http://marcusmiller.com/" . "Marcus Miller")
("http://www.milesdavis.com/" . "Miles Davis"))
do (htm (:a :href link
(:b (str title)))
:br)))
"<a href='http://zappa.com/'><b>Frank Zappa</b></a><br /><a href='http://marcusmiller.com/'><b>Marcus Miller</b></a><br /><a href='http://www.milesdavis.com/'><b>Miles Davis</b></a><br />"
(with-html-output-to-string (http-stream)
(:table :border 0 :cellpadding 4
(loop for i below 25 by 5
do (htm
(:tr :align "right"
(loop for j from i below (+ i 5)
do (htm
(:td :bgcolor (if (oddp j)
"pink"
"green")
(fmt "~@R" (1+ j))))))))))
"<table border='0' cellpadding='4'><tr align='right'><td bgcolor='green'>I</td><td bgcolor='pink'>II</td><td bgcolor='green'>III</td><td bgcolor='pink'>IV</td><td bgcolor='green'>V</td></tr><tr align='right'><td bgcolor='pink'>VI</td><td bgcolor='green'>VII</td><td bgcolor='pink'>VIII</td><td bgcolor='green'>IX</td><td bgcolor='pink'>X</td></tr><tr align='right'><td bgcolor='green'>XI</td><td bgcolor='pink'>XII</td><td bgcolor='green'>XIII</td><td bgcolor='pink'>XIV</td><td bgcolor='green'>XV</td></tr><tr align='right'><td bgcolor='pink'>XVI</td><td bgcolor='green'>XVII</td><td bgcolor='pink'>XVIII</td><td bgcolor='green'>XIX</td><td bgcolor='pink'>XX</td></tr><tr align='right'><td bgcolor='green'>XXI</td><td bgcolor='pink'>XXII</td><td bgcolor='green'>XXIII</td><td bgcolor='pink'>XXIV</td><td bgcolor='green'>XXV</td></tr></table>"
(with-html-output-to-string (http-stream)
(:h4 "Look at the character entities generated by this example")
(loop for i from 0
for string in '("F?te" "S?rensen" "na?ve" "H?hner" "Stra?e")
do (htm
(:p :style (conc "background-color:" (case (mod i 3)
((0) "red")
((1) "orange")
((2) "blue")))
(htm (esc string))))))
"<h4>Look at the character entities generated by this example</h4><p style='background-color:red'>Fête</p><p style='background-color:orange'>Sørensen</p><p style='background-color:blue'>naïve</p><p style='background-color:red'>Hühner</p><p style='background-color:orange'>Straße</p>"
(with-html-output-to-string (str)
(:html (:title "test")))
"<html><title>test</title></html>"
-------------- next part --------------
--
[1] http://paste.lisp.org/display/55662
[2] http://paste.lisp.org/display/55663
More information about the Cl-who-devel
mailing list