From vseloved at gmail.com Sat Jun 28 18:48:41 2008 From: vseloved at gmail.com (Vsevolod) Date: Sat, 28 Jun 2008 21:48:41 +0300 Subject: [cl-who-devel] Macroexpansion of with-html-output body? Message-ID: <89dc7c5b0806281148i74069ce8p1791b3206b70e7b6@mail.gmail.com> Below is the message I've sent today to Edi Weitz on this topic. Unfortunately, I've missed the existence of this mailing-list, that's why I didn't consult the archives. Today I have quickly pierced the discussion and, as far as I've seen, the solution, I propose, hadn't being mentioned. So, I suggest an implementation strategy for the macroexpansion inside with-html-output and provide a patch against the current version (0.11.1)... I tried to use CL-WHO a couple of times in the past and always stumbled over the fact, that it's possible to do something like that (example from the site): (with-html-output (*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)))))))))) ...but not something like this (i.e. make a macro, to compress some of the pseudo-html tree): (with-html-output (*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 (embed-td j)))))))) (defmacro embed-td (j) `(:td :bgcolor (if (oddp ,j) "pink" "green") (fmt "~@R" (1+ ,j)))) Thus to write such a macro for with-htm-output you should do it in two steps (at least, this is the only way I have discovered): The original form should be like the following (with STR): (with-html-output (*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 (STR (embed-td j)))))))) ...and the macro should itself use w-h-o-to-string: (defmacro embed-td (j) (let ((str (gensym))) `(with-html-output-to-string (,str) (:td :bgcolor (if (oddp ,j) "pink" "green") (fmt "~@R" (1+ ,j)))))) I think it's quite a common case in the usage of the w-h-o macro to want such macros (at least for me it always comes up). So I suggest to add another keyword to a list of STR, ESC and HTM -- EMB -- specially for such cases, which will mean "macroexpand-1 the enclosed form". With it the above code may be expressed like: (with-html-output (*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 (emb (embed-td j))))))))) (defmacro embed-td (j) `(:td :bgcolor (if (oddp ,j) "pink" "green") (fmt "~@R" (1+ ,j)))) or like this: (with-html-output (*http-stream*) (:table :border 0 :cellpadding 4 (loop for i below 25 by 5 do (htm (:tr :align "right" (emb (embed-tr i))))))) (defmacro embed-tr (i) (let ((j (gensym))) `(loop for ,j from ,i below (+ ,i 5) do (htm (:td :bgcolor (if (oddp ,j) "pink" "green") (fmt "~@R" (1+ ,j)))))) I think, sometimes such flexibility is necessary. Although, I'm not absolutely sure, that the solution, I've hacked, is flawless... The patch is attached. I tried to follow the guidelines for patches with this one. The only thing, that I didn't do, is provide examples of the usage of EMB keyword in the doc (only a brief reference). I think, that the examples in the letter might suit, but I'm not sure. Best regards, Vsevolod Dyomkin -------------- next part -------------- A non-text attachment was scrubbed... Name: cl-who-patch.tar.gz Type: application/x-gzip Size: 18394 bytes Desc: not available URL: