 : find-between* ( vector i/f tag/f -- vector )
     over integer? [
         [ tail-slice ] [ name>> ] bi*
-        dupd find-matching-close drop 0 or 1 + head
+        dupd find-matching-close drop [ 1 + ] [ 1 ] if*
+        head
     ] [
         3drop V{ } clone
     ] if ; inline

    ] map ;

: find-by-id ( vector id -- vector' elt/f )
    '[ attributes>> "id" swap at _ = ] find ;
    
: find-by-class ( vector id -- vector' elt/f )
    '[ attributes>> "class" swap at _ = ] find ;

: find-by-name ( vector string -- vector elt/f )
    >lower '[ name>> _ = ] find ;

: find-by-id-between ( vector string -- vector' )
    dupd
    '[ attributes>> "id" swap at _ = ] find find-between* ;
    
: find-by-class-between ( vector string -- vector' )
    dupd
    '[ attributes>> "class" swap at _ = ] find find-between* ;
    
: find-by-class-id-between ( vector class id -- vector' )
    '[
        [ attributes>> "class" swap at _ = ]
        [ attributes>> "id" swap at _ = ] bi and
    ] dupd find find-between* ;

: find-by-attribute-key ( vector key -- vector' elt/? )
    >lower

! 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
urls.encoding ;
IN: html.parser.analyzer

: scrape-html ( url -- headers vector )
    http-get parse-html ;

: attribute ( tag string -- obj/f )
    swap attributes>> [ at ] [ drop f ] if* ;

: attribute* ( tag string -- obj ? )
    swap attributes>> [ at* ] [ drop f f ] if* ;

: attribute? ( tag string -- obj )
    swap attributes>> [ key? ] [ drop f ] if* ;

: find-all ( seq quot -- alist )
   [ <enum> >alist ] [ '[ second @ ] ] bi* filter ; inline

: loopn-index ( ... pred: ( ... n -- ... ? ) n -- ... )
    dup 0 > [
        [ swap call ] [ 1 - ] 2bi
        [ loopn-index ] 2curry when
    ] [
        2drop
    ] if ; inline recursive

: loopn ( ... pred: ( ... -- ... ? ) n -- ... )
    [ [ drop ] prepose ] dip loopn-index ; inline

:: find-nth ( n seq quot -- i/f elt/f )
    0 t [
        [ drop seq quot find-from ] dip 1 = [
            over [ [ 1 + ] dip ] when
        ] unless over >boolean
    ] n loopn-index ; inline

: find-first-name ( vector string -- i/f tag/f )
    >lower '[ name>> _ = ] find ; inline
