2012-04-12 3 views
1

sagen, dass ich ein Makro für CL-WHO definiert haben:Common Lisp: Wie Makro zu verwenden, um S-Ausdrücke für CL-WHO zu generieren?

(defmacro test-html (&body body) 
    `(with-html-output-to-string (*standard-output* nil :PROLOGUE t :indent t) 
     (:html 
     (:body 
    ,@body)))) 

Dann:

(test-html (:h1 "hallo")) 

Gibt (erste Zeile entfernt):

"<html> 
    <body> 
    <h1> 
     hallo 
    </h1> 
    </body> 
</html>" 

Wie erwartet. Jetzt habe ich eine Funktion definiert, um den s-Ausdruck zu erzeugen, indem CL-WHO verwendet werden:

(defun test-header (txt) 
    `(:h1 ,txt)) 

Beim Aufruf mit "Hallo" zurück

(:h1 "hallo") 

aber jetzt, wenn ich rufe

(test-html (test-header "hallo")) 

Es gibt:

"<html> 
    <body> 

    </body> 
</html>" 

Was ist schief gegangen und warum?

Antwort

1

So wie ich dieses Problem zu lösen neigen Problem ist, indem Sie ein Shortcut-Makro wie

(defmacro html-to-stout (&body body) 
    "Outputs HTML to standard out." 
    `(with-html-output (*standard-output* nil :indent t) ,@body)) 

oder die Zeichenfolge-Äquivalent definieren. Der Schlüssel hier ist, dass es kein :prologue ausgibt, damit es ein HTML-Chunklet lieber als eine ganze Seite ausgeben kann. Sobald Sie das haben, können Sie Dinge wie

(defun test-header (text) 
    (html-to-stout 
    (:h1 (str text)))) 

(test-html (test-header "Hello Hello")) 
1

Ich hatte das gleiche Problem. Soweit ich google konnte, war, dass es in der offiziellen Version von cl-wer nicht möglich ist: http://lisp-univ-etc.blogspot.com/2009/03/cl-who-macros.html

ich stattdessen diese Version verwendet, die Makros unterstützt: https://github.com/vseloved/cl-who

+1

Danke für den Link! Es ist lustig ... nachdem ich den ganzen Artikel gelesen und den Kommentarteil erreicht habe, habe ich festgestellt, dass ich diesen Artikel vor 2 Monaten gelesen habe und einen Kommentar hinterlassen habe. Meine Erinnerung versagt mir - ich werde Vsevolods Gabel ausprobieren! – mck