Macro: DEFTAG

Documentation

Define a new tag. ATTRIBUTES should be an attribute-spec (see parse-attributes and attribute-bind). BODY is simply the body of the expander lambda. Within the BODY the functions EMIT-CODE, EMIT-PRINC and EMIT-HTML can be used to generate code. EMIT-CODE should be passed lisp code which will be executed at runtime.

Source

(defmacro deftag (name attributes &body body)
  "Define a new tag.

ATTRIBUTES should be an attribute-spec (see parse-attributes and
attribute-bind).

BODY is simply the body of the expander lambda.

Within the BODY the functions EMIT-CODE, EMIT-PRINC and EMIT-HTML can
be used to generate code. EMIT-CODE should be passed lisp code which
will be executed at runtime."
  (with-unique-names (contents)
    `(progn
       (setf (gethash ',name *expanders*)
             (lambda (,contents)
               (handler-bind ((tag-related-error (lambda (c)
                                                   (setf (tag c) ,contents))))
                 (attribute-bind ,attributes ,contents
                   ,@body))))
       (defmacro ,name (&rest contents)
         (let ((%yaclml-code% nil)
	       (%yaclml-indentation-depth% 0))
           ;; build tag's body
	   (funcall (gethash ',name *expanders*) contents)
           (setf %yaclml-code% (nreverse %yaclml-code%))
	   ;; now that we've generated the code we can fold the
	   ;; strings in yaclml-code and princ them, leaving any other
	   ;; forms as they are.
           `(progn ,@(mapcar (lambda (form)
                               (if (stringp form)
                                   `(write-string ,form *yaclml-stream*)
				   form))
                             (fold-strings %yaclml-code%))
             (values)))))))
Source Context