Thu Nov 19 06:25:36 UTC 2009 pix@kepibu.org * Moar CSS selectors, fewer explicit lambdas diff -rN -u old-Oh, Ducks!/notes new-Oh, Ducks!/notes --- old-Oh, Ducks!/notes 2015-10-19 08:27:54.000000000 +0000 +++ new-Oh, Ducks!/notes 2015-10-19 08:27:54.000000000 +0000 @@ -3,8 +3,26 @@ ** working lhtml/xmls support ** write documentation ** improve selector support -*** :nth-child -*** :first-child -*** :last-child -*** universal selector (*) +*** positional selectors + * [ ] :nth-child + * [ ] :nth-last-child + * [ ] :first-child + * [ ] :last-child + * [ ] :nth-of-type + * [ ] :nth-last-of-type + * [ ] :first-of-type + * [ ] :last-of-type + * [ ] :only-child + * [ ] :only-of-type + * [ ] :empty +*** attribute selectors + * [ ] attribute-present [att] + * [ ] attribute-equal [att=val] + * [ ] attribute-member [att~=val] + * [ ] attribute-lang [att|=val] + * [ ] attribute-begins [att^=val] + * [ ] attribute-ends [att$=val] + * [ ] attribute-contains [att*=val] +*** :not(...) *** any others? +** namespace support(?) diff -rN -u old-Oh, Ducks!/oh-ducks.asd new-Oh, Ducks!/oh-ducks.asd --- old-Oh, Ducks!/oh-ducks.asd 2015-10-19 08:27:54.000000000 +0000 +++ new-Oh, Ducks!/oh-ducks.asd 2015-10-19 08:27:54.000000000 +0000 @@ -20,7 +20,7 @@ ;; TODO: submit a patch for cl-unification to use ;; asdf-system-connections. Getting an unmodified version of ;; cl-unification to load the cl-ppcre stuff is a PITA. - :depends-on (:cl-unification :cl-ppcre :split-sequence) + :depends-on (:cl-unification :cl-ppcre :split-sequence :alexandria) :serial t :components ((:file "package") (:file "regexp-template") diff -rN -u old-Oh, Ducks!/package.lisp new-Oh, Ducks!/package.lisp --- old-Oh, Ducks!/package.lisp 2015-10-19 08:27:54.000000000 +0000 +++ new-Oh, Ducks!/package.lisp 2015-10-19 08:27:54.000000000 +0000 @@ -12,6 +12,10 @@ (defpackage #:oh-ducks (:use #:cl #:unify #:oh-ducks.traversal) + (:import-from #:alexandria + #:compose + #:curry + #:rcurry) (:export ;; template machinery #:*default-parser* #:html diff -rN -u old-Oh, Ducks!/selectors.lisp new-Oh, Ducks!/selectors.lisp --- old-Oh, Ducks!/selectors.lisp 2015-10-19 08:27:54.000000000 +0000 +++ new-Oh, Ducks!/selectors.lisp 2015-10-19 08:27:54.000000000 +0000 @@ -29,7 +29,6 @@ (defclass adjacent-combinator (combinator) ()) (defclass sibling-combinator (combinator) ()) -#+FIXME ; is this the right name? (defclass universal-selector (simple-selector) ()) (defclass type-selector (simple-selector) ()) (defclass id-selector (simple-selector) ()) @@ -43,24 +42,24 @@ (defun parse-selector (selector) (match-case (selector) ;; combinators + #+TODO (#T(regexp$ "[ ]*[~][ ]*" ()) (list (make-instance 'sibling-combinator :matcher (parse-selector &rest)))) + #+TODO (#T(regexp$ "[ ]*[+][ ]*" ()) (list (make-instance 'adjacent-combinator :matcher (parse-selector &rest)))) (#T(regexp$ "[ ]*[>][ ]*" ()) (list (make-instance 'child-combinator :matcher (parse-selector &rest)))) (#T(regexp$ "[ ]+" ()) (list (make-instance 'descendant-combinator :matcher (parse-selector &rest)))) ;; simple selector (#T(regexp$ "[#](\\w+)" (?id)) (cons (make-instance 'id-selector :arg id) (parse-selector &rest))) (#T(regexp$ "[\\.](\\w+)" (?class)) (cons (make-instance 'class-selector :arg class) (parse-selector &rest))) (#T(regexp$ "(\\w+)" (?type)) (cons (make-instance 'type-selector :arg type) (parse-selector &rest))) - #+TODO (#T(regexp$ "\\*" ()) (cons (make-instance 'universal-selector) (parse-selector &rest))))) (defgeneric find-matching-elements (selector elements)) (defmethod find-matching-elements (selector (elements list)) (nconc - (remove-if-not (lambda (el) (element-matches-p el selector)) elements) + (remove-if-not (rcurry #'element-matches-p selector) elements) (reduce #'nconc - (remove-if #'null - (mapcar (lambda (element) (find-matching-elements selector (element-children element))) - elements))))) + (mapcar (compose (curry #'find-matching-elements selector) #'element-children) + elements)))) (defmethod find-matching-elements (selector (elements t)) (find-matching-elements selector (list elements))) @@ -78,11 +77,22 @@ (element-classes element) :test #'string=)) +(defmethod element-matches-p (element (selector universal-selector)) + t) + (defmethod element-matches-p (element (selector list)) - (every (lambda (s) (element-matches-p element s)) selector)) + (every (curry #'element-matches-p element) selector)) (defmethod element-matches-p (element (selector child-combinator)) (element-matches-p (element-parent element) (matcher selector))) (defmethod element-matches-p (element (selector descendant-combinator)) - (some (lambda (a) (element-matches-p a (matcher selector))) (element-ancestors element))) + (some (rcurry #'element-matches-p (matcher selector)) (element-ancestors element))) + +#+TODO +(defmethod element-matches-p (element (selector adjacent-combinator)) + ...) + +#+TODO +(defmethod element-matches-p (element (selector sibling-combinator)) + ...) diff -rN -u old-Oh, Ducks!/templates.lisp new-Oh, Ducks!/templates.lisp --- old-Oh, Ducks!/templates.lisp 2015-10-19 08:27:54.000000000 +0000 +++ new-Oh, Ducks!/templates.lisp 2015-10-19 08:27:54.000000000 +0000 @@ -23,6 +23,7 @@ (:method ((parser t) spec) (make-instance 'css-selector-template :parser parser :spec spec)) (:method ((parser null) spec) + (declare (ignore parser spec)) (error "No parser specified."))) (defun %spec-includes-opts (spec)