2009-01-21 19:16:51 -05:00
|
|
|
! Copyright (C) 2005, 2009 Daniel Ehrenberg
|
2007-09-20 18:09:08 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: hashtables kernel math namespaces sequences strings
|
2008-08-27 18:02:54 -04:00
|
|
|
assocs combinators io io.streams.string accessors
|
2009-02-09 02:12:32 -05:00
|
|
|
xml.data wrap.strings xml.entities unicode.categories fry ;
|
2007-09-20 18:09:08 -04:00
|
|
|
IN: xml.writer
|
|
|
|
|
2007-12-29 01:33:21 -05:00
|
|
|
SYMBOL: sensitive-tags
|
|
|
|
SYMBOL: indenter
|
|
|
|
" " indenter set-global
|
|
|
|
|
2009-01-21 19:16:51 -05:00
|
|
|
<PRIVATE
|
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
SYMBOL: xml-pprint?
|
|
|
|
SYMBOL: indentation
|
|
|
|
|
2007-12-29 01:33:21 -05:00
|
|
|
: sensitive? ( tag -- ? )
|
2009-01-29 23:19:07 -05:00
|
|
|
sensitive-tags get swap '[ _ names-match? ] any? ;
|
2007-12-29 01:33:21 -05:00
|
|
|
|
2008-01-30 16:03:02 -05:00
|
|
|
: indent-string ( -- string )
|
2008-01-31 01:47:11 -05:00
|
|
|
xml-pprint? get
|
|
|
|
[ indentation get indenter get <repetition> concat ]
|
|
|
|
[ "" ] if ;
|
2008-01-30 16:03:02 -05:00
|
|
|
|
2007-12-29 01:33:21 -05:00
|
|
|
: ?indent ( -- )
|
2008-01-30 16:03:02 -05:00
|
|
|
xml-pprint? get [ nl indent-string write ] when ;
|
2007-12-29 01:33:21 -05:00
|
|
|
|
|
|
|
: indent ( -- )
|
|
|
|
xml-pprint? get [ 1 indentation +@ ] when ;
|
|
|
|
|
|
|
|
: unindent ( -- )
|
|
|
|
xml-pprint? get [ -1 indentation +@ ] when ;
|
|
|
|
|
|
|
|
: trim-whitespace ( string -- no-whitespace )
|
2008-04-13 04:52:40 -04:00
|
|
|
[ blank? ] trim ;
|
2007-12-29 01:33:21 -05:00
|
|
|
|
|
|
|
: ?filter-children ( children -- no-whitespace )
|
|
|
|
xml-pprint? get [
|
|
|
|
[ dup string? [ trim-whitespace ] when ] map
|
2008-09-06 20:13:59 -04:00
|
|
|
[ [ empty? ] [ string? ] bi and not ] filter
|
2007-12-29 01:33:21 -05:00
|
|
|
] when ;
|
|
|
|
|
2009-01-22 17:44:37 -05:00
|
|
|
PRIVATE>
|
|
|
|
|
2008-09-08 02:11:09 -04:00
|
|
|
: name>string ( name -- string )
|
2008-09-08 03:52:42 -04:00
|
|
|
[ main>> ] [ space>> ] bi [ ":" rot 3append ] unless-empty ;
|
2008-09-08 02:11:09 -04:00
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
: print-name ( name -- )
|
2008-09-08 02:11:09 -04:00
|
|
|
name>string write ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-21 19:16:51 -05:00
|
|
|
<PRIVATE
|
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
: write-quoted ( string -- )
|
|
|
|
CHAR: " write1 write CHAR: " write1 ;
|
|
|
|
|
2007-12-23 14:57:39 -05:00
|
|
|
: print-attrs ( assoc -- )
|
2007-09-20 18:09:08 -04:00
|
|
|
[
|
2009-01-29 14:33:04 -05:00
|
|
|
[ bl print-name "=" write ]
|
|
|
|
[ escape-quoted-string write-quoted ] bi*
|
2007-12-23 14:57:39 -05:00
|
|
|
] assoc-each ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-21 19:16:51 -05:00
|
|
|
PRIVATE>
|
|
|
|
|
2009-01-29 16:15:50 -05:00
|
|
|
GENERIC: write-xml ( xml -- )
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-21 19:16:51 -05:00
|
|
|
<PRIVATE
|
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: string write-xml
|
2009-01-21 19:16:51 -05:00
|
|
|
escape-string xml-pprint? get [
|
|
|
|
dup [ blank? ] all?
|
|
|
|
[ drop "" ]
|
2009-02-03 01:27:34 -05:00
|
|
|
[ nl 80 indent-string wrap-indented-string ] if
|
2009-01-21 19:16:51 -05:00
|
|
|
] when write ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-12-29 01:33:21 -05:00
|
|
|
: write-tag ( tag -- )
|
2008-01-30 16:03:02 -05:00
|
|
|
?indent CHAR: < write1
|
2008-08-27 18:02:54 -04:00
|
|
|
dup print-name attrs>> print-attrs ;
|
2007-12-29 01:33:21 -05:00
|
|
|
|
2008-04-15 07:10:08 -04:00
|
|
|
: write-start-tag ( tag -- )
|
|
|
|
write-tag ">" write ;
|
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: contained-tag write-xml
|
2007-12-29 01:33:21 -05:00
|
|
|
write-tag "/>" write ;
|
|
|
|
|
|
|
|
: write-children ( tag -- )
|
2008-08-27 18:02:54 -04:00
|
|
|
indent children>> ?filter-children
|
2009-01-29 14:33:04 -05:00
|
|
|
[ write-xml ] each unindent ;
|
2007-12-29 01:33:21 -05:00
|
|
|
|
|
|
|
: write-end-tag ( tag -- )
|
|
|
|
?indent "</" write print-name CHAR: > write1 ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: open-tag write-xml
|
2008-12-02 20:59:16 -05:00
|
|
|
xml-pprint? get [
|
|
|
|
{
|
|
|
|
[ write-start-tag ]
|
2009-01-29 16:15:50 -05:00
|
|
|
[ sensitive? not xml-pprint? get and xml-pprint? set ]
|
2008-12-02 20:59:16 -05:00
|
|
|
[ write-children ]
|
|
|
|
[ write-end-tag ]
|
|
|
|
} cleave
|
|
|
|
] dip xml-pprint? set ;
|
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: unescaped write-xml
|
2009-01-27 17:54:41 -05:00
|
|
|
string>> write ;
|
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: comment write-xml
|
2008-08-27 18:02:54 -04:00
|
|
|
"<!--" write text>> write "-->" write ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
: write-decl ( decl name quot: ( decl -- slot ) -- )
|
|
|
|
"<!" write swap write bl
|
|
|
|
[ name>> write bl ]
|
|
|
|
swap '[ @ write ">" write ] bi ; inline
|
2008-12-02 20:59:16 -05:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: element-decl write-xml
|
|
|
|
"ELEMENT" [ content-spec>> ] write-decl ;
|
2008-12-02 20:59:16 -05:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: attlist-decl write-xml
|
|
|
|
"ATTLIST" [ att-defs>> ] write-decl ;
|
2008-12-02 20:59:16 -05:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: notation-decl write-xml
|
|
|
|
"NOTATION" [ id>> ] write-decl ;
|
|
|
|
|
|
|
|
M: entity-decl write-xml
|
2009-01-21 19:16:51 -05:00
|
|
|
"<!ENTITY " write
|
|
|
|
[ pe?>> [ " % " write ] when ]
|
|
|
|
[ name>> write " \"" write ] [
|
|
|
|
def>> f xml-pprint?
|
2009-01-29 14:33:04 -05:00
|
|
|
[ write-xml ] with-variable
|
2009-01-21 19:16:51 -05:00
|
|
|
"\">" write
|
|
|
|
] tri ;
|
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: system-id write-xml
|
|
|
|
"SYSTEM" write bl system-literal>> write-quoted ;
|
2008-12-02 20:59:16 -05:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: public-id write-xml
|
|
|
|
"PUBLIC" write bl
|
|
|
|
[ pubid-literal>> write-quoted bl ]
|
|
|
|
[ system-literal>> write-quoted ] bi ;
|
2008-12-02 20:59:16 -05:00
|
|
|
|
2009-01-23 16:29:28 -05:00
|
|
|
: write-internal-subset ( dtd -- )
|
2009-01-21 19:16:51 -05:00
|
|
|
[
|
|
|
|
"[" write indent
|
2009-01-29 14:33:04 -05:00
|
|
|
directives>> [ ?indent write-xml ] each
|
2009-01-21 19:16:51 -05:00
|
|
|
unindent ?indent "]" write
|
|
|
|
] when* ;
|
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: doctype-decl write-xml
|
2009-01-21 19:16:51 -05:00
|
|
|
?indent "<!DOCTYPE " write
|
2008-12-02 20:59:16 -05:00
|
|
|
[ name>> write " " write ]
|
2009-01-29 14:33:04 -05:00
|
|
|
[ external-id>> [ write-xml " " write ] when* ]
|
2009-01-21 19:16:51 -05:00
|
|
|
[ internal-subset>> write-internal-subset ">" write ] tri ;
|
2008-12-02 20:59:16 -05:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: directive write-xml
|
2009-01-21 19:16:51 -05:00
|
|
|
"<!" write text>> write CHAR: > write1 nl ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: instruction write-xml
|
2008-08-27 18:02:54 -04:00
|
|
|
"<?" write text>> write "?>" write ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: number write-xml
|
2009-01-27 01:30:08 -05:00
|
|
|
"Numbers are not allowed in XML" throw ;
|
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: sequence write-xml
|
|
|
|
[ write-xml ] each ;
|
2009-01-22 17:44:37 -05:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: prolog write-xml
|
|
|
|
"<?xml version=" write
|
|
|
|
[ version>> write-quoted ]
|
2009-02-04 13:32:47 -05:00
|
|
|
[ drop " encoding=\"UTF-8\"" write ]
|
2009-01-29 14:33:04 -05:00
|
|
|
[ standalone>> [ " standalone=\"yes\"" write ] when ] tri
|
|
|
|
"?>" write ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
M: xml write-xml
|
2008-04-15 07:10:08 -04:00
|
|
|
{
|
2009-01-29 14:33:04 -05:00
|
|
|
[ prolog>> write-xml ]
|
|
|
|
[ before>> write-xml ]
|
|
|
|
[ body>> write-xml ]
|
|
|
|
[ after>> write-xml ]
|
2008-04-15 07:10:08 -04:00
|
|
|
} cleave ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
PRIVATE>
|
2008-09-01 20:10:34 -04:00
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
: xml>string ( xml -- string )
|
2008-02-15 23:20:31 -05:00
|
|
|
[ write-xml ] with-string-writer ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-01-29 14:33:04 -05:00
|
|
|
: pprint-xml ( xml -- )
|
2007-12-29 01:33:21 -05:00
|
|
|
[
|
2009-01-29 14:33:04 -05:00
|
|
|
sensitive-tags [ [ assure-name ] map ] change
|
2007-12-29 01:33:21 -05:00
|
|
|
0 indentation set
|
|
|
|
xml-pprint? on
|
2009-01-21 19:16:51 -05:00
|
|
|
write-xml
|
|
|
|
] with-scope ;
|
2007-12-29 01:33:21 -05:00
|
|
|
|
|
|
|
: pprint-xml>string ( xml -- string )
|
2009-01-29 14:33:04 -05:00
|
|
|
[ pprint-xml ] with-string-writer ;
|