@@ -697,44 +697,54 @@ This sets the doctype to be html5 compatible <!DOCTYPE html>."
697697 (setf (slot-value it ' rune-dom::children) (rune-dom ::make-node-list))
698698 it)
699699
700- (defun %enstream (stream s-name content)
701- " Helper to bind a stream or with-output-to-string it, based on whether "
702- ` (let ((, s-name , stream))
703- (if , s-name
704- , content
705- (with-output-to-string (, s-name) , content))))
700+ (defvar *snippet-output-stream* nil )
701+
702+ (defun %enstream (stream content-fn)
703+ (let* ((old-out-stream *snippet-output-stream* )
704+ (*snippet-output-stream* (or stream (make-string-output-stream )))
705+ (result (multiple-value-list (funcall content-fn))))
706+ (cond
707+ (stream (apply #' values result))
708+ (old-out-stream
709+ (write-string (get-output-stream-string *snippet-output-stream* ) old-out-stream))
710+ (t (get-output-stream-string *snippet-output-stream* )))))
711+
712+ (defun %buffer-xml-output (stream sink body-fn)
713+ (let ((cxml ::*sink* (or sink (make-character-stream-sink stream )))
714+ (cxml ::*current-element* nil )
715+ (cxml ::*unparse-namespace-bindings* cxml ::*initial-namespace-bindings* )
716+ (cxml ::*current-namespace-bindings* nil ))
717+ (setf (cxml ::sink-omit-xml-declaration-p cxml ::*sink* ) T )
718+ (sax :start-document cxml ::*sink* )
719+ (funcall body-fn)
720+ (sax :end-document cxml ::*sink* )))
706721
707722(defmacro buffer-xml-output ((&optional stream sink) &body body)
708723 " buffers out sax:events to a sting
709724
710725 xml parameters like <param:foo param:type=\" string\" ><div>bar</div></param:foo>
711726 are requested to be strings (presumably for string processing)
712727 "
713- (alexandria :with-unique-names (out-str)
714- (let ((content
715- ` (let ((cxml ::*sink* (or , sink (make-character-stream-sink , out-str)))
716- (cxml ::*current-element* nil )
717- (cxml ::*unparse-namespace-bindings* cxml ::*initial-namespace-bindings* )
718- (cxml ::*current-namespace-bindings* nil ))
719- (setf (cxml ::sink-omit-xml-declaration-p cxml ::*sink* ) T )
720- (sax :start-document cxml ::*sink* )
721- ,@ body
722- (sax :end-document cxml ::*sink* ))))
723- (%enstream stream out-str content))))
728+ (let ((content ` (lambda () (%buffer-xml-output *snippet-output-stream* , sink (lambda () ,@ body)))))
729+ ` (%enstream , stream , content)))
724730
725731(defmacro %with-snippet ((type &optional stream sink) &body body)
726732 " helper to define with-html-snippet and with-xhtml-snippet"
727733 (assert (member type ' (with-html-document with-xhtml-document)))
728- (alexandria :with-unique-names (out-str)
729- (let ((body
730- ` (let ((*html-compatibility-mode* , (eql type ' with-html-document)))
731- (, type
732- (let ((content (flatten-children (progn ,@ body))))
733- (iter (for n in content)
734- (buffer-xml-output (, out-str , sink) (buildnode ::dom-walk cxml ::*sink* n))))
735- nil ))))
736- (%enstream stream out-str body)
737- )))
734+ (alexandria :with-unique-names (result)
735+ ` (let ((*html-compatibility-mode* , (eql type ' with-html-document))
736+ , result)
737+ (, type
738+ (progn
739+ (setf
740+ , result
741+ (multiple-value-list
742+ (buffer-xml-output (, stream , sink)
743+ (let ((content (flatten-children (progn ,@ body))))
744+ (iter (for n in content)
745+ (buildnode ::dom-walk cxml ::*sink* n))))))
746+ nil ))
747+ (apply #' values , result))))
738748
739749(defmacro with-html-snippet ((&optional stream sink) &body body)
740750 " builds a little piece of html-dom and renders that to a string / stream"
0 commit comments