你可以改变 Lisp 阅读器的情况。
保存
(setf (readtable-case *readtable*) :preserve)
从现在开始,所有 CL 符号都必须用大写字母书写,但您只能在需要读取 SVG 树的文件中使用named-readtables对更改进行本地化。
(DEFPACKAGE :TWHO (:USE :CL :CL-WHO))
(IN-PACKAGE :TWHO)
(SETF *DOWNCASE-TOKENS-P* NIL)
(WITH-HTML-OUTPUT (*STANDARD-OUTPUT* *STANDARD-OUTPUT* :INDENT T)
(:defs
(:radialGradient :id "grad1" :cy "20" :fx "10%" :fy "50%" :r "8"
(:stop :offset "0%" :stop-color "#fff")
(:stop :offset "100%" :stop-color "#000"))))
写入以下内容:
<defs>
<radialGradient id='grad1' cy='20' fx='10%' fy='50%' r='8'>
<stop offset='0%' stop-color='#fff'></stop>
<stop offset='100%' stop-color='#000'></stop>
</radialGradient>
</defs>
倒置
我个人会使用:invert
,但在这种情况下,您必须将所有小写 SVG 符号都写成大写。
(SETF (READTABLE-CASE *READTABLE*) :INVERT)
(with-html-output (*standard-output* *standard-output* :indent t)
(:DEFS
(:radialGradient :ID "grad1" :CY "20" :FX "10%" :FY "50%" :R "8"
(:STOP :OFFSET "0%" :STOP-COLOR "#fff")
(:STOP :OFFSET "100%" :STOP-COLOR "#000"))))
写同样的事情:
<defs>
<radialGradient id='grad1' cy='20' fx='10%' fy='50%' r='8'>
<stop offset='0%' stop-color='#fff'></stop>
<stop offset='100%' stop-color='#000'></stop>
</radialGradient>
</defs>"
但至少你的 CL 代码不需要写成大写。
宏和/或宏字符
您可以使用宏和宏字符在本地进行更改。
将所有内容重置为默认值:
(setf *downcase-tokens-p* t)
(setf (readtable-case *readtable*) :upcase)
我个人不介意*downcase-tokens-p*
全局更改,但如果您真的想要,除了使用之外的另一种方法eval
是手动进行宏扩展。对于此示例,我使用的是macroexpand-dammit:
(ql:quickload "macroexpand-dammit")
然后,定义一个自定义宏:
(defmacro with-svg-output ((stream) &body body)
(let ((*downcase-tokens-p* nil))
(let ((stream% (copy-symbol :stream)))
(macroexpand-dammit:macroexpand-dammit
`(let ((,stream% ,stream))
(with-html-output (,stream% ,stream% :indent t)
,@body))))))
最后,为了只在读取 SVG 表单时改变 readtable 的大小写,定义一个自定义的 reader 函数;我将它绑定到#@
字符序列:
(set-dispatch-macro-character
#\# #\@
(lambda (stream &rest args)
(declare (ignore args))
(let ((*readtable* (copy-readtable)))
(setf (readtable-case *readtable*) :invert)
(read stream t nil t))))
该示例可以重写为:
(with-svg-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"))))
这里的优点是您的更改仅在本地应用,并且有一种非常独特的语法,表明发生了不同的事情。如果您可以在 SVG 表达式中以大写形式编写代码,则可以:preserve
改用。这取决于什么对你更方便。