+(defun process-attributes (args)
+ (do* ((xx args (cddr xx))
+ (res)
+ (name (first xx) (first xx))
+ (value (second xx) (second xx)))
+ ((null xx)
+ (nreverse res))
+ (case name
+ (:if*
+ (push `(if* ,value
+ then (write-string ,(format nil " ~(~a~)" (third xx))
+ *html-stream*)
+ (prin1-safe-http-string ,(fourth xx)))
+ res)
+ (pop xx) (pop xx))
+ (:fformat
+ (unless (and (listp value)
+ (>= (length value) 2))
+ (error ":fformat must be given a list at least 2 elements"))
+ (push `(write-string
+ ,(format nil " ~(~a~)=\"" (first value))
+ *html-stream*) res)
+ (push
+ `(fformat *html-stream* ,(second value) ,@(cddr value)) res)
+ (push `(write-char #\" *html-stream*) res))
+ (:format
+ (unless (and (listp value) (>= (length value) 2))
+ (error ":format must be given a list at least 2 elements"))
+ (push `(write-string ,(format nil " ~(~a~)" (first value))
+ *html-stream*) res)
+ (push `(prin1-safe-http-string
+ (fformat nil ,(second value) ,@(cddr value)))
+ res))
+ (:optional
+ (push `(when ,(second value)
+ (write-string
+ ,(format nil " ~(~a~)" (first value))
+ *html-stream*)
+ (prin1-safe-http-string ,(second value)))
+ res))
+ (:if
+ (unless (and (listp value)
+ (>= (length value) 3)
+ (<= (length value) 4))
+ (error ":if must be given a list with 3 and 4 elements"))
+ (let ((eval-if (gensym "EVAL-IF-")))
+ (push `(let ((,eval-if ,(second value)))
+ (write-string ,(format nil " ~(~a~)" (first value)) *html-stream*)
+ (prin1-safe-http-string
+ (if ,eval-if
+ ,(third value)
+ ,(fourth value))))
+ res)))
+ (t
+ (push `(write-string ,(format nil " ~(~a~)" name) *html-stream*)
+ res)
+ (push `(prin1-safe-http-string ,value) res)))))
+