@@ -25,82 +25,86 @@ const Walker = @import("../dom/walker.zig").WalkerChildren;
2525// writer must be a std.io.Writer
2626pub fn writeHTML (doc : * parser.Document , writer : anytype ) ! void {
2727 try writer .writeAll ("<!DOCTYPE html>\n " );
28- try writeNode (parser .documentToNode (doc ), writer );
28+ try writeChildren (parser .documentToNode (doc ), writer );
2929 try writer .writeAll ("\n " );
3030}
3131
32+ pub fn writeNode (node : * parser.Node , writer : anytype ) anyerror ! void {
33+ switch (try parser .nodeType (node )) {
34+ .element = > {
35+ // open the tag
36+ const tag = try parser .nodeLocalName (node );
37+ try writer .writeAll ("<" );
38+ try writer .writeAll (tag );
39+
40+ // write the attributes
41+ const map = try parser .nodeGetAttributes (node );
42+ const ln = try parser .namedNodeMapGetLength (map );
43+ var i : u32 = 0 ;
44+ while (i < ln ) {
45+ const attr = try parser .namedNodeMapItem (map , i ) orelse break ;
46+ try writer .writeAll (" " );
47+ try writer .writeAll (try parser .attributeGetName (attr ));
48+ try writer .writeAll ("=\" " );
49+ try writer .writeAll (try parser .attributeGetValue (attr ) orelse "" );
50+ try writer .writeAll ("\" " );
51+ i += 1 ;
52+ }
53+
54+ try writer .writeAll (">" );
55+
56+ // void elements can't have any content.
57+ if (try isVoid (parser .nodeToElement (node ))) return ;
58+
59+ // write the children
60+ // TODO avoid recursion
61+ try writeChildren (node , writer );
62+
63+ // close the tag
64+ try writer .writeAll ("</" );
65+ try writer .writeAll (tag );
66+ try writer .writeAll (">" );
67+ },
68+ .text = > {
69+ const v = try parser .nodeValue (node ) orelse return ;
70+ try writer .writeAll (v );
71+ },
72+ .cdata_section = > {
73+ const v = try parser .nodeValue (node ) orelse return ;
74+ try writer .writeAll ("<![CDATA[" );
75+ try writer .writeAll (v );
76+ try writer .writeAll ("]]>" );
77+ },
78+ .comment = > {
79+ const v = try parser .nodeValue (node ) orelse return ;
80+ try writer .writeAll ("<!--" );
81+ try writer .writeAll (v );
82+ try writer .writeAll ("-->" );
83+ },
84+ // TODO handle processing instruction dump
85+ .processing_instruction = > return ,
86+ // document fragment is outside of the main document DOM, so we
87+ // don't output it.
88+ .document_fragment = > return ,
89+ // document will never be called, but required for completeness.
90+ .document = > return ,
91+ // done globally instead, but required for completeness.
92+ .document_type = > return ,
93+ // deprecated
94+ .attribute = > return ,
95+ .entity_reference = > return ,
96+ .entity = > return ,
97+ .notation = > return ,
98+ }
99+ }
100+
32101// writer must be a std.io.Writer
33- pub fn writeNode (root : * parser.Node , writer : anytype ) ! void {
102+ pub fn writeChildren (root : * parser.Node , writer : anytype ) ! void {
34103 const walker = Walker {};
35104 var next : ? * parser.Node = null ;
36105 while (true ) {
37106 next = try walker .get_next (root , next ) orelse break ;
38- switch (try parser .nodeType (next .? )) {
39- .element = > {
40- // open the tag
41- const tag = try parser .nodeLocalName (next .? );
42- try writer .writeAll ("<" );
43- try writer .writeAll (tag );
44-
45- // write the attributes
46- const map = try parser .nodeGetAttributes (next .? );
47- const ln = try parser .namedNodeMapGetLength (map );
48- var i : u32 = 0 ;
49- while (i < ln ) {
50- const attr = try parser .namedNodeMapItem (map , i ) orelse break ;
51- try writer .writeAll (" " );
52- try writer .writeAll (try parser .attributeGetName (attr ));
53- try writer .writeAll ("=\" " );
54- try writer .writeAll (try parser .attributeGetValue (attr ) orelse "" );
55- try writer .writeAll ("\" " );
56- i += 1 ;
57- }
58-
59- try writer .writeAll (">" );
60-
61- // void elements can't have any content.
62- if (try isVoid (parser .nodeToElement (next .? ))) continue ;
63-
64- // write the children
65- // TODO avoid recursion
66- try writeNode (next .? , writer );
67-
68- // close the tag
69- try writer .writeAll ("</" );
70- try writer .writeAll (tag );
71- try writer .writeAll (">" );
72- },
73- .text = > {
74- const v = try parser .nodeValue (next .? ) orelse continue ;
75- try writer .writeAll (v );
76- },
77- .cdata_section = > {
78- const v = try parser .nodeValue (next .? ) orelse continue ;
79- try writer .writeAll ("<![CDATA[" );
80- try writer .writeAll (v );
81- try writer .writeAll ("]]>" );
82- },
83- .comment = > {
84- const v = try parser .nodeValue (next .? ) orelse continue ;
85- try writer .writeAll ("<!--" );
86- try writer .writeAll (v );
87- try writer .writeAll ("-->" );
88- },
89- // TODO handle processing instruction dump
90- .processing_instruction = > continue ,
91- // document fragment is outside of the main document DOM, so we
92- // don't output it.
93- .document_fragment = > continue ,
94- // document will never be called, but required for completeness.
95- .document = > continue ,
96- // done globally instead, but required for completeness.
97- .document_type = > continue ,
98- // deprecated
99- .attribute = > continue ,
100- .entity_reference = > continue ,
101- .entity = > continue ,
102- .notation = > continue ,
103- }
107+ try writeNode (next .? , writer );
104108 }
105109}
106110
0 commit comments