I'm using cl-who to generate svg, and it is working fine up until I need a mixed case tag:
(with-html-output (*standard-output*)
(:defs
(:|radialGradient| :id "grad1" :cy "20" :fx "10%" :fy "50%" :r "8"
(:stop :offset "0%" :stop-color "#fff")
(:stop :offset "100%" :stop-color "#000"))))
There is a variable, *downcase-tokens-p*, for situations like this. It's a bit hard to work with:
(let ((*downcase-tokens-p* nil))
(with-html-output (*standard-output*)
(:defs
(:|radialGradient| :id "grad1" :cy "20" :fx "10%" :fy "50%" :r "8"))))
Output:
<defs>
<radialgradient id='grad1' cy='20' fx='10%' fy='50%' r='8'>
</radialgradient>
</defs>
Wrapping with let has no effect because *downcase-tokens-p* was evidently set T at macro expansion time.
So we need to haul out eval:
(let ((*downcase-tokens-p* nil))
(eval
'(with-html-output (*standard-output*)
(:defs
(:|radialGradient| :id "grad1" :cy "20" :fx "10%" :fy "50%" :r "8")))))
Output:
<DEFS>
<radialGradient ID='grad1' CY='20' FX='10%' FY='50%' R='8'>
</radialGradient>
</DEFS>
This works for the radialGradient tag, but now I'll need to || wrap everything else.
What is the simplest way to get the radialGradient tag to display properly while leaving everything else alone?
Edit: examples added.
Here's a generic solution:
(defmethod convert-tag-to-string-list :around ((tag t) attr-list body body-fn)
(if (find-if #'lower-case-p (symbol-name tag))
(nconc (list* "<"
(symbol-name tag)
(convert-attributes attr-list))
(list ">")
(funcall body-fn body)
(list (format nil "</~a>" (symbol-name tag))))
(call-next-method)))
Results:
CL-USER> (with-html-output (*standard-output*)
(:asdf
(:ASDF
(:|aSDf|
(:|ASDF|)))))
<asdf><asdf><aSDf><asdf></asdf></aSDf></asdf></asdf>