Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Svg cl who中的混合案例标记名称_Svg_Common Lisp_Cl Who - Fatal编程技术网

Svg cl who中的混合案例标记名称

Svg cl who中的混合案例标记名称,svg,common-lisp,cl-who,Svg,Common Lisp,Cl Who,我正在使用cl who生成svg,在我需要混合大小写标记之前,它工作正常: (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"))

我正在使用cl who生成svg,在我需要混合大小写标记之前,它工作正常:

(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"))))
对于这种情况,有一个变量*downcase-tokens-p*。工作起来有点难:

(let ((*downcase-tokens-p* nil))
  (with-html-output (*standard-output*)
    (:defs
        (:|radialGradient| :id "grad1" :cy "20" :fx "10%" :fy "50%" :r "8"))))
输出:

<defs>
  <radialgradient id='grad1' cy='20' fx='10%' fy='50%' r='8'>
  </radialgradient>
</defs>
<DEFS>
  <radialGradient ID='grad1' CY='20' FX='10%' FY='50%' R='8'>
  </radialGradient>
</DEFS>
<defs>
  <radialGradient id='grad1' cy='20' fx='10%' fy='50%' r='8'
  </radialGradient>
</defs>
输出:

<defs>
  <radialgradient id='grad1' cy='20' fx='10%' fy='50%' r='8'>
  </radialgradient>
</defs>
<DEFS>
  <radialGradient ID='grad1' CY='20' FX='10%' FY='50%' R='8'>
  </radialGradient>
</DEFS>
<defs>
  <radialGradient id='grad1' cy='20' fx='10%' fy='50%' r='8'
  </radialGradient>
</defs>
这适用于radialGradient标记,但现在我需要| |包装其他所有内容

让radialGradient标记正确显示的最简单方法是什么


编辑:添加示例。

覆盖单个标记的呈现方法:

(defmethod convert-tag-to-string-list ((tag (eql :radialgradient))
                                       attr-list body body-fn)
  (nconc (cons "<radialGradient"
               (convert-attributes attr-list))
         (list ">")
         (funcall body-fn body)
         (list "</radialGradient>")))
输出:

<defs>
  <radialgradient id='grad1' cy='20' fx='10%' fy='50%' r='8'>
  </radialgradient>
</defs>
<DEFS>
  <radialGradient ID='grad1' CY='20' FX='10%' FY='50%' R='8'>
  </radialGradient>
</DEFS>
<defs>
  <radialGradient id='grad1' cy='20' fx='10%' fy='50%' r='8'
  </radialGradient>
</defs>

需要为正在使用的每个混合大小写SVG标记定义将标记转换为字符串列表方法。

覆盖单个标记的呈现方法:

(defmethod convert-tag-to-string-list ((tag (eql :radialgradient))
                                       attr-list body body-fn)
  (nconc (cons "<radialGradient"
               (convert-attributes attr-list))
         (list ">")
         (funcall body-fn body)
         (list "</radialGradient>")))
输出:

<defs>
  <radialgradient id='grad1' cy='20' fx='10%' fy='50%' r='8'>
  </radialgradient>
</defs>
<DEFS>
  <radialGradient ID='grad1' CY='20' FX='10%' FY='50%' R='8'>
  </radialGradient>
</DEFS>
<defs>
  <radialGradient id='grad1' cy='20' fx='10%' fy='50%' r='8'
  </radialGradient>
</defs>

需要为正在使用的每个混合大小写SVG标记定义一个将标记转换为字符串列表的方法。

以下是一个通用解决方案:

(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)))
结果:

CL-USER> (with-html-output (*standard-output*)
           (:asdf
            (:ASDF
             (:|aSDf|
               (:|ASDF|)))))
<asdf><asdf><aSDf><asdf></asdf></aSDf></asdf></asdf>

这里有一个通用的解决方案:

(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)))
结果:

CL-USER> (with-html-output (*standard-output*)
           (:asdf
            (:ASDF
             (:|aSDf|
               (:|ASDF|)))))
<asdf><asdf><aSDf><asdf></asdf></aSDf></asdf></asdf>

您可以更改Lisp阅读器的大小写

保护 从现在起,所有CL符号都必须用大写字母书写,但您可以仅在需要读取SVG树的文件中进行本地化更改

(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>
写了同样的东西:

<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>"
我个人不介意全局更改*downcase-tokens-p*,但如果您真的想更改,除了使用eval之外的另一种方法是手动宏扩展。在本例中,我使用的是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表单时更改可读表的大小写,请定义一个自定义读取器函数;我将其绑定到@字符序列:

(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。这取决于什么对您更方便。

您可以更改Lisp读取器的大小写

保护 从现在起,所有CL符号都必须用大写字母书写,但您可以仅在需要读取SVG树的文件中进行本地化更改

(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>
写了同样的东西:

<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>"
我个人不介意全局更改*downcase-tokens-p*,但如果您真的想更改,除了使用eval之外的另一种方法是手动宏扩展。在本例中,我使用的是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表单时更改可读表的大小写,请定义一个自定义读取器函数;我将其绑定到@字符序列:

(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。这取决于什么对您更方便。

自cl-who-20190710-git起,默认情况下,它将混合大小写关键字保留为标记名,因此无需添加任何宏/方法即可使用:

 (htm 
   (:|clipPath| :x 0 :y 0 ...))

有*downcase-tokens-p*选项可对其进行配置。

自cl-who-20190710-git起,默认情况下,它将混合大小写关键字保留为标记名,因此无需添加任何宏/方法即可使用:

 (htm 
   (:|clipPath| :x 0 :y 0 ...))

有*downcase-tokens-p*选项来配置它。

为什么需要这样做?html是一种不区分大小写的语言?我正在生成svg,我可能希望将其嵌入html页面中。Cl谁有xml模式,顺便说一句:为什么这是必要的?html是一种不区分大小写的语言?我正在生成svg,我可能希望将其嵌入html页面中。具有xml模式的Cl,顺便说一句: