Merge branch 'master' of git://factorcode.org/git/factor
commit
b655f71d5b
|
@ -14,8 +14,8 @@ HELP: parse-farkup ( string -- farkup )
|
||||||
{ $description "Parses Farkup and outputs a tree of " { $link "farkup-ast" } "." } ;
|
{ $description "Parses Farkup and outputs a tree of " { $link "farkup-ast" } "." } ;
|
||||||
|
|
||||||
HELP: (write-farkup)
|
HELP: (write-farkup)
|
||||||
{ $values { "farkup" "a Farkup syntax tree node" } }
|
{ $values { "farkup" "a Farkup syntax tree node" } { "xml" "an XML chunk" } }
|
||||||
{ $description "Writes a Farkup syntax tree as HTML on " { $link output-stream } "." } ;
|
{ $description "Converts a Farkup syntax tree node to XML." } ;
|
||||||
|
|
||||||
ARTICLE: "farkup-ast" "Farkup syntax tree nodes"
|
ARTICLE: "farkup-ast" "Farkup syntax tree nodes"
|
||||||
"The " { $link parse-farkup } " word outputs a tree of nodes corresponding to the Farkup syntax of the input string. This tree can be programatically traversed and mutated before being passed on to " { $link write-farkup } "."
|
"The " { $link parse-farkup } " word outputs a tree of nodes corresponding to the Farkup syntax of the input string. This tree can be programatically traversed and mutated before being passed on to " { $link write-farkup } "."
|
||||||
|
|
|
@ -70,8 +70,8 @@ HELP: render
|
||||||
{ $description "Renders an HTML component to the " { $link output-stream } "." } ;
|
{ $description "Renders an HTML component to the " { $link output-stream } "." } ;
|
||||||
|
|
||||||
HELP: render*
|
HELP: render*
|
||||||
{ $values { "value" "a value" } { "name" "a value name" } { "renderer" "a component renderer" } }
|
{ $values { "value" "a value" } { "name" "a value name" } { "renderer" "a component renderer" } { "xml" "an XML chunk" } }
|
||||||
{ $contract "Renders an HTML component to the " { $link output-stream } "." } ;
|
{ $contract "Renders an HTML component, outputting an XHTML snippet." } ;
|
||||||
|
|
||||||
ARTICLE: "html.components" "HTML components"
|
ARTICLE: "html.components" "HTML components"
|
||||||
"The " { $vocab-link "html.components" } " vocabulary provides various HTML form components."
|
"The " { $vocab-link "html.components" } " vocabulary provides various HTML form components."
|
||||||
|
|
|
@ -159,7 +159,7 @@ TUPLE: person first-name last-name ;
|
||||||
"true" "b" set-value
|
"true" "b" set-value
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ "<input type='checkbox' name='a'>a</input><input type='checkbox' name='b' checked='true'>b</input>" ] [
|
[ "<input type=\"checkbox\" name=\"a\">a</input><input type=\"checkbox\" checked=\"true\" name=\"b\">b</input>" ] [
|
||||||
[
|
[
|
||||||
"test12" test-template call-template
|
"test12" test-template call-template
|
||||||
] run-template
|
] run-template
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
! Copyright (C) 2009 Daniel Ehrenberg
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: lcs.diff2html lcs kernel tools.test strings sequences xml.writer ;
|
||||||
|
IN: lcs.diff2html.tests
|
||||||
|
|
||||||
|
[ ] [ "hello" "heyo" [ 1string ] { } map-as diff htmlize-diff xml-chunk>string drop ] unit-test
|
|
@ -3,7 +3,7 @@
|
||||||
USING: accessors kernel xml arrays math generic http.client
|
USING: accessors kernel xml arrays math generic http.client
|
||||||
combinators hashtables namespaces io base64 sequences strings
|
combinators hashtables namespaces io base64 sequences strings
|
||||||
calendar xml.data xml.writer xml.utilities assocs math.parser
|
calendar xml.data xml.writer xml.utilities assocs math.parser
|
||||||
debugger calendar.format math.order xml.interpolate ;
|
debugger calendar.format math.order xml.interpolate xml.dispatch ;
|
||||||
IN: xml-rpc
|
IN: xml-rpc
|
||||||
|
|
||||||
! * Sending RPC requests
|
! * Sending RPC requests
|
||||||
|
@ -15,7 +15,7 @@ GENERIC: item>xml ( object -- xml )
|
||||||
M: integer item>xml
|
M: integer item>xml
|
||||||
dup 31 2^ neg 31 2^ 1 - between?
|
dup 31 2^ neg 31 2^ 1 - between?
|
||||||
[ "Integers must fit in 32 bits" throw ] unless
|
[ "Integers must fit in 32 bits" throw ] unless
|
||||||
number>string [XML <i4><-></i4> XML] ;
|
[XML <i4><-></i4> XML] ;
|
||||||
|
|
||||||
UNION: boolean t POSTPONE: f ;
|
UNION: boolean t POSTPONE: f ;
|
||||||
|
|
||||||
|
@ -176,10 +176,3 @@ TAG: array xml>item
|
||||||
|
|
||||||
: invoke-method ( params method url -- )
|
: invoke-method ( params method url -- )
|
||||||
[ swap <rpc-method> ] dip post-rpc ;
|
[ swap <rpc-method> ] dip post-rpc ;
|
||||||
|
|
||||||
: put-http-response ( string -- )
|
|
||||||
"HTTP/1.1 200 OK\nConnection: close\nContent-Length: " write
|
|
||||||
dup length number>string write
|
|
||||||
"\nContent-Type: text/xml\nDate: " write
|
|
||||||
now timestamp>http-string write "\n\n" write
|
|
||||||
write ;
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
collections
|
||||||
|
assocs
|
|
@ -0,0 +1 @@
|
||||||
|
Daniel Ehrenberg
|
|
@ -0,0 +1,25 @@
|
||||||
|
! Copyright (C) 2005, 2009 Daniel Ehrenberg
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: help.markup help.syntax ;
|
||||||
|
IN: xml.dispatch
|
||||||
|
|
||||||
|
ABOUT: "xml.dispatch"
|
||||||
|
|
||||||
|
ARTICLE: "xml.dispatch" "Dispatch on XML tag names"
|
||||||
|
"Two parsing words define a system, analogous to generic words, for processing XML. A word can dispatch off the name of the tag that is passed to it. To define such a word, use"
|
||||||
|
{ $subsection POSTPONE: PROCESS: }
|
||||||
|
"and to define a new 'method' for this word, use"
|
||||||
|
{ $subsection POSTPONE: TAG: } ;
|
||||||
|
|
||||||
|
HELP: PROCESS:
|
||||||
|
{ $syntax "PROCESS: word" }
|
||||||
|
{ $values { "word" "a new word to define" } }
|
||||||
|
{ $description "creates a new word to process XML tags" }
|
||||||
|
{ $see-also POSTPONE: TAG: } ;
|
||||||
|
|
||||||
|
HELP: TAG:
|
||||||
|
{ $syntax "TAG: tag word definition... ;" }
|
||||||
|
{ $values { "tag" "an xml tag name" } { "word" "an XML process" } }
|
||||||
|
{ $description "defines what a process should do when it encounters a specific tag" }
|
||||||
|
{ $examples { $code "PROCESS: x ( tag -- )\nTAG: a x drop \"hi\" write ;" } }
|
||||||
|
{ $see-also POSTPONE: PROCESS: } ;
|
|
@ -1,7 +1,8 @@
|
||||||
! Copyright (C) 2005, 2006 Daniel Ehrenberg
|
! Copyright (C) 2005, 2009 Daniel Ehrenberg
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
IN: xml.tests
|
USING: xml io kernel math sequences strings xml.utilities
|
||||||
USING: xml io kernel math sequences strings xml.utilities tools.test math.parser ;
|
tools.test math.parser xml.dispatch ;
|
||||||
|
IN: xml.dispatch.tests
|
||||||
|
|
||||||
PROCESS: calculate ( tag -- n )
|
PROCESS: calculate ( tag -- n )
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
! Copyright (C) 2005, 2009 Daniel Ehrenberg
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: words assocs kernel accessors parser sequences summary
|
||||||
|
lexer splitting fry ;
|
||||||
|
IN: xml.dispatch
|
||||||
|
|
||||||
|
TUPLE: process-missing process tag ;
|
||||||
|
M: process-missing summary
|
||||||
|
drop "Tag not implemented on process" ;
|
||||||
|
|
||||||
|
: run-process ( tag word -- )
|
||||||
|
2dup "xtable" word-prop
|
||||||
|
[ dup main>> ] dip at* [ 2nip call ] [
|
||||||
|
drop \ process-missing boa throw
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
: PROCESS:
|
||||||
|
CREATE
|
||||||
|
dup H{ } clone "xtable" set-word-prop
|
||||||
|
dup '[ _ run-process ] define ; parsing
|
||||||
|
|
||||||
|
: TAG:
|
||||||
|
scan scan-word
|
||||||
|
parse-definition
|
||||||
|
swap "xtable" word-prop
|
||||||
|
rot "/" split [ [ 2dup ] dip swap set-at ] each 2drop ;
|
||||||
|
parsing
|
|
@ -0,0 +1 @@
|
||||||
|
'Generic words' that dispatch on XML tag names
|
|
@ -0,0 +1 @@
|
||||||
|
syntax
|
|
@ -23,10 +23,11 @@ ARTICLE: { "xml.interpolate" "in-depth" } "XML interpolation syntax"
|
||||||
$nl
|
$nl
|
||||||
"These forms can be used where a tag might go, as in " { $snippet "[XML <foo><-></foo> XML]" } " or where an attribute might go, as in " { $snippet "[XML <foo bar=<->/> XML]" } ". When an attribute is spliced in, it is not included if the value is " { $snippet "f" } " and if the value is not a string, the value is put through " { $link present } ". Here is an example of the fry style of XML interpolation:"
|
"These forms can be used where a tag might go, as in " { $snippet "[XML <foo><-></foo> XML]" } " or where an attribute might go, as in " { $snippet "[XML <foo bar=<->/> XML]" } ". When an attribute is spliced in, it is not included if the value is " { $snippet "f" } " and if the value is not a string, the value is put through " { $link present } ". Here is an example of the fry style of XML interpolation:"
|
||||||
{ $example
|
{ $example
|
||||||
{" "one two three" " " split
|
{" USING: splitting sequences xml.writer xml.interpolate ;
|
||||||
|
"one two three" " " split
|
||||||
[ [XML <item><-></item> XML] ] map
|
[ [XML <item><-></item> XML] ] map
|
||||||
<XML <doc><-></doc> XML> pprint-xml>string "}
|
<XML <doc><-></doc> XML> pprint-xml"}
|
||||||
{" <' <?xml version="1.0" encoding="UTF-8"?>
|
{" <?xml version="1.0" encoding="UTF-8"?>
|
||||||
<doc>
|
<doc>
|
||||||
<item>
|
<item>
|
||||||
one
|
one
|
||||||
|
@ -37,10 +38,11 @@ $nl
|
||||||
<item>
|
<item>
|
||||||
three
|
three
|
||||||
</item>
|
</item>
|
||||||
</doc>'> "} }
|
</doc>"} }
|
||||||
"Here is an example of the locals version:"
|
"Here is an example of the locals version:"
|
||||||
{ $example
|
{ $example
|
||||||
{" [let |
|
{" USING: locals urls xml.interpolate xml.writer ;
|
||||||
|
[let |
|
||||||
number [ 3 ]
|
number [ 3 ]
|
||||||
false [ f ]
|
false [ f ]
|
||||||
url [ URL" http://factorcode.org/" ]
|
url [ URL" http://factorcode.org/" ]
|
||||||
|
@ -53,6 +55,6 @@ $nl
|
||||||
url=<-url->
|
url=<-url->
|
||||||
string=<-string->
|
string=<-string->
|
||||||
word=<-word-> />
|
word=<-word-> />
|
||||||
XML> pprint-xml>string ] "}
|
XML> pprint-xml ] "}
|
||||||
{" <' <?xml version="1.0" encoding="UTF-8"?>
|
{" <?xml version="1.0" encoding="UTF-8"?>
|
||||||
<x number="3" url="http://factorcode.org/" string="hello" word="drop"/>'> "} } ;
|
<x number="3" url="http://factorcode.org/" string="hello" word="drop"/>"} } ;
|
||||||
|
|
|
@ -50,3 +50,10 @@ IN: xml.interpolate.tests
|
||||||
[ 3 f URL" http://factorcode.org/" "hello" \ drop
|
[ 3 f URL" http://factorcode.org/" "hello" \ drop
|
||||||
<XML <x number=<-> false=<-> url=<-> string=<-> word=<->/> XML>
|
<XML <x number=<-> false=<-> url=<-> string=<-> word=<->/> XML>
|
||||||
pprint-xml>string ] unit-test
|
pprint-xml>string ] unit-test
|
||||||
|
|
||||||
|
[ "<x>3</x>" ] [ 3 [XML <x><-></x> XML] xml-chunk>string ] unit-test
|
||||||
|
[ "<x></x>" ] [ f [XML <x><-></x> XML] xml-chunk>string ] unit-test
|
||||||
|
|
||||||
|
\ parse-def must-infer
|
||||||
|
[ "" interpolate-chunk ] must-infer
|
||||||
|
[ [XML <foo><-></foo> <bar val=<->/> XML] ] must-infer
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: xml xml.state kernel sequences fry assocs xml.data
|
USING: xml xml.state kernel sequences fry assocs xml.data
|
||||||
accessors strings make multiline parser namespaces macros
|
accessors strings make multiline parser namespaces macros
|
||||||
sequences.deep generalizations locals words combinators
|
sequences.deep generalizations words combinators
|
||||||
math present arrays ;
|
math present arrays ;
|
||||||
IN: xml.interpolate
|
IN: xml.interpolate
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ M: xml-data push-item , ;
|
||||||
M: object push-item present , ;
|
M: object push-item present , ;
|
||||||
M: sequence push-item
|
M: sequence push-item
|
||||||
[ dup array? [ % ] [ , ] if ] each ;
|
[ dup array? [ % ] [ , ] if ] each ;
|
||||||
|
M: number push-item present , ;
|
||||||
|
|
||||||
GENERIC: interpolate-item ( table item -- )
|
GENERIC: interpolate-item ( table item -- )
|
||||||
M: object interpolate-item nip , ;
|
M: object interpolate-item nip , ;
|
||||||
|
@ -47,23 +48,23 @@ M: interpolated interpolate-item
|
||||||
: interpolate-xml-doc ( table xml -- xml )
|
: interpolate-xml-doc ( table xml -- xml )
|
||||||
(clone) [ interpolate-tag ] change-body ;
|
(clone) [ interpolate-tag ] change-body ;
|
||||||
|
|
||||||
GENERIC# (each-interpolated) 1 ( item quot -- ) inline
|
: (each-interpolated) ( item quot: ( interpolated -- ) -- )
|
||||||
M: interpolated (each-interpolated) call ;
|
{
|
||||||
M: tag (each-interpolated)
|
{ [ over interpolated? ] [ call ] }
|
||||||
swap attrs>> values
|
{ [ over tag? ] [
|
||||||
[ interpolated? ] filter
|
[ attrs>> values [ interpolated? ] filter ] dip each
|
||||||
swap each ;
|
] }
|
||||||
M: xml (each-interpolated)
|
{ [ over xml? ] [ [ body>> ] dip (each-interpolated) ] }
|
||||||
[ body>> ] dip (each-interpolated) ;
|
[ 2drop ]
|
||||||
M: object (each-interpolated) 2drop ;
|
} cond ; inline recursive
|
||||||
|
|
||||||
: each-interpolated ( xml quot -- )
|
: each-interpolated ( xml quot -- )
|
||||||
'[ _ (each-interpolated) ] deep-each ; inline
|
'[ _ (each-interpolated) ] deep-each ; inline
|
||||||
|
|
||||||
:: number<-> ( doc -- doc )
|
: number<-> ( doc -- dup )
|
||||||
0 :> n! doc [
|
0 over [
|
||||||
dup var>> [ n >>var n 1+ n! ] unless drop
|
dup var>> [ over >>var [ 1+ ] dip ] unless drop
|
||||||
] each-interpolated doc ;
|
] each-interpolated drop ;
|
||||||
|
|
||||||
MACRO: interpolate-xml ( string -- doc )
|
MACRO: interpolate-xml ( string -- doc )
|
||||||
string>doc number<-> '[ _ interpolate-xml-doc ] ;
|
string>doc number<-> '[ _ interpolate-xml-doc ] ;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Syntax for XML interpolation
|
|
@ -0,0 +1,2 @@
|
||||||
|
syntax
|
||||||
|
enterprise
|
|
@ -1,4 +1,4 @@
|
||||||
! Copyright (C) 2005, 2006 Daniel Ehrenberg
|
! Copyright (C) 2005, 2009 Daniel Ehrenberg
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
IN: xml.tests
|
IN: xml.tests
|
||||||
USING: kernel xml tools.test io namespaces make sequences
|
USING: kernel xml tools.test io namespaces make sequences
|
||||||
|
@ -8,7 +8,7 @@ sequences.deep accessors io.streams.string ;
|
||||||
|
|
||||||
! This is insufficient
|
! This is insufficient
|
||||||
\ read-xml must-infer
|
\ read-xml must-infer
|
||||||
[ [ drop ] sax ] must-infer
|
[ [ drop ] each-element ] must-infer
|
||||||
\ string>xml must-infer
|
\ string>xml must-infer
|
||||||
|
|
||||||
SYMBOL: xml-file
|
SYMBOL: xml-file
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
syntax
|
|
@ -6,11 +6,6 @@ IN: xml.utilities
|
||||||
ABOUT: "xml.utilities"
|
ABOUT: "xml.utilities"
|
||||||
|
|
||||||
ARTICLE: "xml.utilities" "Utilities for processing XML"
|
ARTICLE: "xml.utilities" "Utilities for processing XML"
|
||||||
"Utilities for processing XML include..."
|
|
||||||
$nl
|
|
||||||
"System sfor creating words which dispatch on XML tags:"
|
|
||||||
{ $subsection POSTPONE: PROCESS: }
|
|
||||||
{ $subsection POSTPONE: TAG: }
|
|
||||||
"Getting parts of an XML document or tag:"
|
"Getting parts of an XML document or tag:"
|
||||||
$nl
|
$nl
|
||||||
"Note: the difference between deep-tag-named and tag-named is that the former searches recursively among all children and children of children of the tag, while the latter only looks at the direct children, and is therefore more efficient."
|
"Note: the difference between deep-tag-named and tag-named is that the former searches recursively among all children and children of children of the tag, while the latter only looks at the direct children, and is therefore more efficient."
|
||||||
|
@ -19,11 +14,7 @@ ARTICLE: "xml.utilities" "Utilities for processing XML"
|
||||||
{ $subsection deep-tag-named }
|
{ $subsection deep-tag-named }
|
||||||
{ $subsection deep-tags-named }
|
{ $subsection deep-tags-named }
|
||||||
{ $subsection get-id }
|
{ $subsection get-id }
|
||||||
"Words for simplified generation of XML:"
|
"To get at the contents of a single tag, use"
|
||||||
{ $subsection build-tag* }
|
|
||||||
{ $subsection build-tag }
|
|
||||||
{ $subsection build-xml }
|
|
||||||
"Other relevant words:"
|
|
||||||
{ $subsection children>string }
|
{ $subsection children>string }
|
||||||
{ $subsection children-tags }
|
{ $subsection children-tags }
|
||||||
{ $subsection first-child-tag }
|
{ $subsection first-child-tag }
|
||||||
|
@ -31,71 +22,42 @@ ARTICLE: "xml.utilities" "Utilities for processing XML"
|
||||||
|
|
||||||
HELP: deep-tag-named
|
HELP: deep-tag-named
|
||||||
{ $values { "tag" "an XML tag or document" } { "name/string" "an XML name or string representing a name" } { "matching-tag" tag } }
|
{ $values { "tag" "an XML tag or document" } { "name/string" "an XML name or string representing a name" } { "matching-tag" tag } }
|
||||||
{ $description "finds an XML tag with a matching name, recursively searching children and children of children" }
|
{ $description "Finds an XML tag with a matching name, recursively searching children and children of children." }
|
||||||
{ $see-also tags-named tag-named deep-tags-named } ;
|
{ $see-also tags-named tag-named deep-tags-named } ;
|
||||||
|
|
||||||
HELP: deep-tags-named
|
HELP: deep-tags-named
|
||||||
{ $values { "tag" "an XML tag or document" } { "name/string" "an XML name or string representing a name" } { "tags-seq" "a sequence of tags" } }
|
{ $values { "tag" "an XML tag or document" } { "name/string" "an XML name or string representing a name" } { "tags-seq" "a sequence of tags" } }
|
||||||
{ $description "returns a sequence of all tags of a matching name, recursively searching children and children of children" }
|
{ $description "Returns a sequence of all tags of a matching name, recursively searching children and children of children." }
|
||||||
{ $see-also tag-named deep-tag-named tags-named } ;
|
{ $see-also tag-named deep-tag-named tags-named } ;
|
||||||
|
|
||||||
HELP: children>string
|
HELP: children>string
|
||||||
{ $values { "tag" "an XML tag or document" } { "string" "a string" } }
|
{ $values { "tag" "an XML tag or document" } { "string" "a string" } }
|
||||||
{ $description "concatenates the children of the tag, ignoring everything that's not a string" } ;
|
{ $description "Concatenates the children of the tag, throwing an exception when there is a non-string child." } ;
|
||||||
|
|
||||||
HELP: children-tags
|
HELP: children-tags
|
||||||
{ $values { "tag" "an XML tag or document" } { "sequence" sequence } }
|
{ $values { "tag" "an XML tag or document" } { "sequence" sequence } }
|
||||||
{ $description "gets the children of the tag that are themselves tags" }
|
{ $description "Gets the children of the tag that are themselves tags." }
|
||||||
{ $see-also first-child-tag } ;
|
{ $see-also first-child-tag } ;
|
||||||
|
|
||||||
HELP: first-child-tag
|
HELP: first-child-tag
|
||||||
{ $values { "tag" "an XML tag or document" } { "tag" tag } }
|
{ $values { "tag" "an XML tag or document" } { "tag" tag } }
|
||||||
{ $description "returns the first child of the given tag that is a tag" }
|
{ $description "Returns the first child of the given tag that is a tag." }
|
||||||
{ $see-also children-tags } ;
|
{ $see-also children-tags } ;
|
||||||
|
|
||||||
HELP: tag-named
|
HELP: tag-named
|
||||||
{ $values { "tag" "an XML tag or document" }
|
{ $values { "tag" "an XML tag or document" }
|
||||||
{ "name/string" "an XML name or string representing the name" }
|
{ "name/string" "an XML name or string representing the name" }
|
||||||
{ "matching-tag" tag } }
|
{ "matching-tag" tag } }
|
||||||
{ $description "finds the first tag with matching name which is the direct child of the given tag" }
|
{ $description "Finds the first tag with matching name which is the direct child of the given tag." }
|
||||||
{ $see-also deep-tags-named deep-tag-named tags-named } ;
|
{ $see-also deep-tags-named deep-tag-named tags-named } ;
|
||||||
|
|
||||||
HELP: tags-named
|
HELP: tags-named
|
||||||
{ $values { "tag" "an XML tag or document" }
|
{ $values { "tag" "an XML tag or document" }
|
||||||
{ "name/string" "an XML name or string representing the name" }
|
{ "name/string" "an XML name or string representing the name" }
|
||||||
{ "tags-seq" "a sequence of tags" } }
|
{ "tags-seq" "a sequence of tags" } }
|
||||||
{ $description "finds all tags with matching name that are the direct children of the given tag" }
|
{ $description "Finds all tags with matching name that are the direct children of the given tag." }
|
||||||
{ $see-also deep-tag-named deep-tags-named tag-named } ;
|
{ $see-also deep-tag-named deep-tags-named tag-named } ;
|
||||||
|
|
||||||
HELP: get-id
|
HELP: get-id
|
||||||
{ $values { "tag" "an XML tag or document" } { "id" "a string" } { "elem" "an XML element or f" } }
|
{ $values { "tag" "an XML tag or document" } { "id" "a string" } { "elem" "an XML element or f" } }
|
||||||
{ $description "finds the XML tag with the specified id, ignoring the namespace" } ;
|
{ $description "Finds the XML tag with the specified id, ignoring the namespace." } ;
|
||||||
|
|
||||||
HELP: PROCESS:
|
|
||||||
{ $syntax "PROCESS: word" }
|
|
||||||
{ $values { "word" "a new word to define" } }
|
|
||||||
{ $description "creates a new word to process XML tags" }
|
|
||||||
{ $see-also POSTPONE: TAG: } ;
|
|
||||||
|
|
||||||
HELP: TAG:
|
|
||||||
{ $syntax "TAG: tag word definition... ;" }
|
|
||||||
{ $values { "tag" "an xml tag name" } { "word" "an XML process" } }
|
|
||||||
{ $description "defines what a process should do when it encounters a specific tag" }
|
|
||||||
{ $examples { $code "PROCESS: x ( tag -- )\nTAG: a x drop \"hi\" write ;" } }
|
|
||||||
{ $see-also POSTPONE: PROCESS: } ;
|
|
||||||
|
|
||||||
HELP: build-tag*
|
|
||||||
{ $values { "items" "sequence of elements" } { "name" "string" }
|
|
||||||
{ "tag" tag } }
|
|
||||||
{ $description "builds a " { $link tag } " with the specified name, in the namespace \"\" and URL \"\" containing the children listed in item" }
|
|
||||||
{ $see-also build-tag build-xml } ;
|
|
||||||
|
|
||||||
HELP: build-tag
|
|
||||||
{ $values { "item" "an element" } { "name" string } { "tag" tag } }
|
|
||||||
{ $description "builds a " { $link tag } " with the specified name containing the single child item" }
|
|
||||||
{ $see-also build-tag* build-xml } ;
|
|
||||||
|
|
||||||
HELP: build-xml
|
|
||||||
{ $values { "tag" tag } { "xml" "an XML document" } }
|
|
||||||
{ $description "builds an XML document out of a tag" }
|
|
||||||
{ $see-also build-tag* build-tag } ;
|
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
|
! Copyright (C) 2005, 2009 Daniel Ehrenberg
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: xml xml.utilities tools.test xml.data ;
|
||||||
IN: xml.utilities.tests
|
IN: xml.utilities.tests
|
||||||
USING: xml xml.utilities tools.test ;
|
|
||||||
|
|
||||||
[ "bar" ] [ "<foo>bar</foo>" string>xml children>string ] unit-test
|
[ "bar" ] [ "<foo>bar</foo>" string>xml children>string ] unit-test
|
||||||
|
|
||||||
[ "" ] [ "<foo></foo>" string>xml children>string ] unit-test
|
[ "" ] [ "<foo></foo>" string>xml children>string ] unit-test
|
||||||
|
|
||||||
[ "" ] [ "<foo/>" string>xml children>string ] unit-test
|
[ "" ] [ "<foo/>" string>xml children>string ] unit-test
|
||||||
|
|
||||||
|
XML-NS: foo http://blah.com
|
||||||
|
|
||||||
|
[ T{ name { main "bling" } { url "http://blah.com" } } ] [ "bling" foo ] unit-test
|
||||||
|
|
|
@ -1,52 +1,10 @@
|
||||||
! Copyright (C) 2005, 2006 Daniel Ehrenberg
|
! Copyright (C) 2005, 2009 Daniel Ehrenberg
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors kernel namespaces sequences words io assocs
|
USING: accessors kernel namespaces sequences words io assocs
|
||||||
quotations strings parser lexer arrays xml.data xml.writer debugger
|
quotations strings parser lexer arrays xml.data xml.writer debugger
|
||||||
splitting vectors sequences.deep combinators fry ;
|
splitting vectors sequences.deep combinators fry memoize ;
|
||||||
IN: xml.utilities
|
IN: xml.utilities
|
||||||
|
|
||||||
! * System for words specialized on tag names
|
|
||||||
|
|
||||||
TUPLE: process-missing process tag ;
|
|
||||||
M: process-missing error.
|
|
||||||
"Tag <" write
|
|
||||||
dup tag>> print-name
|
|
||||||
"> not implemented on process process " write
|
|
||||||
name>> print ;
|
|
||||||
|
|
||||||
: run-process ( tag word -- )
|
|
||||||
2dup "xtable" word-prop
|
|
||||||
[ dup main>> ] dip at* [ 2nip call ] [
|
|
||||||
drop \ process-missing boa throw
|
|
||||||
] if ;
|
|
||||||
|
|
||||||
: PROCESS:
|
|
||||||
CREATE
|
|
||||||
dup H{ } clone "xtable" set-word-prop
|
|
||||||
dup '[ _ run-process ] define ; parsing
|
|
||||||
|
|
||||||
: TAG:
|
|
||||||
scan scan-word
|
|
||||||
parse-definition
|
|
||||||
swap "xtable" word-prop
|
|
||||||
rot "/" split [ [ 2dup ] dip swap set-at ] each 2drop ;
|
|
||||||
parsing
|
|
||||||
|
|
||||||
|
|
||||||
! * Common utility functions
|
|
||||||
|
|
||||||
: build-tag* ( items name -- tag )
|
|
||||||
assure-name swap f swap <tag> ;
|
|
||||||
|
|
||||||
: build-tag ( item name -- tag )
|
|
||||||
[ 1array ] dip build-tag* ;
|
|
||||||
|
|
||||||
: standard-prolog ( -- prolog )
|
|
||||||
T{ prolog f "1.0" "UTF-8" f } ;
|
|
||||||
|
|
||||||
: build-xml ( tag -- xml )
|
|
||||||
standard-prolog { } rot { } <xml> ;
|
|
||||||
|
|
||||||
: children>string ( tag -- string )
|
: children>string ( tag -- string )
|
||||||
children>> {
|
children>> {
|
||||||
{ [ dup empty? ] [ drop "" ] }
|
{ [ dup empty? ] [ drop "" ] }
|
||||||
|
@ -115,3 +73,7 @@ M: process-missing error.
|
||||||
|
|
||||||
: insert-child ( child tag -- )
|
: insert-child ( child tag -- )
|
||||||
[ 1vector ] dip insert-children ;
|
[ 1vector ] dip insert-children ;
|
||||||
|
|
||||||
|
: XML-NS:
|
||||||
|
CREATE-WORD (( string -- name )) over set-stack-effect
|
||||||
|
scan '[ f swap _ <name> ] define-memoized ; parsing
|
||||||
|
|
|
@ -1,66 +1,82 @@
|
||||||
! Copyright (C) 2005, 2009 Daniel Ehrenberg
|
! Copyright (C) 2005, 2009 Daniel Ehrenberg
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: help.markup help.syntax xml.data io ;
|
USING: help.markup help.syntax xml.data io strings ;
|
||||||
IN: xml
|
IN: xml
|
||||||
|
|
||||||
HELP: string>xml
|
HELP: string>xml
|
||||||
{ $values { "string" "a string" } { "xml" "an xml document" } }
|
{ $values { "string" string } { "xml" xml } }
|
||||||
{ $description "converts a string into an " { $link xml }
|
{ $description "Converts a string into an " { $link xml }
|
||||||
" datatype for further processing" } ;
|
" tree for further processing." } ;
|
||||||
|
|
||||||
HELP: read-xml
|
HELP: read-xml
|
||||||
{ $values { "stream" "a stream that supports readln" }
|
{ $values { "stream" "an input stream" } { "xml" xml } }
|
||||||
{ "xml" "an XML document" } }
|
{ $description "Exausts the given stream, reading an XML document from it. A binary stream, one without encoding, should be used as input, and the encoding is automatically detected." } ;
|
||||||
{ $description "exausts the given stream, reading an XML document from it. A binary stream, one without encoding, should be used as input, and the encoding is automatically detected." } ;
|
|
||||||
|
|
||||||
HELP: file>xml
|
HELP: file>xml
|
||||||
{ $values { "filename" "a string representing a filename" }
|
{ $values { "filename" string } { "xml" xml } }
|
||||||
{ "xml" "an XML document" } }
|
{ $description "Opens the given file, reads it in as XML, closes the file and returns the corresponding XML tree. The encoding is automatically detected." } ;
|
||||||
{ $description "opens the given file, reads it in as XML, closes the file and returns the corresponding XML tree" } ;
|
|
||||||
|
|
||||||
{ string>xml read-xml file>xml } related-words
|
{ string>xml read-xml file>xml } related-words
|
||||||
|
|
||||||
HELP: read-xml-chunk
|
HELP: read-xml-chunk
|
||||||
{ $values { "stream" "an input stream" } { "seq" "a sequence of elements" } }
|
{ $values { "stream" "an input stream" } { "seq" "a sequence of elements" } }
|
||||||
{ $description "rather than parse a document, as " { $link read-xml } " does, this word parses and returns a sequence of XML elements (tags, strings, etc), ie a document fragment. This is useful for pieces of XML which may have more than one main tag." }
|
{ $description "Rather than parse a document, as " { $link read-xml } " does, this word parses and returns a sequence of XML elements (tags, strings, etc), ie a document fragment. This is useful for pieces of XML which may have more than one main tag." }
|
||||||
{ $see-also read-xml } ;
|
{ $see-also read-xml } ;
|
||||||
|
|
||||||
HELP: sax
|
HELP: each-element
|
||||||
{ $values { "stream" "an input stream" } { "quot" "a quotation ( xml-elem -- )" } }
|
{ $values { "stream" "an input stream" } { "quot" "a quotation ( xml-elem -- )" } }
|
||||||
{ $description "parses the XML document, and whenever an event is encountered (a tag piece, comment, parsing instruction, directive or string element), the quotation is called with that event on the stack. The quotation has all responsibility to deal with the event properly, and it is advised that generic words be used in dispatching on the event class." }
|
{ $description "Parses the XML document, and whenever an event is encountered (a tag piece, comment, parsing instruction, directive or string element), the quotation is called with that event on the stack. The quotation has all responsibility to deal with the event properly, and it is advised that generic words be used in dispatching on the event class." }
|
||||||
{ $notes "It is important to note that this is not SAX, merely an event-based XML view" }
|
{ $notes "It is important to note that this is not SAX, merely an event-based XML view" }
|
||||||
{ $see-also read-xml } ;
|
{ $see-also read-xml } ;
|
||||||
|
|
||||||
HELP: pull-xml
|
HELP: pull-xml
|
||||||
{ $class-description "represents the state of a pull-parser for XML. Has one slot, scope, which is a namespace which contains all relevant state information." }
|
{ $class-description "Represents the state of a pull-parser for XML. Has one slot, scope, which is a namespace which contains all relevant state information." }
|
||||||
{ $see-also <pull-xml> pull-event pull-elem } ;
|
{ $see-also <pull-xml> pull-event pull-elem } ;
|
||||||
|
|
||||||
HELP: <pull-xml>
|
HELP: <pull-xml>
|
||||||
{ $values { "pull-xml" "a pull-xml tuple" } }
|
{ $values { "pull-xml" "a pull-xml tuple" } }
|
||||||
{ $description "creates an XML pull-based parser which reads from " { $link input-stream } ", executing all initial XML commands to set up the parser." }
|
{ $description "Creates an XML pull-based parser which reads from " { $link input-stream } ", executing all initial XML commands to set up the parser." }
|
||||||
{ $see-also pull-xml pull-elem pull-event } ;
|
{ $see-also pull-xml pull-elem pull-event } ;
|
||||||
|
|
||||||
HELP: pull-elem
|
HELP: pull-elem
|
||||||
{ $values { "pull" "an XML pull parser" } { "xml-elem/f" "an XML tag, string, or f" } }
|
{ $values { "pull" "an XML pull parser" } { "xml-elem/f" "an XML tag, string, or f" } }
|
||||||
{ $description "gets the next XML element from the given XML pull parser. Returns f upon exhaustion." }
|
{ $description "Gets the next XML element from the given XML pull parser. Returns f upon exhaustion." }
|
||||||
{ $see-also pull-xml <pull-xml> pull-event } ;
|
{ $see-also pull-xml <pull-xml> pull-event } ;
|
||||||
|
|
||||||
HELP: pull-event
|
HELP: pull-event
|
||||||
{ $values { "pull" "an XML pull parser" } { "xml-event/f" "an XML tag event, string, or f" } }
|
{ $values { "pull" "an XML pull parser" } { "xml-event/f" "an XML tag event, string, or f" } }
|
||||||
{ $description "gets the next XML event from the given XML pull parser. Returns f upon exhaustion." }
|
{ $description "Gets the next XML event from the given XML pull parser. Returns f upon exhaustion." }
|
||||||
{ $see-also pull-xml <pull-xml> pull-elem } ;
|
{ $see-also pull-xml <pull-xml> pull-elem } ;
|
||||||
|
|
||||||
|
HELP: read-dtd
|
||||||
|
{ $values { "stream" "an input stream" } { "dtd" dtd } }
|
||||||
|
{ $description "Exhausts a stream, producing a " { $link dtd } " from the contents." } ;
|
||||||
|
|
||||||
|
HELP: file>dtd
|
||||||
|
{ $values { "filename" string } { "dtd" dtd } }
|
||||||
|
{ $description "Reads a file in UTF-8, converting it into an XML " { $link dtd } "." } ;
|
||||||
|
|
||||||
|
HELP: string>dtd
|
||||||
|
{ $values { "string" string } { "dtd" dtd } }
|
||||||
|
{ $description "Interprets a string as an XML " { $link dtd } "." } ;
|
||||||
|
|
||||||
|
{ read-dtd file>dtd string>dtd } related-words
|
||||||
|
|
||||||
ARTICLE: { "xml" "reading" } "Reading XML"
|
ARTICLE: { "xml" "reading" } "Reading XML"
|
||||||
"The following words are used to read something into an XML document"
|
"The following words are used to read something into an XML document"
|
||||||
{ $subsection string>xml }
|
{ $subsection string>xml }
|
||||||
{ $subsection read-xml }
|
{ $subsection read-xml }
|
||||||
{ $subsection read-xml-chunk }
|
{ $subsection read-xml-chunk }
|
||||||
{ $subsection string>xml-chunk }
|
{ $subsection string>xml-chunk }
|
||||||
{ $subsection file>xml } ;
|
{ $subsection file>xml }
|
||||||
|
"To read a DTD:"
|
||||||
|
{ $subsection read-dtd }
|
||||||
|
{ $subsection file>dtd }
|
||||||
|
{ $subsection string>dtd } ;
|
||||||
|
|
||||||
ARTICLE: { "xml" "events" } "Event-based XML parsing"
|
ARTICLE: { "xml" "events" } "Event-based XML parsing"
|
||||||
"In addition to DOM-style parsing based around " { $link read-xml } ", the XML module also provides SAX-style event-based parsing. This uses much of the same data structures as normal XML, with the exception of the classes " { $link xml } " and " { $link tag } " and as such, the article " { $vocab-link "xml.data" } " may be useful in learning how to process documents in this way. Other useful words are:"
|
"In addition to DOM-style parsing based around " { $link read-xml } ", the XML module also provides SAX-style event-based parsing. This uses much of the same data structures as normal XML, with the exception of the classes " { $link xml } " and " { $link tag } " and as such, the article " { $vocab-link "xml.data" } " may be useful in learning how to process documents in this way. Other useful words are:"
|
||||||
{ $subsection sax }
|
{ $subsection each-element }
|
||||||
{ $subsection opener }
|
{ $subsection opener }
|
||||||
{ $subsection closer }
|
{ $subsection closer }
|
||||||
{ $subsection contained }
|
{ $subsection contained }
|
||||||
|
@ -74,10 +90,11 @@ ARTICLE: "xml" "XML parser"
|
||||||
"The " { $vocab-link "xml" } " vocabulary implements the XML 1.0 and 1.1 standards, converting strings of text into XML and vice versa."
|
"The " { $vocab-link "xml" } " vocabulary implements the XML 1.0 and 1.1 standards, converting strings of text into XML and vice versa."
|
||||||
{ $subsection { "xml" "reading" } }
|
{ $subsection { "xml" "reading" } }
|
||||||
{ $subsection { "xml" "events" } }
|
{ $subsection { "xml" "events" } }
|
||||||
{ $vocab-subsection "Utilities for processing XML" "xml.utilities" }
|
|
||||||
{ $vocab-subsection "Writing XML" "xml.writer" }
|
{ $vocab-subsection "Writing XML" "xml.writer" }
|
||||||
{ $vocab-subsection "XML parsing errors" "xml.errors" }
|
{ $vocab-subsection "XML parsing errors" "xml.errors" }
|
||||||
{ $vocab-subsection "XML entities" "xml.entities" }
|
{ $vocab-subsection "XML entities" "xml.entities" }
|
||||||
{ $vocab-subsection "XML data types" "xml.data" } ;
|
{ $vocab-subsection "XML data types" "xml.data" }
|
||||||
|
{ $vocab-subsection "Utilities for processing XML" "xml.utilities" }
|
||||||
|
{ $vocab-subsection "Dispatch on XML tag names" "xml.dispatch" } ;
|
||||||
|
|
||||||
ABOUT: "xml"
|
ABOUT: "xml"
|
||||||
|
|
|
@ -6,7 +6,7 @@ xml.data xml.errors xml.elements ascii xml.entities
|
||||||
xml.writer xml.state xml.autoencoding assocs xml.tokenize xml.name ;
|
xml.writer xml.state xml.autoencoding assocs xml.tokenize xml.name ;
|
||||||
IN: xml
|
IN: xml
|
||||||
|
|
||||||
! -- Overall parser with data tree
|
<PRIVATE
|
||||||
|
|
||||||
: add-child ( object -- )
|
: add-child ( object -- )
|
||||||
xml-stack get peek second push ;
|
xml-stack get peek second push ;
|
||||||
|
@ -89,6 +89,8 @@ M: closer process
|
||||||
|
|
||||||
SYMBOL: text-now?
|
SYMBOL: text-now?
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
TUPLE: pull-xml scope ;
|
TUPLE: pull-xml scope ;
|
||||||
: <pull-xml> ( -- pull-xml )
|
: <pull-xml> ( -- pull-xml )
|
||||||
[
|
[
|
||||||
|
@ -106,6 +108,8 @@ TUPLE: pull-xml scope ;
|
||||||
] if text-now? set
|
] if text-now? set
|
||||||
] bind ;
|
] bind ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
: done? ( -- ? )
|
: done? ( -- ? )
|
||||||
xml-stack get length 1 = ;
|
xml-stack get length 1 = ;
|
||||||
|
|
||||||
|
@ -116,27 +120,33 @@ TUPLE: pull-xml scope ;
|
||||||
[ (pull-elem) ] if
|
[ (pull-elem) ] if
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
: pull-elem ( pull -- xml-elem/f )
|
: pull-elem ( pull -- xml-elem/f )
|
||||||
[ init-xml-stack (pull-elem) ] with-scope ;
|
[ init-xml-stack (pull-elem) ] with-scope ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
: call-under ( quot object -- quot )
|
: call-under ( quot object -- quot )
|
||||||
swap dup slip ; inline
|
swap dup slip ; inline
|
||||||
|
|
||||||
: sax-loop ( quot: ( xml-elem -- ) -- )
|
: xml-loop ( quot: ( xml-elem -- ) -- )
|
||||||
parse-text call-under
|
parse-text call-under
|
||||||
get-char [ make-tag call-under sax-loop ]
|
get-char [ make-tag call-under xml-loop ]
|
||||||
[ drop ] if ; inline recursive
|
[ drop ] if ; inline recursive
|
||||||
|
|
||||||
: sax ( stream quot: ( xml-elem -- ) -- )
|
PRIVATE>
|
||||||
|
|
||||||
|
: each-element ( stream quot: ( xml-elem -- ) -- )
|
||||||
swap [
|
swap [
|
||||||
reset-prolog init-ns-stack
|
reset-prolog init-ns-stack
|
||||||
start-document [ call-under ] when*
|
start-document [ call-under ] when*
|
||||||
sax-loop
|
xml-loop
|
||||||
] with-state ; inline recursive
|
] with-state ; inline
|
||||||
|
|
||||||
: (read-xml) ( -- )
|
: (read-xml) ( -- )
|
||||||
start-document [ process ] when*
|
start-document [ process ] when*
|
||||||
[ process ] sax-loop ; inline
|
[ process ] xml-loop ; inline
|
||||||
|
|
||||||
: (read-xml-chunk) ( stream -- prolog seq )
|
: (read-xml-chunk) ( stream -- prolog seq )
|
||||||
[
|
[
|
||||||
|
@ -155,7 +165,8 @@ TUPLE: pull-xml scope ;
|
||||||
[ (read-xml-chunk) nip ] with-variable ;
|
[ (read-xml-chunk) nip ] with-variable ;
|
||||||
|
|
||||||
: string>xml ( string -- xml )
|
: string>xml ( string -- xml )
|
||||||
<string-reader> read-xml ;
|
t string-input?
|
||||||
|
[ <string-reader> read-xml ] with-variable ;
|
||||||
|
|
||||||
: string>xml-chunk ( string -- xml )
|
: string>xml-chunk ( string -- xml )
|
||||||
t string-input?
|
t string-input?
|
||||||
|
|
|
@ -1,17 +1,7 @@
|
||||||
! Copyright (C) 2008 Jeff Bigot
|
! Copyright (C) 2008 Jeff Bigot
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: adsoda
|
USING: adsoda xml xml.utilities xml.dispatch accessors combinators
|
||||||
xml
|
sequences math.parser kernel splitting values continuations ;
|
||||||
xml.utilities
|
|
||||||
accessors
|
|
||||||
combinators
|
|
||||||
sequences
|
|
||||||
math.parser
|
|
||||||
kernel
|
|
||||||
splitting
|
|
||||||
values
|
|
||||||
continuations
|
|
||||||
;
|
|
||||||
IN: 4DNav.space-file-decoder
|
IN: 4DNav.space-file-decoder
|
||||||
|
|
||||||
: decode-number-array ( x -- y ) "," split [ string>number ] map ;
|
: decode-number-array ( x -- y ) "," split [ string>number ] map ;
|
||||||
|
|
Loading…
Reference in New Issue