[closure-cvs] CVS closure/src/parse
emarsden
emarsden at common-lisp.net
Wed Jan 3 16:07:25 UTC 2007
Update of /project/closure/cvsroot/closure/src/parse
In directory clnet:/tmp/cvs-serv3355/src/parse
Modified Files:
pt.lisp
Log Message:
Reimplement the LHTML parser. The previous version could not handle
forms like ((:a :href "/foo.html") "foo").
--- /project/closure/cvsroot/closure/src/parse/pt.lisp 2006/12/31 13:24:49 1.5
+++ /project/closure/cvsroot/closure/src/parse/pt.lisp 2007/01/03 16:07:25 1.6
@@ -148,7 +148,7 @@
(setf (pt-parent k) res))
res))
-(defun ppt (pt &optional (prefix "") (barp nil))
+(defun ppt (pt &optional (stream *standard-output*) (prefix "") (barp nil))
(cond ((eq (pt-name pt) :pcdata)
(let ((s (map 'string
#'(lambda (x)
@@ -162,15 +162,16 @@
(setq s (concatenate 'string (subseq s 0 (- 120 (length prefix))))
flag t))
(write-string (format nil "~%~A| ~S ~A" prefix s
- (if flag "..." "")))))
+ (if flag "..." "")) stream)))
(t
- (write-string (format nil "~%~A| ~A" prefix (pt-name pt)))
+ (write-string (format nil "~%~A| ~A" prefix (pt-name pt)) stream)
(when (pt-children pt)
(write-string (format nil "~%~A~A-~A."
prefix
(if barp "+" "`")
(make-string (length (symbol-name (pt-name pt)))
- :initial-element #\- )))
+ :initial-element #\- ))
+ stream)
(let ((prefix1 (concatenate 'string
prefix (if barp "|" " ")
(make-string (length (symbol-name (pt-name pt)))
@@ -178,7 +179,7 @@
" ")))
(do ((q (pt-children pt) (cdr q)))
((null q))
- (ppt (car q) prefix1 (if (cdr q) 't 'nil))))))))
+ (ppt (car q) stream prefix1 (if (cdr q) 't 'nil))))))))
;;; -------------------------------------------------------------------------------------------
@@ -218,27 +219,33 @@
(cond ((null pt) nil)
((cons (pt-name pt) (pt-full-name-path (pt-parent pt))))))
-(defun lhtml->pt (tree)
- (cond ((typep tree 'rod)
- (sgml::make-pt :name :pcdata :attrs tree))
- ((stringp tree)
- (sgml::make-pt :name :pcdata :attrs (string-rod tree)))
- ((sgml::pt-p tree) tree)
- ((and (consp tree) (keywordp (car tree)))
- (let ((attrs nil)
- (gi (car tree)))
- (do ((q (cdr tree) (cddr q)))
- ((or (null q)
- (not (keywordp (car q))))
- (sgml::make-pt :name gi
- :attrs (nreverse attrs)
- :children (mapcar #'lhtml->pt q)))
- (push (car q) attrs)
- (push (rod (cadr q)) attrs))))
- (t
- (error "~S does not look like LHTML." tree)) ))
+(defun walk-lhtml (lhtml tag-callback text-callback)
+ (if (stringp lhtml)
+ (funcall text-callback lhtml)
+ (destructuring-bind (tag &rest body)
+ (if (consp lhtml) lhtml (list lhtml))
+ (destructuring-bind (tag-name &rest attributes)
+ (if (consp tag) tag (list tag))
+ (funcall tag-callback tag-name attributes body)))))
+
+(defun lhtml->pt (lhtml)
+ (walk-lhtml lhtml
+ ;; tag callback
+ (lambda (tag-name attributes body)
+ (make-pt :name tag-name
+ :attrs (loop :for (key value) :on attributes :by #'cddr
+ :collect key
+ :collect (etypecase value
+ (string (runes:string-rod value))
+ (sgml::rod value)))
+ :children (mapcar #'lhtml->pt body)))
+ ;; text callback
+ (lambda (string)
+ (assert (stringp string))
+ (make-pt :name :pcdata :attrs (runes:string-rod string)))))
(defun lhtml-reader (stream subchar arg)
+ (declare (ignore subchar arg))
`(lhtml->pt
,(funcall (get-macro-character #\`) stream nil)))
More information about the Closure-cvs
mailing list