ruricolist / spinneret

Common Lisp HTML5 generator
MIT License
369 stars 26 forks source link

:CDATA tag returns double cdata-end #50

Closed faeredia closed 3 years ago

faeredia commented 3 years ago

:CDATA is doubling up on the closing ]]>. The following example:

(defun example ()
  (with-html-string
    (:html
     (:head
      (:script
       (:CDATA (ps (defvar n 1))))))))

Returns

"<html lang=en>
 <head>
  <meta charset=UTF-8>
  <script><![CDATA[if ('undefined' === typeof n) {
    var n = 1;
};]]>]]&gt</script>
 </head>
</html>"

Note the additional cdata-end (the closing > converted to &gt)

Changing the definition of cdata in run.lisp to return (values) results in the expected behaviour (no double cdata-end)

(defun cdata (text safe? &aux (html *html*))
  (write-string cdata-start html)
  (write-string (if safe?
                    text
                    (escape-cdata text))
                html)
  (write-string cdata-end html)
  (values))

Not sure yet why the return value of cdata is being written

faeredia commented 3 years ago

Looks like the comment function in run.lisp also doubles the closing --> under certain conditions.

(defun example ()
  (with-html-string
    (:html
      (:!-- "something"))))

returns

"<html lang=en>
 <!-- something -->

</html>"

but, calling it with

(let ((spinneret::*print-pretty* nil)) (example))

returns

"<html lang=en><!-- something --> --&gt</html>"

Note the double closing -->.

Seems to boil down to the use of format, which returns nil, and write-string, which returns the string written.

So the comment function in run.lisp could be fixed by returning (values) as well

ruricolist commented 3 years ago

Thanks for catching this. If you'd like to make a pull request (ideally with tests) I'd be happy to merge it.