Merge branch 'master' of git://factorcode.org/git/factor
commit
c0d2906ffb
|
@ -92,22 +92,22 @@ link-no-follow? off
|
||||||
[ "<p>=</p><h2>foo</h2>" ] [ "===foo==" convert-farkup ] unit-test
|
[ "<p>=</p><h2>foo</h2>" ] [ "===foo==" convert-farkup ] unit-test
|
||||||
[ "<h1>foo</h1><p>=</p>" ] [ "=foo==" convert-farkup ] unit-test
|
[ "<h1>foo</h1><p>=</p>" ] [ "=foo==" convert-farkup ] unit-test
|
||||||
|
|
||||||
[ "<pre><span class='KEYWORD3'>int</span> <span class='FUNCTION'>main</span><span class='OPERATOR'>(</span><span class='OPERATOR'>)</span>\n</pre>" ]
|
[ "<pre><span class=\"KEYWORD3\">int</span> <span class=\"FUNCTION\">main</span><span class=\"OPERATOR\">(</span><span class=\"OPERATOR\">)</span></pre>" ]
|
||||||
[ "[c{int main()}]" convert-farkup ] unit-test
|
[ "[c{int main()}]" convert-farkup ] unit-test
|
||||||
|
|
||||||
[ "<p><img src='lol.jpg'/></p>" ] [ "[[image:lol.jpg]]" convert-farkup ] unit-test
|
[ "<p><img src=\"lol.jpg\"/></p>" ] [ "[[image:lol.jpg]]" convert-farkup ] unit-test
|
||||||
[ "<p><img src='lol.jpg' alt='teh lol'/></p>" ] [ "[[image:lol.jpg|teh lol]]" convert-farkup ] unit-test
|
[ "<p><img src=\"lol.jpg\" alt=\"teh lol\"/></p>" ] [ "[[image:lol.jpg|teh lol]]" convert-farkup ] unit-test
|
||||||
[ "<p><a href='http://lol.com'>http://lol.com</a></p>" ] [ "[[http://lol.com]]" convert-farkup ] unit-test
|
[ "<p><a href=\"http://lol.com\">http://lol.com</a></p>" ] [ "[[http://lol.com]]" convert-farkup ] unit-test
|
||||||
[ "<p><a href='http://lol.com'>haha</a></p>" ] [ "[[http://lol.com|haha]]" convert-farkup ] unit-test
|
[ "<p><a href=\"http://lol.com\">haha</a></p>" ] [ "[[http://lol.com|haha]]" convert-farkup ] unit-test
|
||||||
[ "<p><a href='Foo/Bar'>Bar</a></p>" ] [ "[[Foo/Bar]]" convert-farkup ] unit-test
|
[ "<p><a href=\"Foo/Bar\">Bar</a></p>" ] [ "[[Foo/Bar]]" convert-farkup ] unit-test
|
||||||
|
|
||||||
"/wiki/view/" relative-link-prefix [
|
"/wiki/view/" relative-link-prefix [
|
||||||
[ "<p><a href='/wiki/view/Foo/Bar'>Bar</a></p>" ] [ "[[Foo/Bar]]" convert-farkup ] unit-test
|
[ "<p><a href=\"/wiki/view/Foo/Bar\">Bar</a></p>" ] [ "[[Foo/Bar]]" convert-farkup ] unit-test
|
||||||
] with-variable
|
] with-variable
|
||||||
|
|
||||||
[ ] [ "[{}]" convert-farkup drop ] unit-test
|
[ ] [ "[{}]" convert-farkup drop ] unit-test
|
||||||
|
|
||||||
[ "<pre>hello\n</pre>" ] [ "[{hello}]" convert-farkup ] unit-test
|
[ "<pre>hello</pre>" ] [ "[{hello}]" convert-farkup ] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
"<p>Feature comparison:\n<table><tr><td>a</td><td>Factor</td><td>Java</td><td>Lisp</td></tr><tr><td>Coolness</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Badass</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Enterprise</td><td>Yes</td><td>Yes</td><td>No</td></tr><tr><td>Kosher</td><td>Yes</td><td>No</td><td>Yes</td></tr></table></p>"
|
"<p>Feature comparison:\n<table><tr><td>a</td><td>Factor</td><td>Java</td><td>Lisp</td></tr><tr><td>Coolness</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Badass</td><td>Yes</td><td>No</td><td>No</td></tr><tr><td>Enterprise</td><td>Yes</td><td>Yes</td><td>No</td></tr><tr><td>Kosher</td><td>Yes</td><td>No</td><td>Yes</td></tr></table></p>"
|
||||||
|
@ -118,15 +118,15 @@ link-no-follow? off
|
||||||
] [ "Feature comparison:\n\n|a|Factor|Java|Lisp|\n|Coolness|Yes|No|No|\n|Badass|Yes|No|No|\n|Enterprise|Yes|Yes|No|\n|Kosher|Yes|No|Yes|\n" convert-farkup ] unit-test
|
] [ "Feature comparison:\n\n|a|Factor|Java|Lisp|\n|Coolness|Yes|No|No|\n|Badass|Yes|No|No|\n|Enterprise|Yes|Yes|No|\n|Kosher|Yes|No|Yes|\n" convert-farkup ] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
"<p>This wiki is written in <a href='Factor'>Factor</a> and is hosted on a <a href='http://linode.com'>http://linode.com</a> virtual server.</p>"
|
"<p>This wiki is written in <a href=\"Factor\">Factor</a> and is hosted on a <a href=\"http://linode.com\">http://linode.com</a> virtual server.</p>"
|
||||||
] [
|
] [
|
||||||
"This wiki is written in [[Factor]] and is hosted on a [[http://linode.com|http://linode.com]] virtual server."
|
"This wiki is written in [[Factor]] and is hosted on a [[http://linode.com|http://linode.com]] virtual server."
|
||||||
convert-farkup
|
convert-farkup
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ "<p><a href='a'>a</a> <a href='b'>c</a></p>" ] [ "[[a]] [[b|c]]" convert-farkup ] unit-test
|
[ "<p><a href=\"a\">a</a> <a href=\"b\">c</a></p>" ] [ "[[a]] [[b|c]]" convert-farkup ] unit-test
|
||||||
|
|
||||||
[ "<p><a href='C%2b%2b'>C++</a></p>" ] [ "[[C++]]" convert-farkup ] unit-test
|
[ "<p><a href=\"C%2b%2b\">C++</a></p>" ] [ "[[C++]]" convert-farkup ] unit-test
|
||||||
|
|
||||||
[ "<p><foo></p>" ] [ "<foo>" convert-farkup ] unit-test
|
[ "<p><foo></p>" ] [ "<foo>" convert-farkup ] unit-test
|
||||||
|
|
||||||
|
@ -138,10 +138,10 @@ link-no-follow? off
|
||||||
[ "<hr/>" ] [ "___" convert-farkup ] unit-test
|
[ "<hr/>" ] [ "___" convert-farkup ] unit-test
|
||||||
[ "<hr/>\n" ] [ "___\n" convert-farkup ] unit-test
|
[ "<hr/>\n" ] [ "___\n" convert-farkup ] unit-test
|
||||||
|
|
||||||
[ "<p>before:\n<pre><span class='OPERATOR'>{</span> <span class='DIGIT'>1</span> <span class='DIGIT'>2</span> <span class='DIGIT'>3</span> <span class='OPERATOR'>}</span> <span class='DIGIT'>1</span> tail\n</pre></p>" ]
|
[ "<p>before:\n<pre><span class=\"OPERATOR\">{</span> <span class=\"DIGIT\">1</span> <span class=\"DIGIT\">2</span> <span class=\"DIGIT\">3</span> <span class=\"OPERATOR\">}</span> <span class=\"DIGIT\">1</span> tail</pre></p>" ]
|
||||||
[ "before:\n[factor{{ 1 2 3 } 1 tail}]" convert-farkup ] unit-test
|
[ "before:\n[factor{{ 1 2 3 } 1 tail}]" convert-farkup ] unit-test
|
||||||
|
|
||||||
[ "<p><a href='Factor'>Factor</a>-rific!</p>" ]
|
[ "<p><a href=\"Factor\">Factor</a>-rific!</p>" ]
|
||||||
[ "[[Factor]]-rific!" convert-farkup ] unit-test
|
[ "[[Factor]]-rific!" convert-farkup ] unit-test
|
||||||
|
|
||||||
[ "<p>[ factor { 1 2 3 }]</p>" ]
|
[ "<p>[ factor { 1 2 3 }]</p>" ]
|
||||||
|
@ -163,7 +163,7 @@ link-no-follow? off
|
||||||
convert-farkup string>xml-chunk
|
convert-farkup string>xml-chunk
|
||||||
"a" deep-tag-named "href" swap at url-decode ;
|
"a" deep-tag-named "href" swap at url-decode ;
|
||||||
|
|
||||||
[ "Trader Joe's" ] [ "[[Trader Joe's]]" check-link-escaping ] unit-test
|
[ "Trader Joe\"s" ] [ "[[Trader Joe\"s]]" check-link-escaping ] unit-test
|
||||||
[ "<foo>" ] [ "[[<foo>]]" check-link-escaping ] unit-test
|
[ "<foo>" ] [ "[[<foo>]]" check-link-escaping ] unit-test
|
||||||
[ "&blah;" ] [ "[[&blah;]]" check-link-escaping ] unit-test
|
[ "&blah;" ] [ "[[&blah;]]" check-link-escaping ] unit-test
|
||||||
[ "C++" ] [ "[[C++]]" check-link-escaping ] unit-test
|
[ "C++" ] [ "[[C++]]" check-link-escaping ] unit-test
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors arrays combinators html.elements io
|
USING: accessors arrays combinators html.elements io
|
||||||
io.streams.string kernel math namespaces peg peg.ebnf
|
io.streams.string kernel math namespaces peg peg.ebnf
|
||||||
sequences sequences.deep strings xml.entities
|
sequences sequences.deep strings xml.entities xml.interpolate
|
||||||
vectors splitting xmode.code2html urls.encoding ;
|
vectors splitting xmode.code2html urls.encoding xml.data
|
||||||
|
xml.writer ;
|
||||||
IN: farkup
|
IN: farkup
|
||||||
|
|
||||||
SYMBOL: relative-link-prefix
|
SYMBOL: relative-link-prefix
|
||||||
|
@ -74,6 +75,7 @@ inline-code = "%" (!("%" | nl).)+ "%"
|
||||||
=> [[ second >string inline-code boa ]]
|
=> [[ second >string inline-code boa ]]
|
||||||
|
|
||||||
link-content = (!("|"|"]").)+
|
link-content = (!("|"|"]").)+
|
||||||
|
=> [[ >string ]]
|
||||||
|
|
||||||
image-link = "[[image:" link-content "|" link-content "]]"
|
image-link = "[[image:" link-content "|" link-content "]]"
|
||||||
=> [[ [ second >string ] [ fourth >string ] bi image boa ]]
|
=> [[ [ second >string ] [ fourth >string ] bi image boa ]]
|
||||||
|
@ -146,7 +148,7 @@ named-code
|
||||||
|
|
||||||
simple-code
|
simple-code
|
||||||
= "[{" (!("}]").)+ "}]"
|
= "[{" (!("}]").)+ "}]"
|
||||||
=> [[ second f swap code boa ]]
|
=> [[ second >string f swap code boa ]]
|
||||||
|
|
||||||
code = named-code | simple-code
|
code = named-code | simple-code
|
||||||
|
|
||||||
|
@ -163,66 +165,78 @@ stand-alone
|
||||||
{ [ dup [ 127 > ] contains? ] [ drop invalid-url ] }
|
{ [ dup [ 127 > ] contains? ] [ drop invalid-url ] }
|
||||||
{ [ dup first "/\\" member? ] [ drop invalid-url ] }
|
{ [ dup first "/\\" member? ] [ drop invalid-url ] }
|
||||||
{ [ CHAR: : over member? ] [ dup absolute-url? [ drop invalid-url ] unless ] }
|
{ [ CHAR: : over member? ] [ dup absolute-url? [ drop invalid-url ] unless ] }
|
||||||
[ relative-link-prefix get prepend ]
|
[ relative-link-prefix get prepend "" like ]
|
||||||
} cond ;
|
} cond url-encode ;
|
||||||
|
|
||||||
: escape-link ( href text -- href-esc text-esc )
|
: write-link ( href text -- xml )
|
||||||
[ check-url ] dip escape-string ;
|
[ check-url link-no-follow? get "true" and ] dip
|
||||||
|
[XML <a href=<-> nofollow=<->><-></a> XML] ;
|
||||||
|
|
||||||
: write-link ( href text -- )
|
: write-image-link ( href text -- xml )
|
||||||
escape-link
|
|
||||||
[ <a url-encode =href link-no-follow? get [ "true" =nofollow ] when a> ]
|
|
||||||
[ write </a> ]
|
|
||||||
bi* ;
|
|
||||||
|
|
||||||
: write-image-link ( href text -- )
|
|
||||||
disable-images? get [
|
disable-images? get [
|
||||||
2drop
|
2drop
|
||||||
<strong> "Images are not allowed" write </strong>
|
[XML <strong>Images are not allowed</strong> XML]
|
||||||
] [
|
] [
|
||||||
escape-link
|
[ check-url ] [ f like ] bi*
|
||||||
[ <img url-encode =src ] [ [ =alt ] unless-empty img/> ] bi*
|
[XML <img src=<-> alt=<->/> XML]
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
: render-code ( string mode -- string' )
|
: render-code ( string mode -- xml )
|
||||||
[ string-lines ] dip
|
[ string-lines ] dip htmlize-lines
|
||||||
[
|
[XML <pre><-></pre> XML] ;
|
||||||
<pre>
|
|
||||||
htmlize-lines
|
|
||||||
</pre>
|
|
||||||
] with-string-writer write ;
|
|
||||||
|
|
||||||
GENERIC: (write-farkup) ( farkup -- )
|
GENERIC: (write-farkup) ( farkup -- xml )
|
||||||
: <foo.> ( string -- ) <foo> write ;
|
|
||||||
: </foo.> ( string -- ) </foo> write ;
|
|
||||||
: in-tag. ( obj quot string -- ) [ <foo.> call ] keep </foo.> ; inline
|
|
||||||
M: heading1 (write-farkup) [ child>> (write-farkup) ] "h1" in-tag. ;
|
|
||||||
M: heading2 (write-farkup) [ child>> (write-farkup) ] "h2" in-tag. ;
|
|
||||||
M: heading3 (write-farkup) [ child>> (write-farkup) ] "h3" in-tag. ;
|
|
||||||
M: heading4 (write-farkup) [ child>> (write-farkup) ] "h4" in-tag. ;
|
|
||||||
M: strong (write-farkup) [ child>> (write-farkup) ] "strong" in-tag. ;
|
|
||||||
M: emphasis (write-farkup) [ child>> (write-farkup) ] "em" in-tag. ;
|
|
||||||
M: superscript (write-farkup) [ child>> (write-farkup) ] "sup" in-tag. ;
|
|
||||||
M: subscript (write-farkup) [ child>> (write-farkup) ] "sub" in-tag. ;
|
|
||||||
M: inline-code (write-farkup) [ child>> (write-farkup) ] "code" in-tag. ;
|
|
||||||
M: list-item (write-farkup) [ child>> (write-farkup) ] "li" in-tag. ;
|
|
||||||
M: unordered-list (write-farkup) [ child>> (write-farkup) ] "ul" in-tag. ;
|
|
||||||
M: ordered-list (write-farkup) [ child>> (write-farkup) ] "ol" in-tag. ;
|
|
||||||
M: paragraph (write-farkup) [ child>> (write-farkup) ] "p" in-tag. ;
|
|
||||||
M: link (write-farkup) [ href>> ] [ text>> ] bi write-link ;
|
|
||||||
M: image (write-farkup) [ href>> ] [ text>> ] bi write-image-link ;
|
|
||||||
M: code (write-farkup) [ string>> ] [ mode>> ] bi render-code ;
|
|
||||||
M: line (write-farkup) drop <hr/> ;
|
|
||||||
M: line-break (write-farkup) drop <br/> nl ;
|
|
||||||
M: table-row (write-farkup) ( obj -- )
|
|
||||||
child>> [ [ [ (write-farkup) ] "td" in-tag. ] each ] "tr" in-tag. ;
|
|
||||||
M: table (write-farkup) [ child>> (write-farkup) ] "table" in-tag. ;
|
|
||||||
M: string (write-farkup) escape-string write ;
|
|
||||||
M: vector (write-farkup) [ (write-farkup) ] each ;
|
|
||||||
M: f (write-farkup) drop ;
|
|
||||||
|
|
||||||
: write-farkup ( string -- )
|
: farkup-inside ( farkup name -- xml )
|
||||||
|
<simple-name> swap T{ attrs } swap
|
||||||
|
child>> (write-farkup) 1array <tag> ;
|
||||||
|
|
||||||
|
M: heading1 (write-farkup) "h1" farkup-inside ;
|
||||||
|
M: heading2 (write-farkup) "h2" farkup-inside ;
|
||||||
|
M: heading3 (write-farkup) "h3" farkup-inside ;
|
||||||
|
M: heading4 (write-farkup) "h4" farkup-inside ;
|
||||||
|
M: strong (write-farkup) "strong" farkup-inside ;
|
||||||
|
M: emphasis (write-farkup) "em" farkup-inside ;
|
||||||
|
M: superscript (write-farkup) "sup" farkup-inside ;
|
||||||
|
M: subscript (write-farkup) "sub" farkup-inside ;
|
||||||
|
M: inline-code (write-farkup) "code" farkup-inside ;
|
||||||
|
M: list-item (write-farkup) "li" farkup-inside ;
|
||||||
|
M: unordered-list (write-farkup) "ul" farkup-inside ;
|
||||||
|
M: ordered-list (write-farkup) "ol" farkup-inside ;
|
||||||
|
M: paragraph (write-farkup) "p" farkup-inside ;
|
||||||
|
M: table (write-farkup) "table" farkup-inside ;
|
||||||
|
|
||||||
|
M: link (write-farkup)
|
||||||
|
[ href>> ] [ text>> ] bi write-link ;
|
||||||
|
|
||||||
|
M: image (write-farkup)
|
||||||
|
[ href>> ] [ text>> ] bi write-image-link ;
|
||||||
|
|
||||||
|
M: code (write-farkup)
|
||||||
|
[ string>> ] [ mode>> ] bi render-code ;
|
||||||
|
|
||||||
|
M: line (write-farkup)
|
||||||
|
drop [XML <hr/> XML] ;
|
||||||
|
|
||||||
|
M: line-break (write-farkup)
|
||||||
|
drop [XML <br/> XML] ;
|
||||||
|
|
||||||
|
M: table-row (write-farkup)
|
||||||
|
child>>
|
||||||
|
[ (write-farkup) [XML <td><-></td> XML] ] map
|
||||||
|
[XML <tr><-></tr> XML] ;
|
||||||
|
|
||||||
|
M: string (write-farkup) ;
|
||||||
|
|
||||||
|
M: vector (write-farkup) [ (write-farkup) ] map ;
|
||||||
|
|
||||||
|
M: f (write-farkup) ;
|
||||||
|
|
||||||
|
: farkup>xml ( string -- xml )
|
||||||
parse-farkup (write-farkup) ;
|
parse-farkup (write-farkup) ;
|
||||||
|
|
||||||
|
: write-farkup ( string -- )
|
||||||
|
farkup>xml write-xml-chunk ;
|
||||||
|
|
||||||
: convert-farkup ( string -- string' )
|
: convert-farkup ( string -- string' )
|
||||||
parse-farkup [ (write-farkup) ] with-string-writer ;
|
[ write-farkup ] with-string-writer ;
|
||||||
|
|
|
@ -31,7 +31,7 @@ TUPLE: color red green blue ;
|
||||||
] with-string-writer
|
] with-string-writer
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ "<input type='hidden' name='red' value='<jimmy>'/>" ] [
|
[ "<input value=\"<jimmy>\" name=\"red\" type=\"hidden\"/>" ] [
|
||||||
[
|
[
|
||||||
"red" hidden render
|
"red" hidden render
|
||||||
] with-string-writer
|
] with-string-writer
|
||||||
|
@ -39,13 +39,13 @@ TUPLE: color red green blue ;
|
||||||
|
|
||||||
[ ] [ "'jimmy'" "red" set-value ] unit-test
|
[ ] [ "'jimmy'" "red" set-value ] unit-test
|
||||||
|
|
||||||
[ "<input type='text' size='5' name='red' value=''jimmy''/>" ] [
|
[ "<input value=\"'jimmy'\" name=\"red\" size=\"5\" type=\"text\"/>" ] [
|
||||||
[
|
[
|
||||||
"red" <field> 5 >>size render
|
"red" <field> 5 >>size render
|
||||||
] with-string-writer
|
] with-string-writer
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ "<input type='password' size='5' name='red' value=''/>" ] [
|
[ "<input value=\"\" name=\"red\" size=\"5\" type=\"password\"/>" ] [
|
||||||
[
|
[
|
||||||
"red" <password> 5 >>size render
|
"red" <password> 5 >>size render
|
||||||
] with-string-writer
|
] with-string-writer
|
||||||
|
@ -105,7 +105,7 @@ TUPLE: color red green blue ;
|
||||||
|
|
||||||
[ ] [ t "delivery" set-value ] unit-test
|
[ ] [ t "delivery" set-value ] unit-test
|
||||||
|
|
||||||
[ "<input type='checkbox' name='delivery' checked='true'>Delivery</input>" ] [
|
[ "<input type=\"checkbox\" checked=\"true\" name=\"delivery\">Delivery</input>" ] [
|
||||||
[
|
[
|
||||||
"delivery"
|
"delivery"
|
||||||
<checkbox>
|
<checkbox>
|
||||||
|
@ -116,7 +116,7 @@ TUPLE: color red green blue ;
|
||||||
|
|
||||||
[ ] [ f "delivery" set-value ] unit-test
|
[ ] [ f "delivery" set-value ] unit-test
|
||||||
|
|
||||||
[ "<input type='checkbox' name='delivery'>Delivery</input>" ] [
|
[ "<input type=\"checkbox\" name=\"delivery\">Delivery</input>" ] [
|
||||||
[
|
[
|
||||||
"delivery"
|
"delivery"
|
||||||
<checkbox>
|
<checkbox>
|
||||||
|
@ -133,7 +133,7 @@ M: link-test link-href drop "http://www.apple.com/foo&bar" ;
|
||||||
|
|
||||||
[ ] [ link-test "link" set-value ] unit-test
|
[ ] [ link-test "link" set-value ] unit-test
|
||||||
|
|
||||||
[ "<a href='http://www.apple.com/foo&bar'><Link Title></a>" ] [
|
[ "<a href=\"http://www.apple.com/foo&bar\"><Link Title></a>" ] [
|
||||||
[ "link" link new render ] with-string-writer
|
[ "link" link new render ] with-string-writer
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ M: link-test link-href drop "http://www.apple.com/foo&bar" ;
|
||||||
|
|
||||||
[ ] [ "java" "mode" set-value ] unit-test
|
[ ] [ "java" "mode" set-value ] unit-test
|
||||||
|
|
||||||
[ "<span class='KEYWORD3'>int</span> x <span class='OPERATOR'>=</span> <span class='DIGIT'>4</span>;\n" ] [
|
[ "<span class=\"KEYWORD3\">int</span> x <span class=\"OPERATOR\">=</span> <span class=\"DIGIT\">4</span>;" ] [
|
||||||
[ "code" <code> "mode" >>mode render ] with-string-writer
|
[ "code" <code> "mode" >>mode render ] with-string-writer
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
@ -163,6 +163,8 @@ M: link-test link-href drop "http://www.apple.com/foo&bar" ;
|
||||||
|
|
||||||
[ t ] [
|
[ t ] [
|
||||||
[ "object" inspector render ] with-string-writer
|
[ "object" inspector render ] with-string-writer
|
||||||
|
USING: splitting sequences ;
|
||||||
|
"\"" split "'" join ! replace " with ' for now
|
||||||
[ "object" value [ describe ] with-html-writer ] with-string-writer
|
[ "object" value [ describe ] with-html-writer ] with-string-writer
|
||||||
=
|
=
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
|
@ -4,12 +4,12 @@ USING: accessors kernel namespaces io math.parser assocs classes
|
||||||
classes.tuple words arrays sequences splitting mirrors
|
classes.tuple words arrays sequences splitting mirrors
|
||||||
hashtables combinators continuations math strings inspector
|
hashtables combinators continuations math strings inspector
|
||||||
fry locals calendar calendar.format xml.entities
|
fry locals calendar calendar.format xml.entities
|
||||||
validators urls present
|
validators urls present xml.writer xml.interpolate xml
|
||||||
xmode.code2html lcs.diff2html farkup
|
xmode.code2html lcs.diff2html farkup io.streams.string
|
||||||
html.elements html.streams html.forms ;
|
html.elements html.streams html.forms ;
|
||||||
IN: html.components
|
IN: html.components
|
||||||
|
|
||||||
GENERIC: render* ( value name renderer -- )
|
GENERIC: render* ( value name renderer -- xml )
|
||||||
|
|
||||||
: render ( name renderer -- )
|
: render ( name renderer -- )
|
||||||
prepare-value
|
prepare-value
|
||||||
|
@ -19,38 +19,36 @@ GENERIC: render* ( value name renderer -- )
|
||||||
[ f swap ]
|
[ f swap ]
|
||||||
if
|
if
|
||||||
] 2dip
|
] 2dip
|
||||||
render*
|
render* write-xml-chunk
|
||||||
[ render-error ] when* ;
|
[ render-error ] when* ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: render-input ( value name type -- )
|
: render-input ( value name type -- xml )
|
||||||
<input =type =name present =value input/> ;
|
[XML <input value=<-> name=<-> type=<->/> XML] ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
SINGLETON: label
|
SINGLETON: label
|
||||||
|
|
||||||
M: label render* 2drop present escape-string write ;
|
M: label render*
|
||||||
|
2drop present ;
|
||||||
|
|
||||||
SINGLETON: hidden
|
SINGLETON: hidden
|
||||||
|
|
||||||
M: hidden render* drop "hidden" render-input ;
|
M: hidden render*
|
||||||
|
drop "hidden" render-input ;
|
||||||
|
|
||||||
: render-field ( value name size type -- )
|
: render-field ( value name size type -- xml )
|
||||||
<input
|
[XML <input value=<-> name=<-> size=<-> type=<->/> XML] ;
|
||||||
=type
|
|
||||||
[ present =size ] when*
|
|
||||||
=name
|
|
||||||
present =value
|
|
||||||
input/> ;
|
|
||||||
|
|
||||||
TUPLE: field size ;
|
TUPLE: field size ;
|
||||||
|
|
||||||
: <field> ( -- field )
|
: <field> ( -- field )
|
||||||
field new ;
|
field new ;
|
||||||
|
|
||||||
M: field render* size>> "text" render-field ;
|
M: field render*
|
||||||
|
size>> "text" render-field ;
|
||||||
|
|
||||||
TUPLE: password size ;
|
TUPLE: password size ;
|
||||||
|
|
||||||
|
@ -67,14 +65,12 @@ TUPLE: textarea rows cols ;
|
||||||
: <textarea> ( -- renderer )
|
: <textarea> ( -- renderer )
|
||||||
textarea new ;
|
textarea new ;
|
||||||
|
|
||||||
M: textarea render*
|
M: textarea render* ( value name area -- xml )
|
||||||
<textarea
|
rot [ [ rows>> ] [ cols>> ] bi ] dip
|
||||||
[ rows>> [ present =rows ] when* ]
|
[XML <textarea
|
||||||
[ cols>> [ present =cols ] when* ] bi
|
name=<->
|
||||||
=name
|
rows=<->
|
||||||
textarea>
|
cols=<->><-></textarea> XML] ;
|
||||||
present escape-string write
|
|
||||||
</textarea> ;
|
|
||||||
|
|
||||||
! Choice
|
! Choice
|
||||||
TUPLE: choice size multiple choices ;
|
TUPLE: choice size multiple choices ;
|
||||||
|
@ -82,24 +78,23 @@ TUPLE: choice size multiple choices ;
|
||||||
: <choice> ( -- choice )
|
: <choice> ( -- choice )
|
||||||
choice new ;
|
choice new ;
|
||||||
|
|
||||||
: render-option ( text selected? -- )
|
: render-option ( text selected? -- xml )
|
||||||
<option [ "selected" =selected ] when option>
|
"selected" and swap
|
||||||
present escape-string write
|
[XML <option selected=<->><-></option> XML] ;
|
||||||
</option> ;
|
|
||||||
|
|
||||||
: render-options ( options selected -- )
|
: render-options ( value choice -- xml )
|
||||||
'[ dup _ member? render-option ] each ;
|
[ choices>> value ] [ multiple>> ] bi
|
||||||
|
[ swap ] [ swap 1array ] if
|
||||||
|
'[ dup _ member? render-option ] map ;
|
||||||
|
|
||||||
M: choice render*
|
M:: choice render* ( value name choice -- xml )
|
||||||
<select
|
choice size>> :> size
|
||||||
swap =name
|
choice multiple>> "true" and :> multiple
|
||||||
dup size>> [ present =size ] when*
|
value choice render-options :> contents
|
||||||
dup multiple>> [ "true" =multiple ] when
|
[XML <select
|
||||||
select>
|
name=<-name->
|
||||||
[ choices>> value ] [ multiple>> ] bi
|
size=<-size->
|
||||||
[ swap ] [ swap 1array ] if
|
multiple=<-multiple->><-contents-></select> XML] ;
|
||||||
render-options
|
|
||||||
</select> ;
|
|
||||||
|
|
||||||
! Checkboxes
|
! Checkboxes
|
||||||
TUPLE: checkbox label ;
|
TUPLE: checkbox label ;
|
||||||
|
@ -108,13 +103,10 @@ TUPLE: checkbox label ;
|
||||||
checkbox new ;
|
checkbox new ;
|
||||||
|
|
||||||
M: checkbox render*
|
M: checkbox render*
|
||||||
<input
|
[ "true" and ] [ ] [ label>> ] tri*
|
||||||
"checkbox" =type
|
[XML <input
|
||||||
swap =name
|
type="checkbox"
|
||||||
swap [ "true" =checked ] when
|
checked=<-> name=<->><-></input> XML] ;
|
||||||
input>
|
|
||||||
label>> escape-string write
|
|
||||||
</input> ;
|
|
||||||
|
|
||||||
! Link components
|
! Link components
|
||||||
GENERIC: link-title ( obj -- string )
|
GENERIC: link-title ( obj -- string )
|
||||||
|
@ -129,10 +121,9 @@ M: url link-href ;
|
||||||
TUPLE: link target ;
|
TUPLE: link target ;
|
||||||
|
|
||||||
M: link render*
|
M: link render*
|
||||||
nip
|
nip swap
|
||||||
<a target>> [ =target ] when* dup link-href =href a>
|
[ target>> ] [ [ link-href ] [ link-title ] bi ] bi*
|
||||||
link-title present escape-string write
|
[XML <a target=<-> href=<->><-></a> XML] ;
|
||||||
</a> ;
|
|
||||||
|
|
||||||
! XMode code component
|
! XMode code component
|
||||||
TUPLE: code mode ;
|
TUPLE: code mode ;
|
||||||
|
@ -161,7 +152,7 @@ M: farkup render*
|
||||||
nip
|
nip
|
||||||
[ no-follow>> [ string>boolean link-no-follow? set ] when* ]
|
[ no-follow>> [ string>boolean link-no-follow? set ] when* ]
|
||||||
[ disable-images>> [ string>boolean disable-images? set ] when* ]
|
[ disable-images>> [ string>boolean disable-images? set ] when* ]
|
||||||
[ parsed>> string>boolean [ (write-farkup) ] [ write-farkup ] if ]
|
[ parsed>> string>boolean [ (write-farkup) ] [ farkup>xml ] if ]
|
||||||
tri
|
tri
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
||||||
|
@ -169,7 +160,8 @@ M: farkup render*
|
||||||
SINGLETON: inspector
|
SINGLETON: inspector
|
||||||
|
|
||||||
M: inspector render*
|
M: inspector render*
|
||||||
2drop [ describe ] with-html-writer ;
|
2drop [ [ describe ] with-html-writer ] with-string-writer
|
||||||
|
string>xml-chunk ;
|
||||||
|
|
||||||
! Diff component
|
! Diff component
|
||||||
SINGLETON: comparison
|
SINGLETON: comparison
|
||||||
|
@ -180,4 +172,4 @@ M: comparison render*
|
||||||
! HTML component
|
! HTML component
|
||||||
SINGLETON: html
|
SINGLETON: html
|
||||||
|
|
||||||
M: html render* 2drop write ;
|
M: html render* 2drop string>xml-chunk ;
|
||||||
|
|
|
@ -1,44 +1,42 @@
|
||||||
! Copyright (C) 2008 Slava Pestov
|
! Copyright (C) 2008 Slava Pestov
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: lcs html.elements kernel ;
|
USING: lcs xml.interpolate xml.writer kernel strings ;
|
||||||
FROM: accessors => item>> ;
|
FROM: accessors => item>> ;
|
||||||
FROM: io => write ;
|
FROM: io => write ;
|
||||||
FROM: sequences => each if-empty ;
|
FROM: sequences => each if-empty when-empty map ;
|
||||||
FROM: xml.entities => escape-string ;
|
|
||||||
IN: lcs.diff2html
|
IN: lcs.diff2html
|
||||||
|
|
||||||
GENERIC: diff-line ( obj -- )
|
GENERIC: diff-line ( obj -- xml )
|
||||||
|
|
||||||
: write-item ( item -- )
|
: item-string ( item -- string )
|
||||||
item>> [ " " ] [ escape-string ] if-empty write ;
|
item>> [ CHAR: no-break-space 1string ] when-empty ;
|
||||||
|
|
||||||
M: retain diff-line
|
M: retain diff-line
|
||||||
<tr>
|
item-string
|
||||||
dup [
|
[XML <td class="retain"><-></td> XML]
|
||||||
<td "retain" =class td>
|
dup [XML <tr><-><-></tr> XML] ;
|
||||||
write-item
|
|
||||||
</td>
|
|
||||||
] bi@
|
|
||||||
</tr> ;
|
|
||||||
|
|
||||||
M: insert diff-line
|
M: insert diff-line
|
||||||
<tr>
|
item-string [XML
|
||||||
<td> </td>
|
<tr>
|
||||||
<td "insert" =class td>
|
<td> </td>
|
||||||
write-item
|
<td class="insert"><-></td>
|
||||||
</td>
|
</tr>
|
||||||
</tr> ;
|
XML] ;
|
||||||
|
|
||||||
M: delete diff-line
|
M: delete diff-line
|
||||||
<tr>
|
item-string [XML
|
||||||
<td "delete" =class td>
|
<tr>
|
||||||
write-item
|
<td class="delete"><-></td>
|
||||||
</td>
|
<td> </td>
|
||||||
<td> </td>
|
</tr>
|
||||||
</tr> ;
|
XML] ;
|
||||||
|
|
||||||
: htmlize-diff ( diff -- )
|
: htmlize-diff ( diff -- xml )
|
||||||
<table "100%" =width "comparison" =class table>
|
[ diff-line ] map
|
||||||
<tr> <th> "Old" write </th> <th> "New" write </th> </tr>
|
[XML
|
||||||
[ diff-line ] each
|
<table width="100%" class="comparison">
|
||||||
</table> ;
|
<tr><th>Old</th><th>New</th></tr>
|
||||||
|
<->
|
||||||
|
</table>
|
||||||
|
XML] ;
|
||||||
|
|
|
@ -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 ;
|
debugger calendar.format math.order xml.interpolate ;
|
||||||
IN: xml-rpc
|
IN: xml-rpc
|
||||||
|
|
||||||
! * Sending RPC requests
|
! * Sending RPC requests
|
||||||
|
@ -15,56 +15,70 @@ 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 "i4" build-tag ;
|
number>string [XML <i4><-></i4> XML] ;
|
||||||
|
|
||||||
UNION: boolean t POSTPONE: f ;
|
UNION: boolean t POSTPONE: f ;
|
||||||
|
|
||||||
M: boolean item>xml
|
M: boolean item>xml
|
||||||
"1" "0" ? "boolean" build-tag ;
|
"1" "0" ? [XML <boolean><-></boolean> XML] ;
|
||||||
|
|
||||||
M: float item>xml
|
M: float item>xml
|
||||||
number>string "double" build-tag ;
|
number>string [XML <double><-></double> XML] ;
|
||||||
|
|
||||||
M: string item>xml ! This should change < and &
|
M: string item>xml
|
||||||
"string" build-tag ;
|
[XML <string><-></string> XML] ;
|
||||||
|
|
||||||
: struct-member ( name value -- tag )
|
: struct-member ( name value -- tag )
|
||||||
swap dup string?
|
over string? [ "Struct member name must be string" throw ] unless
|
||||||
[ "Struct member name must be string" throw ] unless
|
item>xml
|
||||||
"name" build-tag swap
|
[XML
|
||||||
item>xml "value" build-tag
|
<member>
|
||||||
2array "member" build-tag* ;
|
<name><-></name>
|
||||||
|
<value><-></value>
|
||||||
|
</member>
|
||||||
|
XML] ;
|
||||||
|
|
||||||
M: hashtable item>xml
|
M: hashtable item>xml
|
||||||
[ struct-member ] { } assoc>map
|
[ struct-member ] { } assoc>map
|
||||||
"struct" build-tag* ;
|
[XML <struct><-></struct> XML] ;
|
||||||
|
|
||||||
M: array item>xml
|
M: array item>xml
|
||||||
[ item>xml "value" build-tag ] map
|
[ item>xml [XML <value><-></value> XML] ] map
|
||||||
"data" build-tag* "array" build-tag ;
|
[XML <array><data><-></data></array> XML] ;
|
||||||
|
|
||||||
TUPLE: base64 string ;
|
TUPLE: base64 string ;
|
||||||
|
|
||||||
C: <base64> base64
|
C: <base64> base64
|
||||||
|
|
||||||
M: base64 item>xml
|
M: base64 item>xml
|
||||||
string>> >base64 "base64" build-tag ;
|
string>> >base64
|
||||||
|
[XML <base64><-></base64> XML] ;
|
||||||
|
|
||||||
: params ( seq -- xml )
|
: params ( seq -- xml )
|
||||||
[ item>xml "value" build-tag "param" build-tag ] map
|
[ item>xml [XML <param><value><-></value></param> XML] ] map
|
||||||
"params" build-tag* ;
|
[XML <params><-></params> XML] ;
|
||||||
|
|
||||||
: method-call ( name seq -- xml )
|
: method-call ( name seq -- xml )
|
||||||
params [ "methodName" build-tag ] dip
|
params
|
||||||
2array "methodCall" build-tag* build-xml ;
|
<XML
|
||||||
|
<methodCall>
|
||||||
|
<methodName><-></methodName>
|
||||||
|
<->
|
||||||
|
</methodCall>
|
||||||
|
XML> ;
|
||||||
|
|
||||||
: return-params ( seq -- xml )
|
: return-params ( seq -- xml )
|
||||||
params "methodResponse" build-tag build-xml ;
|
params <XML <methodResponse><-></methodResponse> XML> ;
|
||||||
|
|
||||||
: return-fault ( fault-code fault-string -- xml )
|
: return-fault ( fault-code fault-string -- xml )
|
||||||
[ "faultString" set "faultCode" set ] H{ } make-assoc item>xml
|
[ "faultString" set "faultCode" set ] H{ } make-assoc item>xml
|
||||||
"value" build-tag "fault" build-tag "methodResponse" build-tag
|
<XML
|
||||||
build-xml ;
|
<methodResponse>
|
||||||
|
<fault>
|
||||||
|
<value><-></value>
|
||||||
|
</fault>
|
||||||
|
</methodResponse>
|
||||||
|
XML> ;
|
||||||
|
|
||||||
TUPLE: rpc-method name params ;
|
TUPLE: rpc-method name params ;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ IN: xml.data
|
||||||
ABOUT: "xml.data"
|
ABOUT: "xml.data"
|
||||||
|
|
||||||
ARTICLE: "xml.data" "XML data types"
|
ARTICLE: "xml.data" "XML data types"
|
||||||
{ $vocab-link "xml.data" } " defines a simple document object model for XML. Everything is simply a tuple and can be manipulated as such."
|
"The " { $vocab-link "xml.data" } " vocabulary defines a simple document object model for XML. Everything is simply a tuple and can be manipulated as such."
|
||||||
{ $subsection { "xml.data" "classes" } }
|
{ $subsection { "xml.data" "classes" } }
|
||||||
{ $subsection { "xml.data" "constructors" } }
|
{ $subsection { "xml.data" "constructors" } }
|
||||||
"Simple words for manipulating names:"
|
"Simple words for manipulating names:"
|
||||||
|
@ -49,7 +49,7 @@ ARTICLE: { "xml.data" "constructors" } "XML data constructors"
|
||||||
{ $subsection <notation-decl> } ;
|
{ $subsection <notation-decl> } ;
|
||||||
|
|
||||||
HELP: tag
|
HELP: tag
|
||||||
{ $class-description "tuple representing an XML tag, delegating to a " { $link
|
{ $class-description "Tuple representing an XML tag, delegating to a " { $link
|
||||||
name } ", containing the slots attrs (an alist of names to strings) and children (a sequence). Tags implement the sequence protocol by acting like a sequence of its chidren, and the assoc protocol by acting like its attributes." }
|
name } ", containing the slots attrs (an alist of names to strings) and children (a sequence). Tags implement the sequence protocol by acting like a sequence of its chidren, and the assoc protocol by acting like its attributes." }
|
||||||
{ $see-also <tag> name contained-tag xml } ;
|
{ $see-also <tag> name contained-tag xml } ;
|
||||||
|
|
||||||
|
@ -58,32 +58,32 @@ HELP: <tag>
|
||||||
{ "attrs" "an alist of names to strings" }
|
{ "attrs" "an alist of names to strings" }
|
||||||
{ "children" sequence }
|
{ "children" sequence }
|
||||||
{ "tag" tag } }
|
{ "tag" tag } }
|
||||||
{ $description "constructs an XML " { $link tag } " with the name (not a string) and tag attributes specified in attrs and children specified" }
|
{ $description "Constructs an XML " { $link tag } " with the name (not a string) and tag attributes specified in attrs and children specified." }
|
||||||
{ $see-also tag <contained-tag> } ;
|
{ $see-also tag <contained-tag> } ;
|
||||||
|
|
||||||
HELP: name
|
HELP: name
|
||||||
{ $class-description "represents an XML name, with the fields space (a string representing the namespace, as written in the document, tag (a string of the actual name of the tag) and url (a string of the URL that the namespace points to)" }
|
{ $class-description "Represents an XML name, with the fields space (a string representing the namespace, as written in the document, tag (a string of the actual name of the tag) and url (a string of the URL that the namespace points to)." }
|
||||||
{ $see-also <name> tag } ;
|
{ $see-also <name> tag } ;
|
||||||
|
|
||||||
HELP: <name>
|
HELP: <name>
|
||||||
{ $values { "space" "a string" } { "main" "a string" } { "url" "a string" }
|
{ $values { "space" "a string" } { "main" "a string" } { "url" "a string" }
|
||||||
{ "name" "an XML tag name" } }
|
{ "name" "an XML tag name" } }
|
||||||
{ $description "creates a name tuple with the name-space space and the tag-name tag and the tag-url url." }
|
{ $description "Creates a name tuple with the namespace prefix space, the the given main part of the name, and the namespace URL given by url." }
|
||||||
{ $see-also name <tag> } ;
|
{ $see-also name <tag> } ;
|
||||||
|
|
||||||
HELP: contained-tag
|
HELP: contained-tag
|
||||||
{ $class-description "delegates to tag representing a tag like <a/> with no contents. The tag attributes are accessed with tag-attrs" }
|
{ $class-description "This is a subclass of " { $link tag } " consisting of tags with no body, like " { $snippet "<a/>" } "." }
|
||||||
{ $see-also tag <contained-tag> } ;
|
{ $see-also tag <contained-tag> } ;
|
||||||
|
|
||||||
HELP: <contained-tag>
|
HELP: <contained-tag>
|
||||||
{ $values { "name" "an XML tag name" }
|
{ $values { "name" "an XML tag name" }
|
||||||
{ "attrs" "an alist from names to strings" }
|
{ "attrs" "an alist from names to strings" }
|
||||||
{ "tag" tag } }
|
{ "tag" tag } }
|
||||||
{ $description "creates an empty tag (like <a/>) with the specified name and tag attributes. This delegates to tag" }
|
{ $description "Creates an empty tag (like " { $snippet "<a/>" } ") with the specified name and tag attributes." }
|
||||||
{ $see-also contained-tag <tag> } ;
|
{ $see-also contained-tag <tag> } ;
|
||||||
|
|
||||||
HELP: xml
|
HELP: xml
|
||||||
{ $class-description "tuple representing an XML document, delegating to the main tag, containing the fields prolog (the header <?xml...?>), before (whatever comes between the prolog and the main tag) and after (whatever comes after the main tag)" }
|
{ $class-description "Tuple representing an XML document, delegating to the main tag, containing the fields prolog (the header " { $snippet "<?xml...?>" } "), before (whatever comes between the prolog and the main tag) and after (whatever comes after the main tag)." }
|
||||||
{ $see-also <xml> tag prolog } ;
|
{ $see-also <xml> tag prolog } ;
|
||||||
|
|
||||||
HELP: <xml>
|
HELP: <xml>
|
||||||
|
@ -159,35 +159,35 @@ HELP: <element-decl>
|
||||||
{ $description "Creates an element declaration object, of the class " { $link element-decl } } ;
|
{ $description "Creates an element declaration object, of the class " { $link element-decl } } ;
|
||||||
|
|
||||||
HELP: attlist-decl
|
HELP: attlist-decl
|
||||||
{ $class-description "Describes the class of element declarations, like <!ATTLIST pre xml:space (preserve) #FIXED 'preserve'>." } ;
|
{ $class-description "Describes the class of element declarations, like " { $snippet "<!ATTLIST pre xml:space (preserve) #FIXED 'preserve'>" } "." } ;
|
||||||
|
|
||||||
HELP: <attlist-decl>
|
HELP: <attlist-decl>
|
||||||
{ $values { "name" name } { "att-defs" string } { "attlist-decl" attlist-decl } }
|
{ $values { "name" name } { "att-defs" string } { "attlist-decl" attlist-decl } }
|
||||||
{ $description "Creates an element declaration object, of the class " { $link attlist-decl } } ;
|
{ $description "Creates an element declaration object, of the class " { $link attlist-decl } } ;
|
||||||
|
|
||||||
HELP: entity-decl
|
HELP: entity-decl
|
||||||
{ $class-description "Describes the class of element declarations, like <!ENTITY foo 'bar'>." } ;
|
{ $class-description "Describes the class of element declarations, like " { $snippet "<!ENTITY foo 'bar'>" } "." } ;
|
||||||
|
|
||||||
HELP: <entity-decl>
|
HELP: <entity-decl>
|
||||||
{ $values { "name" name } { "def" string } { "pe?" "t or f" } { "entity-decl" entity-decl } }
|
{ $values { "name" name } { "def" string } { "pe?" "t or f" } { "entity-decl" entity-decl } }
|
||||||
{ $description "Creates an entity declaration object, of the class " { $link entity-decl } ". The pe? slot should be t if the object is a DTD-internal entity, like <!ENTITY % foo 'bar'> and f if the object is like <!ENTITY foo 'bar'>, that is, it can be used outside of the DTD." } ;
|
{ $description "Creates an entity declaration object, of the class " { $link entity-decl } ". The pe? slot should be t if the object is a DTD-internal entity, like " { $snippet "<!ENTITY % foo 'bar'>" } " and f if the object is like " { $snippet "<!ENTITY foo 'bar'>" } ", that is, it can be used outside of the DTD." } ;
|
||||||
|
|
||||||
HELP: system-id
|
HELP: system-id
|
||||||
{ $class-description "Describes the class of system identifiers within an XML DTD directive, such as <!DOCTYPE greeting " { $emphasis "SYSTEM 'hello.dtd'" } ">" } ;
|
{ $class-description "Describes the class of system identifiers within an XML DTD directive, such as " { $snippet "<!DOCTYPE greeting " { $emphasis "SYSTEM 'hello.dtd'" } ">" } } ;
|
||||||
|
|
||||||
HELP: <system-id>
|
HELP: <system-id>
|
||||||
{ $values { "system-literal" string } { "system-id" system-id } }
|
{ $values { "system-literal" string } { "system-id" system-id } }
|
||||||
{ $description "Constructs a " { $link system-id } " tuple." } ;
|
{ $description "Constructs a " { $link system-id } " tuple." } ;
|
||||||
|
|
||||||
HELP: public-id
|
HELP: public-id
|
||||||
{ $class-description "Describes the class of public identifiers within an XML DTD directive, such as <!DOCTYPE open-hatch " { $emphasis "PUBLIC '-//Textuality//TEXT Standard open-hatch boilerplate//EN' 'http://www.textuality.com/boilerplate/OpenHatch.xml'" } ">" } ;
|
{ $class-description "Describes the class of public identifiers within an XML DTD directive, such as " { $snippet "<!DOCTYPE open-hatch " { $emphasis "PUBLIC '-//Textuality//TEXT Standard open-hatch boilerplate//EN' 'http://www.textuality.com/boilerplate/OpenHatch.xml'" } ">" } } ;
|
||||||
|
|
||||||
HELP: <public-id>
|
HELP: <public-id>
|
||||||
{ $values { "pubid-literal" string } { "system-literal" string } { "public-id" public-id } }
|
{ $values { "pubid-literal" string } { "system-literal" string } { "public-id" public-id } }
|
||||||
{ $description "Constructs a " { $link system-id } " tuple." } ;
|
{ $description "Constructs a " { $link system-id } " tuple." } ;
|
||||||
|
|
||||||
HELP: notation-decl
|
HELP: notation-decl
|
||||||
{ $class-description "Describes the class of element declarations, like <!NOTATION jpg SYSTEM './jpgviewer'>." } ;
|
{ $class-description "Describes the class of element declarations, like " { $snippet "<!NOTATION jpg SYSTEM './jpgviewer'>" } "." } ;
|
||||||
|
|
||||||
HELP: <notation-decl>
|
HELP: <notation-decl>
|
||||||
{ $values { "name" string } { "id" id } { "notation-decl" notation-decl } }
|
{ $values { "name" string } { "id" id } { "notation-decl" notation-decl } }
|
||||||
|
|
|
@ -216,3 +216,6 @@ M: xml like
|
||||||
|
|
||||||
PREDICATE: contained-tag < tag children>> not ;
|
PREDICATE: contained-tag < tag children>> not ;
|
||||||
PREDICATE: open-tag < tag children>> ;
|
PREDICATE: open-tag < tag children>> ;
|
||||||
|
|
||||||
|
UNION: xml-data
|
||||||
|
tag comment string directive instruction ;
|
||||||
|
|
|
@ -3,16 +3,15 @@
|
||||||
USING: kernel namespaces xml.tokenize xml.state xml.name
|
USING: kernel namespaces xml.tokenize xml.state xml.name
|
||||||
xml.data accessors arrays make xml.char-classes fry assocs sequences
|
xml.data accessors arrays make xml.char-classes fry assocs sequences
|
||||||
math xml.errors sets combinators io.encodings io.encodings.iana
|
math xml.errors sets combinators io.encodings io.encodings.iana
|
||||||
unicode.case xml.dtd strings xml.entities ;
|
unicode.case xml.dtd strings xml.entities unicode.categories ;
|
||||||
IN: xml.elements
|
IN: xml.elements
|
||||||
|
|
||||||
: take-interpolated ( quot -- interpolated )
|
: take-interpolated ( quot -- interpolated )
|
||||||
interpolating? get [
|
interpolating? get [
|
||||||
drop get-char CHAR: > =
|
drop get-char CHAR: > =
|
||||||
[ next f ] [
|
[ next f ]
|
||||||
pass-blank " \t\r\n-" take-to
|
[ "->" take-string [ blank? ] trim ]
|
||||||
pass-blank "->" expect
|
if <interpolated>
|
||||||
] if <interpolated>
|
|
||||||
] [ call ] if ; inline
|
] [ call ] if ; inline
|
||||||
|
|
||||||
: interpolate-quote ( -- interpolated )
|
: interpolate-quote ( -- interpolated )
|
||||||
|
|
|
@ -16,6 +16,7 @@ IN: xml.entities
|
||||||
{ CHAR: & "&" }
|
{ CHAR: & "&" }
|
||||||
{ CHAR: ' "'" }
|
{ CHAR: ' "'" }
|
||||||
{ CHAR: " """ }
|
{ CHAR: " """ }
|
||||||
|
{ CHAR: < "<" }
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
: escape-string-by ( str table -- escaped )
|
: escape-string-by ( str table -- escaped )
|
||||||
|
|
|
@ -10,44 +10,68 @@ HELP: notags
|
||||||
{ $class-description "XML parsing error describing the case where an XML document contains no main tag, or any tags at all" } ;
|
{ $class-description "XML parsing error describing the case where an XML document contains no main tag, or any tags at all" } ;
|
||||||
|
|
||||||
HELP: extra-attrs
|
HELP: extra-attrs
|
||||||
{ $class-description "XML parsing error describing the case where the XML prolog (<?xml ...?>) contains attributes other than the three allowed ones, standalone, version and encoding. Contains one slot, attrs, which is a hashtable of all the extra attributes' names. Delegates to " { $link parsing-error } "." } ;
|
{ $class-description "XML parsing error describing the case where the XML prolog (" { $snippet "<?xml ...?>" } ") contains attributes other than the three allowed ones, standalone, version and encoding. Contains one slot, attrs, which is a hashtable of all the extra attributes' names. Delegates to " { $link xml-error-at } "." } ;
|
||||||
|
|
||||||
HELP: nonexist-ns
|
HELP: nonexist-ns
|
||||||
{ $class-description "XML parsing error describing the case where a namespace doesn't exist but it is used in a tag. Contains one slot, name, which contains the name of the undeclared namespace, and delegates to " { $link parsing-error } "." } ;
|
{ $class-description "XML parsing error describing the case where a namespace doesn't exist but it is used in a tag. Contains one slot, name, which contains the name of the undeclared namespace, and delegates to " { $link xml-error-at } "." } ;
|
||||||
|
|
||||||
HELP: not-yes/no
|
HELP: not-yes/no
|
||||||
{ $class-description "XML parsing error used to describe the case where standalone is set in the XML prolog to something other than 'yes' or 'no'. Delegates to " { $link parsing-error } " and contains one slot, text, which contains offending value." } ;
|
{ $class-description "XML parsing error used to describe the case where standalone is set in the XML prolog to something other than 'yes' or 'no'. Delegates to " { $link xml-error-at } " and contains one slot, text, which contains offending value." } ;
|
||||||
|
|
||||||
HELP: unclosed
|
HELP: unclosed
|
||||||
{ $class-description "XML parsing error used to describe the case where the XML document contains classes which are not closed by the end of the document. Contains one slot, tags, a sequence of names." } ;
|
{ $class-description "XML parsing error used to describe the case where the XML document contains classes which are not closed by the end of the document. Contains one slot, tags, a sequence of names." } ;
|
||||||
|
|
||||||
HELP: mismatched
|
HELP: mismatched
|
||||||
{ $class-description "XML parsing error describing mismatched tags, eg <a></c>. Contains two slots: open is the name of the opening tag and close is the name of the closing tag. Delegates to " { $link parsing-error } " showing the location of the closing tag" } ;
|
{ $class-description "XML parsing error describing mismatched tags, eg " { $snippet "<a></c>" } ". Contains two slots: open is the name of the opening tag and close is the name of the closing tag. Delegates to " { $link xml-error-at } " showing the location of the closing tag" } ;
|
||||||
|
|
||||||
HELP: expected
|
HELP: expected
|
||||||
{ $class-description "XML parsing error describing when an expected token was not present. Delegates to " { $link parsing-error } ". Contains two slots, should-be, which has the expected string, and was, which has the actual string." } ;
|
{ $class-description "XML parsing error describing when an expected token was not present. Delegates to " { $link xml-error-at } ". Contains two slots, should-be, which has the expected string, and was, which has the actual string." } ;
|
||||||
|
|
||||||
HELP: no-entity
|
HELP: no-entity
|
||||||
{ $class-description "XML parsing error describing the use of an undefined entity in a case where standalone is marked yes. Delegates to " { $link parsing-error } ". Contains one slot, thing, containing a string representing the entity." } ;
|
{ $class-description "XML parsing error describing the use of an undefined entity in a case where standalone is marked yes. Delegates to " { $link xml-error-at } ". Contains one slot, thing, containing a string representing the entity." } ;
|
||||||
|
|
||||||
|
|
||||||
HELP: pre/post-content
|
HELP: pre/post-content
|
||||||
{ $class-description "describes the error where a non-whitespace string is used before or after the main tag in an XML document. Contains two slots: string contains the offending string, and pre? is t if it occured before the main tag and f if it occured after" } ;
|
{ $class-description "Describes the error where a non-whitespace string is used before or after the main tag in an XML document. Contains two slots: string contains the offending string, and pre? is t if it occured before the main tag and f if it occured after" } ;
|
||||||
|
|
||||||
HELP: unclosed-quote
|
HELP: unclosed-quote
|
||||||
{ $class-description "describes the error where a quotation for an attribute value is opened but not closed before the end of the document." } ;
|
{ $class-description "Describes the error where a quotation for an attribute value is opened but not closed before the end of the document." } ;
|
||||||
|
|
||||||
HELP: bad-name
|
HELP: bad-name
|
||||||
{ $class-description "describes the error where a name is used, for example in an XML tag or attribute key, which is invalid." } ;
|
{ $class-description "Describes the error where a name is used, for example in an XML tag or attribute key, which is invalid." } ;
|
||||||
|
|
||||||
HELP: quoteless-attr
|
HELP: quoteless-attr
|
||||||
{ $class-description "describes the error where an attribute of an XML tag is missing quotes around a value." } ;
|
{ $class-description "Describes the error where an attribute of an XML tag is missing quotes around a value." } ;
|
||||||
|
|
||||||
HELP: xml-parse-error
|
HELP: disallowed-char
|
||||||
{ $class-description "the exception class that all parsing errors in XML documents are in." } ;
|
{ $class-description "Describes the error where a disallowed character occurs in an XML document." } ;
|
||||||
|
|
||||||
|
HELP: missing-close
|
||||||
|
{ $class-description "Describes the error where a particular closing token is missing." } ;
|
||||||
|
|
||||||
|
HELP: unexpected-end
|
||||||
|
{ $class-description "Describes the error where a document unexpectedly ends, and the XML parser expected it to continue." } ;
|
||||||
|
|
||||||
|
HELP: duplicate-attr
|
||||||
|
{ $class-description "Describes the error where there is more than one attribute of the same key." } ;
|
||||||
|
|
||||||
|
HELP: bad-cdata
|
||||||
|
{ $class-description "Describes the error where CDATA is used outside of the main tag of an XML document." } ;
|
||||||
|
|
||||||
|
HELP: text-w/]]>
|
||||||
|
{ $class-description "Describes the error where a text node contains the literal string " { $snippet "]]>" } " which is disallowed." } ;
|
||||||
|
|
||||||
|
HELP: attr-w/<
|
||||||
|
{ $class-description "Describes the error where an attribute value contains the literal character " { $snippet "<" } " which is disallowed." } ;
|
||||||
|
|
||||||
|
HELP: misplaced-directive
|
||||||
|
{ $class-description "Describes the error where an internal DTD directive is used outside of a DOCTYPE or DTD file, or where a DOCTYPE occurs somewhere other than before the main tag of an XML document." } ;
|
||||||
|
|
||||||
|
HELP: xml-error
|
||||||
|
{ $class-description "The exception class that all parsing errors in XML documents are in." } ;
|
||||||
|
|
||||||
ARTICLE: "xml.errors" "XML parsing errors"
|
ARTICLE: "xml.errors" "XML parsing errors"
|
||||||
{ $vocab-link "xml.errors" } " provides a rich and highly inspectable set of parsing errors. All XML errors are described by the union class " { $link xml-parse-error } " but there are many classes contained in that:"
|
"The " { $vocab-link "xml.errors" } " vocabulary provides a rich and highly inspectable set of parsing errors. All XML errors are described by the union class " { $link xml-error } " but there are many classes contained in that:"
|
||||||
{ $subsection multitags }
|
{ $subsection multitags }
|
||||||
{ $subsection notags }
|
{ $subsection notags }
|
||||||
{ $subsection extra-attrs }
|
{ $subsection extra-attrs }
|
||||||
|
@ -61,7 +85,15 @@ ARTICLE: "xml.errors" "XML parsing errors"
|
||||||
{ $subsection unclosed-quote }
|
{ $subsection unclosed-quote }
|
||||||
{ $subsection bad-name }
|
{ $subsection bad-name }
|
||||||
{ $subsection quoteless-attr }
|
{ $subsection quoteless-attr }
|
||||||
"Additionally, most of these errors are a kind of " { $link parsing-error } " which provides more information"
|
{ $subsection disallowed-char }
|
||||||
|
{ $subsection missing-close }
|
||||||
|
{ $subsection unexpected-end }
|
||||||
|
{ $subsection duplicate-attr }
|
||||||
|
{ $subsection bad-cdata }
|
||||||
|
{ $subsection text-w/]]> }
|
||||||
|
{ $subsection attr-w/< }
|
||||||
|
{ $subsection misplaced-directive }
|
||||||
|
"Additionally, most of these errors are a kind of " { $link xml-error-at } " which provides more information"
|
||||||
$nl
|
$nl
|
||||||
"Note that, in parsing an XML document, only the first error is reported." ;
|
"Note that, in parsing an XML document, only the first error is reported." ;
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,16 @@ T{ pre/post-content f "x" t } "x<y/>" xml-error-test
|
||||||
T{ versionless-prolog f 1 8 } "<?xml?><x/>" xml-error-test
|
T{ versionless-prolog f 1 8 } "<?xml?><x/>" xml-error-test
|
||||||
T{ unclosed-quote f 1 13 } "<x value='/>" xml-error-test
|
T{ unclosed-quote f 1 13 } "<x value='/>" xml-error-test
|
||||||
T{ bad-name f 1 3 "-" } "<-/>" xml-error-test
|
T{ bad-name f 1 3 "-" } "<-/>" xml-error-test
|
||||||
|
T{ quoteless-attr f 1 12 } "<x value=<->/>" xml-error-test
|
||||||
T{ quoteless-attr f 1 10 } "<x value=3/>" xml-error-test
|
T{ quoteless-attr f 1 10 } "<x value=3/>" xml-error-test
|
||||||
T{ attr-w/< f 1 11 } "<x value='<'/>" xml-error-test
|
T{ attr-w/< f 1 11 } "<x value='<'/>" xml-error-test
|
||||||
T{ text-w/]]> f 1 6 } "<x>]]></x>" xml-error-test
|
T{ text-w/]]> f 1 6 } "<x>]]></x>" xml-error-test
|
||||||
T{ duplicate-attr f 1 21 T{ name { space "" } { main "this" } } V{ "a" "b" } } "<x this='a' this='b'/>" xml-error-test
|
T{ duplicate-attr f 1 21 T{ name { space "" } { main "this" } } V{ "a" "b" } } "<x this='a' this='b'/>" xml-error-test
|
||||||
T{ bad-cdata f 1 3 } "<![CDATA[]]><x/>" xml-error-test
|
T{ bad-cdata f 1 3 } "<![CDATA[]]><x/>" xml-error-test
|
||||||
T{ bad-cdata f 1 7 } "<x/><![CDATA[]]>" xml-error-test
|
T{ bad-cdata f 1 7 } "<x/><![CDATA[]]>" xml-error-test
|
||||||
T{ pre/post-content f "&" t } "&32;<x/>" xml-error-test
|
T{ pre/post-content f "&" t } " <x/>" xml-error-test
|
||||||
T{ bad-doctype f 1 17 "a" } "<!DOCTYPE foo [ a ]><x/>" xml-error-test
|
T{ bad-doctype f 1 17 "a" } "<!DOCTYPE foo [ a ]><x/>" xml-error-test
|
||||||
T{ bad-doctype f 1 22 T{ opener { name T{ name f "" "foo" "" } } { attrs T{ attrs } } } } "<!DOCTYPE foo [ <foo> ]><x/>" xml-error-test
|
T{ bad-doctype f 1 22 T{ opener { name T{ name f "" "foo" "" } } { attrs T{ attrs } } } } "<!DOCTYPE foo [ <foo> ]><x/>" xml-error-test
|
||||||
|
T{ disallowed-char f 1 3 1 } "<x>\u000001</x>" xml-error-test
|
||||||
|
T{ missing-close f 1 9 } "<!-- foo" xml-error-test
|
||||||
|
T{ misplaced-directive f 1 9 "ENTITY" } "<!ENTITY foo 'bar'><x/>" xml-error-test
|
||||||
|
|
|
@ -5,22 +5,22 @@ debugger sequences xml.state accessors summary
|
||||||
namespaces io.streams.string ;
|
namespaces io.streams.string ;
|
||||||
IN: xml.errors
|
IN: xml.errors
|
||||||
|
|
||||||
TUPLE: parsing-error line column ;
|
TUPLE: xml-error-at line column ;
|
||||||
|
|
||||||
: parsing-error ( class -- obj )
|
: xml-error-at ( class -- obj )
|
||||||
new
|
new
|
||||||
get-line >>line
|
get-line >>line
|
||||||
get-column >>column ;
|
get-column >>column ;
|
||||||
M: parsing-error summary ( obj -- str )
|
M: xml-error-at summary ( obj -- str )
|
||||||
[
|
[
|
||||||
"Parsing error" print
|
"XML parsing error" print
|
||||||
"Line: " write dup line>> .
|
"Line: " write dup line>> .
|
||||||
"Column: " write column>> .
|
"Column: " write column>> .
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: expected < parsing-error should-be was ;
|
TUPLE: expected < xml-error-at should-be was ;
|
||||||
: expected ( should-be was -- * )
|
: expected ( should-be was -- * )
|
||||||
\ expected parsing-error
|
\ expected xml-error-at
|
||||||
swap >>was
|
swap >>was
|
||||||
swap >>should-be throw ;
|
swap >>should-be throw ;
|
||||||
M: expected summary ( obj -- str )
|
M: expected summary ( obj -- str )
|
||||||
|
@ -30,26 +30,26 @@ M: expected summary ( obj -- str )
|
||||||
"Token present: " write was>> print
|
"Token present: " write was>> print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: unexpected-end < parsing-error ;
|
TUPLE: unexpected-end < xml-error-at ;
|
||||||
: unexpected-end ( -- * ) \ unexpected-end parsing-error throw ;
|
: unexpected-end ( -- * ) \ unexpected-end xml-error-at throw ;
|
||||||
M: unexpected-end summary ( obj -- str )
|
M: unexpected-end summary ( obj -- str )
|
||||||
[
|
[
|
||||||
call-next-method write
|
call-next-method write
|
||||||
"File unexpectedly ended." print
|
"File unexpectedly ended." print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: missing-close < parsing-error ;
|
TUPLE: missing-close < xml-error-at ;
|
||||||
: missing-close ( -- * ) \ missing-close parsing-error throw ;
|
: missing-close ( -- * ) \ missing-close xml-error-at throw ;
|
||||||
M: missing-close summary ( obj -- str )
|
M: missing-close summary ( obj -- str )
|
||||||
[
|
[
|
||||||
call-next-method write
|
call-next-method write
|
||||||
"Missing closing token." print
|
"Missing closing token." print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: disallowed-char < parsing-error char ;
|
TUPLE: disallowed-char < xml-error-at char ;
|
||||||
|
|
||||||
: disallowed-char ( char -- * )
|
: disallowed-char ( char -- * )
|
||||||
\ disallowed-char parsing-error swap >>char throw ;
|
\ disallowed-char xml-error-at swap >>char throw ;
|
||||||
|
|
||||||
M: disallowed-char summary
|
M: disallowed-char summary
|
||||||
[ call-next-method ]
|
[ call-next-method ]
|
||||||
|
@ -72,10 +72,10 @@ M: pre/post-content summary ( obj -- str )
|
||||||
" the main tag." print
|
" the main tag." print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: no-entity < parsing-error thing ;
|
TUPLE: no-entity < xml-error-at thing ;
|
||||||
|
|
||||||
: no-entity ( string -- * )
|
: no-entity ( string -- * )
|
||||||
\ no-entity parsing-error swap >>thing throw ;
|
\ no-entity xml-error-at swap >>thing throw ;
|
||||||
|
|
||||||
M: no-entity summary ( obj -- str )
|
M: no-entity summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -83,10 +83,10 @@ M: no-entity summary ( obj -- str )
|
||||||
"Entity does not exist: &" write thing>> write ";" print
|
"Entity does not exist: &" write thing>> write ";" print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: mismatched < parsing-error open close ;
|
TUPLE: mismatched < xml-error-at open close ;
|
||||||
|
|
||||||
: mismatched ( open close -- * )
|
: mismatched ( open close -- * )
|
||||||
\ mismatched parsing-error swap >>close swap >>open throw ;
|
\ mismatched xml-error-at swap >>close swap >>open throw ;
|
||||||
|
|
||||||
M: mismatched summary ( obj -- str )
|
M: mismatched summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -96,10 +96,10 @@ M: mismatched summary ( obj -- str )
|
||||||
"Closing tag: </" write close>> print-name ">" print
|
"Closing tag: </" write close>> print-name ">" print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: unclosed < parsing-error tags ;
|
TUPLE: unclosed < xml-error-at tags ;
|
||||||
|
|
||||||
: unclosed ( -- * )
|
: unclosed ( -- * )
|
||||||
\ unclosed parsing-error
|
\ unclosed xml-error-at
|
||||||
xml-stack get rest-slice [ first name>> ] map >>tags
|
xml-stack get rest-slice [ first name>> ] map >>tags
|
||||||
throw ;
|
throw ;
|
||||||
|
|
||||||
|
@ -111,10 +111,10 @@ M: unclosed summary ( obj -- str )
|
||||||
tags>> [ " <" write print-name ">" print ] each
|
tags>> [ " <" write print-name ">" print ] each
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: bad-uri < parsing-error string ;
|
TUPLE: bad-uri < xml-error-at string ;
|
||||||
|
|
||||||
: bad-uri ( string -- * )
|
: bad-uri ( string -- * )
|
||||||
\ bad-uri parsing-error swap >>string throw ;
|
\ bad-uri xml-error-at swap >>string throw ;
|
||||||
|
|
||||||
M: bad-uri summary ( obj -- str )
|
M: bad-uri summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -122,10 +122,10 @@ M: bad-uri summary ( obj -- str )
|
||||||
"Bad URI:" print string>> .
|
"Bad URI:" print string>> .
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: nonexist-ns < parsing-error name ;
|
TUPLE: nonexist-ns < xml-error-at name ;
|
||||||
|
|
||||||
: nonexist-ns ( name-string -- * )
|
: nonexist-ns ( name-string -- * )
|
||||||
\ nonexist-ns parsing-error swap >>name throw ;
|
\ nonexist-ns xml-error-at swap >>name throw ;
|
||||||
|
|
||||||
M: nonexist-ns summary ( obj -- str )
|
M: nonexist-ns summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -133,10 +133,10 @@ M: nonexist-ns summary ( obj -- str )
|
||||||
"Namespace " write name>> write " has not been declared" print
|
"Namespace " write name>> write " has not been declared" print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: unopened < parsing-error ; ! this should give which tag was unopened
|
TUPLE: unopened < xml-error-at ; ! this should give which tag was unopened
|
||||||
|
|
||||||
: unopened ( -- * )
|
: unopened ( -- * )
|
||||||
\ unopened parsing-error throw ;
|
\ unopened xml-error-at throw ;
|
||||||
|
|
||||||
M: unopened summary ( obj -- str )
|
M: unopened summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -144,10 +144,10 @@ M: unopened summary ( obj -- str )
|
||||||
"Closed an unopened tag" print
|
"Closed an unopened tag" print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: not-yes/no < parsing-error text ;
|
TUPLE: not-yes/no < xml-error-at text ;
|
||||||
|
|
||||||
: not-yes/no ( text -- * )
|
: not-yes/no ( text -- * )
|
||||||
\ not-yes/no parsing-error swap >>text throw ;
|
\ not-yes/no xml-error-at swap >>text throw ;
|
||||||
|
|
||||||
M: not-yes/no summary ( obj -- str )
|
M: not-yes/no summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -157,10 +157,10 @@ M: not-yes/no summary ( obj -- str )
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
! this should actually print the names
|
! this should actually print the names
|
||||||
TUPLE: extra-attrs < parsing-error attrs ;
|
TUPLE: extra-attrs < xml-error-at attrs ;
|
||||||
|
|
||||||
: extra-attrs ( attrs -- * )
|
: extra-attrs ( attrs -- * )
|
||||||
\ extra-attrs parsing-error swap >>attrs throw ;
|
\ extra-attrs xml-error-at swap >>attrs throw ;
|
||||||
|
|
||||||
M: extra-attrs summary ( obj -- str )
|
M: extra-attrs summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -169,10 +169,10 @@ M: extra-attrs summary ( obj -- str )
|
||||||
attrs>> .
|
attrs>> .
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: bad-version < parsing-error num ;
|
TUPLE: bad-version < xml-error-at num ;
|
||||||
|
|
||||||
: bad-version ( num -- * )
|
: bad-version ( num -- * )
|
||||||
\ bad-version parsing-error swap >>num throw ;
|
\ bad-version xml-error-at swap >>num throw ;
|
||||||
|
|
||||||
M: bad-version summary ( obj -- str )
|
M: bad-version summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -185,10 +185,10 @@ ERROR: notags ;
|
||||||
M: notags summary ( obj -- str )
|
M: notags summary ( obj -- str )
|
||||||
drop "XML document lacks a main tag" ;
|
drop "XML document lacks a main tag" ;
|
||||||
|
|
||||||
TUPLE: bad-prolog < parsing-error prolog ;
|
TUPLE: bad-prolog < xml-error-at prolog ;
|
||||||
|
|
||||||
: bad-prolog ( prolog -- * )
|
: bad-prolog ( prolog -- * )
|
||||||
\ bad-prolog parsing-error swap >>prolog throw ;
|
\ bad-prolog xml-error-at swap >>prolog throw ;
|
||||||
|
|
||||||
M: bad-prolog summary ( obj -- str )
|
M: bad-prolog summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -197,10 +197,10 @@ M: bad-prolog summary ( obj -- str )
|
||||||
prolog>> write-prolog nl
|
prolog>> write-prolog nl
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: capitalized-prolog < parsing-error name ;
|
TUPLE: capitalized-prolog < xml-error-at name ;
|
||||||
|
|
||||||
: capitalized-prolog ( name -- capitalized-prolog )
|
: capitalized-prolog ( name -- capitalized-prolog )
|
||||||
\ capitalized-prolog parsing-error swap >>name throw ;
|
\ capitalized-prolog xml-error-at swap >>name throw ;
|
||||||
|
|
||||||
M: capitalized-prolog summary ( obj -- str )
|
M: capitalized-prolog summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -210,10 +210,10 @@ M: capitalized-prolog summary ( obj -- str )
|
||||||
" instead of <?xml...?>" print
|
" instead of <?xml...?>" print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: versionless-prolog < parsing-error ;
|
TUPLE: versionless-prolog < xml-error-at ;
|
||||||
|
|
||||||
: versionless-prolog ( -- * )
|
: versionless-prolog ( -- * )
|
||||||
\ versionless-prolog parsing-error throw ;
|
\ versionless-prolog xml-error-at throw ;
|
||||||
|
|
||||||
M: versionless-prolog summary ( obj -- str )
|
M: versionless-prolog summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -221,10 +221,10 @@ M: versionless-prolog summary ( obj -- str )
|
||||||
"XML prolog lacks a version declaration" print
|
"XML prolog lacks a version declaration" print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: bad-directive < parsing-error dir ;
|
TUPLE: bad-directive < xml-error-at dir ;
|
||||||
|
|
||||||
: bad-directive ( directive -- * )
|
: bad-directive ( directive -- * )
|
||||||
\ bad-directive parsing-error swap >>dir throw ;
|
\ bad-directive xml-error-at swap >>dir throw ;
|
||||||
|
|
||||||
M: bad-directive summary ( obj -- str )
|
M: bad-directive summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -233,26 +233,26 @@ M: bad-directive summary ( obj -- str )
|
||||||
dir>> write
|
dir>> write
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: bad-decl < parsing-error ;
|
TUPLE: bad-decl < xml-error-at ;
|
||||||
|
|
||||||
: bad-decl ( -- * )
|
: bad-decl ( -- * )
|
||||||
\ bad-decl parsing-error throw ;
|
\ bad-decl xml-error-at throw ;
|
||||||
|
|
||||||
M: bad-decl summary ( obj -- str )
|
M: bad-decl summary ( obj -- str )
|
||||||
call-next-method "\nExtra content in directive" append ;
|
call-next-method "\nExtra content in directive" append ;
|
||||||
|
|
||||||
TUPLE: bad-external-id < parsing-error ;
|
TUPLE: bad-external-id < xml-error-at ;
|
||||||
|
|
||||||
: bad-external-id ( -- * )
|
: bad-external-id ( -- * )
|
||||||
\ bad-external-id parsing-error throw ;
|
\ bad-external-id xml-error-at throw ;
|
||||||
|
|
||||||
M: bad-external-id summary ( obj -- str )
|
M: bad-external-id summary ( obj -- str )
|
||||||
call-next-method "\nBad external ID" append ;
|
call-next-method "\nBad external ID" append ;
|
||||||
|
|
||||||
TUPLE: misplaced-directive < parsing-error dir ;
|
TUPLE: misplaced-directive < xml-error-at dir ;
|
||||||
|
|
||||||
: misplaced-directive ( directive -- * )
|
: misplaced-directive ( directive -- * )
|
||||||
\ misplaced-directive parsing-error swap >>dir throw ;
|
\ misplaced-directive xml-error-at swap >>dir throw ;
|
||||||
|
|
||||||
M: misplaced-directive summary ( obj -- str )
|
M: misplaced-directive summary ( obj -- str )
|
||||||
[
|
[
|
||||||
|
@ -261,86 +261,82 @@ M: misplaced-directive summary ( obj -- str )
|
||||||
dir>> write-xml-chunk nl
|
dir>> write-xml-chunk nl
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: bad-name < parsing-error name ;
|
TUPLE: bad-name < xml-error-at name ;
|
||||||
|
|
||||||
: bad-name ( name -- * )
|
: bad-name ( name -- * )
|
||||||
\ bad-name parsing-error swap >>name throw ;
|
\ bad-name xml-error-at swap >>name throw ;
|
||||||
|
|
||||||
M: bad-name summary ( obj -- str )
|
M: bad-name summary ( obj -- str )
|
||||||
[ call-next-method ]
|
[ call-next-method ]
|
||||||
[ "Invalid name: " swap name>> "\n" 3append ]
|
[ "Invalid name: " swap name>> "\n" 3append ]
|
||||||
bi append ;
|
bi append ;
|
||||||
|
|
||||||
TUPLE: unclosed-quote < parsing-error ;
|
TUPLE: unclosed-quote < xml-error-at ;
|
||||||
|
|
||||||
: unclosed-quote ( -- * )
|
: unclosed-quote ( -- * )
|
||||||
\ unclosed-quote parsing-error throw ;
|
\ unclosed-quote xml-error-at throw ;
|
||||||
|
|
||||||
M: unclosed-quote summary
|
M: unclosed-quote summary
|
||||||
call-next-method
|
call-next-method
|
||||||
"XML document ends with quote still open\n" append ;
|
"XML document ends with quote still open\n" append ;
|
||||||
|
|
||||||
TUPLE: quoteless-attr < parsing-error ;
|
TUPLE: quoteless-attr < xml-error-at ;
|
||||||
|
|
||||||
: quoteless-attr ( -- * )
|
: quoteless-attr ( -- * )
|
||||||
\ quoteless-attr parsing-error throw ;
|
\ quoteless-attr xml-error-at throw ;
|
||||||
|
|
||||||
M: quoteless-attr summary
|
M: quoteless-attr summary
|
||||||
call-next-method "Attribute lacks quotes around value\n" append ;
|
call-next-method "Attribute lacks quotes around value\n" append ;
|
||||||
|
|
||||||
TUPLE: attr-w/< < parsing-error ;
|
TUPLE: attr-w/< < xml-error-at ;
|
||||||
|
|
||||||
: attr-w/< ( value -- * )
|
: attr-w/< ( value -- * )
|
||||||
\ attr-w/< parsing-error throw ;
|
\ attr-w/< xml-error-at throw ;
|
||||||
|
|
||||||
M: attr-w/< summary
|
M: attr-w/< summary
|
||||||
call-next-method
|
call-next-method
|
||||||
"Attribute value contains literal <" append ;
|
"Attribute value contains literal <" append ;
|
||||||
|
|
||||||
TUPLE: text-w/]]> < parsing-error ;
|
TUPLE: text-w/]]> < xml-error-at ;
|
||||||
|
|
||||||
: text-w/]]> ( text -- * )
|
: text-w/]]> ( text -- * )
|
||||||
\ text-w/]]> parsing-error throw ;
|
\ text-w/]]> xml-error-at throw ;
|
||||||
|
|
||||||
M: text-w/]]> summary
|
M: text-w/]]> summary
|
||||||
call-next-method
|
call-next-method
|
||||||
"Text node contains ']]>'" append ;
|
"Text node contains ']]>'" append ;
|
||||||
|
|
||||||
TUPLE: duplicate-attr < parsing-error key values ;
|
TUPLE: duplicate-attr < xml-error-at key values ;
|
||||||
|
|
||||||
: duplicate-attr ( key values -- * )
|
: duplicate-attr ( key values -- * )
|
||||||
\ duplicate-attr parsing-error
|
\ duplicate-attr xml-error-at
|
||||||
swap >>values swap >>key throw ;
|
swap >>values swap >>key throw ;
|
||||||
|
|
||||||
M: duplicate-attr summary
|
M: duplicate-attr summary
|
||||||
call-next-method "\nDuplicate attribute" append ;
|
call-next-method "\nDuplicate attribute" append ;
|
||||||
|
|
||||||
TUPLE: bad-cdata < parsing-error ;
|
TUPLE: bad-cdata < xml-error-at ;
|
||||||
|
|
||||||
: bad-cdata ( -- * )
|
: bad-cdata ( -- * )
|
||||||
\ bad-cdata parsing-error throw ;
|
\ bad-cdata xml-error-at throw ;
|
||||||
|
|
||||||
M: bad-cdata summary
|
M: bad-cdata summary
|
||||||
call-next-method "\nCDATA occurs before or after main tag" append ;
|
call-next-method "\nCDATA occurs before or after main tag" append ;
|
||||||
|
|
||||||
TUPLE: not-enough-characters < parsing-error ;
|
TUPLE: not-enough-characters < xml-error-at ;
|
||||||
: not-enough-characters ( -- * )
|
: not-enough-characters ( -- * )
|
||||||
\ not-enough-characters parsing-error throw ;
|
\ not-enough-characters xml-error-at throw ;
|
||||||
M: not-enough-characters summary ( obj -- str )
|
M: not-enough-characters summary ( obj -- str )
|
||||||
[
|
[
|
||||||
call-next-method write
|
call-next-method write
|
||||||
"Not enough characters" print
|
"Not enough characters" print
|
||||||
] with-string-writer ;
|
] with-string-writer ;
|
||||||
|
|
||||||
TUPLE: bad-doctype < parsing-error contents ;
|
TUPLE: bad-doctype < xml-error-at contents ;
|
||||||
: bad-doctype ( contents -- * )
|
: bad-doctype ( contents -- * )
|
||||||
\ bad-doctype parsing-error swap >>contents throw ;
|
\ bad-doctype xml-error-at swap >>contents throw ;
|
||||||
M: bad-doctype summary
|
M: bad-doctype summary
|
||||||
call-next-method "\nDTD contains invalid object" append ;
|
call-next-method "\nDTD contains invalid object" append ;
|
||||||
|
|
||||||
UNION: xml-parse-error
|
UNION: xml-error
|
||||||
multitags notags extra-attrs nonexist-ns bad-decl
|
multitags notags pre/post-content xml-error-at ;
|
||||||
not-yes/no unclosed mismatched expected no-entity
|
|
||||||
bad-prolog versionless-prolog capitalized-prolog
|
|
||||||
bad-directive bad-name unclosed-quote quoteless-attr
|
|
||||||
attr-w/< text-w/]]> duplicate-attr ;
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
USING: help.markup help.syntax present multiline ;
|
||||||
|
IN: xml.interpolate
|
||||||
|
|
||||||
|
ABOUT: "xml.interpolate"
|
||||||
|
|
||||||
|
ARTICLE: "xml.interpolate" "XML literal interpolation"
|
||||||
|
"The " { $vocab-link "xml.interpolate" } " vocabulary provides a convenient syntax for generating XML documents and chunks. It defines the following parsing words:"
|
||||||
|
{ $subsection POSTPONE: <XML }
|
||||||
|
{ $subsection POSTPONE: [XML }
|
||||||
|
"For a description of the common syntax of these two, see"
|
||||||
|
{ $subsection { "xml.interpolate" "in-depth" } } ;
|
||||||
|
|
||||||
|
HELP: <XML
|
||||||
|
{ $syntax "<XML <?xml version=\"1.0\"?><document>...</document> XML>" }
|
||||||
|
{ $description "This syntax allows the interpolation of XML documents. When evaluated, there is an XML document on the stack. For more information about XML interpolation, see " { $link { "xml.interpolate" "in-depth" } } "." } ;
|
||||||
|
|
||||||
|
HELP: [XML
|
||||||
|
{ $syntax "[XML foo <x>...</x> bar <y>...</y> baz XML]" }
|
||||||
|
{ $description "This syntax allows the interpolation of XML chunks. When evaluated, there is a sequence of XML elements (tags, strings, comments, etc) on the stack. For more information about XML interpolation, see " { $link { "xml.interpolate" "in-depth" } } "." } ;
|
||||||
|
|
||||||
|
ARTICLE: { "xml.interpolate" "in-depth" } "XML interpolation syntax"
|
||||||
|
"XML interpolation has two forms for each of the words " { $link POSTPONE: <XML } " and " { $link POSTPONE: [XML } ": a fry-like form and a locals form. To splice locals in, use the syntax " { $snippet "<-variable->" } ". To splice something in from the stack, in the style of " { $vocab-link "fry" } ", use the syntax " { $snippet "<->" } ". An XML interpolation form may only use one of these styles."
|
||||||
|
$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:"
|
||||||
|
{ $example
|
||||||
|
{" "one two three" " " split
|
||||||
|
[ [XML <item><-></item> XML] ] map
|
||||||
|
<XML <doc><-></doc> XML> pprint-xml>string "}
|
||||||
|
{" <' <?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<doc>
|
||||||
|
<item>
|
||||||
|
one
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
two
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
three
|
||||||
|
</item>
|
||||||
|
</doc>'> "} }
|
||||||
|
"Here is an example of the locals version:"
|
||||||
|
{ $example
|
||||||
|
{" [let |
|
||||||
|
number [ 3 ]
|
||||||
|
false [ f ]
|
||||||
|
url [ URL" http://factorcode.org/" ]
|
||||||
|
string [ "hello" ]
|
||||||
|
word [ \ drop ] |
|
||||||
|
<XML
|
||||||
|
<x
|
||||||
|
number=<-number->
|
||||||
|
false=<-false->
|
||||||
|
url=<-url->
|
||||||
|
string=<-string->
|
||||||
|
word=<-word-> />
|
||||||
|
XML> pprint-xml>string ] "}
|
||||||
|
{" <' <?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<x number="3" url="http://factorcode.org/" string="hello" word="drop"/>'> "} } ;
|
|
@ -2,12 +2,12 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: tools.test xml.interpolate multiline kernel assocs
|
USING: tools.test xml.interpolate multiline kernel assocs
|
||||||
sequences accessors xml.writer xml.interpolate.private
|
sequences accessors xml.writer xml.interpolate.private
|
||||||
locals splitting ;
|
locals splitting urls ;
|
||||||
IN: xml.interpolate.tests
|
IN: xml.interpolate.tests
|
||||||
|
|
||||||
[ "a" "c" { "a" "c" f } ] [
|
[ "a" "c" { "a" "c" f } ] [
|
||||||
"<?xml version='1.0'?><x><-a-><b val=<-c->/><-></x>"
|
"<?xml version='1.0'?><x><-a-><b val=<-c->/><-></x>"
|
||||||
interpolated-doc
|
string>doc
|
||||||
[ second var>> ]
|
[ second var>> ]
|
||||||
[ fourth "val" swap at var>> ]
|
[ fourth "val" swap at var>> ]
|
||||||
[ extract-variables ] tri
|
[ extract-variables ] tri
|
||||||
|
@ -44,3 +44,9 @@ IN: xml.interpolate.tests
|
||||||
[ [XML <item><-></item> XML] ] map
|
[ [XML <item><-></item> XML] ] map
|
||||||
<XML <doc><-></doc> XML> pprint-xml>string
|
<XML <doc><-></doc> XML> pprint-xml>string
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
[ {" <?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<x number="3" url="http://factorcode.org/" string="hello" word="drop"/>"} ]
|
||||||
|
[ 3 f URL" http://factorcode.org/" "hello" \ drop
|
||||||
|
<XML <x number=<-> false=<-> url=<-> string=<-> word=<->/> XML>
|
||||||
|
pprint-xml>string ] unit-test
|
||||||
|
|
|
@ -3,21 +3,24 @@
|
||||||
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 locals words combinators
|
||||||
math ;
|
math present arrays ;
|
||||||
IN: xml.interpolate
|
IN: xml.interpolate
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: interpolated-chunk ( string -- chunk )
|
: string>chunk ( string -- chunk )
|
||||||
t interpolating? [ string>xml-chunk ] with-variable ;
|
t interpolating? [ string>xml-chunk ] with-variable ;
|
||||||
|
|
||||||
: interpolated-doc ( string -- xml )
|
: string>doc ( string -- xml )
|
||||||
t interpolating? [ string>xml ] with-variable ;
|
t interpolating? [ string>xml ] with-variable ;
|
||||||
|
|
||||||
DEFER: interpolate-sequence
|
DEFER: interpolate-sequence
|
||||||
|
|
||||||
: interpolate-attrs ( table attrs -- attrs )
|
: interpolate-attrs ( table attrs -- attrs )
|
||||||
swap '[ dup interpolated? [ var>> _ at ] when ] assoc-map ;
|
swap '[
|
||||||
|
dup interpolated?
|
||||||
|
[ var>> _ at dup [ present ] when ] when
|
||||||
|
] assoc-map [ nip ] assoc-filter ;
|
||||||
|
|
||||||
: interpolate-tag ( table tag -- tag )
|
: interpolate-tag ( table tag -- tag )
|
||||||
[ nip name>> ]
|
[ nip name>> ]
|
||||||
|
@ -27,8 +30,10 @@ DEFER: interpolate-sequence
|
||||||
|
|
||||||
GENERIC: push-item ( item -- )
|
GENERIC: push-item ( item -- )
|
||||||
M: string push-item , ;
|
M: string push-item , ;
|
||||||
M: object push-item , ;
|
M: xml-data push-item , ;
|
||||||
M: sequence push-item % ;
|
M: object push-item present , ;
|
||||||
|
M: sequence push-item
|
||||||
|
[ dup array? [ % ] [ , ] if ] each ;
|
||||||
|
|
||||||
GENERIC: interpolate-item ( table item -- )
|
GENERIC: interpolate-item ( table item -- )
|
||||||
M: object interpolate-item nip , ;
|
M: object interpolate-item nip , ;
|
||||||
|
@ -48,6 +53,8 @@ M: tag (each-interpolated)
|
||||||
swap attrs>> values
|
swap attrs>> values
|
||||||
[ interpolated? ] filter
|
[ interpolated? ] filter
|
||||||
swap each ;
|
swap each ;
|
||||||
|
M: xml (each-interpolated)
|
||||||
|
[ body>> ] dip (each-interpolated) ;
|
||||||
M: object (each-interpolated) 2drop ;
|
M: object (each-interpolated) 2drop ;
|
||||||
|
|
||||||
: each-interpolated ( xml quot -- )
|
: each-interpolated ( xml quot -- )
|
||||||
|
@ -59,10 +66,10 @@ M: object (each-interpolated) 2drop ;
|
||||||
] each-interpolated doc ;
|
] each-interpolated doc ;
|
||||||
|
|
||||||
MACRO: interpolate-xml ( string -- doc )
|
MACRO: interpolate-xml ( string -- doc )
|
||||||
interpolated-doc number<-> '[ _ interpolate-xml-doc ] ;
|
string>doc number<-> '[ _ interpolate-xml-doc ] ;
|
||||||
|
|
||||||
MACRO: interpolate-chunk ( string -- chunk )
|
MACRO: interpolate-chunk ( string -- chunk )
|
||||||
interpolated-chunk number<-> '[ _ interpolate-sequence ] ;
|
string>chunk number<-> '[ _ interpolate-sequence ] ;
|
||||||
|
|
||||||
: >search-hash ( seq -- hash )
|
: >search-hash ( seq -- hash )
|
||||||
[ dup search ] H{ } map>assoc ;
|
[ dup search ] H{ } map>assoc ;
|
||||||
|
@ -70,19 +77,22 @@ MACRO: interpolate-chunk ( string -- chunk )
|
||||||
: extract-variables ( xml -- seq )
|
: extract-variables ( xml -- seq )
|
||||||
[ [ var>> , ] each-interpolated ] { } make ;
|
[ [ var>> , ] each-interpolated ] { } make ;
|
||||||
|
|
||||||
|
: nenum ( ... n -- assoc )
|
||||||
|
narray <enum> ; inline
|
||||||
|
|
||||||
: collect ( accum seq -- accum )
|
: collect ( accum seq -- accum )
|
||||||
{
|
{
|
||||||
{ [ dup [ ] all? ] [ >search-hash parsed ] } ! locals
|
{ [ dup [ ] all? ] [ >search-hash parsed ] } ! locals
|
||||||
{ [ dup [ not ] all? ] [ ! fry
|
{ [ dup [ not ] all? ] [ ! fry
|
||||||
length parsed \ narray parsed \ <enum> parsed
|
length parsed \ nenum parsed
|
||||||
] }
|
] }
|
||||||
[ drop "XML interpolation contains both fry and locals" throw ] ! mixed
|
[ drop "XML interpolation contains both fry and locals" throw ] ! mixed
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
: parse-def ( accum delimiter word -- accum )
|
: parse-def ( accum delimiter word -- accum )
|
||||||
[
|
[
|
||||||
parse-multiline-string
|
parse-multiline-string but-last
|
||||||
[ interpolated-chunk extract-variables collect ] keep
|
[ string>chunk extract-variables collect ] keep
|
||||||
parsed
|
parsed
|
||||||
] dip parsed ;
|
] dip parsed ;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ SYMBOL: xml-file
|
||||||
xml-file get T{ name f "" "this" "http://d.de" } swap at
|
xml-file get T{ name f "" "this" "http://d.de" } swap at
|
||||||
] unit-test
|
] unit-test
|
||||||
[ t ] [ xml-file get children>> second contained-tag? ] unit-test
|
[ t ] [ xml-file get children>> second contained-tag? ] unit-test
|
||||||
[ "<a></b>" string>xml ] [ xml-parse-error? ] must-fail-with
|
[ "<a></b>" string>xml ] [ xml-error? ] must-fail-with
|
||||||
[ T{ comment f "This is where the fun begins!" } ] [
|
[ T{ comment f "This is where the fun begins!" } ] [
|
||||||
xml-file get before>> [ comment? ] find nip
|
xml-file get before>> [ comment? ] find nip
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
|
@ -155,6 +155,9 @@ M: directive write-xml-chunk
|
||||||
M: instruction write-xml-chunk
|
M: instruction write-xml-chunk
|
||||||
"<?" write text>> write "?>" write ;
|
"<?" write text>> write "?>" write ;
|
||||||
|
|
||||||
|
M: number write-xml-chunk
|
||||||
|
"Numbers are not allowed in XML" throw ;
|
||||||
|
|
||||||
M: sequence write-xml-chunk
|
M: sequence write-xml-chunk
|
||||||
[ write-xml-chunk ] each ;
|
[ write-xml-chunk ] each ;
|
||||||
|
|
||||||
|
|
|
@ -1,48 +1,45 @@
|
||||||
USING: xmode.tokens xmode.marker xmode.catalog kernel
|
USING: xmode.tokens xmode.marker xmode.catalog kernel locals
|
||||||
html.elements io io.files sequences words io.encodings.utf8
|
html.elements io io.files sequences words io.encodings.utf8
|
||||||
namespaces xml.entities accessors ;
|
namespaces xml.entities accessors xml.interpolate locals xml.writer ;
|
||||||
IN: xmode.code2html
|
IN: xmode.code2html
|
||||||
|
|
||||||
: htmlize-tokens ( tokens -- )
|
: htmlize-tokens ( tokens -- xml )
|
||||||
[
|
[
|
||||||
[ str>> ] [ id>> ] bi [
|
[ str>> ] [ id>> ] bi [
|
||||||
<span name>> =class span> escape-string write </span>
|
name>> swap
|
||||||
] [
|
[XML <span class=<->><-></span> XML]
|
||||||
escape-string write
|
] [ ] if*
|
||||||
] if*
|
] map ;
|
||||||
] each ;
|
|
||||||
|
|
||||||
: htmlize-line ( line-context line rules -- line-context' )
|
: htmlize-line ( line-context line rules -- line-context' xml )
|
||||||
tokenize-line htmlize-tokens ;
|
tokenize-line htmlize-tokens ;
|
||||||
|
|
||||||
: htmlize-lines ( lines mode -- )
|
: htmlize-lines ( lines mode -- xml )
|
||||||
f swap load-mode [ htmlize-line nl ] curry reduce drop ;
|
f -rot load-mode [ htmlize-line ] curry map nip ;
|
||||||
|
|
||||||
: default-stylesheet ( -- )
|
: default-stylesheet ( -- xml )
|
||||||
<style>
|
"resource:basis/xmode/code2html/stylesheet.css"
|
||||||
"resource:basis/xmode/code2html/stylesheet.css"
|
utf8 file-contents
|
||||||
utf8 file-contents escape-string write
|
[XML <style><-></style> XML] ;
|
||||||
</style> ;
|
|
||||||
|
|
||||||
: htmlize-stream ( path stream -- )
|
:: htmlize-stream ( path stream -- xml )
|
||||||
lines swap
|
stream lines
|
||||||
<html>
|
[ "" ] [ first find-mode path swap htmlize-lines ]
|
||||||
|
if-empty :> input
|
||||||
|
default-stylesheet :> stylesheet
|
||||||
|
<XML <html>
|
||||||
<head>
|
<head>
|
||||||
default-stylesheet
|
<-stylesheet->
|
||||||
<title> dup escape-string write </title>
|
<title><-path-></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre>
|
<pre><-input-></pre>
|
||||||
over empty?
|
|
||||||
[ 2drop ]
|
|
||||||
[ over first find-mode htmlize-lines ] if
|
|
||||||
</pre>
|
|
||||||
</body>
|
</body>
|
||||||
</html> ;
|
</html> XML> ;
|
||||||
|
|
||||||
: htmlize-file ( path -- )
|
: htmlize-file ( path -- )
|
||||||
dup utf8 [
|
dup utf8 [
|
||||||
dup ".html" append utf8 [
|
dup ".html" append utf8 [
|
||||||
input-stream get htmlize-stream
|
input-stream get htmlize-stream write-xml
|
||||||
] with-file-writer
|
] with-file-writer
|
||||||
] with-file-reader ;
|
] with-file-reader ;
|
||||||
|
|
Loading…
Reference in New Issue