Update of /project/cxml/cvsroot/cxml/xml In directory clnet:/tmp/cvs-serv26802
Modified Files: unparse.lisp Log Message: escape % in internal entities new function unparsed-internal-subset use " to escape IDs containing '
--- /project/cxml/cvsroot/cxml/xml/unparse.lisp 2007/06/16 11:27:19 1.16 +++ /project/cxml/cvsroot/cxml/xml/unparse.lisp 2007/07/01 17:25:39 1.17 @@ -79,6 +79,7 @@ (name-for-dtd :accessor name-for-dtd) (previous-notation :initform nil :accessor previous-notation) (have-doctype :initform nil :accessor have-doctype) + (have-internal-subset :initform nil :accessor have-internal-subset) (stack :initform nil :accessor stack)))
(defmethod initialize-instance :after ((instance sink) &key) @@ -156,6 +157,9 @@ (%write-rod #""" sink)))))
(defmethod sax:start-internal-subset ((sink sink)) + (when (have-internal-subset sink) + (error "duplicate internal subset")) + (setf (have-internal-subset sink) t) (ensure-doctype sink) (%write-rod #" [" sink) (%write-rune #/U+000A sink)) @@ -164,6 +168,25 @@ (ensure-doctype sink) (%write-rod #"]" sink))
+(defmethod sax:unparsed-internal-subset ((sink sink) str) + (when (have-internal-subset sink) + (error "duplicate internal subset")) + (setf (have-internal-subset sink) t) + (ensure-doctype sink) + (%write-rod #" [" sink) + (%write-rune #/U+000A sink) + (unparse-string str sink) + (%write-rod #"]" sink)) + +;; for the benefit of the XML test suite, prefer ' over " +(defun write-quoted-rod (x sink) + (let ((q (if (find #/' x) #/" #/' + ;; '" (thanks you Emacs indentation, the if ends here) + ))) + (%write-rune q sink) + (%write-rod x sink) + (%write-rune q sink))) + (defmethod sax:notation-declaration ((sink sink) name public-id system-id) (let ((prev (previous-notation sink))) (when (and (and (canonical sink) (>= (canonical sink) 2)) @@ -175,19 +198,16 @@ (%write-rod name sink) (cond ((zerop (length public-id)) - (%write-rod #" SYSTEM '" sink) - (%write-rod system-id sink) - (%write-rune #/' sink)) + (%write-rod #" SYSTEM " sink) + (write-quoted-rod system-id sink)) ((zerop (length system-id)) - (%write-rod #" PUBLIC '" sink) - (%write-rod public-id sink) - (%write-rune #/' sink)) + (%write-rod #" PUBLIC " sink) + (write-quoted-rod public-id sink)) (t - (%write-rod #" PUBLIC '" sink) - (%write-rod public-id sink) - (%write-rod #"' '" sink) - (%write-rod system-id sink) - (%write-rune #/' sink))) + (%write-rod #" PUBLIC " sink) + (write-quoted-rod public-id sink) + (%write-rod #" " sink) + (write-quoted-rod system-id sink))) (%write-rune #/> sink) (%write-rune #/U+000A sink))
@@ -198,19 +218,16 @@ (%write-rod name sink) (cond ((zerop (length public-id)) - (%write-rod #" SYSTEM '" sink) - (%write-rod system-id sink) - (%write-rune #/' sink)) + (%write-rod #" SYSTEM " sink) + (write-quoted-rod system-id sink)) ((zerop (length system-id)) - (%write-rod #" PUBLIC '" sink) - (%write-rod public-id sink) - (%write-rune #/' sink)) + (%write-rod #" PUBLIC " sink) + (write-quoted-rod public-id sink)) (t - (%write-rod #" PUBLIC '" sink) - (%write-rod public-id sink) - (%write-rod #"' '" sink) - (%write-rod system-id sink) - (%write-rune #/' sink))) + (%write-rod #" PUBLIC " sink) + (write-quoted-rod public-id sink) + (%write-rod #" " sink) + (write-quoted-rod system-id sink))) (%write-rod #" NDATA " sink) (%write-rod notation-name sink) (%write-rune #/> sink) @@ -226,19 +243,16 @@ (%write-rod name sink) (cond ((zerop (length public-id)) - (%write-rod #" SYSTEM '" sink) - (%write-rod system-id sink) - (%write-rune #/' sink)) + (%write-rod #" SYSTEM " sink) + (write-quoted-rod system-id sink)) ((zerop (length system-id)) - (%write-rod #" PUBLIC '" sink) - (%write-rod public-id sink) - (%write-rune #/' sink)) + (%write-rod #" PUBLIC " sink) + (write-quoted-rod public-id sink)) (t - (%write-rod #" PUBLIC '" sink) - (%write-rod public-id sink) - (%write-rod #"' '" sink) - (%write-rod system-id sink) - (%write-rune #/' sink))) + (%write-rod #" PUBLIC " sink) + (write-quoted-rod public-id sink) + (%write-rod #" " sink) + (write-quoted-rod system-id sink))) (%write-rune #/> sink) (%write-rune #/U+000A sink))
@@ -251,7 +265,7 @@ (%write-rod name sink) (%write-rune #/U+0020 sink) (%write-rune #/" sink) - (unparse-string value sink) + (unparse-dtd-string value sink) (%write-rune #/" sink) (%write-rune #/> sink) (%write-rune #/U+000A sink)) @@ -319,6 +333,7 @@ (when rest (%write-rune #| sink))) (%write-rune #/) sink))) + (%write-rune #/U+0020 sink) (cond ((atom default) (%write-rune #/# sink) @@ -498,6 +513,22 @@ (t (write-rune c ystream))))
+(defun unparse-dtd-string (str sink) + (let ((y (sink-ystream sink))) + (loop for rune across str do (unparse-dtd-char rune y)))) + +(defun unparse-dtd-char (c ystream) + (cond ((rune= c #/%) (write-rod '#.(string-rod "%") ystream)) + ((rune= c #/&) (write-rod '#.(string-rod "&") ystream)) + ((rune= c #/<) (write-rod '#.(string-rod "<") ystream)) + ((rune= c #/>) (write-rod '#.(string-rod ">") ystream)) + ((rune= c #/") (write-rod '#.(string-rod """) ystream)) + ((rune= c #/U+0009) (write-rod '#.(string-rod "	") ystream)) + ((rune= c #/U+000A) (write-rod '#.(string-rod " ") ystream)) + ((rune= c #/U+000D) (write-rod '#.(string-rod " ") ystream)) + (t + (write-rune c ystream)))) + (defun %write-rune (c sink) (write-rune c (sink-ystream sink)))