[valadoc] Html: Introduce MarkupWriter to pretty-print generated html



commit e8b422fed2c5ef5b5f68bf76e47de0d73f278ecc
Author: Didier "Ptitjes <ptitjes free fr>
Date:   Tue Oct 20 01:55:33 2009 +0200

    Html: Introduce MarkupWriter to pretty-print generated html

 src/doclets/devhelp/doclet/doclet.vala           |  120 +-
 src/doclets/htm/doclet/doclet.vala               |  156 ++-
 src/doclets/htmlhelpers/deps/style.css           |    3 +-
 src/doclets/htmlhelpers/doclet/Makefile.am       |    4 +-
 src/doclets/htmlhelpers/doclet/doclet.vala       | 1794 +++++++++++-----------
 src/doclets/htmlhelpers/doclet/htmlrenderer.vala |  174 ++-
 src/doclets/htmlhelpers/doclet/markupwriter.vala |  222 +++
 src/libvaladoc/api/package.vala                  |    2 +
 8 files changed, 1414 insertions(+), 1061 deletions(-)
---
diff --git a/src/doclets/devhelp/doclet/doclet.vala b/src/doclets/devhelp/doclet/doclet.vala
index 4d02cf6..c3d29b1 100755
--- a/src/doclets/devhelp/doclet/doclet.vala
+++ b/src/doclets/devhelp/doclet/doclet.vala
@@ -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 );
 }
 
+
diff --git a/src/doclets/htm/doclet/doclet.vala b/src/doclets/htm/doclet/doclet.vala
index e446218..28ea47b 100755
--- a/src/doclets/htm/doclet/doclet.vala
+++ b/src/doclets/htm/doclet/doclet.vala
@@ -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 );
 }
 
+
diff --git a/src/doclets/htmlhelpers/deps/style.css b/src/doclets/htmlhelpers/deps/style.css
index 4bac34b..cd25af7 100644
--- a/src/doclets/htmlhelpers/deps/style.css
+++ b/src/doclets/htmlhelpers/deps/style.css
@@ -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;
 }
 
+
diff --git a/src/doclets/htmlhelpers/doclet/Makefile.am b/src/doclets/htmlhelpers/doclet/Makefile.am
index e1a1fdd..f69abb4 100644
--- a/src/doclets/htmlhelpers/doclet/Makefile.am
+++ b/src/doclets/htmlhelpers/doclet/Makefile.am
@@ -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)
 
+
diff --git a/src/doclets/htmlhelpers/doclet/doclet.vala b/src/doclets/htmlhelpers/doclet/doclet.vala
index 98da9d9..0548fe0 100755
--- a/src/doclets/htmlhelpers/doclet/doclet.vala
+++ b/src/doclets/htmlhelpers/doclet/doclet.vala
@@ -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");
 	}
 }
 
diff --git a/src/doclets/htmlhelpers/doclet/htmlrenderer.vala b/src/doclets/htmlhelpers/doclet/htmlrenderer.vala
index 0d0cd17..3647124 100755
--- a/src/doclets/htmlhelpers/doclet/htmlrenderer.vala
+++ b/src/doclets/htmlhelpers/doclet/htmlrenderer.vala
@@ -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
index 0000000..30ce0d6
--- /dev/null
+++ b/src/doclets/htmlhelpers/doclet/markupwriter.vala
@@ -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, ' ') : "";
+	}		
+}
+
diff --git a/src/libvaladoc/api/package.vala b/src/libvaladoc/api/package.vala
index 583031d..f9f9c2b 100644
--- a/src/libvaladoc/api/package.vala
+++ b/src/libvaladoc/api/package.vala
@@ -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> ();
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]