From vseloved at gmail.com Sun Jul 6 19:19:19 2008 From: vseloved at gmail.com (Vsevolod) Date: Sun, 6 Jul 2008 22:19:19 +0300 Subject: [cl-who-devel] Macroexpansion of with-html-output body? Message-ID: <89dc7c5b0807061219m67a6c5c2r2a733e346855f93b@mail.gmail.com> I have experimented with the solution, that I've sent previously and have found out, that it's better to place the macroexpansion part in the TREE-TO-TEMPLATE function (instead of TREE-TO-COMMANDS). Thus it's possible to support nested EMB's. The diff looks like this: @@ -11,12 +11,10 @@ ;; normal tag (process-tag element #'tree-to-template)) ((listp element) - ;; most likely a normal Lisp form (check if we - ;; have nested HTM subtrees) or an EMB form + ;; most likely a normal Lisp form - check if we + ;; have nested HTM subtrees (list - (if (eql (car element) 'emb) - (replace-htm (list 'htm (macroexpand-1 (cadr element))) #'tree-to-template) - (replace-htm element #'tree-to-template)))) + (replace-htm element #'tree-to-template))) (t (if *indent* (list +newline+ (n-spaces *indent*) element) - Vsevolod From stassats at gmail.com Tue Jul 8 12:33:13 2008 From: stassats at gmail.com (Stas Boukarev) Date: Tue, 8 Jul 2008 16:33:13 +0400 Subject: [cl-who-devel] Strange (str ...) behavior. Message-ID: <9f0fec110807080533k1f9cb824gbb4ebe82786f9ef5@mail.gmail.com> I have the following with cl-who-0.11.1: > (with-html-output-to-string (i) (:div :id (str "foo"))) "" -- With Best Regards, Stas. From edi at agharta.de Tue Jul 8 12:36:00 2008 From: edi at agharta.de (Edi Weitz) Date: Tue, 08 Jul 2008 14:36:00 +0200 Subject: [cl-who-devel] Strange (str ...) behavior. In-Reply-To: <9f0fec110807080533k1f9cb824gbb4ebe82786f9ef5@mail.gmail.com> (Stas Boukarev's message of "Tue, 8 Jul 2008 16:33:13 +0400") References: <9f0fec110807080533k1f9cb824gbb4ebe82786f9ef5@mail.gmail.com> Message-ID: On Tue, 8 Jul 2008 16:33:13 +0400, "Stas Boukarev" wrote: > I have the following with cl-who-0.11.1: >> (with-html-output-to-string (i) > (:div :id (str "foo"))) > > "" You're mixing tag content and attributes. Try this: (with-html-output-to-string (i) (:div :id "foo")) The documentation for CL-WHO is here: http://weitz.de/cl-who/#syntax Edi. From stassats at gmail.com Tue Jul 8 12:46:40 2008 From: stassats at gmail.com (Stas Boukarev) Date: Tue, 8 Jul 2008 16:46:40 +0400 Subject: [cl-who-devel] Strange (str ...) behavior. In-Reply-To: References: <9f0fec110807080533k1f9cb824gbb4ebe82786f9ef5@mail.gmail.com> Message-ID: <9f0fec110807080546nbaa1e8ci2241121b085ec49a@mail.gmail.com> On Tue, Jul 8, 2008 at 4:36 PM, Edi Weitz wrote: > On Tue, 8 Jul 2008 16:33:13 +0400, "Stas Boukarev" wrote: > >> I have the following with cl-who-0.11.1: >>> (with-html-output-to-string (i) >> (:div :id (str "foo"))) >> >> "" > > You're mixing tag content and attributes. Try this: > > (with-html-output-to-string (i) > (:div :id "foo")) Ah, thanks. -- With Best Regards, Stas. From vseloved at gmail.com Fri Jul 25 20:28:00 2008 From: vseloved at gmail.com (Vsevolod) Date: Fri, 25 Jul 2008 23:28:00 +0300 Subject: [cl-who-devel] Macroexpansion of with-html-output body? (follow-up) Message-ID: <89dc7c5b0807251328i4b2a74c8re1ada0856f39a910@mail.gmail.com> Hi, Once again (hopefully, for the last time) I want to address the question "to use or not to use", so to say, macroexpansion inside w-h-o form, and moreover, how to do it right. I have experimented with the previously proposed solution of introducing additional EMB keyword and have found, that it as well has some drawbacks. More precisely, they exist because of the nature of the w-h-o macro itself, which uses special processing for the forms, contained inside HTM: they are processed before any function application, that is why if you EMBed some macros, which use HTM keyword, which should output to their own streams, the result can be emitted in the unexpected order. To illustrate this vague statement, I can show the piece of the code, that combines cl-who and parenscript forms to make a currency selection form with some javascript backing: (defmacro cur-sel () (w/uniqs (cur) (let ((sel-str `(:select :id "currency" (dolist (,cur *currencies*) (htm (:option :selected (string= ,cur *default-currency*) (str ,cur))))))) `(htm (emb (ps-script* (write-htm (:a :class "toggle" :onclick (ps-inline* `(lambda () ,(write-htm ,sel-str))) (str (ie-val *default-currency*)))))) (:noscript ,sel-str))))) (defmacro write-htm (form) ``(.write document ,(who ,form))) The macro CUR-SEL, that is intended to itself be EMBedded, uses WRITE-HTM to emit HTML forms to string, that will in turn be an argument to javascript document.write(). But, as after macroexpansion of sel-str HTM forms appear as arguments to WRITE-HTM, the output of the containing w-h-o forms goes to the stream, bound by the topmost w-h-o and not the innermost, as it's supposed... Anyway, after some re-thinking of a problem, I've come to a conclusion, that my approach was not the most natural one. Now, I believe, that the more lispy way is to view w-h-o macro as solely a good processor for static pseudo-html data (like '(:p some text (:br) (:a :href ....), and on top of it build macros, which will allow eventually to add macroexpansion ability. My initial target was to be able to use macros with pseudo-html forms, like in the following simple example: (def-who-macro (arg) `(:p some text (:br) (:a :href ,arg))) inside w-h-o body the same way you would use an ordinary macro, but I'd got carried away with modifying the w-h-o macro itself to allow for such usage. It turned out, that it's not hard to implement the separated approach. My variant is below: (defmacro def-who-macro (name (&rest args) pseudo-html-form) "Produces functions for generating pseudo-html forms, which can be embedded in WHO-PAGEs" `(defun ,name (, at args) ,pseudo-html-form)) (defmacro def-who-page (name (&optional stream) pseudo-html-form) "Creates a function to generate an HTML page with the use of WITH-HTML-OUTPUT macro, in which pseudo-html forms, constructed with DEF-WHO-MACRO, can be embedded. If STREAM is nil/not supplied WITH-HTML-OUTPUT-TO-STRING to a throwaway string will be used, otherwise -- WITH-HTML-OUTPUT" `(macrolet ((who-tmp () `(,@',(if stream `(with-html-output (,stream nil :prologue t)) `(with-html-output-to-string (,(gensym) nil :prologue t))) ,,pseudo-html-form))) (defun ,name () (who-tmp)))) (defmacro who (pseudo-html-form) "An analog of DEF-WHO-PAGE, which not only creates an w-h-o pseudo-HTML to HTML translation function, but as well runs it and emits the obtained HTML as a string" `(macrolet ((who-tmp () `(with-html-output-to-string (,(gensym)) ,,pseudo-html-form))) (who-tmp))) And the example usage can be: (def-who-macro ps-script (&body body) `(:script :type "text/javascript" (fmt "~%// ~%"))) (def-who-page demo-page () `(:html (:head ,(:ps-script (defun hi () (alert "Hello world!")))) (:body (:input :type "button" :value "Click here...")))) The only catch is that DEF-WHO-MACRO actually generates not a macro in Lisp terms, but a function, which constructs lists of pseudo-HTML forms. I hope, the given code will be useful. Best regards, Vsevolod Dyomkin From taylor at metasyntax.net Sun Jul 27 15:10:03 2008 From: taylor at metasyntax.net (Taylor Venable) Date: Sun, 27 Jul 2008 11:10:03 -0400 Subject: [cl-who-devel] Generating HTML using the result of a function call Message-ID: <20080727111003.fac99d8b.taylor@metasyntax.net> Hello, I've been trying to figure out how to do something in CL-WHO and haven't been able to get it yet, so I thought perhaps somebody on here might be able to help me out. I'm working on an RSS / blog component on my website which is written in Lisp (running on top of Hunchentoot, specifically). Each entry in the blog consists of a file located in a hierarchy that composes a date: e.g. /blog/2008/05/02 for the entry of May 2nd, 2008. Each entry file is a Lisp file with the following structure: ((title . "The Title Goes Here") (description . "This is what gets shown in the RSS feed.") (body . (:div :id "content" (:p "This is the first paragraph in the entry.") (:p "Here's another paragraph with " (:a :href "/foo" "a link") " inside of it.")))) My goal is to use the Lisp reader to read the list into a variable, let's call it "content", and to pull out of "content" the things that I need to render. With RSS this was possible by using something like: (cl-who:with-html-output (output) (:item (:title (cl-who:str (cdr (assoc :title content)))) (:description (cl-who:str (cdr (assoc :description content)))))) But I also want to render HTML pages constructed from the "body" part of the entry, something that would work like: (with-open-file (input (site-file path)) (let ((content (read input))) (cl-who:with-html-output (output) (cdr (assoc :body content))))) But evaluate (cdr (assoc :body content)) and use the result [in this case it would turn into the HTML template code that I wanted] rather than doing what seems to be the default behaviour of evaluating the expression but then outputting nothing. Is this possible with CL-WHO at this time? If not, would it be difficult to add such feature in a manner similar to how CL-WHO:STR and CL-WHO:HTM work? Thanks for any help or ideas. I'm using version 0.11.1 running under SBCL 1.0.11 on Ubuntu GNU/Linux 8.04.1 -- Taylor Venable http://real.metasyntax.net:2357/ foldr = lambda f, i, l: (len(l) == 1 and [f(l[0], i)] or [f(l[0], foldr(f, i, l[1:]))])[0] From info at jensteich.de Mon Jul 28 09:07:53 2008 From: info at jensteich.de (Jens Teich) Date: Mon, 28 Jul 2008 11:07:53 +0200 Subject: [cl-who-devel] Generating HTML using the result of a function call In-Reply-To: <20080727111003.fac99d8b.taylor@metasyntax.net> References: <20080727111003.fac99d8b.taylor@metasyntax.net> Message-ID: <488D8C69.8090001@jensteich.de> > ... similar to how CL-WHO:STR and CL-WHO:HTM work? Have you already discovered cl-who:fmt? jens From leslie.polzer at gmx.net Tue Jul 29 07:36:48 2008 From: leslie.polzer at gmx.net (Leslie P. Polzer) Date: Tue, 29 Jul 2008 09:36:48 +0200 (CEST) Subject: [cl-who-devel] Macroexpansion of with-html-output body? (follow-up) In-Reply-To: <89dc7c5b0807251328i4b2a74c8re1ada0856f39a910@mail.gmail.com> References: <89dc7c5b0807251328i4b2a74c8re1ada0856f39a910@mail.gmail.com> Message-ID: <61446.88.73.249.231.1217317008.squirrel@mail.stardawn.org> Have you looked at Parenscript's macro implementation? It seems more natural to use. It would be great to have this in mainline when it's clean. From vseloved at gmail.com Tue Jul 29 09:09:01 2008 From: vseloved at gmail.com (Vsevolod) Date: Tue, 29 Jul 2008 12:09:01 +0300 Subject: [cl-who-devel] Macroexpansion of with-html-output body? (follow-up) In-Reply-To: <61446.88.73.249.231.1217317008.squirrel@mail.stardawn.org> References: <89dc7c5b0807251328i4b2a74c8re1ada0856f39a910@mail.gmail.com> <61446.88.73.249.231.1217317008.squirrel@mail.stardawn.org> Message-ID: <89dc7c5b0807290209h6647d49fh9d4846ecda0ad8f8@mail.gmail.com> If you mean process-html-forms (from lib/js-html as of 20071104 release), as afar as I understand, it's just a simplistic alternative to CL-WHO. While all the code examples in the manual are for Allegro's net.html.generator library (more info can be seen here: http://common-lisp.net/pipermail/parenscript-devel/2008-April/000180.html)... And, speaking about naturalness of use, that was exactly my starting point, when I tried to use macros with (as I call them for a lack of a better name) pseudo-html-forms inside w-h-o body just like it could be done for macros with ordinary forms inside of other lisp forms, and saw that it's not possible, because pseudo-html-forms inside w-h-o are not evaluated by the same rules as lisp forms. So I thought, that maybe a good idea would be to add another layer of special processing with the EMB keyword (http://common-lisp.net/pipermail/cl-who-devel/2008-June/000156.html), the same as STR, FMT etc. But keywords add complexity, because you should remember their usage rules. Once again it's not lispy enough, so to say. That's why I moved to the next idea. To conclude, I don't see a way to integrate fully implicit macroexpansion in with-html-output without a substantial refactoring of the library code. By the way, you can see one such attempt here: http://common-lisp.net/pipermail/cl-who-devel/2008-February/000127.html But, again, there arises a dilemma: should there be syntactic hints in the code, that a 'special' cl-who-macro is used. In this variant, there are none. In the variants, I've proposed, there is either EMB keyword or a comma. That's an open topic for discussion, which, I think, can be resolved by Edi Weitz, who will determine how to implement that himself. P.S. Btw, I think, the above link can as well be of interest in the weblocks group. On 7/29/08, Leslie P. Polzer wrote: > > Have you looked at Parenscript's macro implementation? > It seems more natural to use. > > It would be great to have this in mainline when it's clean. > > _______________________________________________ > cl-who-devel site list > cl-who-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cl-who-devel From taylor at metasyntax.net Wed Jul 30 00:33:53 2008 From: taylor at metasyntax.net (Taylor Venable) Date: Tue, 29 Jul 2008 20:33:53 -0400 Subject: [cl-who-devel] Generating HTML using the result of a function call In-Reply-To: <488D8C69.8090001@jensteich.de> References: <20080727111003.fac99d8b.taylor@metasyntax.net> <488D8C69.8090001@jensteich.de> Message-ID: <20080729203353.e9b83a15.taylor@metasyntax.net> On Mon, 28 Jul 2008 11:07:53 +0200 Jens Teich wrote: > > ... similar to how CL-WHO:STR and CL-WHO:HTM work? > > Have you already discovered cl-who:fmt? This won't do it. For example: METASYNTAX> (cl-who:with-html-output (*standard-output*) (cl-who:fmt "~A" (car '((:p "foo"))))) (P foo) NIL I need something like: METASYNTAX> (cl-who:with-html-output (*standard-output*) (cl-who:evaluate (car '((:p "foo")))))

foo

NIL -- Taylor Venable http://real.metasyntax.net:2357/ foldr = lambda f, i, l: (len(l) == 1 and [f(l[0], i)] or [f(l[0], foldr(f, i, l[1:]))])[0]