1 USING: arrays browser.utils hashtables io kernel namespaces
3 sequences splitting state-parser strings ;
7 TUPLE: tag name attributes text matched? closing? ;
18 : closing-tag? ( string -- ? )
23 swap peek CHAR: / = or
26 : <tag> ( name attributes closing? -- tag )
27 { set-tag-name set-tag-attributes set-tag-closing? }
30 : make-tag ( str attribs -- tag )
31 >r [ closing-tag? ] keep "/" trim1 r> rot <tag> ;
33 : make-text-tag ( str -- tag )
34 T{ tag f text } clone [ set-tag-text ] keep ;
36 : make-comment-tag ( str -- tag )
37 T{ tag f comment } clone [ set-tag-text ] keep ;
39 : make-dtd-tag ( str -- tag )
40 T{ tag f dtd } clone [ set-tag-text ] keep ;
42 : read-whitespace ( -- str )
43 [ get-char blank? not ] take-until ;
45 : read-whitespace* ( -- )
46 read-whitespace drop ;
48 : read-token ( -- str )
50 [ get-char blank? ] take-until ;
52 : read-single-quote ( -- str )
53 [ get-char CHAR: ' = ] take-until ;
55 : read-double-quote ( -- str )
56 [ get-char CHAR: " = ] take-until ;
58 : read-quote ( -- str )
59 get-char next* CHAR: ' = [
67 [ get-char CHAR: = = get-char blank? or ] take-until ;
71 [ get-char CHAR: = = ] take-until drop next* ;
73 : read-value ( -- str )
82 "-->" take-string* make-comment-tag push-tag ;
85 ">" take-string* make-dtd-tag push-tag ;
88 next* get-char CHAR: - = get-next CHAR: - = and [
96 [ get-char CHAR: > = get-char CHAR: < = or ] take-until
97 get-char CHAR: < = [ next* ] unless ;
100 next* get-char CHAR: ! = [
106 : read-until-< ( -- str )
107 [ get-char CHAR: < = ] take-until ;
110 read-until-< dup empty? [
113 make-text-tag push-tag
116 : (parse-attributes) ( -- )
119 read-key >lower read-= read-value
120 2array , (parse-attributes)
123 : parse-attributes ( -- hashtable )
124 [ (parse-attributes) ] { } make >hashtable ;
136 (parse-tag) make-tag push-tag
139 : (parse-html) ( tag -- )
146 : tag-parse ( quot -- vector )
148 V{ } clone tagstack set
152 : parse-html ( string -- vector )