1 ! Copyright (C) 2005, 2009 Daniel Ehrenberg
\r
2 ! See http://factorcode.org/license.txt for BSD license.
\r
3 USING: hashtables kernel math namespaces sequences strings
\r
4 assocs combinators io io.streams.string accessors
\r
5 xml.data wrap xml.entities unicode.categories fry ;
\r
8 SYMBOL: sensitive-tags
\r
10 " " indenter set-global
\r
17 : sensitive? ( tag -- ? )
\r
18 sensitive-tags get swap '[ _ names-match? ] any? ;
\r
20 : indent-string ( -- string )
\r
22 [ indentation get indenter get <repetition> concat ]
\r
26 xml-pprint? get [ nl indent-string write ] when ;
\r
29 xml-pprint? get [ 1 indentation +@ ] when ;
\r
32 xml-pprint? get [ -1 indentation +@ ] when ;
\r
34 : trim-whitespace ( string -- no-whitespace )
\r
37 : ?filter-children ( children -- no-whitespace )
\r
39 [ dup string? [ trim-whitespace ] when ] map
\r
40 [ [ empty? ] [ string? ] bi and not ] filter
\r
45 : name>string ( name -- string )
\r
46 [ main>> ] [ space>> ] bi [ ":" rot 3append ] unless-empty ;
\r
48 : print-name ( name -- )
\r
53 : write-quoted ( string -- )
\r
54 CHAR: " write1 write CHAR: " write1 ;
\r
56 : print-attrs ( assoc -- )
\r
58 [ bl print-name "=" write ]
\r
59 [ escape-quoted-string write-quoted ] bi*
\r
64 GENERIC: write-xml ( xml -- )
\r
69 escape-string xml-pprint? get [
\r
72 [ nl 80 indent-string indented-break ] if
\r
75 : write-tag ( tag -- )
\r
76 ?indent CHAR: < write1
\r
77 dup print-name attrs>> print-attrs ;
\r
79 : write-start-tag ( tag -- )
\r
80 write-tag ">" write ;
\r
82 M: contained-tag write-xml
\r
83 write-tag "/>" write ;
\r
85 : write-children ( tag -- )
\r
86 indent children>> ?filter-children
\r
87 [ write-xml ] each unindent ;
\r
89 : write-end-tag ( tag -- )
\r
90 ?indent "</" write print-name CHAR: > write1 ;
\r
92 M: open-tag write-xml
\r
96 [ sensitive? not xml-pprint? get and xml-pprint? set ]
\r
100 ] dip xml-pprint? set ;
\r
102 M: unescaped write-xml
\r
105 M: comment write-xml
\r
106 "<!--" write text>> write "-->" write ;
\r
108 : write-decl ( decl name quot: ( decl -- slot ) -- )
\r
109 "<!" write swap write bl
\r
110 [ name>> write bl ]
\r
111 swap '[ @ write ">" write ] bi ; inline
\r
113 M: element-decl write-xml
\r
114 "ELEMENT" [ content-spec>> ] write-decl ;
\r
116 M: attlist-decl write-xml
\r
117 "ATTLIST" [ att-defs>> ] write-decl ;
\r
119 M: notation-decl write-xml
\r
120 "NOTATION" [ id>> ] write-decl ;
\r
122 M: entity-decl write-xml
\r
124 [ pe?>> [ " % " write ] when ]
\r
125 [ name>> write " \"" write ] [
\r
126 def>> f xml-pprint?
\r
127 [ write-xml ] with-variable
\r
131 M: system-id write-xml
\r
132 "SYSTEM" write bl system-literal>> write-quoted ;
\r
134 M: public-id write-xml
\r
136 [ pubid-literal>> write-quoted bl ]
\r
137 [ system-literal>> write-quoted ] bi ;
\r
139 : write-internal-subset ( dtd -- )
\r
142 directives>> [ ?indent write-xml ] each
\r
143 unindent ?indent "]" write
\r
146 M: doctype-decl write-xml
\r
147 ?indent "<!DOCTYPE " write
\r
148 [ name>> write " " write ]
\r
149 [ external-id>> [ write-xml " " write ] when* ]
\r
150 [ internal-subset>> write-internal-subset ">" write ] tri ;
\r
152 M: directive write-xml
\r
153 "<!" write text>> write CHAR: > write1 nl ;
\r
155 M: instruction write-xml
\r
156 "<?" write text>> write "?>" write ;
\r
158 M: number write-xml
\r
159 "Numbers are not allowed in XML" throw ;
\r
161 M: sequence write-xml
\r
162 [ write-xml ] each ;
\r
164 M: prolog write-xml
\r
165 "<?xml version=" write
\r
166 [ version>> write-quoted ]
\r
167 [ " encoding=" write encoding>> write-quoted ]
\r
168 [ standalone>> [ " standalone=\"yes\"" write ] when ] tri
\r
173 [ prolog>> write-xml ]
\r
174 [ before>> write-xml ]
\r
175 [ body>> write-xml ]
\r
176 [ after>> write-xml ]
\r
181 : xml>string ( xml -- string )
\r
182 [ write-xml ] with-string-writer ;
\r
184 : pprint-xml ( xml -- )
\r
186 sensitive-tags [ [ assure-name ] map ] change
\r
192 : pprint-xml>string ( xml -- string )
\r
193 [ pprint-xml ] with-string-writer ;
\r