]> gitweb.factorcode.org Git - factor.git/commitdiff
html.parser.analyzer: make find-between* work on nested tags.
authorbjourne@gmail.com <bjourne@gmail.com>
Wed, 24 Apr 2013 18:40:28 +0000 (20:40 +0200)
committerJohn Benediktsson <mrjbq7@gmail.com>
Wed, 24 Apr 2013 20:35:04 +0000 (13:35 -0700)
extra/html/parser/analyzer/analyzer-tests.factor
extra/html/parser/analyzer/analyzer.factor

index 4d2378c7ead40b7e45f83541afb455164087abf0..426fd75b2690ff15436eb6c3ae24f4fb7af816fe 100644 (file)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2010 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: html.parser.analyzer math tools.test ;
+USING: html.parser html.parser.analyzer math tools.test ;
 IN: html.parser.analyzer.tests
 
 [ 0 3 ]
@@ -27,3 +27,46 @@ IN: html.parser.analyzer.tests
 
 [ 0 { 3 5 7 9 11 } [ odd? ] find-last-nth ]
 [ undefined-find-nth? ] must-fail-with
+
+[ V{
+    T{ tag f text f "foo" f }
+}
+] [
+    "<html><head><title>foo</title></head></html>" parse-html
+    "title" find-between-first
+] unit-test
+
+[ V{
+    T{ tag f "p" H{ } f f }
+    T{ tag f text f "para" f }
+    T{ tag f "p" H{ } f t }
+}
+] [
+    "<body><div><p>para</p></div></body>" parse-html "div" find-between-first
+] unit-test
+
+[ V{
+    T{ tag f "div" H{ { "class" "foo" } } f f }
+    T{ tag f "p" H{ } f f }
+    T{ tag f text f "para" f }
+    T{ tag f "p" H{ } f t }
+    T{ tag f "div" H{ } f t }
+}
+] [
+    "<body><div class=\"foo\"><p>para</p></div></body>" parse-html
+    "foo" find-by-class-between
+] unit-test
+
+[ V{
+    T{ tag f "div" H{ { "class" "foo" } } f f }
+    T{ tag f "div" H{ } f f }
+    T{ tag f "p" H{ } f f }
+    T{ tag f text f "para" f }
+    T{ tag f "p" H{ } f t }
+    T{ tag f "div" H{ } f t }
+    T{ tag f "div" H{ } f t }
+}
+] [
+    "<body><div class=\"foo\"><div><p>para</p></div></div></body>" parse-html
+    "foo" find-by-class-between
+] unit-test
index d9ae88675abfcd2dbb13930a26f6631b3ab064f8..eeb15950a7da85f0a53b38b9cdc88643eea806f6 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs combinators combinators.short-circuit
-fry html.parser http.client io kernel locals math sequences
-sets splitting unicode.case unicode.categories urls
+fry html.parser http.client io kernel locals math math.statistics
+sequences sets splitting unicode.case unicode.categories urls
 urls.encoding shuffle ;
 IN: html.parser.analyzer
 
@@ -51,14 +51,24 @@ ERROR: undefined-find-nth m n seq quot ;
 : find-first-name ( vector string -- i/f tag/f )
     >lower '[ name>> _ = ] find ; inline
 
-: find-matching-close ( vector string -- i/f tag/f )
+! Takes a sequence and a quotation expected to return -1 if the
+! element decrements the stack, 0 if it doesnt affect it and 1 if it
+! increments it. Then finds the matching element where the stack is
+! empty.
+: stack-find ( seq quot -- i/f )
+    map cum-sum [ 0 = ] find drop ; inline
+
+! Produces a function which returns 1 if the input item is an opening
+! tag element with the specified name, -1 if it is a closing tag of
+! the same name and 0 otherwise.
+: tag-classifier ( string -- quot )
     >lower
-    '[ [ name>> _ = ] [ closing?>> ] bi and ] find ; inline
+    '[ dup name>> _ = [ closing?>> [ -1 ] [ 1 ] if ] [ drop 0 ] if ] ; inline
 
 : find-between* ( vector i/f tag/f -- vector )
     over integer? [
         [ tail-slice ] [ name>> ] bi*
-        dupd find-matching-close drop [ 1 + ] [ 1 ] if*
+        dupd tag-classifier stack-find [ 1 + ] [ 1 ] if*
         head
     ] [
         3drop V{ } clone