Hi,
While using CL-WHO recently, I ran into a small problem wherein some tagnames/attributes could be determined only at runtime. Not knowing any easy way to do this "out of the box" in CL-WHO, I wrote this small macro (inspired by XML-EMITTER:WITH-TAG) -
(defmacro with-html-tag ((name &optional attributes) &body body) (let ((body-fn (gensym))) `(flet ((,body-fn () ,@body)) (call-with-html-tag ,name ,attributes #',body-fn))))
(defun call-with-html-tag (name attributes body-fn) (let ((tag-name (typecase name (symbol (string-downcase name)) (t name))))
(format t "<~A" tag-name) (when attributes (format t "~{~A~}" (cl-who:convert-attributes attributes))) (format t ">") (funcall body-fn) (format t "</~A>" tag-name)))
Note that it writes only to *standard-output*.
Usage -----
(defvar *x* :blockquote) => *X*
(with-output-to-string (*standard-output*) (cl-who:with-html-output (*standard-output*) (:body (with-html-tag (*x*) (cl-who:htm (:p "foo bar")))))) => "<body><blockquote><p>foo bar</p></blockquote></body>"
(with-output-to-string (*standard-output*) (cl-who:with-html-output (*standard-output*) (:body (with-html-tag (*x* '(("id" . "foo123"))) (cl-who:htm (:p "foo bar")))))) => "<body><blockquote id='foo123'><p>foo bar</p></blockquote></body>"
I think this will be a useful addition to CL-WHO (although this particular implementation can be improved a bit). Or did I miss out on some other way that CL-WHO can easily handle this?
Chaitanya