factor/basis/xml/writer/writer.factor

205 lines
5.0 KiB
Factor
Raw Normal View History

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
xml.data wrap 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: xml-pprint?
SYMBOL: sensitive-tags
SYMBOL: indentation
SYMBOL: indenter
" " indenter set-global
2009-01-21 19:16:51 -05:00
<PRIVATE
2007-12-29 01:33:21 -05:00
: sensitive? ( tag -- ? )
sensitive-tags get swap '[ _ names-match? ] contains? ;
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 ;
PRIVATE>
: name>string ( name -- string )
2008-09-08 03:52:42 -04:00
[ main>> ] [ space>> ] bi [ ":" rot 3append ] unless-empty ;
2007-09-20 18:09:08 -04:00
: print-name ( name -- )
name>string write ;
2007-09-20 18:09:08 -04:00
2009-01-21 19:16:51 -05:00
<PRIVATE
2007-12-23 14:57:39 -05:00
: print-attrs ( assoc -- )
2007-09-20 18:09:08 -04:00
[
2007-12-23 14:57:39 -05:00
" " write
2007-09-20 18:09:08 -04:00
swap print-name
"=\"" write
2007-12-29 01:33:21 -05:00
escape-quoted-string write
2007-09-20 18:09:08 -04:00
"\"" write
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>
GENERIC: write-xml-chunk ( object -- )
2007-09-20 18:09:08 -04:00
2009-01-21 19:16:51 -05:00
<PRIVATE
M: string write-xml-chunk
2009-01-21 19:16:51 -05:00
escape-string xml-pprint? get [
dup [ blank? ] all?
[ drop "" ]
[ nl 80 indent-string indented-break ] if
] 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 ;
M: contained-tag write-xml-chunk
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
[ write-xml-chunk ] 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
M: open-tag write-xml-chunk
xml-pprint? get [
{
[ sensitive? not xml-pprint? get and xml-pprint? set ]
[ write-start-tag ]
[ write-children ]
[ write-end-tag ]
} cleave
] dip xml-pprint? set ;
M: comment write-xml-chunk
2008-08-27 18:02:54 -04:00
"<!--" write text>> write "-->" write ;
2007-09-20 18:09:08 -04:00
M: element-decl write-xml-chunk
"<!ELEMENT " write
[ name>> write " " write ]
[ content-spec>> write ">" write ]
bi ;
M: attlist-decl write-xml-chunk
"<!ATTLIST " write
[ name>> write " " write ]
[ att-defs>> write ">" write ]
bi ;
2009-01-21 19:16:51 -05:00
M: notation-decl write-xml-chunk
"<!NOTATION " write
[ name>> write " " write ]
2009-01-21 19:16:51 -05:00
[ id>> write ">" write ]
bi ;
2009-01-21 19:16:51 -05:00
M: entity-decl write-xml-chunk
"<!ENTITY " write
[ pe?>> [ " % " write ] when ]
[ name>> write " \"" write ] [
def>> f xml-pprint?
[ write-xml-chunk ] with-variable
"\">" write
] tri ;
M: system-id write-xml-chunk
"SYSTEM '" write system-literal>> write "'" write ;
M: public-id write-xml-chunk
"PUBLIC '" write
[ pubid-literal>> write "' '" write ]
2008-12-19 01:52:52 -05:00
[ system-literal>> write "'" write ] bi ;
: write-internal-subset ( dtd -- )
2009-01-21 19:16:51 -05:00
[
"[" write indent
directives>> [ ?indent write-xml-chunk ] each
2009-01-21 19:16:51 -05:00
unindent ?indent "]" write
] when* ;
M: doctype-decl write-xml-chunk
2009-01-21 19:16:51 -05:00
?indent "<!DOCTYPE " write
[ name>> write " " write ]
[ external-id>> [ write-xml-chunk " " write ] when* ]
2009-01-21 19:16:51 -05:00
[ internal-subset>> write-internal-subset ">" write ] tri ;
M: directive write-xml-chunk
2009-01-21 19:16:51 -05:00
"<!" write text>> write CHAR: > write1 nl ;
2007-09-20 18:09:08 -04:00
M: instruction write-xml-chunk
2008-08-27 18:02:54 -04:00
"<?" write text>> write "?>" write ;
2007-09-20 18:09:08 -04:00
M: number write-xml-chunk
"Numbers are not allowed in XML" throw ;
M: sequence write-xml-chunk
[ write-xml-chunk ] each ;
PRIVATE>
2007-09-20 18:09:08 -04:00
: write-prolog ( xml -- )
2008-08-27 18:02:54 -04:00
"<?xml version=\"" write dup version>> write
"\" encoding=\"" write dup encoding>> write
standalone>> [ "\" standalone=\"yes" write ] when
2008-01-30 16:03:02 -05:00
"\"?>" write ;
2007-09-20 18:09:08 -04:00
: write-xml ( xml -- )
2008-04-15 07:10:08 -04:00
{
2008-08-27 18:02:54 -04:00
[ prolog>> write-prolog ]
[ before>> write-xml-chunk ]
[ body>> write-xml-chunk ]
[ after>> write-xml-chunk ]
2008-04-15 07:10:08 -04:00
} cleave ;
2007-09-20 18:09:08 -04:00
M: xml write-xml-chunk
body>> write-xml-chunk ;
2007-09-20 18:09:08 -04:00
: xml>string ( xml -- string )
[ write-xml ] with-string-writer ;
2007-09-20 18:09:08 -04:00
2009-01-19 23:25:15 -05:00
: xml-chunk>string ( object -- string )
[ write-xml-chunk ] with-string-writer ;
2009-01-21 19:16:51 -05:00
: pprint-xml-but ( xml sensitive-tags -- )
2007-12-29 01:33:21 -05:00
[
2009-01-21 19:16:51 -05:00
[ assure-name ] map sensitive-tags set
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 ( xml -- )
f pprint-xml-but ;
: pprint-xml>string-but ( xml sensitive-tags -- string )
2009-01-21 19:16:51 -05:00
[ pprint-xml-but ] with-string-writer ;
2007-12-29 01:33:21 -05:00
: pprint-xml>string ( xml -- string )
f pprint-xml>string-but ;