]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Html: Introduce MarkupWriter to pretty-print generated html
authorDidier "Ptitjes <ptitjes@free.fr>
Mon, 19 Oct 2009 23:55:33 +0000 (01:55 +0200)
committerFlorian Brosch <flo.brosch@gmail.com>
Mon, 19 Oct 2009 23:55:33 +0000 (01:55 +0200)
src/doclets/devhelp/doclet/doclet.vala
src/doclets/htm/doclet/doclet.vala
src/doclets/htmlhelpers/deps/style.css
src/doclets/htmlhelpers/doclet/Makefile.am
src/doclets/htmlhelpers/doclet/doclet.vala
src/doclets/htmlhelpers/doclet/htmlrenderer.vala
src/doclets/htmlhelpers/doclet/markupwriter.vala [new file with mode: 0644]
src/libvaladoc/api/package.vala

index 4d02cf68a1d8341881779254ca7e396a6e16838d..c3d29b18d353a4bb57e3c447d160faf6280ae10f 100755 (executable)
@@ -20,6 +20,7 @@
 
 using Valadoc;
 using Valadoc.Api;
+using Valadoc.Html;
 using Xml;
 using Gee;
 
@@ -227,8 +228,8 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                }
        }
 
-       public override void visit_package ( Package file ) {
-               string pkg_name = file.name;
+       public override void visit_package (Package package) {
+               string pkg_name = package.name;
 
                string path = GLib.Path.build_filename ( this.settings.path, pkg_name );
                string filepath = GLib.Path.build_filename ( path, "index.htm" );
@@ -236,26 +237,27 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                string devpath = GLib.Path.build_filename ( path, pkg_name + ".devhelp2" );
 
                WikiPage wikipage = null;
-               if ( this.settings.pkg_name == file.name && this.tree.wikitree != null ) {
+               if ( this.settings.pkg_name == package.name && this.tree.wikitree != null ) {
                        wikipage = this.tree.wikitree.search ("index.valadoc");
                }
 
                this.package_dir_name = pkg_name;
 
-
                var rt = DirUtils.create ( path, 0777 );
                rt = DirUtils.create ( imgpath, 0777 );
                copy_directory ( Config.doclet_path + "deps/", path );
 
                this.devhelp = new DevhelpFormat ( pkg_name, "" );
 
-               GLib.FileStream ifile = GLib.FileStream.open ( filepath, "w" );
-               this.write_file_header ( ifile, this.css_path, pkg_name );
-               this.write_file_content ( ifile, file, file, wikipage );
-               this.write_file_footer ( ifile );
-               ifile = null;
+               GLib.FileStream file = GLib.FileStream.open ( filepath, "w" );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, pkg_name);
+               this.write_file_content (package, package, wikipage);
+               this.write_file_footer ();
+               file = null;
 
-               file.visit_namespaces ( this );
+               package.visit_namespaces ( this );
 
                this.devhelp.save_file ( devpath );
        }
@@ -266,9 +268,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                        string path = this.get_path ( ns );
 
                        GLib.FileStream file = GLib.FileStream.open ( rpath, "w" );
-                       this.write_file_header ( file, this.css_path, ns.full_name() );
-                       this.write_namespace_content ( file, ns, ns );
-                       this.write_file_footer ( file );
+                       writer = new MarkupWriter (file);
+                       _renderer.set_writer (writer);
+                       this.write_file_header (this.css_path, ns.full_name());
+                       this.write_namespace_content (ns, ns);
+                       this.write_file_footer ();
                        file = null;
 
                        this.devhelp.add_keyword ( KeywordType.NAMESPACE, ns.name, path );
@@ -313,9 +317,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                this.devhelp.add_keyword ( KeywordType.INTERFACE, iface.name, path );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, iface.full_name() );
-               this.write_interface_content ( file, iface, iface );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, iface.full_name());
+               this.write_interface_content (iface, iface);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -342,9 +348,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
 
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, cl.full_name() );
-               this.write_class_content ( file, cl, cl );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, cl.full_name());
+               this.write_class_content (cl, cl);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -365,10 +373,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
 
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, stru.full_name() );
-
-               this.write_struct_content ( file, stru, stru );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, stru.full_name());
+               this.write_struct_content (stru, stru);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -382,9 +391,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                this.devhelp.add_chapter ( errdom.name, path );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, errdom.full_name() );
-               this.write_error_domain_content ( file, errdom, errdom );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, errdom.full_name());
+               this.write_error_domain_content (errdom, errdom);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -399,9 +410,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                this.devhelp.add_chapter ( en.name, path );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, en.full_name() );
-               this.write_enum_content ( file, en, en );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, en.full_name());
+               this.write_enum_content (en, en);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -413,9 +426,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                this.devhelp.add_chapter ( prop.name, path );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, prop.full_name() );
-               this.write_property_content ( file, prop );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, prop.full_name());
+               this.write_property_content (prop);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -427,9 +442,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                this.devhelp.add_chapter ( constant.name, path );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, constant.full_name() );
-               this.write_constant_content (file, constant);
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, constant.full_name());
+               this.write_constant_content (constant);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -441,9 +458,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                this.devhelp.add_chapter ( field.name, path );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, field.full_name() );
-               this.write_field_content (file, field);
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, field.full_name());
+               this.write_field_content (field);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -461,9 +480,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                this.devhelp.add_chapter ( del.name, path );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, del.full_name() );
-               this.write_delegate_content ( file, del );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, del.full_name());
+               this.write_delegate_content (del);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -475,9 +496,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                this.devhelp.add_chapter ( sig.name, path );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, sig.full_name() );
-               write_signal_content ( file, sig );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, sig.full_name());
+               write_signal_content (sig);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -489,9 +512,11 @@ public class Valadoc.Devhelp.Doclet : Valadoc.Html.BasicDoclet {
                this.devhelp.add_chapter ( m.name, path );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, m.full_name() );
-               this.write_method_content (file, m);
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, m.full_name());
+               this.write_method_content (m);
+               this.write_file_footer ();
                file = null;
        }
 }
@@ -506,3 +531,4 @@ public Type register_plugin ( ) {
        return typeof ( Valadoc.Devhelp.Doclet );
 }
 
+
index e446218a30073f550758fffb962d59a34295c402..28ea47bf0d175619210f1fdf0923852819b2397b 100755 (executable)
@@ -20,6 +20,7 @@
 
 using Valadoc;
 using Valadoc.Api;
+using Valadoc.Html;
 using Gee;
 
 namespace Valadoc {
@@ -104,6 +105,10 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
        private const string css_path_wiki = "../style.css";
        private const string css_path = "../style.css";
 
+       construct {
+               _renderer = new HtmlRenderer (this);
+       }
+
        private string get_real_path ( Api.Node element ) {
                return GLib.Path.build_filename ( this.settings.path, element.package.name, element.full_name () + ".html" );
        }
@@ -117,10 +122,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                this.write_wiki_pages ( tree, css_path_wiki, Path.build_filename(settings.path, "content") );
 
                GLib.FileStream file = GLib.FileStream.open ( GLib.Path.build_filename ( settings.path, "index.html" ), "w" );
-               this.write_file_header ( file, this.css_path_package, settings.pkg_name );
-               this.write_navi_packages ( file, tree );
-               this.write_packages_content ( file, tree );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path_package, settings.pkg_name);
+               this.write_navi_packages (tree);
+               this.write_packages_content (tree);
+               this.write_file_footer ();
                file = null;
 
                Gee.Collection<Package> packages = tree.get_package_list ();
@@ -129,21 +136,23 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                }
        }
 
-       public override void visit_package ( Package file ) {
-               string pkg_name = file.name;
+       public override void visit_package (Package package) {
+               string pkg_name = package.name;
                string path = GLib.Path.build_filename ( this.settings.path, pkg_name );
 
                var rt = DirUtils.create ( path, 0777 );
                rt = DirUtils.create ( GLib.Path.build_filename ( path, "img" ), 0777 );
 
-               GLib.FileStream ifile = GLib.FileStream.open ( GLib.Path.build_filename ( path, "index.htm" ), "w" );
-               this.write_file_header ( ifile, this.css_path, pkg_name );
-               this.write_navi_file ( ifile, file, file );
-               this.write_file_content ( ifile, file, file );
-               this.write_file_footer ( ifile );
-               ifile = null;
+               GLib.FileStream file = GLib.FileStream.open ( GLib.Path.build_filename ( path, "index.htm" ), "w" );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, pkg_name);
+               this.write_navi_file (package, package);
+               this.write_file_content (package, package);
+               this.write_file_footer ();
+               file = null;
 
-               file.visit_namespaces ( this );
+               package.visit_namespaces ( this );
        }
 
        public override void visit_namespace ( Namespace ns ) {
@@ -151,10 +160,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
 
                if ( ns.name != null ) {
                        GLib.FileStream file = GLib.FileStream.open ( rpath, "w" );
-                       this.write_file_header ( file, this.css_path, ns.full_name() );
-                       this.write_navi_namespace ( file, ns );
-                       this.write_namespace_content ( file, ns, ns );
-                       this.write_file_footer ( file );
+                       writer = new MarkupWriter (file);
+                       _renderer.set_writer (writer);
+                       this.write_file_header (this.css_path, ns.full_name());
+                       this.write_navi_namespace (ns);
+                       this.write_namespace_content (ns, ns);
+                       this.write_file_footer ();
                        file = null;
                }
 
@@ -185,10 +196,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                iface.visit_constants ( this );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, iface.full_name() );
-               this.write_navi_interface ( file, iface, iface );
-               this.write_interface_content ( file, iface, iface );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, iface.full_name());
+               this.write_navi_interface (iface, iface);
+               this.write_interface_content (iface, iface);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -207,10 +220,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                cl.visit_constants ( this );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, cl.full_name() );
-               this.write_navi_class ( file, cl, cl );
-               this.write_class_content ( file, cl, cl );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, cl.full_name());
+               this.write_navi_class (cl, cl);
+               this.write_class_content (cl, cl);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -223,10 +238,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                stru.visit_constants ( this );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, stru.full_name() );
-               this.write_navi_struct ( file, stru, stru );
-               this.write_struct_content ( file, stru, stru );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, stru.full_name());
+               this.write_navi_struct (stru, stru);
+               this.write_struct_content (stru, stru);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -236,10 +253,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                errdom.visit_methods ( this );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, errdom.full_name() );
-               this.write_navi_error_domain ( file, errdom, errdom );
-               this.write_error_domain_content ( file, errdom, errdom );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, errdom.full_name());
+               this.write_navi_error_domain (errdom, errdom);
+               this.write_error_domain_content (errdom, errdom);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -250,10 +269,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                en.visit_methods ( this );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, en.full_name() );
-               this.write_navi_enum ( file, en, en );
-               this.write_enum_content ( file, en, en );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, en.full_name());
+               this.write_navi_enum (en, en);
+               this.write_enum_content (en, en);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -261,10 +282,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                string rpath = this.get_real_path ( prop );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, prop.full_name() );
-               this.write_navi_property ( file, prop );
-               this.write_property_content ( file, prop );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, prop.full_name());
+               this.write_navi_property (prop);
+               this.write_property_content (prop);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -272,10 +295,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                string rpath = this.get_real_path ( constant );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, constant.full_name() );
-               this.write_navi_constant ( file, constant );
-               this.write_constant_content (file, constant);
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, constant.full_name());
+               this.write_navi_constant (constant);
+               this.write_constant_content (constant);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -283,10 +308,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                string rpath = this.get_real_path ( field );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, field.full_name() );
-               this.write_navi_field ( file, field );
-               this.write_field_content (file, field);
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, field.full_name());
+               this.write_navi_field (field);
+               this.write_field_content (field);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -300,10 +327,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                string rpath = this.get_real_path ( del );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, del.full_name() );
-               this.write_navi_delegate ( file, del );
-               this.write_delegate_content ( file, del );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, del.full_name());
+               this.write_navi_delegate (del);
+               this.write_delegate_content (del);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -311,10 +340,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                string rpath = this.get_real_path ( sig );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, sig.full_name() );
-               this.write_navi_signal ( file, sig );
-               write_signal_content ( file, sig );
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, sig.full_name());
+               this.write_navi_signal (sig);
+               write_signal_content (sig);
+               this.write_file_footer ();
                file = null;
        }
 
@@ -322,10 +353,12 @@ public class Valadoc.HtmlDoclet : Valadoc.Html.BasicDoclet {
                string rpath = this.get_real_path ( m );
 
                GLib.FileStream file = GLib.FileStream.open ( rpath, "w");
-               this.write_file_header ( file, this.css_path, m.full_name() );
-               this.write_navi_method ( file, m );
-               this.write_method_content (file, m);
-               this.write_file_footer ( file );
+               writer = new MarkupWriter (file);
+               _renderer.set_writer (writer);
+               this.write_file_header (this.css_path, m.full_name());
+               this.write_navi_method (m);
+               this.write_method_content (m);
+               this.write_file_footer ();
                file = null;
        }
 }
@@ -340,3 +373,4 @@ public Type register_plugin ( ) {
        return typeof ( Valadoc.HtmlDoclet );
 }
 
+
index 4bac34b375b085ef33cb9b79c2edc43746b3c52f..cd25af78b6a7cea4dc8167c49ff44485fe338f1c 100644 (file)
@@ -12,7 +12,7 @@ ul.external_link {
 .main_diagram {
        display: block;
        margin: 0px auto;
-       width: 100px;
+       width: 50%;
 }
 
 .site_navi {
@@ -504,3 +504,4 @@ a.navi_link:hover, a.external_link:hover {
        color: #ff01ff;
 }
 
+
index e1a1fdd7f920cc6c0c197ba23218713fe40f8bc8..f69abb4f55bb7f4b739d98791e0d4bb5bf868c49 100644 (file)
@@ -25,7 +25,8 @@ htmlhelpers_LTLIBRARIES =   \
 libhtmlhelpers_la_VALASOURCES = \
        globals.vala                \
        doclet.vala                 \
-       htmlrenderer.vala                 \
+       htmlrenderer.vala           \
+       markupwriter.vala           \
        $(NULL)
 
 
@@ -67,3 +68,4 @@ MAINTAINERCLEANFILES =                        \
        $(libhtmlhelpers_la_VALASOURCES:.vala=.c) \
        $(NULL)
 
+
index 98da9d96b5bd4204032b31a990fe92d57618eb18..0548fe035ce6b829ed84092262970c5b28e50150 100755 (executable)
@@ -24,38 +24,39 @@ using Valadoc.Api;
 public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
        protected Settings settings;
        protected HtmlRenderer _renderer;
-
-       construct {
-               _renderer = new HtmlRenderer (this);
-       }
+       protected MarkupWriter writer;
 
        public abstract void process (Settings settings, Api.Tree tree);
 
-       protected string? get_link ( Api.Node element, Api.Node? pos ) {
-               return get_html_link ( this.settings, element, pos );
+       protected string? get_link (Api.Node element, Api.Node? pos) {
+               return get_html_link (this.settings, element, pos);
        }
 
-       protected void write_navi_entry_html_template ( GLib.FileStream file, string style, string content ) {
-               file.printf ( "\t<li class=\"%s\">%s</li>\n", style, content );
+       protected void write_navi_entry_html_template (string style, string content) {
+               writer.start_tag ("li", style);
+               writer.text (content);
+               writer.end_tag ("li");
        }
 
-       protected void write_navi_entry_html_template_with_link ( GLib.FileStream file, string style, string link, string content ) {
-               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a></li>\n", style, css_navi_link, link, content );
+       protected void write_navi_entry_html_template_with_link (string style, string link, string content) {
+               writer.start_tag ("li", style);
+               writer.link (css_navi_link, link, content);
+               writer.end_tag ("li");
        }
 
-       protected void write_navi_entry ( GLib.FileStream file, Api.Node element, Api.Node? pos, string style, bool link, bool full_name = false ) {
+       protected void write_navi_entry (Api.Node element, Api.Node? pos, string style, bool link, bool full_name = false) {
                string name;
 
-               if ( element is Class ) {
-                       if ( ((Class)element).is_abstract )
+               if (element is Class) {
+                       if (((Class)element).is_abstract)
                                name = "<i>" + element.name + "</i>";
                        else
                                name = element.name;
                }
-               else if ( element is Package ) {
+               else if (element is Package) {
                        name = element.package.name;
                }
-               else if ( full_name == true && element is Namespace ) {
+               else if (full_name == true && element is Namespace) {
                        string tmp = element.full_name();
                        name = (tmp == null)? "Global Namespace" : tmp;
                }
@@ -64,23 +65,23 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
                        name = (tmp == null)? "Global Namespace" : tmp;
                }
 
-               if ( link == true )
-                       this.write_navi_entry_html_template_with_link ( file, style, this.get_link (element, pos), name );
+               if (link == true)
+                       this.write_navi_entry_html_template_with_link (style, this.get_link (element, pos), name);
                else
-                       this.write_navi_entry_html_template ( file, style, name );
+                       this.write_navi_entry_html_template (style, name);
        }
 
        protected void write_wiki_pages (Api.Tree tree, string css_path_wiki, string contentp) {
-               if ( tree.wikitree == null ) {
+               if (tree.wikitree == null) {
                        return ;
                }
 
-               if ( tree.wikitree == null ) {
+               if (tree.wikitree == null) {
                        return ;
                }
 
                Gee.Collection<WikiPage> pages = tree.wikitree.get_pages();
-               if ( pages.size == 0 ) {
+               if (pages.size == 0) {
                        return ;
                }
 
@@ -88,1348 +89,1379 @@ public abstract class Valadoc.Html.BasicDoclet : Api.Visitor, Doclet {
 
                DirUtils.create (Path.build_filename (contentp, "img"), 0777);
 
-               foreach ( WikiPage page in pages ) {
-                       if ( page.name != "index.valadoc" ) {
-                               GLib.FileStream file = GLib.FileStream.open ( Path.build_filename(contentp, page.name.ndup( page.name.len()-7).replace ("/", ".")+"html"), "w" );
-                               this.write_file_header ( file, css_path_wiki, this.settings.pkg_name );
+               foreach (WikiPage page in pages) {
+                       if (page.name != "index.valadoc") {
+                               GLib.FileStream file = GLib.FileStream.open (Path.build_filename(contentp, page.name.ndup(page.name.len()-7).replace ("/", ".")+"html"), "w");
+                               writer = new MarkupWriter (file);
+                               _renderer.set_writer (writer);
+                               this.write_file_header (css_path_wiki, this.settings.pkg_name);
                                _renderer.set_container (page);
-                               _renderer.set_filestream (file);
                                _renderer.render (page.documentation);
-                               this.write_file_footer ( file );
+                               this.write_file_footer ();
                        }
                }
        }
 
-       protected void write_navi_top_entry ( GLib.FileStream file, Api.Node element, Api.Node? mself ) {
+       protected void write_navi_top_entry (Api.Node element, Api.Node? parent) {
                string name = (element.name == null)? "Global Namespace" : element.name;
                string style = null;
 
-               if ( element is Namespace )
+               if (element is Namespace)
                        style = css_navi_namespace;
-               else if ( element is Enum )
+               else if (element is Enum)
                        style = css_navi_enum;
-               else if ( element is ErrorDomain )
+               else if (element is ErrorDomain)
                        style = css_navi_error_domain;
-               else if ( element is Struct )
+               else if (element is Struct)
                        style = css_navi_struct;
-               else if ( element is Class )
-                       style = ( ((Class)element).is_abstract )? css_navi_abstract_class : css_navi_class;
-               else if ( element is Interface )
+               else if (element is Class)
+                       style = (((Class)element).is_abstract)? css_navi_abstract_class : css_navi_class;
+               else if (element is Interface)
                        style = css_navi_iface;
-               else if ( element is Package ) {
+               else if (element is Package) {
                        name = element.package.name;
                        style = css_navi_package;
                }
 
-               file.printf ( "<ul class=\"%s\">\n", css_navi );
+               writer.start_tag ("ul", css_navi);
 
-               if ( element == mself || mself == null )
-                       this.write_navi_entry ( file, element, mself, style, false );
+               if (element == parent || parent == null)
+                       this.write_navi_entry (element, parent, style, false);
                else
-                       this.write_navi_entry ( file, element, mself, style, true );
+                       this.write_navi_entry (element, parent, style, true);
 
-               file.puts ( "</ul>\n" );
-               file.printf ( "\n<hr class=\"%s\">\n", css_navi_hr );
+               writer.end_tag ("ul");
+               writer.simple_tag ("hr", css_navi_hr);
        }
 
-       protected void write_top_element_template ( GLib.FileStream file, string link ) {
-               file.printf ( "<ul class=\"%s\">\n\t\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">Packages</a></li>\n</ul>\n<hr class=\"%s\">\n", css_navi, css_navi_package_index, css_navi_link, link, css_navi_hr );
+       protected void write_top_element_template (string link) {
+               writer.start_tag ("ul", css_navi);
+               writer.start_tag ("li", css_navi_package_index);
+               writer.link (css_navi_link, link, "Packages");
+               writer.end_tag ("li");
+               writer.end_tag ("ul");
+               writer.simple_tag ("hr", css_navi_hr);
        }
 
-       protected void write_top_elements ( GLib.FileStream file, Api.Node element, Api.Node? mself ) {
+       protected void write_top_elements (Api.Node element, Api.Node? parent) {
                Gee.ArrayList<Api.Node> lst = new Gee.ArrayList<Api.Node> ();
                Api.Node pos = element;
 
-               this.write_top_element_template ( file, "../index.html" );
+               this.write_top_element_template ("../index.html");
 
-               while ( pos != null ) {
-                       lst.add ( pos );
+               while (pos != null) {
+                       lst.add (pos);
                        pos = (Api.Node)pos.parent;
                }
 
-               for ( int i = lst.size-1; i >= 0  ; i-- ) {
-                       Api.Node el = lst.get ( i );
+               for (int i = lst.size-1; i >= 0  ; i--) {
+                       Api.Node el = lst.get (i);
 
-                       if ( el.name != null ) {
-                               this.write_navi_top_entry ( file, el, mself );
+                       if (el.name != null) {
+                               this.write_navi_top_entry (el, parent);
                        }
                }
        }
 
-       protected void fetch_subnamespace_names ( NamespaceHandler pos, Gee.ArrayList<Namespace> lst ) {
+       protected void fetch_subnamespace_names (NamespaceHandler pos, Gee.ArrayList<Namespace> lst) {
                Gee.Collection<Namespace> nspaces = pos.get_namespace_list ();
 
-               foreach ( Namespace ns in nspaces ) {
-                       lst.add ( ns );
-                       this.fetch_subnamespace_names ( ns, lst );
+               foreach (Namespace ns in nspaces) {
+                       lst.add (ns);
+                       this.fetch_subnamespace_names (ns, lst);
                }
        }
 
-       protected void write_navi_file ( GLib.FileStream file, Package efile, Api.Node? pos ) {
+       protected void write_navi_file (Package efile, Api.Node? pos) {
                Gee.ArrayList<Namespace> ns_list = new Gee.ArrayList<Namespace> ();
-               this.fetch_subnamespace_names (efile, ns_list );
+               this.fetch_subnamespace_names (efile, ns_list);
 
 
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
+               writer.start_tag ("div", css_style_navigation);
 
 
-               if ( pos == null )
-                       this.write_top_elements ( file, efile, null );
-               else if ( pos == efile )
-                       this.write_top_elements ( file, efile, efile );
+               if (pos == null)
+                       this.write_top_elements (efile, null);
+               else if (pos == efile)
+                       this.write_top_elements (efile, efile);
                else
-                       this.write_top_elements ( file, (Api.Node)pos.parent.parent, pos );
+                       this.write_top_elements ((Api.Node)pos.parent.parent, pos);
 
-               file.printf ( "\t\t\t\t<ul class=\"%s\">\n", css_navi );
+               writer.start_tag ("ul", css_navi);
 
 
                Namespace globals = null;
 
-               foreach ( Namespace ns in ns_list ) {
-                       if ( ns.name == null )
+               foreach (Namespace ns in ns_list) {
+                       if (ns.name == null)
                                globals = ns;
                        else
-                               this.write_navi_entry ( file, ns, pos, css_navi_namespace, true, true );
+                               this.write_navi_entry (ns, pos, css_navi_namespace, true, true);
                }
 
-               if ( globals != null ) {
-                       this.write_navi_child_namespaces_inline_withouth_block ( file, globals, pos );
+               if (globals != null) {
+                       this.write_navi_child_namespaces_inline_withouth_block (globals, pos);
                }
 
-               file.puts ( "\t\t\t\t</ul>\n" );
-               file.puts ( "\t\t\t</div>\n" );
+               writer.end_tag ("ul");
+               writer.end_tag ("div");
        }
 
-       protected void write_navi_child_namespaces_inline_withouth_block ( GLib.FileStream file, Namespace ns, Api.Node? mself ) {
-               this.write_navi_child_namespaces_without_childs ( file, ns, mself );
-               this.write_navi_child_classes_without_childs ( file, ns, mself );
-               this.write_navi_child_interfaces_without_childs ( file, ns, mself );
-               this.write_navi_child_structs_without_childs ( file, ns, mself );
-               this.write_navi_child_enums_without_childs ( file, ns, mself );
-               this.write_navi_child_error_domains_without_childs ( file, ns, mself );
-               this.write_navi_child_delegates ( file, ns, mself );
-               this.write_navi_child_static_methods ( file, ns, mself );
-               this.write_navi_child_methods ( file, ns, mself );
-               this.write_navi_child_fields ( file, ns, mself );
-               this.write_navi_child_constants ( file, ns, mself );
+       protected void write_navi_child_namespaces_inline_withouth_block (Namespace ns, Api.Node? parent) {
+               this.write_navi_child_namespaces_without_childs (ns, parent);
+               this.write_navi_child_classes_without_childs (ns, parent);
+               this.write_navi_child_interfaces_without_childs (ns, parent);
+               this.write_navi_child_structs_without_childs (ns, parent);
+               this.write_navi_child_enums_without_childs (ns, parent);
+               this.write_navi_child_error_domains_without_childs (ns, parent);
+               this.write_navi_child_delegates (ns, parent);
+               this.write_navi_child_static_methods (ns, parent);
+               this.write_navi_child_methods (ns, parent);
+               this.write_navi_child_fields (ns, parent);
+               this.write_navi_child_constants (ns, parent);
        }
 
-       protected void write_navi_child_namespaces_inline ( GLib.FileStream file, Namespace ns, Api.Node? mself ) {
-               file.printf ( "<ul class=\"%s\">\n", css_navi );
+       protected void write_navi_child_namespaces_inline (Namespace ns, Api.Node? parent) {
+               writer.start_tag ("ul", css_navi);
 
-               if ( ns.name == null ) {
-                       this.write_navi_child_namespaces_without_childs ( file, (Package)ns.parent, ns );
+               if (ns.name == null) {
+                       this.write_navi_child_namespaces_without_childs ((Package)ns.parent, ns);
                }
 
-               this.write_navi_child_namespaces_inline_withouth_block ( file, ns, mself );
+               this.write_navi_child_namespaces_inline_withouth_block (ns, parent);
 
-               file.puts ( "</ul>\n" );
+               writer.end_tag ("ul");
        }
 
-       protected void write_navi_child_namespaces ( GLib.FileStream file, Namespace ns, Api.Node? mself ) {
-               this.write_top_elements ( file, ns, mself );
-               this.write_navi_child_namespaces_inline ( file, ns, mself );
+       protected void write_navi_child_namespaces (Namespace ns, Api.Node? parent) {
+               this.write_top_elements (ns, parent);
+               this.write_navi_child_namespaces_inline (ns, parent);
        }
 
-       protected void write_navi_struct_inline ( GLib.FileStream file, Struct stru, Api.Node? mself ) {
-               file.printf ( "<ul class=\"%s\">\n", css_navi );
-               this.write_navi_child_construction_methods ( file, stru, mself );
-               this.write_navi_child_static_methods ( file, stru, mself );
-               this.write_navi_child_methods ( file, stru, mself );
-               this.write_navi_child_fields ( file, stru, mself );
-               this.write_navi_child_constants ( file, stru, mself );
-               file.puts ( "</ul>\n" );
+       protected void write_navi_struct_inline (Struct stru, Api.Node? parent) {
+               writer.start_tag ("ul", css_navi);
+               this.write_navi_child_construction_methods (stru, parent);
+               this.write_navi_child_static_methods (stru, parent);
+               this.write_navi_child_methods (stru, parent);
+               this.write_navi_child_fields (stru, parent);
+               this.write_navi_child_constants (stru, parent);
+               writer.end_tag ("ul");
        }
 
-       protected void write_navi_struct ( GLib.FileStream file, Struct stru, Api.Node? mself ) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-               this.write_top_elements ( file, stru, mself );
-               this.write_navi_struct_inline ( file, stru, mself );
-               file.puts ( "\t\t\t</div>\n" );
+       protected void write_navi_struct (Struct stru, Api.Node? parent) {
+               writer.start_tag ("div", css_style_navigation);
+               this.write_top_elements (stru, parent);
+               this.write_navi_struct_inline (stru, parent);
+               writer.end_tag ("div");
        }
 
-       protected void write_navi_interface_inline ( GLib.FileStream file, Interface iface, Api.Node? mself ) {
-               file.printf ( "<ul class=\"%s\">\n", css_navi );
-               this.write_navi_child_static_methods ( file, iface, mself );
-               this.write_navi_child_delegates ( file, iface, mself );
-               this.write_navi_child_methods ( file, iface, mself );
-               this.write_navi_child_signals ( file, iface, mself );
-               this.write_navi_child_properties ( file, iface, mself );
-               this.write_navi_child_fields ( file, iface, mself );
-               this.write_navi_child_constants ( file, iface, mself );
-               file.puts ( "</ul>\n" );
+       protected void write_navi_interface_inline (Interface iface, Api.Node? parent) {
+               writer.start_tag ("ul", css_navi);
+               this.write_navi_child_static_methods (iface, parent);
+               this.write_navi_child_delegates (iface, parent);
+               this.write_navi_child_methods (iface, parent);
+               this.write_navi_child_signals (iface, parent);
+               this.write_navi_child_properties (iface, parent);
+               this.write_navi_child_fields (iface, parent);
+               this.write_navi_child_constants (iface, parent);
+               writer.end_tag ("ul");
        }
 
-       protected void write_navi_interface ( GLib.FileStream file, Interface iface, Api.Node? mself ) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-               this.write_top_elements ( file, iface, mself );
-               this.write_navi_interface_inline ( file, iface, mself );
-               file.puts ( "\t\t\t</div>\n" );
+       protected void write_navi_interface (Interface iface, Api.Node? parent) {
+               writer.start_tag ("div", css_style_navigation);
+               this.write_top_elements (iface, parent);
+               this.write_navi_interface_inline (iface, parent);
+               writer.end_tag ("div");
        }
 
-       protected void write_navi_enum_inline ( GLib.FileStream file, Enum en, Api.Node? mself ) {
-               Gee.Collection<Api.EnumValue> enum_values = en.get_enum_values ( );
-               file.printf ( "<ul class=\"%s\">\n", css_navi );
+       protected void write_navi_enum_inline (Enum en, Api.Node? parent) {
+               Gee.Collection<Api.EnumValue> enum_values = en.get_enum_values ();
+               writer.start_tag ("ul", css_navi);
 
-               foreach ( Api.EnumValue env in enum_values ) {
-                       this.write_navi_entry ( file, env, en, css_navi_enval, true );
+               foreach (Api.EnumValue env in enum_values) {
+                       this.write_navi_entry (env, en, css_navi_enval, true);
                }
 
-               this.write_navi_child_static_methods ( file, en, mself );
-               this.write_navi_child_methods ( file, en, mself );
-               file.puts ( "</ul>\n" );
+               this.write_navi_child_static_methods (en, parent);
+               this.write_navi_child_methods (en, parent);
+               writer.end_tag ("ul");
        }
 
-       protected void write_navi_enum ( GLib.FileStream file, Enum en, Api.Node? mself ) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-               this.write_top_elements ( file, en, mself );
-               this.write_navi_enum_inline ( file, en, mself );
-               file.puts ( "\t\t\t</div>\n" );
+       protected void write_navi_enum (Enum en, Api.Node? parent) {
+               writer.start_tag ("div", css_style_navigation);
+               this.write_top_elements (en, parent);
+               this.write_navi_enum_inline (en, parent);
+               writer.end_tag ("div");
        }
 
-       protected void write_navi_error_domain_inline ( GLib.FileStream file, ErrorDomain errdom, Api.Node? mself = null ) {
-               Gee.Collection<ErrorCode> error_codes = errdom.get_error_code_list ( );
-               file.printf ( "<ul class=\"%s\">\n", css_navi );
+       protected void write_navi_error_domain_inline (ErrorDomain errdom, Api.Node? parent = null) {
+               Gee.Collection<ErrorCode> error_codes = errdom.get_error_code_list ();
+               writer.start_tag ("ul", css_navi);
 
-               foreach ( ErrorCode ec in error_codes ) {
-                       this.write_navi_entry ( file, ec, errdom, css_navi_errdomcode, true );
+               foreach (ErrorCode ec in error_codes) {
+                       this.write_navi_entry (ec, errdom, css_navi_errdomcode, true);
                }
 
-               this.write_navi_child_static_methods ( file, errdom, mself );
-               this.write_navi_child_methods ( file, errdom, mself );
-               file.puts ( "</ul>\n" );
+               this.write_navi_child_static_methods (errdom, parent);
+               this.write_navi_child_methods (errdom, parent);
+               writer.end_tag ("ul");
        }
 
-       protected void write_navi_namespace ( GLib.FileStream file, Namespace ns ) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-               this.write_top_elements ( file, ns, ns );
-               this.write_navi_child_namespaces_inline ( file, ns, ns );
-               file.puts ( "\t\t\t</div>\n" );
+       protected void write_navi_namespace (Namespace ns) {
+               writer.start_tag ("div", css_style_navigation);
+               this.write_top_elements (ns, ns);
+               this.write_navi_child_namespaces_inline (ns, ns);
+               writer.end_tag ("div");
        }
 
-       protected void write_navi_error_domain ( GLib.FileStream file, ErrorDomain errdom, Api.Node? mself ) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-               this.write_top_elements ( file, errdom, mself );
-               this.write_navi_error_domain_inline ( file, errdom, mself );
-               file.puts ( "\t\t\t</div>\n" );
+       protected void write_navi_error_domain (ErrorDomain errdom, Api.Node? parent) {
+               writer.start_tag ("div", css_style_navigation);
+               this.write_top_elements (errdom, parent);
+               this.write_navi_error_domain_inline (errdom, parent);
+               writer.end_tag ("div");
        }
 
-       protected void write_navi_class_inline ( GLib.FileStream file, Class cl, Api.Node? mself ) {
-               file.printf ( "<ul class=\"%s\">\n", css_navi );
-               this.write_navi_child_construction_methods ( file, cl, mself );
-               this.write_navi_child_static_methods ( file, cl, mself );
-               this.write_navi_child_classes_without_childs ( file, cl, mself );
-               this.write_navi_child_structs_without_childs ( file, cl, mself );
-               this.write_navi_child_enums_without_childs ( file, cl, mself );
-               this.write_navi_child_delegates ( file, cl, mself );
-               this.write_navi_child_methods ( file, cl, mself );
-               this.write_navi_child_signals ( file, cl, mself );
-               this.write_navi_child_properties ( file, cl, mself );
-               this.write_navi_child_fields ( file, cl, mself );
-               this.write_navi_child_constants ( file, cl, mself );
-               file.puts ( "</ul>\n" );
+       protected void write_navi_class_inline (Class cl, Api.Node? parent) {
+               writer.start_tag ("ul", css_navi);
+               this.write_navi_child_construction_methods (cl, parent);
+               this.write_navi_child_static_methods (cl, parent);
+               this.write_navi_child_classes_without_childs (cl, parent);
+               this.write_navi_child_structs_without_childs (cl, parent);
+               this.write_navi_child_enums_without_childs (cl, parent);
+               this.write_navi_child_delegates (cl, parent);
+               this.write_navi_child_methods (cl, parent);
+               this.write_navi_child_signals (cl, parent);
+               this.write_navi_child_properties (cl, parent);
+               this.write_navi_child_fields (cl, parent);
+               this.write_navi_child_constants (cl, parent);
+               writer.end_tag ("ul");
        }
 
-       protected void write_navi_class ( GLib.FileStream file, Class cl, Api.Node? mself ) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-               this.write_top_elements ( file, cl, mself );
-               this.write_navi_class_inline ( file, cl, mself );
-               file.puts ( "\t\t\t</div>\n" );
+       protected void write_navi_class (Class cl, Api.Node? parent) {
+               writer.start_tag ("div", css_style_navigation);
+               this.write_top_elements (cl, parent);
+               this.write_navi_class_inline (cl, parent);
+               writer.end_tag ("div");
        }
 
-       protected void write_navi_method ( GLib.FileStream file, Method m ) {
+       protected void write_navi_method (Method m) {
                Api.Node parent = (Api.Node)m.parent;
 
-               if ( parent.name == null ) {
-                       this.write_navi_file ( file, (Package)parent.parent, m );
+               if (parent.name == null) {
+                       this.write_navi_file ((Package)parent.parent, m);
                }
                else {
-                       file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
+                       writer.start_tag ("div", css_style_navigation);
 
-                       this.write_top_elements ( file, parent, m );
+                       this.write_top_elements (parent, m);
 
-                       if ( parent is Class )
-                               this.write_navi_class_inline ( file, (Class)parent, m );
-                       else if ( m.parent is Interface )
-                               this.write_navi_interface_inline ( file, (Interface)parent, m );
-                       else if ( m.parent is Struct )
-                               this.write_navi_struct_inline ( file, (Struct)parent, m );
-                       else if ( m.parent is Enum )
-                               this.write_navi_enum_inline ( file, (Enum)parent, m );
-                       else if ( m.parent is ErrorDomain )
-                               this.write_navi_error_domain_inline ( file, (ErrorDomain)parent, m );
-                       else if ( m.parent is Namespace )
-                               this.write_navi_child_namespaces_inline ( file, (Namespace)parent, m );
+                       if (parent is Class)
+                               this.write_navi_class_inline ((Class)parent, m);
+                       else if (m.parent is Interface)
+                               this.write_navi_interface_inline ((Interface)parent, m);
+                       else if (m.parent is Struct)
+                               this.write_navi_struct_inline ((Struct)parent, m);
+                       else if (m.parent is Enum)
+                               this.write_navi_enum_inline ((Enum)parent, m);
+                       else if (m.parent is ErrorDomain)
+                               this.write_navi_error_domain_inline ((ErrorDomain)parent, m);
+                       else if (m.parent is Namespace)
+                               this.write_navi_child_namespaces_inline ((Namespace)parent, m);
 
-                       file.puts ( "\t\t\t</div>\n" );
+                       writer.end_tag ("div");
                }
        }
 
-       protected void write_navi_property ( GLib.FileStream file, Property prop ) {
+       protected void write_navi_property (Property prop) {
                Api.Node parent = (Api.Node)prop.parent;
 
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-               this.write_top_elements ( file, parent, prop );
+               writer.start_tag ("div", css_style_navigation);
+               this.write_top_elements (parent, prop);
 
-               if ( parent is Class )
-                       this.write_navi_class_inline ( file, (Class)parent, prop );
-               else if ( parent is Interface )
-                       this.write_navi_interface_inline ( file, (Interface)parent, prop );
+               if (parent is Class)
+                       this.write_navi_class_inline ((Class)parent, prop);
+               else if (parent is Interface)
+                       this.write_navi_interface_inline ((Interface)parent, prop);
 
-               file.puts ( "\t\t\t</div>\n" );
+               writer.end_tag ("div");
        }
 
-       protected void write_navi_signal ( GLib.FileStream file, Api.Signal sig ) {
+       protected void write_navi_signal (Api.Signal sig) {
                Api.Node parent = (Api.Node)sig.parent;
 
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
+               writer.start_tag ("div", css_style_navigation);
 
-               this.write_top_elements ( file, parent, sig );
+               this.write_top_elements (parent, sig);
 
-               if ( parent is Class )
-                       this.write_navi_class_inline ( file, (Class)parent, sig );
-               else if ( parent is Interface )
-                       this.write_navi_interface_inline ( file, (Interface)parent, sig );
+               if (parent is Class)
+                       this.write_navi_class_inline ((Class)parent, sig);
+               else if (parent is Interface)
+                       this.write_navi_interface_inline ((Interface)parent, sig);
 
-               file.puts ( "\t\t\t</div>\n" );
+               writer.end_tag ("div");
        }
 
-       protected void write_navi_constant ( GLib.FileStream file, Constant c ) {
+       protected void write_navi_constant (Constant c) {
                Api.Node parent = (Api.Node)c.parent;
 
-               if ( parent.name == null ) {
-                       this.write_navi_file ( file, (Package)parent.parent, c );
+               if (parent.name == null) {
+                       this.write_navi_file ((Package)parent.parent, c);
                }
                else {
-                       file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-                       this.write_top_elements ( file, parent, c );
+                       writer.start_tag ("div", css_style_navigation);
+                       this.write_top_elements (parent, c);
 
-                       if ( parent is Class )
-                               this.write_navi_class_inline ( file, (Class)parent, c );
-                       else  if ( parent is Struct )
-                               this.write_navi_struct_inline ( file, (Struct)parent, c );
-                       else  if ( parent is Namespace )
-                               this.write_navi_child_namespaces_inline ( file, (Namespace)parent, c );
-                       else if ( parent is Interface )
-                               this.write_navi_interface_inline ( file, (Interface)parent, c );
+                       if (parent is Class)
+                               this.write_navi_class_inline ((Class)parent, c);
+                       else  if (parent is Struct)
+                               this.write_navi_struct_inline ((Struct)parent, c);
+                       else  if (parent is Namespace)
+                               this.write_navi_child_namespaces_inline ((Namespace)parent, c);
+                       else if (parent is Interface)
+                               this.write_navi_interface_inline ((Interface)parent, c);
 
-                       file.puts ( "\t\t\t</div>\n" );
+                       writer.end_tag ("div");
                }
        }
 
-       protected void write_navi_field ( GLib.FileStream file, Field f ) {
+       protected void write_navi_field (Field f) {
                Api.Node parent = (Api.Node)f.parent;
 
-               if ( parent.name == null ) {
-                       this.write_navi_file ( file, (Package)parent.parent, f );
+               if (parent.name == null) {
+                       this.write_navi_file ((Package)parent.parent, f);
                }
                else {
-                       file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-                       this.write_top_elements ( file, parent, f );
+                       writer.start_tag ("div", css_style_navigation);
+                       this.write_top_elements (parent, f);
 
-                       if ( parent is Class )
-                               this.write_navi_class_inline ( file, (Class)parent, f );
-                       else if ( parent is Struct )
-                               this.write_navi_struct_inline ( file, (Struct)parent, f );
-                       else if ( parent is Namespace )
-                               this.write_navi_child_namespaces_inline ( file, (Namespace)parent, f );
-                       else if ( parent is Interface )
-                               this.write_navi_interface_inline ( file, (Interface)parent, f );
+                       if (parent is Class)
+                               this.write_navi_class_inline ((Class)parent, f);
+                       else if (parent is Struct)
+                               this.write_navi_struct_inline ((Struct)parent, f);
+                       else if (parent is Namespace)
+                               this.write_navi_child_namespaces_inline ((Namespace)parent, f);
+                       else if (parent is Interface)
+                               this.write_navi_interface_inline ((Interface)parent, f);
 
-                       file.puts ( "\t\t\t</div>\n" );
+                       writer.end_tag ("div");
                }
        }
 
-       protected void write_navi_delegate ( GLib.FileStream file, Delegate del ) {
+       protected void write_navi_delegate (Delegate del) {
                Api.Node parent = (Api.Node)del.parent;
 
-               if ( parent.name == null ) {
-                       this.write_navi_file ( file, (Package)parent.parent, del );
+               if (parent.name == null) {
+                       this.write_navi_file ((Package)parent.parent, del);
                }
                else {
-                       file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-                       this.write_top_elements ( file, parent, del );
+                       writer.start_tag ("div", css_style_navigation);
+                       this.write_top_elements (parent, del);
 
-                       if ( parent is Namespace )
-                               this.write_navi_child_namespaces_inline ( file, (Namespace)parent, del );
-                       else if ( parent is Class )
-                               this.write_navi_class_inline ( file, (Class)parent, del );
-                       else if ( parent is Interface )
-                               this.write_navi_interface_inline ( file, (Interface)parent, del );
+                       if (parent is Namespace)
+                               this.write_navi_child_namespaces_inline ((Namespace)parent, del);
+                       else if (parent is Class)
+                               this.write_navi_class_inline ((Class)parent, del);
+                       else if (parent is Interface)
+                               this.write_navi_interface_inline ((Interface)parent, del);
 
-                       file.puts ( "\t\t\t</div>\n" );
+                       writer.end_tag ("div");
                }
        }
 
-       protected void write_navi_child_methods_collection ( GLib.FileStream file, Gee.Collection<Method> methods, Api.Node? mself ) {
-               foreach ( Method m in methods ) {
-                       if ( !m.is_static ) {
+       protected void write_navi_child_methods_collection (Gee.Collection<Method> methods, Api.Node? parent) {
+               foreach (Method m in methods) {
+                       if (!m.is_static) {
                                string css;
-                               if ( m.is_virtual || m.is_override )
+                               if (m.is_virtual || m.is_override)
                                        css = css_navi_virtual_method;
-                               else if ( m.is_abstract )
+                               else if (m.is_abstract)
                                        css = css_navi_abstract_method;
                                else
                                        css = css_navi_method;
 
-                               if ( m == mself )
-                                       this.write_navi_entry ( file, m, mself, css, false );
+                               if (m == parent)
+                                       this.write_navi_entry (m, parent, css, false);
                                else
-                                       this.write_navi_entry ( file, m, mself, css, true );
+                                       this.write_navi_entry (m, parent, css, true);
                        }
                }
        }
 
-       protected void write_navi_child_construction_methods_collection ( GLib.FileStream file, Gee.Collection<Method> methods, Api.Node? mself ) {
-               foreach ( Method m in methods ) {
-                       if ( m == mself )
-                               this.write_navi_entry ( file, m, mself, css_navi_construction_method, false );
+       protected void write_navi_child_construction_methods_collection (Gee.Collection<Method> methods, Api.Node? parent) {
+               foreach (Method m in methods) {
+                       if (m == parent)
+                               this.write_navi_entry (m, parent, css_navi_construction_method, false);
                        else
-                               this.write_navi_entry ( file, m, mself, css_navi_construction_method, true );
+                               this.write_navi_entry (m, parent, css_navi_construction_method, true);
                }
        }
 
-       protected void write_navi_child_static_methods_collection ( GLib.FileStream file, Gee.Collection<Method> methods, Api.Node? mself ) {
-               foreach ( Method m in methods ) {
-                       if ( m.is_static ) {
-                               if ( m == mself )
-                                       this.write_navi_entry ( file, m, mself, css_navi_static_method, false );
+       protected void write_navi_child_static_methods_collection (Gee.Collection<Method> methods, Api.Node? parent) {
+               foreach (Method m in methods) {
+                       if (m.is_static) {
+                               if (m == parent)
+                                       this.write_navi_entry (m, parent, css_navi_static_method, false);
                                else
-                                       this.write_navi_entry ( file, m, mself, css_navi_static_method, true );
+                                       this.write_navi_entry (m, parent, css_navi_static_method, true);
                        }
                }
        }
 
-       protected void write_navi_child_methods ( GLib.FileStream file, MethodHandler mh, Api.Node? mself ) {
-               Gee.Collection<Method> methods = mh.get_method_list ( );
-               this.write_navi_child_methods_collection ( file, methods, mself );
+       protected void write_navi_child_methods (MethodHandler mh, Api.Node? parent) {
+               Gee.Collection<Method> methods = mh.get_method_list ();
+               this.write_navi_child_methods_collection (methods, parent);
        }
 
-       protected void write_navi_child_static_methods ( GLib.FileStream file, MethodHandler mh, Api.Node? mself ) {
-               Gee.Collection<Method> methods = mh.get_method_list ( );
-               this.write_navi_child_static_methods_collection ( file, methods, mself );
+       protected void write_navi_child_static_methods (MethodHandler mh, Api.Node? parent) {
+               Gee.Collection<Method> methods = mh.get_method_list ();
+               this.write_navi_child_static_methods_collection (methods, parent);
        }
 
-       protected void write_navi_child_classes_without_childs_collection ( GLib.FileStream file, Gee.Collection<Class> classes, Api.Node? mself ) {
-               foreach ( Class cl in classes ) {
-                       if ( cl == mself )
-                               this.write_navi_entry ( file, cl, mself, (cl.is_abstract)? css_navi_abstract_class : css_navi_class, false );
+       protected void write_navi_child_classes_without_childs_collection (Gee.Collection<Class> classes, Api.Node? parent) {
+               foreach (Class cl in classes) {
+                       if (cl == parent)
+                               this.write_navi_entry (cl, parent, (cl.is_abstract)? css_navi_abstract_class : css_navi_class, false);
                        else
-                               this.write_navi_entry ( file, cl, mself, (cl.is_abstract)? css_navi_abstract_class : css_navi_class, true );
+                               this.write_navi_entry (cl, parent, (cl.is_abstract)? css_navi_abstract_class : css_navi_class, true);
                }
        }
 
-       protected void write_navi_child_classes_without_childs ( GLib.FileStream file, ClassHandler clh, Api.Node? mself ) {
-               Gee.Collection<Class> classes = clh.get_class_list ( );
-               this.write_navi_child_classes_without_childs_collection ( file, classes, mself );
+       protected void write_navi_child_classes_without_childs (ClassHandler clh, Api.Node? parent) {
+               Gee.Collection<Class> classes = clh.get_class_list ();
+               this.write_navi_child_classes_without_childs_collection (classes, parent);
        }
 
-       protected void write_navi_child_construction_methods ( GLib.FileStream file, ConstructionMethodHandler cmh, Api.Node? mself ) {
-               Gee.Collection<Method> methods = cmh.get_construction_method_list ( );
-               this.write_navi_child_construction_methods_collection ( file, methods, mself );
+       protected void write_navi_child_construction_methods (ConstructionMethodHandler cmh, Api.Node? parent) {
+               Gee.Collection<Method> methods = cmh.get_construction_method_list ();
+               this.write_navi_child_construction_methods_collection (methods, parent);
        }
 
-       protected void write_navi_child_signals ( GLib.FileStream file, Api.SignalHandler sh, Api.Node? mself ) {
-               Gee.Collection<Api.Signal> signals = sh.get_signal_list ( );
+       protected void write_navi_child_signals (Api.SignalHandler sh, Api.Node? parent) {
+               Gee.Collection<Api.Signal> signals = sh.get_signal_list ();
 
-               foreach ( Api.Signal sig in signals ) {
-                       if ( sig == mself )
-                               this.write_navi_entry ( file, sig, mself, css_navi_sig, false );
+               foreach (Api.Signal sig in signals) {
+                       if (sig == parent)
+                               this.write_navi_entry (sig, parent, css_navi_sig, false);
                        else
-                               this.write_navi_entry ( file, sig, mself, css_navi_sig, true );
+                               this.write_navi_entry (sig, parent, css_navi_sig, true);
                }
        }
 
-       protected void write_navi_child_properties ( GLib.FileStream file, PropertyHandler ph, Api.Node? mself ) {
-               Gee.Collection<Property> properties = ph.get_property_list ( );
+       protected void write_navi_child_properties (PropertyHandler ph, Api.Node? parent) {
+               Gee.Collection<Property> properties = ph.get_property_list ();
 
-               foreach ( Property p in properties ) {
+               foreach (Property p in properties) {
                        string css;
-                       if ( p.is_virtual )
+                       if (p.is_virtual)
                                css = css_navi_virtual_prop;
-                       else if ( p.is_abstract )
+                       else if (p.is_abstract)
                                css = css_navi_abstract_prop;
                        else
                                css = css_navi_prop;
 
-                       if ( p == mself )
-                               this.write_navi_entry ( file, p, mself, css, false );
+                       if (p == parent)
+                               this.write_navi_entry (p, parent, css, false);
                        else
-                               this.write_navi_entry ( file, p, mself, css, true );
+                               this.write_navi_entry (p, parent, css, true);
                }
        }
 
-       protected void write_navi_child_fields_collection ( GLib.FileStream file, Gee.Collection<Field> fields, Api.Node? mself ) {
-               foreach ( Field f in fields ) {
-                       if ( f == mself )
-                               this.write_navi_entry ( file, f, mself, css_navi_field, false );
+       protected void write_navi_child_fields_collection (Gee.Collection<Field> fields, Api.Node? parent) {
+               foreach (Field f in fields) {
+                       if (f == parent)
+                               this.write_navi_entry (f, parent, css_navi_field, false);
                        else
-                               this.write_navi_entry ( file, f, mself, css_navi_field, true );
+                               this.write_navi_entry (f, parent, css_navi_field, true);
                }
        }
 
-       protected void write_navi_child_fields ( GLib.FileStream file, FieldHandler fh, Api.Node? mself ) {
-               Gee.Collection<Field> fields = fh.get_field_list ( );
-               this.write_navi_child_fields_collection ( file, fields, mself );
+       protected void write_navi_child_fields (FieldHandler fh, Api.Node? parent) {
+               Gee.Collection<Field> fields = fh.get_field_list ();
+               this.write_navi_child_fields_collection (fields, parent);
        }
 
-       protected void write_navi_child_constants_collection ( GLib.FileStream file, Gee.Collection<Constant> constants, Api.Node? mself ) {
-               foreach ( Constant c in constants ) {
-                       if ( c == mself )
-                               this.write_navi_entry ( file, c, mself, css_navi_constant, false );
+       protected void write_navi_child_constants_collection (Gee.Collection<Constant> constants, Api.Node? parent) {
+               foreach (Constant c in constants) {
+                       if (c == parent)
+                               this.write_navi_entry (c, parent, css_navi_constant, false);
                        else
-                               this.write_navi_entry ( file, c, mself, css_navi_constant, true );
+                               this.write_navi_entry (c, parent, css_navi_constant, true);
                }
        }
 
-       protected void write_navi_child_constants ( GLib.FileStream file, ConstantHandler ch, Api.Node? mself ) {
-               Gee.Collection<Constant> constants = ch.get_constant_list ( );
-               this.write_navi_child_constants_collection ( file, constants, mself );
+       protected void write_navi_child_constants (ConstantHandler ch, Api.Node? parent) {
+               Gee.Collection<Constant> constants = ch.get_constant_list ();
+               this.write_navi_child_constants_collection (constants, parent);
        }
 
-       protected void write_navi_child_structs_without_childs_collection ( GLib.FileStream file, Gee.Collection<Struct> structs, Api.Node? mself ) {
-               foreach ( Struct stru in structs ) {
-                       if ( stru == mself )
-                               this.write_navi_entry ( file, stru, mself, css_navi_struct, false );
+       protected void write_navi_child_structs_without_childs_collection (Gee.Collection<Struct> structs, Api.Node? parent) {
+               foreach (Struct stru in structs) {
+                       if (stru == parent)
+                               this.write_navi_entry (stru, parent, css_navi_struct, false);
                        else
-                               this.write_navi_entry ( file, stru, mself, css_navi_struct, true );
+                               this.write_navi_entry (stru, parent, css_navi_struct, true);
                }
        }
 
-       protected void write_navi_child_structs_without_childs ( GLib.FileStream file, StructHandler strh, Api.Node? mself ) {
-               Gee.Collection<Struct> structs = strh.get_struct_list ( );
-               this.write_navi_child_structs_without_childs_collection ( file, structs, mself );
+       protected void write_navi_child_structs_without_childs (StructHandler strh, Api.Node? parent) {
+               Gee.Collection<Struct> structs = strh.get_struct_list ();
+               this.write_navi_child_structs_without_childs_collection (structs, parent);
        }
 
-       protected void write_navi_child_delegates_collection ( GLib.FileStream file, Gee.Collection<Delegate> delegates, Api.Node? mself ) {
-               foreach ( Delegate del in delegates ) {
-                       if ( del == mself )
-                               this.write_navi_entry ( file, del, mself, css_navi_del, false );
+       protected void write_navi_child_delegates_collection (Gee.Collection<Delegate> delegates, Api.Node? parent) {
+               foreach (Delegate del in delegates) {
+                       if (del == parent)
+                               this.write_navi_entry (del, parent, css_navi_del, false);
                        else
-                               this.write_navi_entry ( file, del, mself, css_navi_del, true );
+                               this.write_navi_entry (del, parent, css_navi_del, true);
                }
        }
 
-       protected void write_navi_child_delegates ( GLib.FileStream file, DelegateHandler delh, Api.Node? mself ) {
-               Gee.Collection<Delegate> delegates = delh.get_delegate_list ( );
-               this.write_navi_child_delegates_collection ( file, delegates, mself );
+       protected void write_navi_child_delegates (DelegateHandler delh, Api.Node? parent) {
+               Gee.Collection<Delegate> delegates = delh.get_delegate_list ();
+               this.write_navi_child_delegates_collection (delegates, parent);
        }
 
-       protected void write_navi_child_interfaces_without_childs_collection ( GLib.FileStream file, Gee.Collection<Interface> interfaces, Api.Node? mself ) {
-               foreach ( Interface iface in interfaces ) {
-                       if ( iface == mself )
-                               this.write_navi_entry ( file, iface, mself, css_navi_iface, false );
+       protected void write_navi_child_interfaces_without_childs_collection (Gee.Collection<Interface> interfaces, Api.Node? parent) {
+               foreach (Interface iface in interfaces) {
+                       if (iface == parent)
+                               this.write_navi_entry (iface, parent, css_navi_iface, false);
                        else
-                               this.write_navi_entry ( file, iface, mself, css_navi_iface, true );
+                               this.write_navi_entry (iface, parent, css_navi_iface, true);
                }
        }
 
-       protected void write_navi_child_interfaces_without_childs ( GLib.FileStream file, Namespace ifh, Api.Node? mself ) {
-               Gee.Collection<Interface> interfaces = ifh.get_interface_list ( );
-               this.write_navi_child_interfaces_without_childs_collection ( file, interfaces, mself );
+       protected void write_navi_child_interfaces_without_childs (Namespace ifh, Api.Node? parent) {
+               Gee.Collection<Interface> interfaces = ifh.get_interface_list ();
+               this.write_navi_child_interfaces_without_childs_collection (interfaces, parent);
        }
 
-       protected void write_navi_child_enums_without_childs_collection ( GLib.FileStream file, Gee.Collection<Enum> enums, Api.Node? mself ) {
-               foreach ( Enum en in enums ) {
-                       if ( en == mself )
-                               this.write_navi_entry ( file, en, mself, css_navi_enum, false );
+       protected void write_navi_child_enums_without_childs_collection (Gee.Collection<Enum> enums, Api.Node? parent) {
+               foreach (Enum en in enums) {
+                       if (en == parent)
+                               this.write_navi_entry (en, parent, css_navi_enum, false);
                        else
-                               this.write_navi_entry ( file, en, mself, css_navi_enum, true );
+                               this.write_navi_entry (en, parent, css_navi_enum, true);
                }
        }
 
-       protected void write_navi_child_enums_without_childs ( GLib.FileStream file, EnumHandler eh, Api.Node? mself ) {
-               Gee.Collection<Enum> enums = eh.get_enum_list ( );
-               this.write_navi_child_enums_without_childs_collection ( file, enums, mself );
+       protected void write_navi_child_enums_without_childs (EnumHandler eh, Api.Node? parent) {
+               Gee.Collection<Enum> enums = eh.get_enum_list ();
+               this.write_navi_child_enums_without_childs_collection (enums, parent);
        }
 
-       protected void write_navi_child_error_domains_without_childs_collection ( GLib.FileStream file, Gee.Collection<ErrorDomain> errordomains, Api.Node? mself ) {
-               foreach ( ErrorDomain errdom in errordomains ) {
-                       if ( errdom == mself )
-                               this.write_navi_entry ( file, errdom, mself, css_navi_error_domain, false );
+       protected void write_navi_child_error_domains_without_childs_collection (Gee.Collection<ErrorDomain> errordomains, Api.Node? parent) {
+               foreach (ErrorDomain errdom in errordomains) {
+                       if (errdom == parent)
+                               this.write_navi_entry (errdom, parent, css_navi_error_domain, false);
                        else
-                               this.write_navi_entry ( file, errdom, mself, css_navi_error_domain, true );
+                               this.write_navi_entry (errdom, parent, css_navi_error_domain, true);
                }
        }
 
-       protected void write_navi_child_error_domains_without_childs ( GLib.FileStream file, Namespace errdomh, Api.Node? mself ) {
-               Gee.Collection<ErrorDomain> errordomains = errdomh.get_error_domain_list ( );
-               this.write_navi_child_error_domains_without_childs_collection ( file, errordomains, mself );
+       protected void write_navi_child_error_domains_without_childs (Namespace errdomh, Api.Node? parent) {
+               Gee.Collection<ErrorDomain> errordomains = errdomh.get_error_domain_list ();
+               this.write_navi_child_error_domains_without_childs_collection (errordomains, parent);
        }
 
-       protected void write_navi_child_namespaces_without_childs ( GLib.FileStream file, NamespaceHandler nsh, Api.Node? mself ) {
-               Gee.Collection<Namespace> namespaces = nsh.get_namespace_list ( );
-               foreach ( Namespace ns in namespaces ) {
-                       if ( ns.name == null )
+       protected void write_navi_child_namespaces_without_childs (NamespaceHandler nsh, Api.Node? parent) {
+               Gee.Collection<Namespace> namespaces = nsh.get_namespace_list ();
+               foreach (Namespace ns in namespaces) {
+                       if (ns.name == null)
                                continue ;
 
-                       if ( ns == mself )
-                               this.write_navi_entry ( file, ns, mself, css_navi_namespace, false );
+                       if (ns == parent)
+                               this.write_navi_entry (ns, parent, css_navi_namespace, false);
                        else
-                               this.write_navi_entry ( file, ns, mself, css_navi_namespace, true );
+                               this.write_navi_entry (ns, parent, css_navi_namespace, true);
                }
        }
 
-       protected void write_package_note ( GLib.FileStream file, Api.Node element ) {
+       protected void write_package_note (Api.Node element) {
                string package = element.package.name;
-               if ( package == null )
+               if (package == null)
                        return ;
 
-               file.printf ( "\n\n<br />\n<b>Package:</b> %s\n\n", package );
+               writer.simple_tag ("br");
+               writer.start_tag ("b").text ("Package:").end_tag ("b");
+               writer.text (package);
        }
 
-       protected void write_namespace_note ( GLib.FileStream file, Api.Node element ) {
+       protected void write_namespace_note (Api.Node element) {
                Namespace? ns = element.nspace;
-               if ( ns == null )
+               if (ns == null)
                        return ;
 
-               if ( ns.name == null )
+               if (ns.name == null)
                        return ;
 
-               file.printf ( "\n\n<br />\n<b>Namespace:</b> %s\n\n", ns.full_name() );
+               writer.simple_tag ("br");
+               writer.start_tag ("b").text ("Namespace:").end_tag ("b");
+               writer.text (ns.full_name());
        }
 
-       private void write_brief_description ( GLib.FileStream file, Api.Node element , Api.Node? pos ) {
+       private void write_brief_description (Api.Node element , Api.Node? pos) {
                Comment? doctree = element.documentation;
-               if ( doctree == null )
+               if (doctree == null)
                        return ;
 
                Gee.List<Block> description = doctree.content;
-               if ( description.size > 0 ) {
-                       file.printf ( " <span class=\"%s\">- ", css_inline_navigation_brief_description );
+               if (description.size > 0) {
+                       writer.start_tag ("span", css_inline_navigation_brief_description);
+                       writer.text (" - ");
 
                        _renderer.set_container (pos);
-                       _renderer.set_filestream (file);
                        _renderer.render_children (description.get (0));
 
-                       file.printf ( " </span>\n" );
+                       writer.end_tag ("span");
                }
        }
 
-       private void write_documentation ( GLib.FileStream file, Api.Node element , Api.Node? pos ) {
+       private void write_documentation (Api.Node element , Api.Node? pos) {
                Comment? doctree = element.documentation;
-               if ( doctree == null )
+               if (doctree == null)
                        return ;
 
                _renderer.set_container (pos);
-               _renderer.set_filestream (file);
                _renderer.render (doctree);
        }
 
-       private void write_signature ( GLib.FileStream file, Api.Node element , Api.Node? pos ) {
+       private void write_signature (Api.Node element , Api.Node? pos) {
                _renderer.set_container (pos);
-               _renderer.set_filestream (file);
                _renderer.render (element.signature);
        }
 
-       public void write_navi_packages_inline ( GLib.FileStream file, Api.Tree tree ) {
-               file.printf ( "<ul class=\"%s\">\n", css_navi );
-               foreach ( Package pkg in tree.get_package_list() ) {
+       public void write_navi_packages_inline (Api.Tree tree) {
+               writer.start_tag ("ul", css_navi);
+               foreach (Package pkg in tree.get_package_list()) {
                        if (pkg.is_visitor_accessible (settings)) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>\n", get_html_inline_navigation_link_css_class (pkg), css_navi_link, this.get_link(pkg, null), pkg.name );
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (pkg));
+                               writer.link (css_navi_link, get_link (pkg, null), pkg.name);
                                // brief description
-                               file.puts ( "</li>\n" );
+                               writer.end_tag ("li");
                        }
                        else {
-                               file.printf ( "\t<li class=\"%s\">%s</a></li>\n", get_html_inline_navigation_link_css_class (pkg), pkg.name );
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (pkg));
+                               writer.text (pkg.name);
+                               writer.end_tag ("li");
                        }
                }
-               file.puts ( "</li>\n" );
+               writer.end_tag ("li");
        }
 
-       public void write_navi_packages ( GLib.FileStream file, Api.Tree tree ) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_navigation );
-               this.write_navi_packages_inline ( file, tree );
-               file.puts ( "\t\t\t</div>\n" );
+       public void write_navi_packages (Api.Tree tree) {
+               writer.start_tag ("div", css_style_navigation);
+               this.write_navi_packages_inline (tree);
+               writer.end_tag ("div");
        }
 
-       public void write_packages_content ( GLib.FileStream file, Api.Tree tree ) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">Packages:</h1>\n", css_title );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
+       public void write_packages_content (Api.Tree tree) {
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title).text ("Packages:").end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
 
-               WikiPage? wikiindex = (tree.wikitree == null)? null : tree.wikitree.search ( "index.valadoc" );
-               if ( wikiindex != null ) {
+               WikiPage? wikiindex = (tree.wikitree == null)? null : tree.wikitree.search ("index.valadoc");
+               if (wikiindex != null) {
                        _renderer.set_container (null);
-                       _renderer.set_filestream (file);
                        _renderer.render (wikiindex.documentation);
                }
 
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Content:</h2>\n", css_title );
-               file.printf ( "\t\t\t\t<h3 class=\"%s\">Packages:</h2>\n", css_title );
-               this.write_navi_packages_inline ( file, tree );
-               file.puts ( "\t\t\t</div>\n" );
+               writer.start_tag ("h2", css_title).text ("Content:").end_tag ("h2");
+               writer.start_tag ("h3", css_title).text ("Packages:").end_tag ("h3");
+               this.write_navi_packages_inline (tree);
+               writer.end_tag ("div");
        }
 
-       public void write_method_content (GLib.FileStream file, Method m) {
-               string full_name = m.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-               file.printf ( "\t\t\t\t<div class=\"%s\">\n\t", css_code_definition );
+       public void write_method_content (Method m) {
+               string full_name = m.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (m.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+               writer.start_tag ("div", css_code_definition);
 
-               this.write_signature (file, m, m);
+               this.write_signature (m, m);
 
-               file.printf ( "\n\t\t\t\t</div>\n" );
+               writer.end_tag ("div");
 
-               this.write_documentation ( file, m, m );
+               this.write_documentation (m, m);
 
-               if ( m.parent is Namespace ) {
-                       file.puts ( "\t\t\t\t<br />\n" );
-                       this.write_namespace_note ( file, m );
-                       this.write_package_note ( file, m );
+               if (m.parent is Namespace) {
+                       writer.simple_tag ("br");
+                       this.write_namespace_note (m);
+                       this.write_package_note (m);
                }
 
-               file.puts ( "\t\t\t</div>\n" );
+               writer.end_tag ("div");
        }
 
-       public void write_child_error_values ( GLib.FileStream file, ErrorDomain errdom ) {
+       public void write_child_error_values (ErrorDomain errdom) {
                Gee.Collection<ErrorCode> error_codes = errdom.get_error_code_list ();
-               if ( error_codes.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Error Codes:</h3>\n", css_title );
-                       file.printf ( "<table class=\"%s\">\n", css_errordomain_table );
-                       foreach ( ErrorCode errcode in error_codes ) {
-                               file.puts ( "<tr>\n" );
-                               file.printf ( "\t<td class=\"%s\" id=\"%s\">%s</td>\n", css_errordomain_table_name, errcode.name, errcode.name );
-                               file.printf ( "\t<td class=\"%s\">\n", css_errordomain_table_text );
-
-                               this.write_documentation ( file, errcode, errcode );
-
-                               file.puts ( "\t</td>\n" );
-                               file.puts ( "</tr>\n" );
+               if (error_codes.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Error Codes:").end_tag ("h3");
+                       writer.start_tag ("table", css_errordomain_table);
+                       foreach (ErrorCode errcode in error_codes) {
+                               writer.start_tag ("tr");
+
+                               writer.start_tag ("td", css_errordomain_table_name, errcode.name);
+                               writer.text (errcode.name);
+                               writer.end_tag ("td");
+
+                               writer.start_tag ("td", css_errordomain_table_text);
+                               this.write_documentation (errcode, errcode);
+                               writer.end_tag ("td");
+
+                               writer.end_tag ("tr");
                        }
-                       file.puts ( "</table>\n" );
+                       writer.end_tag ("table");
                }
        }
 
-       public void write_signal_content ( GLib.FileStream file, Api.Signal sig ) {
-               string full_name = sig.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-               file.printf ( "\t\t\t\t<div class=\"%s\">\n\t", css_code_definition );
+       public void write_signal_content (Api.Signal sig) {
+               string full_name = sig.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (sig.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+               writer.start_tag ("div", css_code_definition);
 
-               this.write_signature (file, sig, sig);
+               this.write_signature (sig, sig);
 
-               file.printf ( "\n\t\t\t\t</div>\n" );
-               this.write_documentation ( file, sig, sig );
-               file.puts ( "\t\t\t</div>\n" );
+               writer.end_tag ("div");
+               this.write_documentation (sig, sig);
+               writer.end_tag ("div");
        }
 
-       public void write_delegate_content ( GLib.FileStream file, Delegate del ) {
-               string full_name = del.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-               file.printf ( "\t\t\t\t<div class=\"%s\">\n\t", css_code_definition );
+       public void write_delegate_content (Delegate del) {
+               string full_name = del.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (del.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+               writer.start_tag ("div", css_code_definition);
 
-               this.write_signature (file, del, del);
+               this.write_signature (del, del);
 
-               file.printf ( "\n\t\t\t\t</div>\n" );
+               writer.end_tag ("div");
 
-               this.write_documentation ( file, del, del );
+               this.write_documentation (del, del);
 
-               if ( del.parent is Namespace ) {
-                       file.puts ( "\t\t\t\t<br />\n" );
-                       this.write_namespace_note ( file, del );
-                       this.write_package_note ( file, del );
+               if (del.parent is Namespace) {
+                       writer.simple_tag ("br");
+                       this.write_namespace_note (del);
+                       this.write_package_note (del);
                }
 
-               file.puts ( "\t\t\t</div>\n" );
+               writer.end_tag ("div");
        }
 
-       public void write_field_content (GLib.FileStream file, Field field) {
-               string full_name = field.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-               file.printf ( "\t\t\t\t<div class=\"%s\">\n\t", css_code_definition );
+       public void write_field_content (Field field) {
+               string full_name = field.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (field.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+               writer.start_tag ("div", css_code_definition);
 
-               this.write_signature (file, field, field);
+               this.write_signature (field, field);
 
-               file.printf ( "\n\t\t\t\t</div>\n" );
+               writer.end_tag ("div");
 
-               this.write_documentation ( file, field, field );
+               this.write_documentation (field, field);
 
-               if ( field.parent is Namespace ) {
-                       file.puts ( "\t\t\t\t<br />\n" );
-                       this.write_namespace_note ( file, field );
-                       this.write_package_note ( file, field );
+               if (field.parent is Namespace) {
+                       writer.simple_tag ("br");
+                       this.write_namespace_note (field);
+                       this.write_package_note (field);
                }
 
-               file.puts ( "\t\t\t</div>\n" );
+               writer.end_tag ("div");
        }
 
-       public void write_constant_content (GLib.FileStream file, Constant constant) {
-               string full_name = constant.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-               file.printf ( "\t\t\t\t<div class=\"%s\">\n\t", css_code_definition );
+       public void write_constant_content (Constant constant) {
+               string full_name = constant.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (constant.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+               writer.start_tag ("div", css_code_definition);
 
-               this.write_signature (file, constant, constant);
+               this.write_signature (constant, constant);
 
-               file.printf ( "\n\t\t\t\t</div>\n" );
+               writer.end_tag ("div");
 
-               this.write_documentation ( file, constant, constant );
+               this.write_documentation (constant, constant);
 
-               if ( constant.parent is Namespace ) {
-                       file.puts ( "\t\t\t\t<br />\n" );
-                       this.write_namespace_note ( file, constant );
-                       this.write_package_note ( file, constant );
+               if (constant.parent is Namespace) {
+                       writer.simple_tag ("br");
+                       this.write_namespace_note (constant);
+                       this.write_package_note (constant);
                }
 
-               file.puts ( "\t\t\t</div>\n" );
+               writer.end_tag ("div");
        }
 
-       public void write_property_content ( GLib.FileStream file, Property prop ) {
-               string full_name = prop.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-               file.printf ( "\t\t\t\t<div class=\"%s\">\n\t", css_code_definition );
+       public void write_property_content (Property prop) {
+               string full_name = prop.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (prop.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+               writer.start_tag ("div", css_code_definition);
 
-               this.write_signature (file, prop, prop);
+               this.write_signature (prop, prop);
 
-               file.printf ( "\n\t\t\t\t</div>\n" );
-               this.write_documentation ( file, prop, prop );
-               file.puts ( "\t\t\t</div>\n" );
+               writer.end_tag ("div");
+               this.write_documentation (prop, prop);
+               writer.end_tag ("div");
        }
 
-       public void write_enum_content ( GLib.FileStream file, Enum en, Api.Node? mself ) {
-               string full_name = en.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
+       public void write_enum_content (Enum en, Api.Node? parent) {
+               string full_name = en.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (en.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
 
-               this.write_documentation ( file, en, en );
+               this.write_documentation (en, en);
 
-               if ( en.parent is Namespace ) {
-                       file.puts ( "\t\t\t\t<br />\n" );
-                       this.write_namespace_note ( file, en );
-                       this.write_package_note ( file, en );
+               if (en.parent is Namespace) {
+                       writer.simple_tag ("br");
+                       this.write_namespace_note (en);
+                       this.write_package_note (en);
                }
 
-               file.printf ( "\n\t\t\t\t<h2 class=\"%s\">Content:</h2>\n", css_title );
-               this.write_child_enum_values ( file, en );
-               this.write_child_static_methods ( file, en, mself );
-               this.write_child_methods ( file, en, mself );
-               file.puts ( "\t\t\t</div>\n" );
+               writer.start_tag ("h2", css_title).text ("Content:").end_tag ("h2");
+               this.write_child_enum_values (en);
+               this.write_child_static_methods (en, parent);
+               this.write_child_methods (en, parent);
+               writer.end_tag ("div");
        }
 
-       private void write_child_enum_values ( GLib.FileStream file, Enum en ) {
+       private void write_child_enum_values (Enum en) {
                Gee.Collection<Api.EnumValue> enum_values = en.get_enum_values ();
-               if ( enum_values.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Enum Values:</h3>\n", css_title );
-                       file.printf ( "<table class=\"%s\">\n", css_enum_table );
-                       foreach ( Api.EnumValue enval in enum_values ) {
-                               file.puts ( "<tr>\n" );
-                               file.printf ( "\t<td class=\"%s\" id=\"%s\">%s</td>\n", css_enum_table_name, enval.name, enval.name );
-                               file.printf ( "\t<td class=\"%s\">\n", css_enum_table_text );
-
-                               this.write_documentation ( file, enval, en );
-
-                               file.puts ( "\t</td>\n" );
-                               file.puts ( "</tr>\n" );
+               if (enum_values.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Enum Values:").end_tag ("h3");
+                       writer.start_tag ("table", css_enum_table);
+                       foreach (Api.EnumValue enval in enum_values) {
+                               writer.start_tag ("tr");
+
+                               writer.start_tag ("td", css_enum_table_name, enval.name);
+                               writer.text (enval.name);
+                               writer.end_tag ("td");
+
+                               writer.start_tag ("td", css_enum_table_text);
+                               this.write_documentation (enval, en);
+                               writer.end_tag ("td");
+
+                               writer.end_tag ("tr");
                        }
-                       file.puts ( "</table>\n" );
+                       writer.end_tag ("table");
                }
        }
 
-       protected void write_child_namespaces ( GLib.FileStream file, NamespaceHandler nh, Api.Node? mself ) {
+       protected void write_child_namespaces (NamespaceHandler nh, Api.Node? parent) {
                Gee.ArrayList<Namespace> nsl = new Gee.ArrayList<Namespace> ();
-               this.fetch_subnamespace_names ( nh, nsl );
+               this.fetch_subnamespace_names (nh, nsl);
 
-               if ( nsl.size == 0 )
+               if (nsl.size == 0)
                        return ;
 
-               if ( nsl.size == 1 ) {
-                       if ( nsl.get(0).name == null )
+               if (nsl.size == 1) {
+                       if (nsl.get(0).name == null)
                                return ;
                }
 
-               bool with_childs = (mself == null)? false : mself is Package;
+               bool with_childs = (parent == null)? false : parent is Package;
 
-               file.printf ("<h3 class=\"%s\">Namespaces:</h3>\n", css_title);
-               file.printf ("<ul class=\"%s\">\n", css_inline_navigation);
+               writer.start_tag ("h3", css_title).text ("Namespaces:").end_tag ("h3");
+               writer.start_tag ("ul", css_inline_navigation);
                foreach (Namespace ns in nsl) {
                        if (ns.name != null) {
-                               file.printf ("\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>\n", css_inline_navigation_namespace, css_navi_link, this.get_link(ns, mself), ns.name);
-                               this.write_brief_description (file, ns , mself);
-                               file.printf ("</li>\n");
+                               writer.start_tag ("li", css_inline_navigation_namespace);
+                               writer.link (css_navi_link, get_link (ns, parent), ns.name);
+                               this.write_brief_description (ns , parent);
+                               writer.end_tag ("li");
                                if (with_childs == true) {
-                                       this.write_child_classes (file, ns, mself);
-                                       this.write_child_interfaces (file, ns, mself);
-                                       this.write_child_structs (file, ns, mself);
-                                       this.write_child_enums (file, ns, mself);
-                                       this.write_child_errordomains (file, ns, mself);
-                                       this.write_child_delegates (file, ns, mself);
-                                       this.write_child_methods (file, ns, mself);
-                                       this.write_child_fields (file, ns, mself);
-                                       this.write_child_constants (file, ns, mself);
+                                       this.write_child_classes (ns, parent);
+                                       this.write_child_interfaces (ns, parent);
+                                       this.write_child_structs (ns, parent);
+                                       this.write_child_enums (ns, parent);
+                                       this.write_child_errordomains (ns, parent);
+                                       this.write_child_delegates (ns, parent);
+                                       this.write_child_methods (ns, parent);
+                                       this.write_child_fields (ns, parent);
+                                       this.write_child_constants (ns, parent);
                                }
                        }
                }
-               file.puts ( "</ul>\n" );
+               writer.end_tag ("ul");
        }
 
-       protected void write_child_methods ( GLib.FileStream file, MethodHandler mh, Api.Node? mself ) {
+       protected void write_child_methods (MethodHandler mh, Api.Node? parent) {
                Gee.Collection<Method> methods = mh.get_method_list ();
-               Gee.ArrayList<Method> imethods = new Gee.ArrayList<Method> ( );
-               foreach ( Method m in methods ) {
-                       if ( !m.is_static )
-                               imethods.add ( m );
-               }
-
-               if ( imethods.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Methods:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Method m in imethods ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (m), css_navi_link, this.get_link(m, mself), m.name );
-                               this.write_brief_description ( file, m , mself );
-                               file.printf ( "</li>\n" );
+               Gee.ArrayList<Method> imethods = new Gee.ArrayList<Method> ();
+               foreach (Method m in methods) {
+                       if (!m.is_static)
+                               imethods.add (m);
+               }
+
+               if (imethods.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Methods:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Method m in imethods) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (m));
+                               writer.link (css_navi_link, get_link (m, parent), m.name);
+                               this.write_brief_description (m , parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_dependencies ( GLib.FileStream file, Package package, Api.Node? mself ) {
+       protected void write_child_dependencies (Package package, Api.Node? parent) {
                Gee.Collection<Package> deps = package.get_full_dependency_list ();
-               if ( deps.size == 0 )
+               if (deps.size == 0)
                        return ;
 
-               file.printf ( "<h2 class=\"%s\">Dependencies:</h2>\n", css_title );
-               file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-               foreach ( Package p in deps ) {
-                       string link = this.get_link(p, mself);
-                       if ( link == null )
-                               file.printf ( "\t<li class=\"%s\">%s</li>\n", css_inline_navigation_package, p.name );
-                       else
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a></li>\n", css_inline_navigation_package, css_navi_link, link, p.name );
+               writer.start_tag ("h2", css_title).text ("Dependencies:").end_tag ("h2");
+               writer.start_tag ("ul", css_inline_navigation);
+               foreach (Package p in deps) {
+                       string link = this.get_link(p, parent);
+                       if (link == null)
+                               writer.start_tag ("li", css_inline_navigation_package, p.name).text (p.name).end_tag ("li");
+                       else {
+                               writer.start_tag ("li", css_inline_navigation_package);
+                               writer.link (css_navi_link, get_link (p, parent), p.name);
+                               writer.end_tag ("li");
+                       }
                }
-               file.puts ( "</ul>\n" );
+               writer.end_tag ("ul");
        }
 
-       protected void write_child_static_methods ( GLib.FileStream file, MethodHandler mh, Api.Node? mself ) {
+       protected void write_child_static_methods (MethodHandler mh, Api.Node? parent) {
                Gee.Collection<Method> methods = mh.get_method_list ();
 
-               Gee.ArrayList<Method> static_methods = new Gee.ArrayList<Method> ( );
-               foreach ( Method m in methods ) {
-                       if ( m.is_static )
-                               static_methods.add ( m );
+               Gee.ArrayList<Method> static_methods = new Gee.ArrayList<Method> ();
+               foreach (Method m in methods) {
+                       if (m.is_static)
+                               static_methods.add (m);
                }
 
-               if ( static_methods.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Static Methods:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Method m in static_methods ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (m), css_navi_link, this.get_link(m, mself), m.name );
-                               this.write_brief_description ( file, m , mself );
-                               file.printf ( "</li>\n" );
+               if (static_methods.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Static Methods:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Method m in static_methods) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (m));
+                               writer.link (css_navi_link, get_link (m, parent), m.name);
+                               this.write_brief_description (m , parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       public void write_class_content ( GLib.FileStream file, Class cl, Api.Node? mself ) {
-               string full_name = cl.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               this.write_image_block ( file, cl );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-               file.printf ( "\t\t\t\t<div class=\"%s\">\n\t", css_code_definition );
+       public void write_class_content (Class cl, Api.Node? parent) {
+               string full_name = cl.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (cl.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               this.write_image_block (cl);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+               writer.start_tag ("div", css_code_definition);
 
-               this.write_signature (file, cl, cl);
+               this.write_signature (cl, cl);
 
-               file.printf ( "\n\t\t\t\t</div>\n" );
+               writer.end_tag ("div");
 
-               this.write_documentation ( file, cl, cl );
+               this.write_documentation (cl, cl);
 
-               if ( cl.parent is Namespace ) {
-                       file.puts ( "\t\t\t\t<br />\n" );
-                       this.write_namespace_note ( file, cl );
-                       this.write_package_note ( file, cl );
+               if (cl.parent is Namespace) {
+                       writer.simple_tag ("br");
+                       this.write_namespace_note (cl);
+                       this.write_package_note (cl);
                }
-               file.printf ( "\n\t\t\t\t<h2 class=\"%s\">Content:</h2>\n", css_title );
-               this.write_child_construction_methods ( file, cl, mself );
-               this.write_child_static_methods ( file, cl, mself );
-               this.write_child_classes ( file, cl, mself );
-               this.write_child_structs ( file, cl, mself );
-               this.write_child_enums ( file, cl, mself );
-               this.write_child_delegates ( file, cl, mself );
-               this.write_child_methods ( file, cl, mself );
-               this.write_child_signals ( file, cl, mself );
-               this.write_child_properties ( file, cl, mself );
-               this.write_child_fields ( file, cl, mself );
-               this.write_child_constants ( file, cl, mself );
-               file.puts ( "\t\t\t</div>\n" );
+               writer.start_tag ("h2", css_title).text ("Content:").end_tag ("h2");
+               this.write_child_construction_methods (cl, parent);
+               this.write_child_static_methods (cl, parent);
+               this.write_child_classes (cl, parent);
+               this.write_child_structs (cl, parent);
+               this.write_child_enums (cl, parent);
+               this.write_child_delegates (cl, parent);
+               this.write_child_methods (cl, parent);
+               this.write_child_signals (cl, parent);
+               this.write_child_properties (cl, parent);
+               this.write_child_fields (cl, parent);
+               this.write_child_constants (cl, parent);
+               writer.end_tag ("div");
        }
 
-       public void write_interface_content ( GLib.FileStream file, Interface iface, Api.Node? mself ) {
+       public void write_interface_content (Interface iface, Api.Node? parent) {
                string full_name = iface.full_name ();
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               this.write_image_block ( file, iface );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-               file.printf ( "\t\t\t\t<div class=\"%s\">\n\t", css_code_definition );
-
-               this.write_signature (file, iface, iface);
-
-               file.printf ( "\n\t\t\t\t</div>\n" );
-
-               this.write_documentation ( file, iface, iface );
-
-               if ( iface.parent is Namespace ) {
-                       file.puts ( "\t\t\t\t<br />\n" );
-                       this.write_namespace_note ( file, iface );
-                       this.write_package_note ( file, iface );
-               }
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Content:</h2>\n", css_title );
-               this.write_child_static_methods ( file, iface, mself );
-               this.write_child_classes ( file, iface, mself );
-               this.write_child_structs ( file, iface, mself );
-               this.write_child_enums ( file, iface, mself );
-               this.write_child_delegates ( file, iface, mself );
-               this.write_child_methods ( file, iface, mself );
-               this.write_child_signals ( file, iface, mself );
-               this.write_child_properties ( file, iface, mself );
-               this.write_child_fields ( file, iface, mself );
-               this.write_child_constants ( file, iface, mself );
-               file.puts ( "\t\t\t</div>\n" );
-       }
-
-       public void write_error_domain_content ( GLib.FileStream file, ErrorDomain errdom, Api.Node? mself ) {
-               string full_name = errdom.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-
-               this.write_documentation ( file, errdom, errdom );
-
-               if ( errdom.parent is Namespace ) {
-                       file.puts ( "\t\t\t\t<br />\n" );
-                       this.write_namespace_note ( file, errdom );
-                       this.write_package_note ( file, errdom );
-               }
-               file.printf ( "\n\t\t\t\t<h2 class=\"%s\">Content:</h2>\n", css_title );
-               this.write_child_error_values ( file, errdom );
-               this.write_child_static_methods ( file, errdom, mself );
-               this.write_child_methods ( file, errdom, mself );
-               file.puts ( "\t\t\t</div>\n" );
-       }
-
-       public void write_struct_content ( GLib.FileStream file, Struct stru, Api.Node? mself ) {
-               string full_name = stru.full_name ( );
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, full_name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               this.write_image_block ( file, stru );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
-
-               file.printf ( "\t\t\t\t<div class=\"%s\">\n\t", css_code_definition );
-
-               this.write_signature (file, stru, stru);
-
-               file.printf ( "\n\t\t\t\t</div>\n" );
-
-               this.write_documentation ( file, stru, stru );
-
-               if ( stru.parent is Namespace ) {
-                       file.puts ( "\t\t\t\t<br />\n" );
-                       this.write_namespace_note ( file, stru );
-                       this.write_package_note ( file, stru );
-               }
-               file.printf ( "\n\t\t\t\t<h2 class=\"%s\">Content:</h2>\n", css_title );
-               this.write_child_construction_methods ( file, stru, mself );
-               this.write_child_static_methods ( file, stru, mself );
-               this.write_child_methods ( file, stru, mself );
-               this.write_child_fields ( file, stru, mself );
-               this.write_child_constants ( file, stru, mself );
-               file.puts ( "\t\t\t</div>\n" );
-       }
-
-       protected string get_img_path ( Api.Node element ) {
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (iface.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               this.write_image_block (iface);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+               writer.start_tag ("div", css_code_definition);
+
+               this.write_signature (iface, iface);
+
+               writer.end_tag ("div");
+
+               this.write_documentation (iface, iface);
+
+               if (iface.parent is Namespace) {
+                       writer.simple_tag ("br");
+                       this.write_namespace_note (iface);
+                       this.write_package_note (iface);
+               }
+               writer.start_tag ("h2", css_title).text ("Content:").end_tag ("h2");
+               this.write_child_static_methods (iface, parent);
+               this.write_child_classes (iface, parent);
+               this.write_child_structs (iface, parent);
+               this.write_child_enums (iface, parent);
+               this.write_child_delegates (iface, parent);
+               this.write_child_methods (iface, parent);
+               this.write_child_signals (iface, parent);
+               this.write_child_properties (iface, parent);
+               this.write_child_fields (iface, parent);
+               this.write_child_constants (iface, parent);
+               writer.end_tag ("div");
+       }
+
+       public void write_error_domain_content (ErrorDomain errdom, Api.Node? parent) {
+               string full_name = errdom.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (errdom.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+
+               this.write_documentation (errdom, errdom);
+
+               if (errdom.parent is Namespace) {
+                       writer.simple_tag ("br");
+                       this.write_namespace_note (errdom);
+                       this.write_package_note (errdom);
+               }
+               writer.start_tag ("h2", css_title).text ("Content:").end_tag ("h2");
+               this.write_child_error_values (errdom);
+               this.write_child_static_methods (errdom, parent);
+               this.write_child_methods (errdom, parent);
+               writer.end_tag ("div");
+       }
+
+       public void write_struct_content (Struct stru, Api.Node? parent) {
+               string full_name = stru.full_name ();
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, full_name).text (stru.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               this.write_image_block (stru);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+
+               writer.start_tag ("div", css_code_definition);
+
+               this.write_signature (stru, stru);
+
+               writer.end_tag ("div");
+
+               this.write_documentation (stru, stru);
+
+               if (stru.parent is Namespace) {
+                       writer.simple_tag ("br");
+                       this.write_namespace_note (stru);
+                       this.write_package_note (stru);
+               }
+               writer.start_tag ("h2", css_title).text ("Content:").end_tag ("h2");
+               this.write_child_construction_methods (stru, parent);
+               this.write_child_static_methods (stru, parent);
+               this.write_child_methods (stru, parent);
+               this.write_child_fields (stru, parent);
+               this.write_child_constants (stru, parent);
+               writer.end_tag ("div");
+       }
+
+       protected string get_img_path (Api.Node element) {
                return "img/" + element.full_name () + ".png";
        }
 
-       protected string get_img_real_path ( Api.Node element ) {
+       protected string get_img_real_path (Api.Node element) {
                return this.settings.path + "/" + element.package.name + "/" + "img/" + element.full_name () + ".png";
        }
 
-       protected void write_child_constants ( GLib.FileStream file, ConstantHandler ch, Api.Node? mself ) {
+       protected void write_child_constants (ConstantHandler ch, Api.Node? parent) {
                Gee.Collection<Constant> constants = ch.get_constant_list ();
-               if ( constants.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Constants:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Constant c in constants ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (c), css_navi_link, this.get_link(c, mself), c.name );
-                               this.write_brief_description ( file, c, mself );
-                               file.printf ( "</li>\n" );
+               if (constants.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Constants:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Constant c in constants) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (c));
+                               writer.link (css_navi_link, get_link (c, parent), c.name);
+                               this.write_brief_description (c, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_enums ( GLib.FileStream file, EnumHandler eh, Api.Node? mself ) {
+       protected void write_child_enums (EnumHandler eh, Api.Node? parent) {
                Gee.Collection<Enum> enums = eh.get_enum_list ();
-               if ( enums.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Enums:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Enum en in enums ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>\n", get_html_inline_navigation_link_css_class (en), css_navi_link, this.get_link(en, mself), en.name );
-                               this.write_brief_description ( file, en, mself );
-                               file.printf ( "</li>\n" );
+               if (enums.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Enums:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Enum en in enums) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (en));
+                               writer.link (css_navi_link, get_link (en, parent), en.name);
+                               this.write_brief_description (en, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_errordomains ( GLib.FileStream file, ErrorDomainHandler eh, Api.Node? mself ) {
+       protected void write_child_errordomains (ErrorDomainHandler eh, Api.Node? parent) {
                Gee.Collection<ErrorDomain> errdoms = eh.get_error_domain_list ();
-               if ( errdoms.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Errordomains:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( ErrorDomain err in errdoms ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (err), css_navi_link,  this.get_link(err, mself), err.name );
-                               this.write_brief_description ( file, err, mself );
-                               file.printf ( "</li>\n" );
+               if (errdoms.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Errordomains:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (ErrorDomain err in errdoms) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (err));
+                               writer.link (css_navi_link, get_link (err, parent), err.name);
+                               this.write_brief_description (err, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_construction_methods ( GLib.FileStream file, ConstructionMethodHandler cmh, Api.Node? mself ) {
+       protected void write_child_construction_methods (ConstructionMethodHandler cmh, Api.Node? parent) {
                Gee.Collection<Method> methods = cmh.get_construction_method_list ();
-               if ( methods.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Construction Methods:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Method m in methods ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (m), css_navi_link, this.get_link(m, mself), m.name );
-                               this.write_brief_description ( file, m, mself );
-                               file.printf ( "</li>\n" );
+               if (methods.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Construction Methods:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Method m in methods) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (m));
+                               writer.link (css_navi_link, get_link (m, parent), m.name);
+                               this.write_brief_description (m, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_image_block ( GLib.FileStream file, Api.Node element ) {
-               string realimgpath = this.get_img_real_path ( element );
-               string imgpath = this.get_img_path ( element );
+       protected void write_image_block (Api.Node element) {
+               string realimgpath = this.get_img_real_path (element);
+               string imgpath = this.get_img_path (element);
 
-               if ( element is Class ) {
-                       Diagrams.write_class_diagram ( (Class)element, realimgpath );
+               if (element is Class) {
+                       Diagrams.write_class_diagram ((Class)element, realimgpath);
                }
-               else if ( element is Interface ) {
-                       Diagrams.write_interface_diagram ( (Interface)element, realimgpath );
+               else if (element is Interface) {
+                       Diagrams.write_interface_diagram ((Interface)element, realimgpath);
                }
-               else if ( element is Struct ) {
-                       Diagrams.write_struct_diagram ( (Struct)element, realimgpath );
+               else if (element is Struct) {
+                       Diagrams.write_struct_diagram ((Struct)element, realimgpath);
                }
 
-               file.printf ( "<h2 cass=\"%s\">Object Hierarchy:</h2>\n", css_title );
-               file.printf ( "<img cass=\"%s\" src=\"%s\"/>\n", css_diagram, imgpath );
+               writer.start_tag ("h2", css_title).text ("Object Hierarchy:").end_tag ("h2");
+               writer.image (css_diagram, imgpath);
        }
 
-       protected void write_child_fields ( GLib.FileStream file, FieldHandler fh, Api.Node? mself ) {
+       protected void write_child_fields (FieldHandler fh, Api.Node? parent) {
                Gee.Collection<Field> fields = fh.get_field_list ();
-               if ( fields.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Fields:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Field f in fields ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class(f), css_navi_link, this.get_link(f, mself), f.name );
-                               this.write_brief_description ( file, f, mself );
-                               file.printf ( "</li>\n" );
+               if (fields.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Fields:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Field f in fields) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class(f));
+                               writer.link (css_navi_link, get_link (f, parent), f.name);
+                               this.write_brief_description (f, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_properties ( GLib.FileStream file, PropertyHandler ph, Api.Node? mself ) {
+       protected void write_child_properties (PropertyHandler ph, Api.Node? parent) {
                Gee.Collection<Property> properties = ph.get_property_list ();
-               if ( properties.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Properties:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Property prop in properties ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (prop), css_navi_link, this.get_link(prop, mself), prop.name );
-                               this.write_brief_description ( file, prop, mself );
-                               file.printf ( "</li>\n" );
+               if (properties.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Properties:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Property prop in properties) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (prop));
+                               writer.link (css_navi_link, get_link (prop, parent), prop.name);
+                               this.write_brief_description (prop, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_signals ( GLib.FileStream file, Api.SignalHandler sh, Api.Node? mself ) {
+       protected void write_child_signals (Api.SignalHandler sh, Api.Node? parent) {
                Gee.Collection<Api.Signal> signals = sh.get_signal_list ();
-               if ( signals.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Api.Signals:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Api.Signal sig in signals ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (sig), css_navi_link, this.get_link(sig, mself), sig.name );
-                               this.write_brief_description ( file, sig, mself );
-                               file.printf ( "</li>\n" );
+               if (signals.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Api.Signals:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Api.Signal sig in signals) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (sig));
+                               writer.link (css_navi_link, get_link (sig, parent), sig.name);
+                               this.write_brief_description (sig, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_classes ( GLib.FileStream file, ClassHandler clh, Api.Node? mself ) {
+       protected void write_child_classes (ClassHandler clh, Api.Node? parent) {
                Gee.Collection<Class> classes = clh.get_class_list ();
-               if ( classes.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Classes:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Class subcl in classes ) {
+               if (classes.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Classes:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Class subcl in classes) {
                                string name;
-                               if ( subcl.is_abstract ) {
+                               if (subcl.is_abstract) {
                                        name = "<i>" + subcl.name + "</i>";
                                }
                                else {
                                        name = subcl.name;
                                }
 
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (subcl), css_navi_link, this.get_link(subcl, mself ), name );
-                               this.write_brief_description ( file, subcl, mself );
-                               file.printf ( "</li>\n" );
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (subcl));
+                               writer.link (css_navi_link, get_link (subcl, parent), name);
+                               this.write_brief_description (subcl, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_interfaces ( GLib.FileStream file, InterfaceHandler ih, Api.Node? mself ) {
-               Gee.Collection<Interface> ifaces = ih.get_interface_list ( );
-               if ( ifaces.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Interfaces:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Interface iface in ifaces ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (iface), css_navi_link, this.get_link(iface, mself), iface.name );
-                               this.write_brief_description ( file, iface, mself );
-                               file.printf ( "</li>\n" );
+       protected void write_child_interfaces (InterfaceHandler ih, Api.Node? parent) {
+               Gee.Collection<Interface> ifaces = ih.get_interface_list ();
+               if (ifaces.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Interfaces:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Interface iface in ifaces) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (iface));
+                               writer.link (css_navi_link, get_link (iface, parent), iface.name);
+                               this.write_brief_description (iface, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_delegates ( GLib.FileStream file, DelegateHandler dh, Api.Node? mself ) {
+       protected void write_child_delegates (DelegateHandler dh, Api.Node? parent) {
                Gee.Collection<Delegate> delegates = dh.get_delegate_list ();
-               if ( delegates.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Delegates:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Delegate d in delegates ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class (d), css_navi_link, this.get_link(d, mself), d.name );
-                               this.write_brief_description ( file, d, mself );
-                               file.printf ( "</li>\n" );
+               if (delegates.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Delegates:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Delegate d in delegates) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (d));
+                               writer.link (css_navi_link, get_link (d, parent), d.name);
+                               this.write_brief_description (d, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       protected void write_child_structs ( GLib.FileStream file, StructHandler struh, Api.Node? mself ) {
+       protected void write_child_structs (StructHandler struh, Api.Node? parent) {
                Gee.Collection<Struct> structs = struh.get_struct_list ();
-               if ( structs.size > 0 ) {
-                       file.printf ( "<h3 class=\"%s\">Structs:</h3>\n", css_title );
-                       file.printf ( "<ul class=\"%s\">\n", css_inline_navigation );
-                       foreach ( Struct stru in structs ) {
-                               file.printf ( "\t<li class=\"%s\"><a class=\"%s\" href=\"%s\">%s</a>", get_html_inline_navigation_link_css_class ( stru ), css_navi_link, this.get_link(stru, mself), stru.name );
-                               this.write_brief_description ( file, stru, mself );
-                               file.printf ( "</li>\n" );
+               if (structs.size > 0) {
+                       writer.start_tag ("h3", css_title).text ("Structs:").end_tag ("h3");
+                       writer.start_tag ("ul", css_inline_navigation);
+                       foreach (Struct stru in structs) {
+                               writer.start_tag ("li", get_html_inline_navigation_link_css_class (stru));
+                               writer.link (css_navi_link, get_link (stru, parent), stru.name);
+                               this.write_brief_description (stru, parent);
+                               writer.end_tag ("li");
                        }
-                       file.puts ( "</ul>\n" );
+                       writer.end_tag ("ul");
                }
        }
 
-       public void write_namespace_content ( GLib.FileStream file, Namespace ns, Api.Node? mself ) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, (ns.name == null)? "Global Namespace" : ns.full_name () );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
+       public void write_namespace_content (Namespace ns, Api.Node? parent) {
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title).text (ns.name == null ? "Global Namespace" : ns.full_name ()).end_tag ("h1");
+               writer.simple_tag ("hr", css_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
+
+               this.write_documentation (ns, ns);
 
-               this.write_documentation ( file, ns, ns );
+               writer.start_tag ("h2", css_title).text ("Content:").end_tag ("h2");
 
-               file.printf ( "\n\t\t\t\t<h2 class=\"%s\">Content:</h2>\n", css_title );
-               if ( ns.name == null )
-                       this.write_child_namespaces ( file, (Package)ns.parent, mself );
+               if (ns.name == null)
+                       this.write_child_namespaces ((Package)ns.parent, parent);
                else
-                       this.write_child_namespaces ( file, ns, mself );
-
-               this.write_child_classes ( file, ns, mself );
-               this.write_child_interfaces ( file, ns, mself );
-               this.write_child_structs ( file, ns, mself );
-               this.write_child_enums ( file, ns, mself );
-               this.write_child_errordomains ( file, ns, mself );
-               this.write_child_delegates ( file, ns, mself );
-               this.write_child_methods ( file, ns, mself );
-               this.write_child_fields ( file, ns, mself );
-               this.write_child_constants ( file, ns, mself );
-               file.puts ( "\t\t\t</div>\n" );
-       }
-
-       protected void write_file_content ( GLib.FileStream file, Package f, Api.Node? mself, WikiPage? wikipage = null) {
-               file.printf ( "\t\t\t<div class=\"%s\">\n", css_style_content );
-               file.printf ( "\t\t\t\t<h1 class=\"%s\">%s:</h1>\n", css_title, f.name );
-               file.printf ( "\t\t\t\t<hr class=\"%s\" />\n", css_headline_hr );
-               file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
+                       this.write_child_namespaces (ns, parent);
+
+               this.write_child_classes (ns, parent);
+               this.write_child_interfaces (ns, parent);
+               this.write_child_structs (ns, parent);
+               this.write_child_enums (ns, parent);
+               this.write_child_errordomains (ns, parent);
+               this.write_child_delegates (ns, parent);
+               this.write_child_methods (ns, parent);
+               this.write_child_fields (ns, parent);
+               this.write_child_constants (ns, parent);
+               writer.end_tag ("div");
+       }
+
+       protected void write_file_content (Package f, Api.Node? parent, WikiPage? wikipage = null) {
+               writer.start_tag ("div", css_style_content);
+               writer.start_tag ("h1", css_title, f.name).text (f.name).end_tag ("h1");
+               writer.simple_tag ("hr", css_headline_hr);
+               writer.start_tag ("h2", css_title).text ("Description:").end_tag ("h2");
 
                if (wikipage != null) {
-                       _renderer.set_container (mself);
-                       _renderer.set_filestream (file);
+                       _renderer.set_container (parent);
                        _renderer.render (wikipage.documentation);
                }
 
-               file.printf ( "\n\t\t\t\t<h2 class=\"%s\">Content:</h2>\n", css_title );
+               writer.start_tag ("h2", css_title).text ("Content:").end_tag ("h2");
 
-               this.write_child_namespaces ( file, f, mself );
+               this.write_child_namespaces (f, parent);
 
-               foreach ( Namespace ns in f.get_namespace_list() ) {
-                       if ( ns.name == null ) {
-                               this.write_child_classes ( file, ns, mself );
-                               this.write_child_interfaces ( file, ns, mself );
-                               this.write_child_structs ( file, ns, mself );
-                               this.write_child_enums ( file, ns, mself );
-                               this.write_child_errordomains ( file, ns, mself );
-                               this.write_child_delegates ( file, ns, mself );
-                               this.write_child_methods ( file, ns, mself );
-                               this.write_child_fields ( file, ns, mself );
-                               this.write_child_constants ( file, ns, mself );
+               foreach (Namespace ns in f.get_namespace_list()) {
+                       if (ns.name == null) {
+                               this.write_child_classes (ns, parent);
+                               this.write_child_interfaces (ns, parent);
+                               this.write_child_structs (ns, parent);
+                               this.write_child_enums (ns, parent);
+                               this.write_child_errordomains (ns, parent);
+                               this.write_child_delegates (ns, parent);
+                               this.write_child_methods (ns, parent);
+                               this.write_child_fields (ns, parent);
+                               this.write_child_constants (ns, parent);
                        }
                }
 
-               this.write_child_dependencies ( file, f, mself );
-               file.puts ( "\t\t\t</div>\n" );
-       }
-
-       protected void write_file_header ( GLib.FileStream file, string css, string? title ) {
-               file.puts ( "<?xml version=\"1.0\" encoding=\"utf-8\"?>" );
-               file.puts ( "<html>\n" );
-               file.puts ( "\t<head>\n" );
-               file.puts ( "\t\t<title>Vala Binding Reference</title>\n" );
-               file.printf ( "\t\t<link href=\"%s\" rel=\"stylesheet\" type=\"text/css\" />\n", css );
-               file.puts ( "\t</head>\n" );
-               file.puts ( "\t<body>\n\n" );
-               file.printf ( "\t<div class=\"%s\">\n", css_site_header );
-               file.printf ( "\t\t%s Reference Manual\n", (title == null)? "" : title );
-               file.puts ( "\t</div>\n\n" );
-               file.printf ( "\t\t<div class=\"%s\">\n", css_style_body );
-       }
-
-       protected void write_file_footer ( GLib.FileStream file ) {
-               file.puts ( "\t</div>\n" );
-               file.puts ( "\t<div style= \"clear: left\">\n" );
-               file.puts ( "\t\t<br />\n" );
-               file.puts ( "\t\t<div class=\"site_foother\">\n" );
-               file.puts ( "\t\t\tcreated by <a href=\"http://www.valadoc.org\">valadoc</a>\n" );
-               file.puts ( "\t\t</div>\n" );
-               file.puts ( "\t</div>\n" );
-               file.puts ( "\t</body>\n" );
-               file.puts ( "</html>" );
+               this.write_child_dependencies (f, parent);
+               writer.end_tag ("div");
+       }
+
+       protected void write_file_header (string css, string? title) {
+               writer.start_tag ("html");
+               writer.start_tag ("head");
+               writer.start_tag ("title").text ("Vala Binding Reference").end_tag ("title");
+               writer.stylesheet_link (css);
+               writer.end_tag ("head");
+               writer.start_tag ("body");
+               writer.start_tag ("div", css_site_header);
+               writer.text ("%s Reference Manual".printf (title == null ? "" : title));
+               writer.end_tag ("div");
+               writer.start_tag ("div", css_style_body);
+       }
+
+       protected void write_file_footer () {
+               writer.end_tag ("div");
+               writer.simple_tag ("br");
+               writer.start_tag ("div", "site_foother");
+               writer.text ("Generated by ");
+               writer.link ("site_foother", "http://www.valadoc.org/", "Valadoc");
+               writer.end_tag ("div");
+               writer.end_tag ("body");
+               writer.end_tag ("html");
        }
 }
 
index 0d0cd1795325f835383e1b23b6c9a7fe067abeac..3647124992f9c87fad8c61824cbed10cadeeb408 100755 (executable)
@@ -28,7 +28,7 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
 
        private BasicDoclet _doclet;
        private Documentation? _container;
-       private unowned FileStream _stream;
+       private unowned MarkupWriter writer;
 
        public HtmlRenderer (BasicDoclet doclet) {
                _doclet = doclet;
@@ -38,8 +38,8 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
                _container = container;
        }
 
-       public void set_filestream (FileStream stream) {
-               _stream = stream;
+       public void set_writer (MarkupWriter writer) {
+               this.writer = writer;
        }
 
        public override void render (ContentElement element) {
@@ -56,26 +56,25 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
 
        private void write_symbol_link (Api.Node symbol, string label) {
                var url = get_url (symbol);
-               _stream.printf ("<a href=\"%s\">%s</a>",
-                               url,
-                               (label == null || label == "") ? symbol.full_name () : label);
+               writer.link ("", url, (label == null || label == "") ? symbol.full_name () : label);
        }
 
+       private delegate void Write ();
        private delegate void TagletWrite (Taglet taglet);
 
-       private void write_taglets (string header, string footer, string separator,
+       private void write_taglets (Write header, Write footer, Write separator,
                                    Gee.List<Taglet> taglets, TagletWrite write) {
                if (taglets.size > 0) {
-                       _stream.printf (header);
+                       header ();
                        bool first = true;
                        foreach (var taglet in taglets) {
                                if (!first) {
-                                       _stream.printf (separator);
+                                       separator ();
                                }
                                write (taglet);
                                first = false;
                        }
-                       _stream.printf (footer);
+                       footer ();
                }
        }
 
@@ -84,9 +83,14 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
 
                taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Deprecated));
                write_taglets (
-                       "<p class=\"main_title\"><b>Deprecated:</b> ",
-                       "</p>",
-                       "",
+                       () => {
+                               writer.start_tag ("p", "main_title");
+                               writer.start_tag ("b").text ("Deprecated:").end_tag ("b");
+                       },
+                       () => {
+                               writer.end_tag ("p");
+                       },
+                       () => {},
                        taglets,
                        (taglet) => {
                                var deprecated = taglet as Taglets.Deprecated;
@@ -98,59 +102,94 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
 
                taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Param));
                write_taglets (
-                       "<h2 class=\"main_title\">Parameters:</h2>\n<table class=\"main_parameter_table\">",
-                       "</table>",
-                       "",
+                       () => {
+                               writer.start_tag ("h2", "main_title").text ("Parameters:").end_tag ("h2");
+                               writer.start_tag ("table", "main_parameter_table");
+                       },
+                       () => {
+                               writer.end_tag ("table");
+                       },
+                       () => {},
                        taglets,
                        (taglet) => {
                                var param = taglet as Taglets.Param;
-                               _stream.printf ("<tr><td class=\"main_parameter_table_name\">%s</td><td>", param.parameter_name);
+                               writer.start_tag ("tr");
+                               writer.start_tag ("td", "main_parameter_table_name").text (param.parameter_name).end_tag ("td");
+                               writer.start_tag ("td");
                                param.accept_children (this);
-                               _stream.printf ("</td></tr>");
+                               writer.end_tag ("td");
+                               writer.end_tag ("tr");
                        });
 
                taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Return));
                write_taglets (
-                       "<h2 class=\"main_title\">Returns:</h2>\n<table class=\"main_parameter_table\">",
-                       "</table>",
-                       "",
+                       () => {
+                               writer.start_tag ("h2", "main_title").text ("Returns:").end_tag ("h2");
+                               writer.start_tag ("table", "main_parameter_table");
+                       },
+                       () => {
+                               writer.end_tag ("table");
+                       },
+                       () => {},
                        taglets,
                        (taglet) => {
                                var param = taglet as Taglets.Return;
-                               _stream.printf ("<tr><td>");
+                               writer.start_tag ("tr");
+                               writer.start_tag ("td");
                                param.accept_children (this);
-                               _stream.printf ("</td></tr>");
+                               writer.end_tag ("td");
+                               writer.end_tag ("tr");
                        });
 
                taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Throws));
                write_taglets (
-                       "<h2 class=\"main_title\">Throws:</h2>\n<table class=\"main_parameter_table\">",
-                       "</table>",
-                       "",
+                       () => {
+                               writer.start_tag ("h2", "main_title").text ("Returns:").end_tag ("h2");
+                               writer.start_tag ("table", "main_parameter_table");
+                       },
+                       () => {
+                               writer.end_tag ("table");
+                       },
+                       () => {},
                        taglets,
                        (taglet) => {
                                var exception = taglet as Taglets.Throws;
-                               _stream.printf ("<tr><td class=\"main_parameter_table_name\">%s</td><td>", exception.error_domain_name);
+                               writer.start_tag ("tr");
+                               writer.start_tag ("td", "main_parameter_table_name").text (exception.error_domain_name).end_tag ("td");
+                               writer.start_tag ("td");
                                exception.accept_children (this);
-                               _stream.printf ("</td></tr>");
+                               writer.end_tag ("td");
+                               writer.end_tag ("tr");
                        });
 
                taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.Since));
                write_taglets (
-                       "<h2 class=\"main_title\">Since:</h2>\n<p>",
-                       "</p>",
-                       ", ",
+                       () => {
+                               writer.start_tag ("h2", "main_title").text ("Since:").end_tag ("h2");
+                               writer.start_tag ("p");
+                       },
+                       () => {
+                               writer.end_tag ("p");
+                       },
+                       () => {},
                        taglets,
                        (taglet) => {
                                var since = taglet as Taglets.Since;
-                               _stream.printf ("%s", since.version);
+                               writer.text (since.version);
                        });
 
                taglets = element.find_taglets ((Api.Node) _container, typeof (Taglets.See));
                write_taglets (
-                       "<h2 class=\"main_title\">See also:</h2>\n<p>",
-                       "</p>",
-                       ", ",
+                       () => {
+                               writer.start_tag ("h2", "main_title").text ("Since:").end_tag ("h2");
+                               writer.start_tag ("p");
+                       },
+                       () => {
+                               writer.end_tag ("p");
+                       },
+                       () => {
+                               writer.text (", ");
+                       },
                        taglets,
                        (taglet) => {
                                var see = taglet as Taglets.See;
@@ -160,31 +199,25 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
 
        public override void visit_embedded (Embedded element) {
                var caption = element.caption;
-               if (caption == null) {
-                       _stream.printf ("<img src=\"%s\" />", element.url);
-               } else {
-                       _stream.printf ("<img src=\"%s\" alt=\"%s\" />", element.url, caption);
-               }
+               writer.image ("", element.url, (caption == null || caption == "") ? "" : caption);
        }
 
        public override void visit_headline (Headline element) {
-               _stream.printf ("<h%d>", element.level);
+               writer.start_tag ("h%d".printf (element.level));
                element.accept_children (this);
-               _stream.printf ("</h%d>", element.level);
+               writer.end_tag ("h%d".printf (element.level));
        }
 
        public override void visit_link (Link element) {
                var label = element.label;
-               _stream.printf ("<a href=\"%s\">%s</a>",
-                               element.url,
-                               (label == null || label == "") ? element.url : label);
+               writer.link ("", element.url, (label == null || label == "") ? element.url : label);
        }
 
        public override void visit_symbol_link (SymbolLink element) {
                if (element.symbol == _container
                    || !element.symbol.is_visitor_accessible (_doclet.settings)
                    || !element.symbol.package.is_visitor_accessible (_doclet.settings)) {
-                       _stream.printf (element.label);
+                       writer.text (element.label);
                } else {
                        write_symbol_link (element.symbol, element.label);
                }
@@ -201,9 +234,9 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
        }
 
        public override void visit_paragraph (Paragraph element) {
-               _stream.printf ("<p>");
+               writer.start_tag ("p");
                element.accept_children (this);
-               _stream.printf ("</p>");
+               writer.end_tag ("p");
        }
 
        public override void visit_run (Run element) {
@@ -239,39 +272,39 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
                        break;
                }
                if (tag != null) {
-                       _stream.printf ("<%s%s>", tag, css_type != null ? " class=\"" + css_type + "\"" : "");
+                       writer.start_tag (tag, css_type);
                }
                element.accept_children (this);
                if (tag != null) {
-                       _stream.printf ("</%s>", tag);
+                       writer.end_tag (tag);
                }
        }
 
        public override void visit_source_code (SourceCode element) {
-               _stream.printf ("<pre>");
-               _stream.printf (element.code);
-               _stream.printf ("</pre>");
+               writer.start_tag ("pre");
+               writer.raw_text (element.code);
+               writer.end_tag ("pre");
        }
 
        public override void visit_table (Table element) {
-               _stream.printf ("<table class=\"main_table\">");
+               writer.start_tag ("table", "main_table");
                element.accept_children (this);
-               _stream.printf ("</table>");
+               writer.end_tag ("table");
        }
 
        public override void visit_table_cell (TableCell element) {
-               _stream.printf ("<td class=\"main_table\"%s%s>",
-                       element.colspan != 1 ? " colspan=\"%d\"".printf (element.colspan) : "",
-                       element.rowspan != 1 ? " rowspan=\"%d\"".printf (element.rowspan) : ""
+               writer.start_tag_with_attrs ("td", "main_table",
+                       { "colspan", "rowspan" },
+                       { element.colspan.to_string (), element.rowspan.to_string () }
                );
                element.accept_children (this);
-               _stream.printf ("</td>");
+               writer.end_tag ("td");
        }
 
        public override void visit_table_row (TableRow element) {
-               _stream.printf ("<tr>");
+               writer.start_tag ("tr");
                element.accept_children (this);
-               _stream.printf ("</tr>");
+               writer.end_tag ("tr");
        }
 
        public override void visit_taglet (Taglet element) {
@@ -289,27 +322,28 @@ public class Valadoc.Html.HtmlRenderer : ContentRenderer {
                for (i = 0; chr != '\0' ; i++, chr = content[i]) {
                        switch (chr) {
                        case '\n':
-                               _stream.puts (content.substring (lpos, i-lpos));
-                               _stream.puts ("<br />");
+                               writer.text (content.substring (lpos, i-lpos));
+                               writer.simple_tag ("br");
                                lpos = i+1;
                                break;
                        case '<':
-                               _stream.puts (content.substring (lpos, i-lpos));
-                               _stream.puts ("&lt;");
+                               writer.text (content.substring (lpos, i-lpos));
+                               writer.text ("&lt;");
                                lpos = i+1;
                                break;
                        case '>':
-                               _stream.puts (content.substring (lpos, i-lpos));
-                               _stream.puts ("&gt;");
+                               writer.text (content.substring (lpos, i-lpos));
+                               writer.text ("&gt;");
                                lpos = i+1;
                                break;
                        case '&':
-                               _stream.puts (content.substring (lpos, i-lpos));
-                               _stream.puts ("&amp;");
+                               writer.text (content.substring (lpos, i-lpos));
+                               writer.text ("&amp;");
                                lpos = i+1;
                                break;
                        }
                }
-               _stream.puts (content.substring (lpos, i-lpos));
+               writer.text (content.substring (lpos, i-lpos));
        }
 }
+
diff --git a/src/doclets/htmlhelpers/doclet/markupwriter.vala b/src/doclets/htmlhelpers/doclet/markupwriter.vala
new file mode 100644 (file)
index 0000000..30ce0d6
--- /dev/null
@@ -0,0 +1,222 @@
+/* markupwriter.vala
+ *
+ * Valadoc - a documentation tool for vala.
+ * Copyright (C) 2008-2009 Florian Brosch, Didier Villevalois
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Author:
+ *     Didier 'Ptitjes Villevalois <ptitjes@free.fr>
+ */
+
+using GLib;
+using Valadoc.Content;
+
+public class Valadoc.Html.MarkupWriter {
+       private unowned FileStream stream;
+       private int indent;
+       private long current_column = 0;
+       private bool last_was_tag;
+
+       private const int MAX_COLUMN = 150;
+
+       public MarkupWriter (FileStream stream) {
+               this.stream = stream;
+               do_write ("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+               indent = -1;
+               last_was_tag = true;
+       }
+
+       public MarkupWriter start_tag (string name, string? css_class = null, string? id = null) {
+               indent++;
+               check_column (name);
+               do_write ("<%s%s%s>".printf (
+                       name,
+                       css_class != null ? " class=\"%s\"".printf (css_class) : "",
+                       id != null ? " id=\"%s\"".printf (id) : ""));
+               last_was_tag = true;
+               return this;
+       }
+
+       public MarkupWriter start_tag_with_attrs (string name, string? css_class = null, string[] names, string[] values) {
+               indent++;
+               check_column (name);
+
+               var content = "<%s%s".printf (
+                       name,
+                       css_class != null ? " class=\"%s\"".printf (css_class) : "");
+               for (int i = 0; i < names.length; i++) {
+                       content += " %s=\"%s\"".printf (names[i], values[i]);
+               }
+               content += ">";
+
+               do_write (content);
+               last_was_tag = true;
+               return this;
+       }
+
+       public MarkupWriter end_tag (string name) {
+               check_column (name, true);
+               do_write ("</%s>".printf (name));
+               indent--;
+               last_was_tag = true;
+               return this;
+       }
+
+       public MarkupWriter simple_tag (string name, string? css_class = null) {
+               indent++;
+               check_column (name);
+               do_write ("<%s%s/>".printf (
+                       name,
+                       css_class != null ? " class=\"%s\"".printf (css_class) : ""));
+               indent--;
+               last_was_tag = true;
+               return this;
+       }
+
+       public MarkupWriter link (string css_class, string url, string label) {
+               indent++;
+               check_column ("a");
+               do_write ("<a class=\"%s\" href=\"%s\">%s</a>".printf (
+                       css_class, url, label));
+               indent--;
+               last_was_tag = true;
+               return this;
+       }
+
+       public MarkupWriter image (string css_class, string src, string? caption = null) {
+               indent++;
+               check_column ("img");
+               do_write ("<img class=\"%s\" src=\"%s\"%s/>".printf (
+                       css_class, src,
+                       caption != null ? " alt=\"%s\"".printf (caption) : ""));
+               indent--;
+               last_was_tag = true;
+               return this;
+       }
+
+       public MarkupWriter stylesheet_link (string url) {
+               indent++;
+               check_column ("link");
+               do_write ("<link href=\"%s\" rel=\"stylesheet\" type=\"text/css\" />".printf (url));
+               indent--;
+               last_was_tag = true;
+               return this;
+       }
+
+       public MarkupWriter text (string text) {
+               if (text.length + current_column > MAX_COLUMN) {
+                       long wrote = 0;
+                       while (wrote < text.length) {
+                               long space_pos = -1;
+                               for (long i = wrote + 1; i < text.length; i++) {
+                                       if (text[i] == ' ') {
+                                               if (i - wrote + current_column > MAX_COLUMN) {
+                                                       break;
+                                               }
+                                               space_pos = i;
+                                       }
+                               }
+                               if (text.length - wrote + current_column <= MAX_COLUMN) {
+                                       do_write (text.substring (wrote));
+                                       wrote = text.length + 1;
+                               } else if (space_pos == -1) {
+                                       // Force line break
+                               } else {
+                                       do_write (text.substring (wrote, space_pos - wrote));
+                                       wrote = space_pos + 1;
+                               }
+                               if (wrote < text.length) {
+                                       break_line ();
+                                       do_write ("  ");
+                               }
+                       }
+               } else {
+                       do_write (text);
+               }
+               last_was_tag = false;
+               return this;
+       }
+
+       public MarkupWriter raw_text (string text) {
+               do_write (text);
+               last_was_tag = false;
+               return this;
+       }
+
+       public void break_line () {
+               current_column = 0;
+               do_write ("\n%s".printf (get_indent_string ()));
+       }
+
+       public void do_write (string text) {
+               stream.printf (text);
+               current_column += text.length;
+       }
+
+       private void check_column (string name, bool end_tag = false) {
+               if (!end_tag && inline (name) && !last_was_tag) {
+                       return;
+               } else if (end_tag && content_inline (name)) {
+                       return;
+               }
+               break_line ();
+       }
+
+       private bool inline (string name) {
+               return name != "html"
+                       && name != "head"
+                       && name != "title"
+                       && name != "link"
+                       && name != "body"
+                       && name != "div"
+                       && name != "p"
+                       && name != "table"
+                       && name != "tr"
+                       && name != "td"
+                       && name != "ul"
+                       && name != "ol"
+                       && name != "li"
+                       && name != "h1"
+                       && name != "h2"
+                       && name != "h3"
+                       && name != "h4"
+                       && name != "h5"
+                       && name != "hr"
+                       && name != "img";
+       }
+
+       private bool content_inline (string name) {
+               return name == "title"
+                       || name == "p"
+                       || name == "a"
+                       || name == "h1"
+                       || name == "h2"
+                       || name == "h3"
+                       || name == "h4"
+                       || name == "h5"
+                       || name == "span"
+                       || name == "code"
+                       || name == "b"
+                       || name == "i"
+                       || name == "u"
+                       || name == "stoke";
+       }
+
+       private string get_indent_string () {
+               return current_column == 0 ? string.nfill (indent * 2, ' ') : "";
+       }               
+}
+
index 583031daca692e24dfac4740526d0b58296508c6..f9f9c2b20cd109f08af5b58f146aa8aae44e539c 100644 (file)
@@ -20,6 +20,8 @@
 using Gee;
 using Valadoc.Content;
 
+
+
 public class Valadoc.Api.Package : Node, NamespaceHandler {
        private ArrayList<Vala.SourceFile> vfiles = new ArrayList<Vala.SourceFile> ();