]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/xml/data/data.factor
factor: trim using lists
[factor.git] / basis / xml / data / data.factor
old mode 100755 (executable)
new mode 100644 (file)
index 0af2ec4..645c693
@@ -1,53 +1,43 @@
-! Copyright (C) 2005, 2006 Daniel Ehrenberg
+! Copyright (C) 2005, 2009 Daniel Ehrenberg
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel sequences sequences.private assocs arrays
-delegate.protocols delegate vectors accessors multiline
-macros words quotations combinators slots ;
+USING: accessors arrays assocs combinators
+combinators.short-circuit delegate delegate.protocols kernel
+sequences slots strings vectors words ;
 IN: xml.data
 
-TUPLE: name space main url ;
+TUPLE: interpolated var ;
+C: <interpolated> interpolated
+
+TUPLE: name
+    { space maybe{ string } }
+    { main string }
+    { url maybe{ string } } ;
 C: <name> name
 
 : ?= ( object/f object/f -- ? )
     2dup and [ = ] [ 2drop t ] if ;
 
 : names-match? ( name1 name2 -- ? )
-    [ [ space>> ] bi@ ?= ]
-    [ [ url>> ] bi@ ?= ]
-    [ [ main>> ] bi@ ?= ] 2tri and and ;
+    {
+        [ [ space>> ] bi@ ?= ]
+        [ [ url>> ] bi@ ?= ]
+        [ [ main>> ] bi@ ?= ]
+    } 2&& ;
 
 : <simple-name> ( string -- name )
+    "" swap f <name> ;
+
+: <null-name> ( string -- name )
     f swap f <name> ;
 
 : assure-name ( string/name -- name )
-    dup name? [ <simple-name> ] unless ;
-
-TUPLE: opener name attrs ;
-C: <opener> opener
-
-TUPLE: closer name ;
-C: <closer> closer
-
-TUPLE: contained name attrs ;
-C: <contained> contained
-
-TUPLE: comment text ;
-C: <comment> comment
-
-TUPLE: directive text ;
-C: <directive> directive
-
-TUPLE: instruction text ;
-C: <instruction> instruction
-
-TUPLE: prolog version encoding standalone ;
-C: <prolog> prolog
+    dup name? [ <null-name> ] unless ;
 
-TUPLE: attrs alist ;
+TUPLE: attrs { alist sequence } ;
 C: <attrs> attrs
 
 : attr@ ( key alist -- index {key,value} )
-    >r assure-name r> alist>>
+    [ assure-name ] dip alist>>
     [ first names-match? ] with find ;
 
 M: attrs at*
@@ -56,18 +46,18 @@ M: attrs set-at
     2dup attr@ nip [
         2nip set-second
     ] [
-        >r assure-name swap 2array r>
-        [ alist>> ?push ] keep (>>alist)
+        [ assure-name swap 2array ] dip
+        [ alist>> ?push ] keep alist<<
     ] if* ;
 
 M: attrs assoc-size alist>> length ;
-M: attrs new-assoc drop V{ } new-sequence <attrs> ;
+M: attrs new-assoc drop <vector> <attrs> ;
 M: attrs >alist alist>> ;
 
 : >attrs ( assoc -- attrs )
     dup [
         V{ } assoc-clone-like
-        [ >r assure-name r> ] assoc-map
+        [ [ assure-name ] dip ] assoc-map
     ] when <attrs> ;
 M: attrs assoc-like
     drop dup attrs? [ >attrs ] unless ;
@@ -75,27 +65,101 @@ M: attrs assoc-like
 M: attrs clear-assoc
     f >>alist drop ;
 M: attrs delete-at
-    tuck attr@ drop [ swap alist>> delete-nth ] [ drop ] if* ;
+    [ nip ] [ attr@ drop ] 2bi
+    [ swap alist>> remove-nth! drop ] [ drop ] if* ;
 
 M: attrs clone
     alist>> clone <attrs> ;
 
 INSTANCE: attrs assoc
 
-TUPLE: tag name attrs children ;
+TUPLE: opener { name name } { attrs attrs } ;
+C: <opener> opener
+
+TUPLE: closer { name name } ;
+C: <closer> closer
+
+TUPLE: contained { name name } { attrs attrs } ;
+C: <contained> contained
+
+TUPLE: comment { text string } ;
+C: <comment> comment
+
+TUPLE: directive ;
+
+TUPLE: element-decl < directive
+    { name string }
+    { content-spec string } ;
+C: <element-decl> element-decl
+
+TUPLE: attlist-decl < directive
+    { name string }
+    { att-defs string } ;
+C: <attlist-decl> attlist-decl
+
+TUPLE: entity-decl < directive
+    { name string }
+    { def string }
+    { pe? boolean } ;
+C: <entity-decl> entity-decl
+
+TUPLE: system-id { system-literal string } ;
+C: <system-id> system-id
+
+TUPLE: public-id { pubid-literal string } { system-literal string } ;
+C: <public-id> public-id
+
+UNION: id system-id public-id ;
+
+TUPLE: dtd
+    { directives sequence }
+    { entities assoc }
+    { parameter-entities assoc } ;
+C: <dtd> dtd
+
+TUPLE: doctype-decl < directive
+    { name string }
+    { external-id maybe{ id } }
+    { internal-subset maybe{ dtd } } ;
+C: <doctype-decl> doctype-decl
+
+TUPLE: notation-decl < directive
+    { name string }
+    { id string } ;
+C: <notation-decl> notation-decl
+
+TUPLE: instruction { text string } ;
+C: <instruction> instruction
+
+TUPLE: prolog
+    { version string }
+    { encoding string }
+    { standalone boolean } ;
+C: <prolog> prolog
+
+TUPLE: tag
+    { name name }
+    { attrs attrs }
+    { children sequence } ;
 
 : <tag> ( name attrs children -- tag )
     [ assure-name ] [ T{ attrs } assoc-like ] [ ] tri*
     tag boa ;
 
-! For convenience, tags follow the assoc protocol too (for attrs)
-CONSULT: assoc-protocol tag attrs>> ;
-INSTANCE: tag assoc
+: attr ( tag/xml name -- string )
+    swap attrs>> at ;
+
+: set-attr ( tag/xml value name -- )
+    rot attrs>> set-at ;
 
 ! They also follow the sequence protocol (for children)
 CONSULT: sequence-protocol tag children>> ;
 INSTANCE: tag sequence
 
+! They also follow the assoc protocol (for attributes)
+CONSULT: assoc-protocol tag attrs>> ;
+INSTANCE: tag assoc
+
 CONSULT: name tag name>> ;
 
 M: tag like
@@ -104,35 +168,36 @@ M: tag like
         rot dup [ V{ } like ] when <tag>
     ] if ;
 
-MACRO: clone-slots ( class -- tuple )
+MACRO: clone-slots ( class -- quot )
     [
         "slots" word-prop
-        [ name>> reader-word 1quotation [ clone ] compose ] map
-        [ cleave ] curry
-    ] [ [ boa ] curry ] bi compose ;
+        [ name>> reader-word '[ _ execute clone ] ] map
+        '[ _ cleave ]
+    ] [ '[ _ boa ] ] bi compose ;
 
 M: tag clone
     tag clone-slots ;
 
-TUPLE: xml prolog before body after ;
+TUPLE: xml
+    { prolog prolog }
+    { before sequence }
+    { body tag }
+    { after sequence } ;
 C: <xml> xml
 
 CONSULT: sequence-protocol xml body>> ;
 INSTANCE: xml sequence
 
-CONSULT: assoc-protocol xml body>> ;
-INSTANCE: xml assoc
-
 CONSULT: tag xml body>> ;
 
 CONSULT: name xml body>> ;
 
 <PRIVATE
 : tag>xml ( xml tag -- newxml )
-    >r [ prolog>> ] [ before>> ] [ after>> ] tri r>
+    [ [ prolog>> ] [ before>> ] [ after>> ] tri ] dip
     swap <xml> ;
 
-: seq>xml ( xml seq -- newxml )
+: sequence>xml ( xml seq -- newxml )
     over body>> like tag>xml ;
 PRIVATE>
 
@@ -141,12 +206,24 @@ M: xml clone
 
 M: xml like
     swap dup xml? [ nip ] [
-        dup tag? [ tag>xml ] [ seq>xml ] if
+        dup tag? [ tag>xml ] [ sequence>xml ] if
     ] if ;
 
 ! tag with children=f is contained
 : <contained-tag> ( name attrs -- tag )
     f <tag> ;
 
-PREDICATE: contained-tag < tag children>> not ;
-PREDICATE: open-tag < tag children>> ;
+PREDICATE: contained-tag < tag children>> empty? ;
+PREDICATE: open-tag < tag children>> empty? not ;
+
+TUPLE: unescaped string ;
+C: <unescaped> unescaped
+
+UNION: xml-data
+    tag comment string directive instruction unescaped ;
+
+TUPLE: xml-chunk seq ;
+C: <xml-chunk> xml-chunk
+
+CONSULT: sequence-protocol xml-chunk seq>> ;
+INSTANCE: xml-chunk sequence