[valadoc] Initial import of the rewrited parser



commit ea055f2d1c68da97f718324233724526d320b652
Author: Didier 'Ptitjes <ptitjes free fr>
Date:   Thu Sep 17 01:16:11 2009 +0200

    Initial import of the rewrited parser

 configure.in                                       |    2 +-
 src/doclets/Makefile.am                            |    1 -
 src/doclets/devhelp/doclet/Makefile.am             |    2 +-
 src/doclets/htm/doclet/Makefile.am                 |    2 +-
 src/doclets/htmlhelpers/Makefile.am                |    1 -
 src/doclets/htmlhelpers/doclet/Makefile.am         |    1 +
 src/doclets/htmlhelpers/doclet/doclet.vala         |   50 +-
 src/doclets/htmlhelpers/doclet/htmlrenderer.vala   |  279 +++++++++++
 src/doclets/htmlhelpers/taglets/Makefile.am        |   81 ---
 src/doclets/htmlhelpers/taglets/image.vala         |  113 -----
 src/doclets/htmlhelpers/taglets/link.vala          |   57 ---
 src/doclets/htmlhelpers/taglets/list.vala          |   52 --
 src/doclets/htmlhelpers/taglets/notification.vala  |   49 --
 src/doclets/htmlhelpers/taglets/parameter.vala     |  136 -----
 .../htmlhelpers/taglets/registerfunction.vala      |   51 --
 src/doclets/htmlhelpers/taglets/return.vala        |   62 ---
 src/doclets/htmlhelpers/taglets/right.vala         |   50 --
 src/doclets/htmlhelpers/taglets/see.vala           |   86 ----
 src/doclets/htmlhelpers/taglets/since.vala         |   69 ---
 src/doclets/htmlhelpers/taglets/source.vala        |   53 --
 src/doclets/htmlhelpers/taglets/string.vala        |   66 ---
 src/doclets/htmlhelpers/taglets/table.vala         |   54 --
 src/doclets/htmlhelpers/taglets/tablecell.vala     |   87 ----
 src/doclets/htmlhelpers/taglets/throws.vala        |  139 ------
 src/doclets/htmlhelpers/taglets/typelink.vala      |   77 ---
 src/doclets/htmlhelpers/taglets/underline.vala     |   50 --
 .../html-apiwriter/apiwriter-vala.vala             |    0
 .../valadoc.org}/html-apiwriter/apiwriter.vala     |    0
 .../valadoc.org}/html/attribute.vala               |    0
 .../valadoc.org}/html/block.vala                   |    0
 .../valadoc.org}/html/htmlwriter.vala              |    0
 .../valadoc.org}/html/inline.vala                  |    0
 src/libvaladoc/Makefile.am                         |   61 ++-
 src/libvaladoc/apitree/apitree.vala                |    2 +-
 src/libvaladoc/apitree/class.vala                  |   10 +-
 src/libvaladoc/apitree/classhandler.vala           |    2 +-
 src/libvaladoc/apitree/constant.vala               |    2 +-
 src/libvaladoc/apitree/constanthandler.vala        |    2 +-
 .../apitree/constructionmethodhandler.vala         |    2 +-
 src/libvaladoc/apitree/delegate.vala               |    2 +-
 src/libvaladoc/apitree/delegatehandler.vala        |    2 +-
 src/libvaladoc/apitree/documentedelement.vala      |    4 +-
 src/libvaladoc/apitree/enum.vala                   |    2 +-
 src/libvaladoc/apitree/enumhandler.vala            |    2 +-
 src/libvaladoc/apitree/enumvalue.vala              |    2 +-
 src/libvaladoc/apitree/errorcode.vala              |    2 +-
 src/libvaladoc/apitree/errordomain.vala            |    2 +-
 src/libvaladoc/apitree/errordomainhandler.vala     |    2 +-
 src/libvaladoc/apitree/field.vala                  |    2 +-
 src/libvaladoc/apitree/fieldhandler.vala           |    2 +-
 src/libvaladoc/apitree/interface.vala              |    2 +-
 src/libvaladoc/apitree/interfacehandler.vala       |    2 +-
 src/libvaladoc/apitree/method.vala                 |    8 +-
 src/libvaladoc/apitree/methodhandler.vala          |    2 +-
 src/libvaladoc/apitree/namespace.vala              |    2 +-
 src/libvaladoc/apitree/namespacehandler.vala       |    2 +-
 src/libvaladoc/apitree/package.vala                |    2 +-
 src/libvaladoc/apitree/property.vala               |    8 +-
 src/libvaladoc/apitree/propertyhandler.vala        |    2 +-
 src/libvaladoc/apitree/signal.vala                 |    2 +-
 src/libvaladoc/apitree/signalhandler.vala          |    2 +-
 src/libvaladoc/apitree/struct.vala                 |   10 +-
 src/libvaladoc/apitree/structhandler.vala          |    2 +-
 .../{html/attribute.vala => content/block.vala}    |   30 +-
 src/libvaladoc/content/blockcontent.vala           |   50 ++
 src/libvaladoc/content/comment.vala                |   73 +++
 .../content/contentelement.vala}                   |   36 +-
 src/libvaladoc/content/contentfactory.vala         |  109 ++++
 .../contentrenderer.vala}                          |   30 +-
 src/libvaladoc/content/contentvisitor.vala         |   73 +++
 src/libvaladoc/content/embedded.vala               |   52 ++
 .../taglets => libvaladoc/content}/headline.vala   |   41 +-
 .../content/highlighted.vala}                      |   55 +-
 .../{html/attribute.vala => content/inline.vala}   |   30 +-
 .../content/inlinecontent.vala}                    |   48 +-
 src/libvaladoc/content/inlinetaglet.vala           |   61 +++
 .../headline.vala => libvaladoc/content/link.vala} |   40 +-
 .../content/list.vala}                             |   49 +-
 src/libvaladoc/content/listitem.vala               |   57 +++
 .../headline.vala => libvaladoc/content/page.vala} |   35 +-
 .../taglets => libvaladoc/content}/paragraph.vala  |   48 +-
 .../resourcelocator.vala}                          |   31 +-
 .../content/sourcecode.vala}                       |   44 +-
 .../content/styleattributes.vala}                  |   45 +-
 .../content/symbollink.vala}                       |   43 +-
 src/libvaladoc/content/table.vala                  |   51 ++
 src/libvaladoc/content/tablecell.vala              |   48 ++
 .../{html/attribute.vala => content/taglet.vala}   |   30 +-
 .../content/text.vala}                             |   48 +-
 src/libvaladoc/documentation/doctree.vala          |  322 ------------
 .../documentation/documentation.vala}              |   18 +-
 src/libvaladoc/documentation/errorreporter.vala    |   13 +-
 src/libvaladoc/documentation/moduleloader.vala     |   68 +---
 src/libvaladoc/documentation/wiki.vala             |   36 +-
 src/libvaladoc/parser/commentscanner.vala          |   69 +++
 src/libvaladoc/parser/documentationparser.vala     |  518 ++++++++++++++++++++
 src/libvaladoc/parser/manyrule.vala                |  108 ++++
 src/libvaladoc/parser/oneofrule.vala               |   94 ++++
 src/libvaladoc/parser/optionalrule.vala            |   85 ++++
 src/libvaladoc/parser/parser.vala                  |  286 +++++++++++
 .../parser/parsercallback.vala}                    |   48 +--
 src/libvaladoc/parser/rule.vala                    |  151 ++++++
 .../{html/attribute.vala => parser/scanner.vala}   |   35 +-
 src/libvaladoc/parser/sequencerule.vala            |  129 +++++
 src/libvaladoc/parser/sourcelocation.vala          |   36 ++
 src/libvaladoc/parser/stubrule.vala                |   61 +++
 src/libvaladoc/parser/token.vala                   |  103 ++++
 src/libvaladoc/parser/tokentype.vala               |  183 +++++++
 src/libvaladoc/parser/wikiscanner.vala             |  395 +++++++++++++++
 .../taglets/tagletdeprecated.vala}                 |   38 +-
 src/libvaladoc/taglets/tagletinheritdoc.vala       |   64 +++
 .../taglets/tagletinit.vala}                       |   36 +-
 src/libvaladoc/taglets/tagletlink.vala             |   55 ++
 src/libvaladoc/taglets/tagletparam.vala            |   48 ++
 .../taglets/tagletreturn.vala}                     |   38 +-
 src/libvaladoc/taglets/tagletsee.vala              |   49 ++
 .../taglets/tagletsince.vala}                      |   42 +-
 src/libvaladoc/taglets/tagletthrows.vala           |   53 ++
 src/libvaladoc/testcomment.test                    |   48 ++
 src/libvaladoc/testparser.sh                       |   45 ++
 src/libvaladoc/testparser.vala                     |   16 +
 src/valadoc/valadoc.vala                           |    3 +-
 122 files changed, 4017 insertions(+), 2354 deletions(-)
---
diff --git a/configure.in b/configure.in
index da5130c..b782cdf 100644
--- a/configure.in
+++ b/configure.in
@@ -14,6 +14,7 @@ AC_PATH_PROG(VALAC, valac, valac)
 AC_SUBST(VALAC)
 
 
+AC_SUBST(VALAFLAGS)
 
 AC_ARG_ENABLE(valadocorg, AS_HELP_STRING([--enable-valadocorg], []), enable_valadocorg=$enableval, enable_valadocorg=no)
 AM_CONDITIONAL(ENABLE_VALADOCORG, test x$enable_valadocorg = xyes)
@@ -64,7 +65,6 @@ AC_CONFIG_FILES([Makefile
                  src/doclets/htmlhelpers/Makefile
                  src/doclets/htmlhelpers/deps/Makefile
                  src/doclets/htmlhelpers/doclet/Makefile
-                 src/doclets/htmlhelpers/taglets/Makefile
                  src/doclets/htm/Makefile
                  src/doclets/htm/doclet/Makefile
                  src/doclets/valadoc.org/Makefile
diff --git a/src/doclets/Makefile.am b/src/doclets/Makefile.am
index d4a0a9b..8f261c9 100644
--- a/src/doclets/Makefile.am
+++ b/src/doclets/Makefile.am
@@ -7,7 +7,6 @@ SUBDIRS = \
           htmlhelpers \
           htm    \
           devhelp    \
-          valadoc.org    \
           $(NULL)
 
 
diff --git a/src/doclets/devhelp/doclet/Makefile.am b/src/doclets/devhelp/doclet/Makefile.am
index ab736be..4472c5d 100644
--- a/src/doclets/devhelp/doclet/Makefile.am
+++ b/src/doclets/devhelp/doclet/Makefile.am
@@ -58,7 +58,7 @@ MAINTAINERCLEANFILES =                                \
 
 
 install-data-hook:
-	cd $(libdir)/valadoc/plugins/devhelp/ && if test -d taglets; then unlink taglets; fi && ln -s ../htmlhelpers/taglets && if test -d deps; then unlink deps; fi && ln -s ../htmlhelpers/deps 
+	cd $(libdir)/valadoc/plugins/devhelp/ && if test -d deps; then unlink deps; fi && ln -s ../htmlhelpers/deps 
 
 
 
diff --git a/src/doclets/htm/doclet/Makefile.am b/src/doclets/htm/doclet/Makefile.am
index 6f9c2bd..889d8fc 100644
--- a/src/doclets/htm/doclet/Makefile.am
+++ b/src/doclets/htm/doclet/Makefile.am
@@ -59,5 +59,5 @@ MAINTAINERCLEANFILES =                   \
 
 
 install-data-hook:
-	cd $(libdir)/valadoc/plugins/html/ && if test -d taglets; then unlink taglets; fi && ln -s ../htmlhelpers/taglets && if test -d deps; then unlink deps; fi && ln -s ../htmlhelpers/deps 
+	cd $(libdir)/valadoc/plugins/html/ && if test -d deps; then unlink deps; fi && ln -s ../htmlhelpers/deps 
 
diff --git a/src/doclets/htmlhelpers/Makefile.am b/src/doclets/htmlhelpers/Makefile.am
index acf64ba..fb34352 100644
--- a/src/doclets/htmlhelpers/Makefile.am
+++ b/src/doclets/htmlhelpers/Makefile.am
@@ -3,6 +3,5 @@ NULL =
 
 SUBDIRS =     \
 	doclet    \
-	taglets   \
 	deps      \
 	$(NULL)
diff --git a/src/doclets/htmlhelpers/doclet/Makefile.am b/src/doclets/htmlhelpers/doclet/Makefile.am
index d04758d..b2fdb33 100644
--- a/src/doclets/htmlhelpers/doclet/Makefile.am
+++ b/src/doclets/htmlhelpers/doclet/Makefile.am
@@ -25,6 +25,7 @@ libhtmlhelpers_la_VALASOURCES = \
 	globals.vala                \
 	langlet.vala                \
 	doclet.vala                 \
+	htmlrenderer.vala                 \
 	$(NULL)
 
 
diff --git a/src/doclets/htmlhelpers/doclet/doclet.vala b/src/doclets/htmlhelpers/doclet/doclet.vala
index 3192bd9..e571607 100755
--- a/src/doclets/htmlhelpers/doclet/doclet.vala
+++ b/src/doclets/htmlhelpers/doclet/doclet.vala
@@ -19,11 +19,16 @@
 
 
 using GLib;
-
+using Valadoc.Content;
 
 public abstract class Valadoc.Html.BasicDoclet : Valadoc.Doclet {
 	protected Valadoc.Langlet langlet;
 	protected Settings settings;
+	protected HtmlRenderer _renderer;
+
+	construct {
+		_renderer = new HtmlRenderer (this);
+	}
 
 	protected string? get_link ( DocumentedElement element, DocumentedElement? pos ) {
 		return get_html_link ( this.settings, element, pos );
@@ -86,7 +91,9 @@ public abstract class Valadoc.Html.BasicDoclet : Valadoc.Doclet {
 			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 );
-				page.write ( file );
+				_renderer.set_container (page);
+				_renderer.set_filestream (file);
+				_renderer.render (page.documentation);
 				this.write_file_footer ( file );
 			}
 		}
@@ -682,41 +689,30 @@ public abstract class Valadoc.Html.BasicDoclet : Valadoc.Doclet {
 	}
 
 	private void write_brief_description ( GLib.FileStream file, DocumentedElement element , DocumentedElement? pos ) {
-		DocumentationTree? doctree = element.documentation;
+		Comment? doctree = element.documentation;
 		if ( doctree == null )
 			return ;
 
-		Gee.Collection<DocElement> brief = doctree.get_brief ( );
-		if ( brief.size > 0 ) {
+		Gee.List<Block> description = doctree.content;
+		if ( description.size > 0 ) {
 			file.printf ( " <span class=\"%s\">- ", css_inline_navigation_brief_description );
-			int _max = brief.size;
-			int _index = 0;
 
-			foreach ( DocElement element2 in brief ) {
-				if ( element2 is InlineTaglet )
-					file.puts ( ((InlineTaglet)element2).to_string() );
-				else
-					element2.write ( file, _max, _index );
-
-				_index++;
-			}
+			_renderer.set_container (pos);
+			_renderer.set_filestream (file);
+			_renderer.render_children (description.get (0));
 
 			file.printf ( " </span>\n" );
 		}
 	}
 
 	private void write_documentation ( GLib.FileStream file, DocumentedElement element , DocumentedElement? pos ) {
-		DocumentationTree? doctree = element.documentation;
+		Comment? doctree = element.documentation;
 		if ( doctree == null )
 			return ;
 
-		Gee.Collection<DocElement> brief = doctree.get_brief ( );
-		if ( brief.size > 0 ) {
-			doctree.write_brief ( file );
-		}
-		file.printf ( "\n<br />\n" );
-		file.printf ( "\n<br />\n" );
-		doctree.write_content ( file );
+		_renderer.set_container (pos);
+		_renderer.set_filestream (file);
+		_renderer.render (doctree);
 	}
 
 	public void write_navi_packages_inline ( GLib.FileStream file, Tree tree ) {
@@ -747,7 +743,9 @@ public abstract class Valadoc.Html.BasicDoclet : Valadoc.Doclet {
 
 		WikiPage? wikiindex = (tree.wikitree == null)? null : tree.wikitree.search ( "index.valadoc" );
 		if ( wikiindex != null ) {
-			wikiindex.write ( file );
+			_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 );
@@ -1357,7 +1355,9 @@ public abstract class Valadoc.Html.BasicDoclet : Valadoc.Doclet {
 		file.printf ( "\t\t\t\t<h2 class=\"%s\">Description:</h2>\n", css_title );
 
 		if (wikipage != null) {
-			wikipage.write (file);
+			_renderer.set_container (mself);
+			_renderer.set_filestream (file);
+			_renderer.render (wikipage.documentation);
 		}
 
 		file.printf ( "\n\t\t\t\t<h2 class=\"%s\">Content:</h2>\n", css_title );
diff --git a/src/doclets/htmlhelpers/doclet/htmlrenderer.vala b/src/doclets/htmlhelpers/doclet/htmlrenderer.vala
new file mode 100755
index 0000000..344b57c
--- /dev/null
+++ b/src/doclets/htmlhelpers/doclet/htmlrenderer.vala
@@ -0,0 +1,279 @@
+/* contentvisitor.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.HtmlRenderer : ContentRenderer {
+
+	private BasicDoclet _doclet;
+	private Documentation? _container;
+	private unowned FileStream _stream;
+
+	public HtmlRenderer (BasicDoclet doclet) {
+		_doclet = doclet;
+	}
+
+	public void set_container (Documentation? container) {
+		_container = container;
+	}
+
+	public void set_filestream (FileStream stream) {
+		_stream = stream;
+	}
+
+	public override void render (ContentElement element) {
+		element.accept (this);
+	}
+
+	public override void render_children (ContentElement element) {
+		element.accept_children (this);
+	}
+
+	private string get_url (DocumentedElement symbol) {
+		return get_html_link (_doclet.settings, symbol, _container);
+	}
+
+	private void write_symbol_link (DocumentedElement symbol, string label) {
+		var url = get_url (symbol);
+		_stream.printf ("<a href=\"%s\">%s</a>",
+		                url,
+		                (label == null || label == "") ? symbol.full_name () : label);
+	}
+
+	private delegate void TagletWrite (Taglet taglet);
+
+	private void write_taglets (string header, string footer, string separator,
+	                            Gee.List<Taglet> taglets, TagletWrite write) {
+		if (taglets.size > 0) {
+			_stream.printf (header);
+			bool first = true;
+			foreach (var taglet in taglets) {
+				if (!first) {
+					_stream.printf (separator);
+				}
+				write (taglet);
+				first = false;
+			}
+			_stream.printf (footer);
+		}
+	}
+
+	public override void visit_comment (Comment element) {
+		Gee.List<Taglet> taglets;
+
+		taglets = element.find_taglets ((DocumentedElement) _container, typeof (Taglets.Deprecated));
+		write_taglets (
+			"<p class=\"main_title\"><b>Deprecated:</b> ",
+			"</p>",
+			"",
+			taglets,
+			(taglet) => {
+				var deprecated = taglet as Taglets.Deprecated;
+				deprecated.accept_children (this);
+			});
+
+		// Write description
+		element.accept_children (this);
+
+		taglets = element.find_taglets ((DocumentedElement) _container, typeof (Taglets.Param));
+		write_taglets (
+			"<h2 class=\"main_title\">Parameters:</h2>\n<table class=\"main_parameter_table\">",
+			"</table>",
+			"",
+			taglets,
+			(taglet) => {
+				var param = taglet as Taglets.Param;
+				_stream.printf ("<tr><td class=\"main_parameter_table_name\">%s</td><td>", param.parameter_name);
+				param.accept_children (this);
+				_stream.printf ("</td></tr>");
+			});
+
+		taglets = element.find_taglets ((DocumentedElement) _container, typeof (Taglets.Return));
+		write_taglets (
+			"<h2 class=\"main_title\">Returns:</h2>\n<table class=\"main_parameter_table\">",
+			"</table>",
+			"",
+			taglets,
+			(taglet) => {
+				var param = taglet as Taglets.Return;
+				_stream.printf ("<tr><td>");
+				param.accept_children (this);
+				_stream.printf ("</td></tr>");
+			});
+
+		taglets = element.find_taglets ((DocumentedElement) _container, typeof (Taglets.Throws));
+		write_taglets (
+			"<h2 class=\"main_title\">Throws:</h2>\n<table class=\"main_parameter_table\">",
+			"</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);
+				exception.accept_children (this);
+				_stream.printf ("</td></tr>");
+			});
+
+		taglets = element.find_taglets ((DocumentedElement) _container, typeof (Taglets.Since));
+		write_taglets (
+			"<h2 class=\"main_title\">Since:</h2>\n<p>",
+			"</p>",
+			", ",
+			taglets,
+			(taglet) => {
+				var since = taglet as Taglets.Since;
+				_stream.printf ("%s", since.version);
+			});
+
+		taglets = element.find_taglets ((DocumentedElement) _container, typeof (Taglets.See));
+		write_taglets (
+			"<h2 class=\"main_title\">See also:</h2>\n<p>",
+			"</p>",
+			", ",
+			taglets,
+			(taglet) => {
+				var see = taglet as Taglets.See;
+				write_symbol_link (see.symbol, see.symbol_name);
+			});
+	}
+
+	public override void visit_embedded (Embedded element) {
+		var caption = element.caption;
+		_stream.printf ("<img src=\"%s\">%s</a>",
+		                element.url,
+		                (caption == null || caption == "") ? "" : caption);
+	}
+
+	public override void visit_headline (Headline element) {
+		_stream.printf ("<h%d>", element.level);
+		element.accept_children (this);
+		_stream.printf ("</h%d>", element.level);
+	}
+
+	public override void visit_highlighted (Highlighted element) {
+		string tag = null;
+		switch (element.style) {
+		case Highlighted.Style.BOLD:
+			tag = "b";
+			break;
+		case Highlighted.Style.ITALIC:
+			tag = "i";
+			break;
+		case Highlighted.Style.UNDERLINED:
+			tag = "u";
+			break;
+		case Highlighted.Style.MONOSPACED:
+			tag = "code";
+			break;
+		case Highlighted.Style.STROKE:
+			tag = "stroke";
+			break;
+		}
+		if (tag != null) {
+			_stream.printf ("<%s>", tag);
+		}
+		element.accept_children (this);
+		if (tag != null) {
+			_stream.printf ("</%s>", tag);
+		}
+	}
+
+	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);
+	}
+
+	public override void visit_symbol_link (SymbolLink element) {
+		write_symbol_link (element.symbol, element.label);
+	}
+
+	public override void visit_list (Content.List element) {
+	}
+
+	public override void visit_list_item (ListItem element) {
+	}
+
+	public override void visit_page (Page element) {
+		element.accept_children (this);
+	}
+
+	public override void visit_paragraph (Paragraph element) {
+		_stream.printf ("<p>");
+		element.accept_children (this);
+		_stream.printf ("</p>");
+	}
+
+	public override void visit_source_code (SourceCode element) {
+		_stream.printf ("<pre>");
+		_stream.printf (element.code);
+		_stream.printf ("</pre>");
+	}
+
+	public override void visit_table (Table element) {
+	}
+
+	public override void visit_table_cell (TableCell element) {
+	}
+
+	public override void visit_taglet (Taglet element) {
+	}
+
+	public override void visit_text (Text element) {
+		write_string (element.content);
+	}
+
+	private void write_string (string content) {
+		unichar chr = content[0];
+		long lpos = 0;
+		int i = 0;
+
+		for (i = 0; chr != '\0' ; i++, chr = content[i]) {
+			switch (chr) {
+			case '\n':
+				_stream.puts (content.substring (lpos, i-lpos));
+				_stream.puts ("<br />");
+				lpos = i+1;
+				break;
+			case '<':
+				_stream.puts (content.substring (lpos, i-lpos));
+				_stream.puts ("&lt;");
+				lpos = i+1;
+				break;
+			case '>':
+				_stream.puts (content.substring (lpos, i-lpos));
+				_stream.puts ("&gt;");
+				lpos = i+1;
+				break;
+			case '&':
+				_stream.puts (content.substring (lpos, i-lpos));
+				_stream.puts ("&amp;");
+				lpos = i+1;
+				break;
+			}
+		}
+		_stream.puts (content.substring (lpos, i-lpos));
+	}
+}
diff --git a/src/libvaladoc/html-apiwriter/apiwriter-vala.vala b/src/doclets/valadoc.org/html-apiwriter/apiwriter-vala.vala
similarity index 100%
rename from src/libvaladoc/html-apiwriter/apiwriter-vala.vala
rename to src/doclets/valadoc.org/html-apiwriter/apiwriter-vala.vala
diff --git a/src/libvaladoc/html-apiwriter/apiwriter.vala b/src/doclets/valadoc.org/html-apiwriter/apiwriter.vala
similarity index 100%
rename from src/libvaladoc/html-apiwriter/apiwriter.vala
rename to src/doclets/valadoc.org/html-apiwriter/apiwriter.vala
diff --git a/src/libvaladoc/html/attribute.vala b/src/doclets/valadoc.org/html/attribute.vala
similarity index 100%
copy from src/libvaladoc/html/attribute.vala
copy to src/doclets/valadoc.org/html/attribute.vala
diff --git a/src/libvaladoc/html/block.vala b/src/doclets/valadoc.org/html/block.vala
similarity index 100%
rename from src/libvaladoc/html/block.vala
rename to src/doclets/valadoc.org/html/block.vala
diff --git a/src/libvaladoc/html/htmlwriter.vala b/src/doclets/valadoc.org/html/htmlwriter.vala
similarity index 100%
rename from src/libvaladoc/html/htmlwriter.vala
rename to src/doclets/valadoc.org/html/htmlwriter.vala
diff --git a/src/libvaladoc/html/inline.vala b/src/doclets/valadoc.org/html/inline.vala
similarity index 100%
rename from src/libvaladoc/html/inline.vala
rename to src/doclets/valadoc.org/html/inline.vala
diff --git a/src/libvaladoc/Makefile.am b/src/libvaladoc/Makefile.am
index 9a934f2..9ebad31 100644
--- a/src/libvaladoc/Makefile.am
+++ b/src/libvaladoc/Makefile.am
@@ -26,10 +26,9 @@ libvaladoc_la_VALASOURCES = \
 	filehelper.vala \
 	langlet.vala \
 	settings.vala \
-	documentation/doctree.vala \
+	documentation/documentation.vala \
 	documentation/errorreporter.vala \
 	documentation/moduleloader.vala \
-	documentation/parser.vala \
 	documentation/wiki.vala \
 	apitree/apitree.vala \
 	apitree/array.vala \
@@ -74,12 +73,56 @@ libvaladoc_la_VALASOURCES = \
 	apitree/typeparameter.vala \
 	apitree/typereference.vala \
 	apitree/visitable.vala \
-	html/attribute.vala \
-	html/block.vala \
-	html/htmlwriter.vala \
-	html/inline.vala \
-	html-apiwriter/apiwriter.vala \
-	html-apiwriter/apiwriter-vala.vala \
+	content/block.vala \
+	content/blockcontent.vala \
+	content/comment.vala \
+	content/contentfactory.vala \
+	content/contentelement.vala \
+	content/contentrenderer.vala \
+	content/contentvisitor.vala \
+	content/embedded.vala \
+	content/headline.vala \
+	content/highlighted.vala \
+	content/inline.vala \
+	content/inlinetaglet.vala \
+	content/inlinecontent.vala \
+	content/link.vala \
+	content/list.vala \
+	content/listitem.vala \
+	content/page.vala \
+	content/paragraph.vala \
+	content/resourcelocator.vala \
+	content/sourcecode.vala \
+	content/styleattributes.vala \
+	content/symbollink.vala \
+	content/table.vala \
+	content/tablecell.vala \
+	content/taglet.vala \
+	content/text.vala \
+	parser/commentscanner.vala \
+	parser/documentationparser.vala \
+	parser/manyrule.vala \
+	parser/oneofrule.vala \
+	parser/optionalrule.vala \
+	parser/parser.vala \
+	parser/parsercallback.vala \
+	parser/rule.vala \
+	parser/scanner.vala \
+	parser/sequencerule.vala \
+	parser/sourcelocation.vala \
+	parser/stubrule.vala \
+	parser/token.vala \
+	parser/tokentype.vala \
+	parser/wikiscanner.vala \
+	taglets/tagletdeprecated.vala \
+	taglets/tagletinheritdoc.vala \
+	taglets/tagletinit.vala \
+	taglets/tagletlink.vala \
+	taglets/tagletparam.vala \
+	taglets/tagletreturn.vala \
+	taglets/tagletsee.vala \
+	taglets/tagletsince.vala \
+	taglets/tagletthrows.vala \
 	$(NULL)
 
 
@@ -98,7 +141,7 @@ libvaladocincludedir = $(includedir)/
 
 
 libvaladoc.vala.stamp: $(libvaladoc_la_VALASOURCES)
-	$(VALAC) -C -H valadoc-1.0.h --pkg vala-1.0 --pkg gmodule-2.0 --vapidir ../vapi --pkg libxml-2.0 --pkg libgvc --library valadoc-1.0 --basedir $(top_srcdir)/src/libvaladoc/ --save-temps $^
+	$(VALAC) $(VALAFLAGS) -C -H valadoc-1.0.h --pkg vala-1.0 --pkg gmodule-2.0 --vapidir ../vapi --pkg libxml-2.0 --pkg libgvc --library valadoc-1.0 --basedir $(top_srcdir)/src/libvaladoc/ --save-temps $^
 	touch $@
 
 
diff --git a/src/libvaladoc/apitree/apitree.vala b/src/libvaladoc/apitree/apitree.vala
index 31a9e83..ec7c7f1 100644
--- a/src/libvaladoc/apitree/apitree.vala
+++ b/src/libvaladoc/apitree/apitree.vala
@@ -471,7 +471,7 @@ public class Valadoc.Tree : Vala.CodeVisitor {
 		}
 	}
 
-	public void parse_comments (Valadoc.Parser docparser) {
+	public void parse_comments (DocumentationParser docparser) {
 		this.wikitree = new WikiPageTree(this.reporter, this.settings);
 		wikitree.create_tree (docparser);
 
diff --git a/src/libvaladoc/apitree/class.vala b/src/libvaladoc/apitree/class.vala
index 3139432..858ceca 100644
--- a/src/libvaladoc/apitree/class.vala
+++ b/src/libvaladoc/apitree/class.vala
@@ -274,18 +274,12 @@ public class Valadoc.Class : DocumentedElement, SymbolAccessibility, Visitable,
 		doclet.visit_class ( this );
 	}
 
-	internal void parse_comments ( Valadoc.Parser docparser ) {
+	internal void parse_comments ( DocumentationParser docparser ) {
 		if ( this.documentation != null )
 			return ;
 
 		if ( this.vcomment != null ) {
-			if ( docparser.is_inherit_doc ( this ) && this.base_type != null ) {
-				((Class)this.base_type).parse_comments ( docparser );
-				this.documentation = this.base_type.documentation;
-			}
-			else {
-				this.parse_comment_helper ( docparser );
-			}
+			this.parse_comment_helper ( docparser );
 		}
 
 		this.parse_construction_method_comments ( docparser );
diff --git a/src/libvaladoc/apitree/classhandler.vala b/src/libvaladoc/apitree/classhandler.vala
index be5e206..a93ad26 100644
--- a/src/libvaladoc/apitree/classhandler.vala
+++ b/src/libvaladoc/apitree/classhandler.vala
@@ -95,7 +95,7 @@ public interface Valadoc.ClassHandler : Basic {
 		}
 	}
 
-	protected void parse_class_comments ( Valadoc.Parser docparser ) {
+	protected void parse_class_comments ( DocumentationParser docparser ) {
 		foreach ( Class cl in this.classes ) {
 			cl.parse_comments ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/constant.vala b/src/libvaladoc/apitree/constant.vala
index c9f033f..1f74294 100644
--- a/src/libvaladoc/apitree/constant.vala
+++ b/src/libvaladoc/apitree/constant.vala
@@ -55,7 +55,7 @@ public class Valadoc.Constant : DocumentedElement, SymbolAccessibility, Visitabl
 		((ReturnTypeHandler)this).set_return_type_references ( );
 	}
 
-	internal void parse_comment ( Valadoc.Parser docparser ) {
+	internal void parse_comment ( DocumentationParser docparser ) {
 		this.parse_comment_helper ( docparser );
 	}
 
diff --git a/src/libvaladoc/apitree/constanthandler.vala b/src/libvaladoc/apitree/constanthandler.vala
index e9fbb48..6caa948 100644
--- a/src/libvaladoc/apitree/constanthandler.vala
+++ b/src/libvaladoc/apitree/constanthandler.vala
@@ -87,7 +87,7 @@ public interface Valadoc.ConstantHandler : Basic {
 		}
 	}
 
-	internal void parse_constant_comments ( Valadoc.Parser docparser ) {
+	internal void parse_constant_comments ( DocumentationParser docparser ) {
 		foreach ( Constant c in this.constants ) {
 			c.parse_comment ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/constructionmethodhandler.vala b/src/libvaladoc/apitree/constructionmethodhandler.vala
index 6a6f004..efe336e 100644
--- a/src/libvaladoc/apitree/constructionmethodhandler.vala
+++ b/src/libvaladoc/apitree/constructionmethodhandler.vala
@@ -75,7 +75,7 @@ public interface Valadoc.ConstructionMethodHandler : Basic, MethodHandler {
 		return lst.read_only_view;
 	}
 
-	protected void parse_construction_method_comments ( Valadoc.Parser docparser ) {
+	protected void parse_construction_method_comments ( DocumentationParser docparser ) {
 		foreach ( Method cm in this.construction_methods ) {
 			cm.parse_comment ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/delegate.vala b/src/libvaladoc/apitree/delegate.vala
index c0a1516..9e46310 100644
--- a/src/libvaladoc/apitree/delegate.vala
+++ b/src/libvaladoc/apitree/delegate.vala
@@ -90,7 +90,7 @@ public class Valadoc.Delegate : DocumentedElement, SymbolAccessibility, Visitabl
 		this.add_exception_list ( vexceptionlst );
 	}
 
-	internal void parse_comment ( Valadoc.Parser docparser ) {
+	internal void parse_comment ( DocumentationParser docparser ) {
 		this.parse_comment_helper ( docparser );
 	}
 
diff --git a/src/libvaladoc/apitree/delegatehandler.vala b/src/libvaladoc/apitree/delegatehandler.vala
index c8d24fd..cf98391 100644
--- a/src/libvaladoc/apitree/delegatehandler.vala
+++ b/src/libvaladoc/apitree/delegatehandler.vala
@@ -90,7 +90,7 @@ public interface Valadoc.DelegateHandler : Basic {
 		}
 	}
 
-	public void parse_delegate_comments ( Valadoc.Parser docparser ) {
+	public void parse_delegate_comments ( DocumentationParser docparser ) {
 		foreach ( Delegate del in this.delegates ) {
 			del.parse_comment ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/documentedelement.vala b/src/libvaladoc/apitree/documentedelement.vala
index ba88f56..db94184 100644
--- a/src/libvaladoc/apitree/documentedelement.vala
+++ b/src/libvaladoc/apitree/documentedelement.vala
@@ -74,7 +74,7 @@ public abstract class Valadoc.DocumentedElement : Basic, Documentation {
 		get; set;
 	}
 
-	public DocumentationTree? documentation {
+	public Content.Comment? documentation {
 		protected set;
 		get;
 	}
@@ -120,7 +120,7 @@ public abstract class Valadoc.DocumentedElement : Basic, Documentation {
 		return GLib.Path.get_basename ( path );
 	}
 
-	protected void parse_comment_helper ( Valadoc.Parser docparser ) {
+	protected void parse_comment_helper ( DocumentationParser docparser ) {
 		this.documentation = docparser.parse ( this );
 	}
 
diff --git a/src/libvaladoc/apitree/enum.vala b/src/libvaladoc/apitree/enum.vala
index d71a834..f798d2f 100644
--- a/src/libvaladoc/apitree/enum.vala
+++ b/src/libvaladoc/apitree/enum.vala
@@ -134,7 +134,7 @@ public class Valadoc.Enum : DocumentedElement, SymbolAccessibility, Visitable, M
 		return this.en_values.read_only_view;
 	}
 
-	internal void parse_comments ( Valadoc.Parser docparser ) {
+	internal void parse_comments ( DocumentationParser docparser ) {
 		this.parse_comment_helper ( docparser );
 
 		foreach ( EnumValue enval in this.en_values ) {
diff --git a/src/libvaladoc/apitree/enumhandler.vala b/src/libvaladoc/apitree/enumhandler.vala
index 1efe3b1..03b3974 100644
--- a/src/libvaladoc/apitree/enumhandler.vala
+++ b/src/libvaladoc/apitree/enumhandler.vala
@@ -82,7 +82,7 @@ public interface Valadoc.EnumHandler : Basic {
 		this.enums.add( tmp );
 	}
 
-	protected void parse_enum_comments ( Valadoc.Parser docparser ) {
+	protected void parse_enum_comments ( DocumentationParser docparser ) {
 		foreach ( Enum en in this.enums ) {
 			en.parse_comments ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/enumvalue.vala b/src/libvaladoc/apitree/enumvalue.vala
index ceac5e3..e7f4053 100644
--- a/src/libvaladoc/apitree/enumvalue.vala
+++ b/src/libvaladoc/apitree/enumvalue.vala
@@ -43,7 +43,7 @@ public class Valadoc.EnumValue: DocumentedElement {
 		return ( this.venval == venval );
 	}
 
-	public void parse_comment ( Valadoc.Parser docparser ) {
+	public void parse_comment ( DocumentationParser docparser ) {
 		this.parse_comment_helper ( docparser );
 	}
 
diff --git a/src/libvaladoc/apitree/errorcode.vala b/src/libvaladoc/apitree/errorcode.vala
index ca4f0fa..29d38ab 100644
--- a/src/libvaladoc/apitree/errorcode.vala
+++ b/src/libvaladoc/apitree/errorcode.vala
@@ -47,7 +47,7 @@ public class Valadoc.ErrorCode : DocumentedElement {
 		langlet.write_error_code ( this, ptr );
 	}
 
-	public void parse_comment ( Valadoc.Parser docparser ) {
+	public void parse_comment ( DocumentationParser docparser ) {
 		this.parse_comment_helper ( docparser );
 	}
 
diff --git a/src/libvaladoc/apitree/errordomain.vala b/src/libvaladoc/apitree/errordomain.vala
index dbcfe0d..71794f6 100644
--- a/src/libvaladoc/apitree/errordomain.vala
+++ b/src/libvaladoc/apitree/errordomain.vala
@@ -128,7 +128,7 @@ public class Valadoc.ErrorDomain : DocumentedElement, SymbolAccessibility, Visit
 		return null;
 	}
 
-	internal void parse_comments ( Valadoc.Parser docparser ) {
+	internal void parse_comments ( DocumentationParser docparser ) {
 		this.parse_comment_helper ( docparser );
 		this.parse_method_comments ( docparser );
 
diff --git a/src/libvaladoc/apitree/errordomainhandler.vala b/src/libvaladoc/apitree/errordomainhandler.vala
index 69711fc..6a8f391 100644
--- a/src/libvaladoc/apitree/errordomainhandler.vala
+++ b/src/libvaladoc/apitree/errordomainhandler.vala
@@ -90,7 +90,7 @@ public interface Valadoc.ErrorDomainHandler : Basic {
 		}
 	}
 
-	protected void parse_errordomain_comments ( Valadoc.Parser docparser ) {
+	protected void parse_errordomain_comments ( DocumentationParser docparser ) {
 		foreach ( ErrorDomain errdom in this.errdoms ) {
 			errdom.parse_comments ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/field.vala b/src/libvaladoc/apitree/field.vala
index 36b72a5..80f51f4 100644
--- a/src/libvaladoc/apitree/field.vala
+++ b/src/libvaladoc/apitree/field.vala
@@ -70,7 +70,7 @@ public class Valadoc.Field : DocumentedElement, SymbolAccessibility, ReturnTypeH
 		((ReturnTypeHandler)this).set_return_type_references ( );
 	}
 
-	internal void parse_comment ( Valadoc.Parser docparser ) {
+	internal void parse_comment ( DocumentationParser docparser ) {
 		this.parse_comment_helper ( docparser );
 	}
 
diff --git a/src/libvaladoc/apitree/fieldhandler.vala b/src/libvaladoc/apitree/fieldhandler.vala
index d5e3d3a..5474af7 100644
--- a/src/libvaladoc/apitree/fieldhandler.vala
+++ b/src/libvaladoc/apitree/fieldhandler.vala
@@ -90,7 +90,7 @@ public interface Valadoc.FieldHandler : Basic {
 		}
 	}
 
-	internal void parse_field_comments ( Valadoc.Parser docparser ) {
+	internal void parse_field_comments ( DocumentationParser docparser ) {
 		foreach ( Field field in this.fields ) {
 			field.parse_comment ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/interface.vala b/src/libvaladoc/apitree/interface.vala
index b0a4b22..6f0a532 100644
--- a/src/libvaladoc/apitree/interface.vala
+++ b/src/libvaladoc/apitree/interface.vala
@@ -246,7 +246,7 @@ public class Valadoc.Interface : DocumentedElement, SymbolAccessibility, Visitab
 		langlet.write_interface ( this, ptr );
 	}
 
-	internal void parse_comments ( Valadoc.Parser docparser ) {
+	internal void parse_comments ( DocumentationParser docparser ) {
 		this.parse_comment_helper ( docparser );
 		this.parse_delegate_comments ( docparser );
 		this.parse_property_comments ( docparser );
diff --git a/src/libvaladoc/apitree/interfacehandler.vala b/src/libvaladoc/apitree/interfacehandler.vala
index 8f45722..6624417 100644
--- a/src/libvaladoc/apitree/interfacehandler.vala
+++ b/src/libvaladoc/apitree/interfacehandler.vala
@@ -82,7 +82,7 @@ public interface Valadoc.InterfaceHandler : Basic {
 		}
 	}
 
-	protected void parse_interface_comments ( Valadoc.Parser docparser ) {
+	protected void parse_interface_comments ( DocumentationParser docparser ) {
 		foreach ( Interface iface in this.interfaces ) {
 			iface.parse_comments ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/method.vala b/src/libvaladoc/apitree/method.vala
index 4fd4766..75ae1cb 100644
--- a/src/libvaladoc/apitree/method.vala
+++ b/src/libvaladoc/apitree/method.vala
@@ -85,19 +85,13 @@ public class Valadoc.Method : DocumentedElement, ParameterListHandler, Exception
 		return (m.vmethod == this.vmethod);
 	}
 
-	internal void parse_comment (Valadoc.Parser docparser) {
+	internal void parse_comment (DocumentationParser docparser) {
 		if (this.documentation != null)
 			return ;
 
 		if (this.vcomment == null)
 			return ;
 
-		if (this.base_method != null && docparser.is_inherit_doc (this)) {
-			this.base_method.parse_comment (docparser);
-			this.documentation = this.base_method.documentation;
-			return ;
-		}
-
 		this.parse_comment_helper (docparser);
 	}
 
diff --git a/src/libvaladoc/apitree/methodhandler.vala b/src/libvaladoc/apitree/methodhandler.vala
index 0c7b34a..fc2c1a7 100644
--- a/src/libvaladoc/apitree/methodhandler.vala
+++ b/src/libvaladoc/apitree/methodhandler.vala
@@ -64,7 +64,7 @@ public interface Valadoc.MethodHandler : Basic {
 		}
 	}
 
-	internal void parse_method_comments ( Valadoc.Parser docparser ) {
+	internal void parse_method_comments ( DocumentationParser docparser ) {
 		foreach ( Method m in this.methods ) {
 			m.parse_comment ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/namespace.vala b/src/libvaladoc/apitree/namespace.vala
index 0533224..101c4ed 100644
--- a/src/libvaladoc/apitree/namespace.vala
+++ b/src/libvaladoc/apitree/namespace.vala
@@ -247,7 +247,7 @@ public class Valadoc.Namespace : DocumentedElement, MethodHandler, FieldHandler,
 		this.set_enum_type_references ();
 	}
 
-	internal void parse_comments (Valadoc.Parser docparser) {
+	internal void parse_comments (DocumentationParser docparser) {
 		this.parse_comment_helper (docparser);
 		this.parse_enum_comments (docparser);
 		this.parse_field_comments (docparser);
diff --git a/src/libvaladoc/apitree/namespacehandler.vala b/src/libvaladoc/apitree/namespacehandler.vala
index 961f24f..8ff6d9f 100644
--- a/src/libvaladoc/apitree/namespacehandler.vala
+++ b/src/libvaladoc/apitree/namespacehandler.vala
@@ -130,7 +130,7 @@ public interface Valadoc.NamespaceHandler : Basic {
 		}
 	}
 
-	internal void parse_namespace_comments ( Valadoc.Parser docparser ) {
+	internal void parse_namespace_comments ( DocumentationParser docparser ) {
 		foreach ( Namespace ns in this.namespaces ){
 			ns.parse_comments ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/package.vala b/src/libvaladoc/apitree/package.vala
index 26ef9ed..c54f08d 100644
--- a/src/libvaladoc/apitree/package.vala
+++ b/src/libvaladoc/apitree/package.vala
@@ -149,7 +149,7 @@ public class Valadoc.Package : DocumentedElement, NamespaceHandler {
 		doclet.visit_package ( this );
 	}
 
-	internal void parse_comments ( Valadoc.Parser docparser ) {
+	internal void parse_comments ( DocumentationParser docparser ) {
 		this.parse_namespace_comments ( docparser );
 	}
 
diff --git a/src/libvaladoc/apitree/property.vala b/src/libvaladoc/apitree/property.vala
index 9861f86..35551ea 100644
--- a/src/libvaladoc/apitree/property.vala
+++ b/src/libvaladoc/apitree/property.vala
@@ -113,19 +113,13 @@ public class Valadoc.Property : DocumentedElement, SymbolAccessibility, ReturnTy
 		this.set_return_type_references ( );
 	}
 
-	public void parse_comment (Valadoc.Parser docparser) {
+	public void parse_comment (DocumentationParser docparser) {
 		if (this.documentation != null)
 			return ;
 
 		if (this.vcomment == null)
 			return ;
 
-		if (this.base_property != null && docparser.is_inherit_doc (this)) {
-			this.base_property.parse_comment (docparser);
-			this.documentation = this.base_property.documentation;
-			return ;
-		}
-
 		this.parse_comment_helper (docparser);
 	}
 
diff --git a/src/libvaladoc/apitree/propertyhandler.vala b/src/libvaladoc/apitree/propertyhandler.vala
index 4d84e48..d7872c5 100644
--- a/src/libvaladoc/apitree/propertyhandler.vala
+++ b/src/libvaladoc/apitree/propertyhandler.vala
@@ -84,7 +84,7 @@ public interface Valadoc.PropertyHandler : Basic {
 		return lst.read_only_view;
 	}
 
-	protected void parse_property_comments ( Valadoc.Parser docparser ) {
+	protected void parse_property_comments ( DocumentationParser docparser ) {
 		foreach ( Property prop in this.properties ) {
 			prop.parse_comment ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/signal.vala b/src/libvaladoc/apitree/signal.vala
index 67df446..f6c54e8 100644
--- a/src/libvaladoc/apitree/signal.vala
+++ b/src/libvaladoc/apitree/signal.vala
@@ -66,7 +66,7 @@ public class Valadoc.Signal : DocumentedElement, ParameterListHandler, SymbolAcc
 		this.set_return_type_references ( );
 	}
 
-	internal void parse_comment (Valadoc.Parser docparser) {
+	internal void parse_comment (DocumentationParser docparser) {
 		this.parse_comment_helper (docparser);
 	}
 
diff --git a/src/libvaladoc/apitree/signalhandler.vala b/src/libvaladoc/apitree/signalhandler.vala
index 573b7ac..2886551 100644
--- a/src/libvaladoc/apitree/signalhandler.vala
+++ b/src/libvaladoc/apitree/signalhandler.vala
@@ -89,7 +89,7 @@ public interface Valadoc.SignalHandler : Basic {
 		}
 	}
 
-	internal void parse_signal_comments ( Valadoc.Parser docparser ) {
+	internal void parse_signal_comments ( DocumentationParser docparser ) {
 		foreach ( Signal sig in this.signals ) {
 			sig.parse_comment ( docparser );
 		}
diff --git a/src/libvaladoc/apitree/struct.vala b/src/libvaladoc/apitree/struct.vala
index 7996ea2..96712a5 100644
--- a/src/libvaladoc/apitree/struct.vala
+++ b/src/libvaladoc/apitree/struct.vala
@@ -156,18 +156,12 @@ public class Valadoc.Struct : DocumentedElement, SymbolAccessibility, Visitable,
 		langlet.write_struct (this, ptr);
 	}
 
-	internal void parse_comments (Valadoc.Parser docparser) {
+	internal void parse_comments (DocumentationParser docparser) {
 		if (this.documentation != null)
 			return ;
 
 		if (this.vcomment != null) {
-			if ( docparser.is_inherit_doc (this) && this.base_type != null) {
-				((Valadoc.Struct)this.base_type).parse_comments (docparser);
-				this.documentation = this.base_type.documentation;
-			}
-			else {
-				this.parse_comment_helper (docparser);
-			}
+			this.parse_comment_helper (docparser);
 		}
 
 		this.parse_construction_method_comments (docparser);
diff --git a/src/libvaladoc/apitree/structhandler.vala b/src/libvaladoc/apitree/structhandler.vala
index f42f8b6..6b4e727 100644
--- a/src/libvaladoc/apitree/structhandler.vala
+++ b/src/libvaladoc/apitree/structhandler.vala
@@ -83,7 +83,7 @@ public interface Valadoc.StructHandler : Basic {
 		}
 	}
 
-	protected void parse_struct_comments ( Valadoc.Parser docparser ) {
+	protected void parse_struct_comments ( DocumentationParser docparser ) {
 		foreach ( Struct stru in this.structs ) {
 			stru.parse_comments ( docparser );
 		}
diff --git a/src/libvaladoc/html/attribute.vala b/src/libvaladoc/content/block.vala
similarity index 69%
copy from src/libvaladoc/html/attribute.vala
copy to src/libvaladoc/content/block.vala
index 7d8e89e..8c23390 100755
--- a/src/libvaladoc/html/attribute.vala
+++ b/src/libvaladoc/content/block.vala
@@ -1,36 +1,28 @@
-/*
+/* block.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2009 Florian Brosch
- * 
+ * 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 Gee;
 
-
-public class Valadoc.Html.Attribute {
-	private string name;
-	private string val;
-
-	public Attribute (string name, string val) {
-		this.name = name;
-		this.val = val;
-	}
-
-	public string to_string (string path) {
-		return " %s=\"%s\"".printf (this.name, this.val);
-	}
+public interface Valadoc.Content.Block : ContentElement {
 }
-
diff --git a/src/libvaladoc/content/blockcontent.vala b/src/libvaladoc/content/blockcontent.vala
new file mode 100755
index 0000000..138618b
--- /dev/null
+++ b/src/libvaladoc/content/blockcontent.vala
@@ -0,0 +1,50 @@
+/* blockcontent.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 Gee;
+
+public abstract class Valadoc.Content.BlockContent : ContentElement {
+	public Gee.List<Block> content { get { return _content; } }
+
+	private Gee.List<Block> _content;
+
+	internal BlockContent () {
+		_content = new ArrayList<Block> ();
+	}
+
+	public override void configure (Settings settings, ResourceLocator locator) {
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		foreach (Block element in _content) {
+			element.check (api_root, container, reporter);
+		}
+	}
+
+	public override void accept_children (ContentVisitor visitor) {
+		foreach (Block element in _content) {
+			element.accept (visitor);
+		}
+	}
+}
diff --git a/src/libvaladoc/content/comment.vala b/src/libvaladoc/content/comment.vala
new file mode 100755
index 0000000..5bf656d
--- /dev/null
+++ b/src/libvaladoc/content/comment.vala
@@ -0,0 +1,73 @@
+/* comment.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 Gee;
+
+public class Valadoc.Content.Comment : BlockContent {
+	public Gee.List<Taglet> taglets { get { return _taglets; } }
+
+	private Gee.List<Taglet> _taglets;
+
+	internal Comment () {
+		base ();
+		_taglets = new ArrayList<Taglet> ();
+	}
+
+	public override void configure (Settings settings, ResourceLocator locator) {
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		base.check (api_root, container, reporter);
+
+		foreach (Taglet element in _taglets) {
+			element.check (api_root, container, reporter);
+		}
+	}
+
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_comment (this);
+	}
+
+	public override void accept_children (ContentVisitor visitor) {
+		base.accept_children (visitor);
+
+		foreach (Taglet element in _taglets) {
+			element.accept (visitor);
+		}
+	}
+
+	public Gee.List<Taglet> find_taglets (DocumentedElement? container, Type taglet_type) {
+		Gee.List<Taglet> selected_taglets = new ArrayList<Taglet> ();
+
+		// TODO inherit stuff if needed
+
+		foreach (Taglet taglet in _taglets) {
+			if (taglet.get_type () == taglet_type) {
+				selected_taglets.add (taglet);
+			}
+		}
+
+		return selected_taglets;
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/headline.vala b/src/libvaladoc/content/contentelement.vala
similarity index 59%
copy from src/doclets/htmlhelpers/taglets/headline.vala
copy to src/libvaladoc/content/contentelement.vala
index 117d522..0f2d409 100755
--- a/src/doclets/htmlhelpers/taglets/headline.vala
+++ b/src/libvaladoc/content/contentelement.vala
@@ -1,42 +1,38 @@
-/*
+/* contentelement.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public abstract class Valadoc.Content.ContentElement : Object {
 
-public class Valadoc.Html.HeadlineDocElement : Valadoc.HeadlineDocElement {
-	private string title;
-	private int lvl;
-
-	public override bool parse (string title, int lvl) {
-		this.title = title;
-		this.lvl = lvl;
-		return true;
+	public virtual void configure (Settings settings, ResourceLocator locator) {
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("\n\n<h%d>%s</h%d>\n", this.lvl, this.title, this.lvl);
-		return true;
-	}
-}
+	public abstract void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter);
 
+	public abstract void accept (ContentVisitor visitor);
 
+	public virtual void accept_children (ContentVisitor visitor) {
+	}
+}
diff --git a/src/libvaladoc/content/contentfactory.vala b/src/libvaladoc/content/contentfactory.vala
new file mode 100755
index 0000000..5ce505c
--- /dev/null
+++ b/src/libvaladoc/content/contentfactory.vala
@@ -0,0 +1,109 @@
+/* contentfactory.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 Gee;
+
+public class Valadoc.Content.ContentFactory : Object {
+
+	public ContentFactory (Settings settings, ResourceLocator locator, ModuleLoader modules) {
+		_settings = settings;
+		_locator = locator;
+		_modules = modules;
+	}
+
+	private Settings _settings;
+	private ResourceLocator _locator;
+	private ModuleLoader _modules;
+
+	private inline ContentElement configure (ContentElement element) {
+		element.configure (_settings, _locator);
+		return element;
+	}
+
+	public Comment create_comment () {
+		return (Comment) configure (new Comment ());
+	}
+
+	public Embedded create_embedded () {
+		return (Embedded) configure (new Embedded ());
+	}
+
+	public Headline create_headline () {
+		return (Headline) configure (new Headline ());
+	}
+
+	public Highlighted create_highlighted (Highlighted.Style style) {
+		return (Highlighted) configure (new Highlighted (style));
+	}
+
+	public Link create_link () {
+		return (Link) configure (new Link ());
+	}
+
+	public List create_list () {
+		return (List) configure (new List ());
+	}
+
+	public ListItem create_list_item () {
+		return (ListItem) configure (new ListItem ());
+	}
+
+	public Page create_page () {
+		return (Page) configure (new Page ());
+	}
+
+	public Paragraph create_paragraph () {
+		return (Paragraph) configure (new Paragraph ());
+	}
+
+	public SourceCode create_source_code () {
+		return (SourceCode) configure (new SourceCode ());
+	}
+
+	public Table create_table () {
+		return (Table) configure (new Table ());
+	}
+
+	public TableCell create_table_cell () {
+		return (TableCell) configure (new TableCell ());
+	}
+
+	public Taglet create_taglet (string name) {
+		return _modules.create_taglet (name);
+	}
+
+	public Text create_text (string? text = null) {
+		return (Text) configure (new Text (text));
+	}
+
+	public ContentElement set_style_attributes (StyleAttributes element,
+	                                            VerticalAlign? valign,
+	                                            HorizontalAlign? halign,
+	                                            string? style) {
+		element.vertical_align = valign;
+		element.horizontal_align = halign;
+		element.style = style;
+		return element;
+	}
+}
diff --git a/src/libvaladoc/html/attribute.vala b/src/libvaladoc/content/contentrenderer.vala
similarity index 66%
copy from src/libvaladoc/html/attribute.vala
copy to src/libvaladoc/content/contentrenderer.vala
index 7d8e89e..6f3b849 100755
--- a/src/libvaladoc/html/attribute.vala
+++ b/src/libvaladoc/content/contentrenderer.vala
@@ -1,36 +1,32 @@
-/*
+/* contentrenderer.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2009 Florian Brosch
- * 
+ * 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 Gee;
 
+public abstract class Valadoc.Content.ContentRenderer : ContentVisitor {
 
-public class Valadoc.Html.Attribute {
-	private string name;
-	private string val;
+	public abstract void render (ContentElement element);
 
-	public Attribute (string name, string val) {
-		this.name = name;
-		this.val = val;
-	}
-
-	public string to_string (string path) {
-		return " %s=\"%s\"".printf (this.name, this.val);
-	}
+	public abstract void render_children (ContentElement element);
 }
-
diff --git a/src/libvaladoc/content/contentvisitor.vala b/src/libvaladoc/content/contentvisitor.vala
new file mode 100755
index 0000000..2a47608
--- /dev/null
+++ b/src/libvaladoc/content/contentvisitor.vala
@@ -0,0 +1,73 @@
+/* contentvisitor.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 Gee;
+
+public abstract class Valadoc.Content.ContentVisitor : Object {
+
+	public virtual void visit_comment (Comment element) {
+	}
+
+	public virtual void visit_embedded (Embedded element) {
+	}
+
+	public virtual void visit_headline (Headline element) {
+	}
+
+	public virtual void visit_highlighted (Highlighted element) {
+	}
+
+	public virtual void visit_link (Link element) {
+	}
+
+	public virtual void visit_symbol_link (SymbolLink element) {
+	}
+
+	public virtual void visit_list (List element) {
+	}
+
+	public virtual void visit_list_item (ListItem element) {
+	}
+
+	public virtual void visit_paragraph (Paragraph element) {
+	}
+
+	public virtual void visit_page (Page element) {
+	}
+
+	public virtual void visit_source_code (SourceCode element) {
+	}
+
+	public virtual void visit_table (Table element) {
+	}
+
+	public virtual void visit_table_cell (TableCell element) {
+	}
+
+	public virtual void visit_taglet (Taglet element) {
+	}
+
+	public virtual void visit_text (Text element) {
+	}
+}
diff --git a/src/libvaladoc/content/embedded.vala b/src/libvaladoc/content/embedded.vala
new file mode 100755
index 0000000..543a776
--- /dev/null
+++ b/src/libvaladoc/content/embedded.vala
@@ -0,0 +1,52 @@
+/* embedded.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 Gee;
+
+public class Valadoc.Content.Embedded : ContentElement, Inline, StyleAttributes {
+	public string url { get; set; }
+	public string caption { get; set; }
+
+	public HorizontalAlign? horizontal_align { get; set; }
+	public VerticalAlign? vertical_align { get; set; }
+	public string? style { get; set; }
+
+	private ResourceLocator _locator;
+
+	internal Embedded () {
+		base ();
+	}
+
+	public override void configure (Settings settings, ResourceLocator locator) {
+		_locator = locator;
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// Check the image exists if it a local resource
+	}
+
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_embedded (this);
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/headline.vala b/src/libvaladoc/content/headline.vala
similarity index 55%
copy from src/doclets/htmlhelpers/taglets/headline.vala
copy to src/libvaladoc/content/headline.vala
index 117d522..1d11a74 100755
--- a/src/doclets/htmlhelpers/taglets/headline.vala
+++ b/src/libvaladoc/content/headline.vala
@@ -1,42 +1,45 @@
-/*
+/* headline.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public class Valadoc.Content.Headline : Block, InlineContent {
+	public int level { get; set; }
+
+	internal Headline () {
+		base ();
+		_level = 0;
+	}
 
-public class Valadoc.Html.HeadlineDocElement : Valadoc.HeadlineDocElement {
-	private string title;
-	private int lvl;
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// TODO report error if level == 0 ?
 
-	public override bool parse (string title, int lvl) {
-		this.title = title;
-		this.lvl = lvl;
-		return true;
+		// Check inline content
+		base.check (api_root, container, reporter);
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("\n\n<h%d>%s</h%d>\n", this.lvl, this.title, this.lvl);
-		return true;
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_headline (this);
 	}
 }
-
-
diff --git a/src/doclets/htmlhelpers/taglets/bold.vala b/src/libvaladoc/content/highlighted.vala
similarity index 52%
rename from src/doclets/htmlhelpers/taglets/bold.vala
rename to src/libvaladoc/content/highlighted.vala
index 1aa13a4..2842a00 100755
--- a/src/doclets/htmlhelpers/taglets/bold.vala
+++ b/src/libvaladoc/content/highlighted.vala
@@ -1,51 +1,52 @@
-/*
+/* highlighted.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
-
-public class Valadoc.Html.BoldDocElement : Valadoc.BoldDocElement {
-	private Gee.ArrayList<DocElement> content;
-
-	public override bool parse ( Gee.ArrayList<DocElement> content ) {
-		this.content = content;
-		return true;
+public class Valadoc.Content.Highlighted : InlineContent, Inline {
+	public enum Style {
+		NONE,
+		BOLD,
+		ITALIC,
+		UNDERLINED,
+		MONOSPACED,
+		STROKE
 	}
 
-	public override bool write ( void* res, int max, int index ) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		int _max = this.content.size;
-		int _index = 0;
+	public Style style { get; set; }
 
-		file.printf ( "<b>" );
+	internal Highlighted (Style style) {
+		base ();
+		_style = style;
+	}
 
-		foreach ( DocElement element in this.content ) {
-			element.write ( res, _max, _index );
-			_index++;
-		}
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// Check inline content
+		base.check (api_root, container, reporter);
+	}
 
-		file.printf ( "</b>" );
-		return true;
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_highlighted (this);
 	}
 }
-
-
-
diff --git a/src/libvaladoc/html/attribute.vala b/src/libvaladoc/content/inline.vala
similarity index 69%
copy from src/libvaladoc/html/attribute.vala
copy to src/libvaladoc/content/inline.vala
index 7d8e89e..d225bef 100755
--- a/src/libvaladoc/html/attribute.vala
+++ b/src/libvaladoc/content/inline.vala
@@ -1,36 +1,28 @@
-/*
+/* inline.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2009 Florian Brosch
- * 
+ * 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 Gee;
 
-
-public class Valadoc.Html.Attribute {
-	private string name;
-	private string val;
-
-	public Attribute (string name, string val) {
-		this.name = name;
-		this.val = val;
-	}
-
-	public string to_string (string path) {
-		return " %s=\"%s\"".printf (this.name, this.val);
-	}
+public interface Valadoc.Content.Inline : ContentElement {
 }
-
diff --git a/src/doclets/htmlhelpers/taglets/italic.vala b/src/libvaladoc/content/inlinecontent.vala
similarity index 50%
rename from src/doclets/htmlhelpers/taglets/italic.vala
rename to src/libvaladoc/content/inlinecontent.vala
index a100318..147b9e5 100755
--- a/src/doclets/htmlhelpers/taglets/italic.vala
+++ b/src/libvaladoc/content/inlinecontent.vala
@@ -1,50 +1,50 @@
-/*
+/* inlinecontent.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public abstract class Valadoc.Content.InlineContent : ContentElement {
+	public Gee.List<Inline> content { get { return _content; } }
 
-public class Valadoc.Html.ItalicDocElement : Valadoc.ItalicDocElement {
-	private Gee.ArrayList<DocElement> content;
+	private Gee.List<Inline> _content;
 
-	public override bool parse ( Gee.ArrayList<DocElement> content ) {
-		this.content = content;
-		return true;
+	construct {
+		_content = new ArrayList<Inline> ();
 	}
 
-	public override bool write ( void* res, int max, int index ) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		int _max = this.content.size;
-		int _index = 0;
-
-		file.printf ( "<i>" );
+	internal InlineContent () {
+	}
 
-		foreach ( DocElement element in this.content ) {
-			element.write ( res, _max, _index );
-			_index++;
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		foreach (Inline element in _content) {
+			element.check (api_root, container, reporter);
 		}
+	}
 
-		file.printf ( "</i>" );
-		return true;
+	public override void accept_children (ContentVisitor visitor) {
+		foreach (Inline element in _content) {
+			element.accept (visitor);
+		}
 	}
 }
-
-
diff --git a/src/libvaladoc/content/inlinetaglet.vala b/src/libvaladoc/content/inlinetaglet.vala
new file mode 100755
index 0000000..f474c14
--- /dev/null
+++ b/src/libvaladoc/content/inlinetaglet.vala
@@ -0,0 +1,61 @@
+/* taglet.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 Gee;
+
+public abstract class Valadoc.Content.InlineTaglet : ContentElement, Taglet, Inline {
+	protected Settings settings;
+	protected ResourceLocator locator;
+	private ContentElement _content;
+
+	public InlineTaglet () {
+		base ();
+	}
+
+	public abstract Rule? get_parser_rule (Rule run_rule);
+
+	public abstract ContentElement produce_content ();
+
+	private ContentElement get_content () {
+		if (_content == null) {
+			_content = produce_content ();
+		}
+		return _content;
+	}
+
+	public override void configure (Settings settings, ResourceLocator locator) {
+		this.settings = settings;
+		this.locator = locator;
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		ContentElement element = get_content ();
+		element.check (api_root, container, reporter);
+	}
+
+	public override void accept (ContentVisitor visitor) {
+		ContentElement element = get_content ();
+		element.accept (visitor);
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/headline.vala b/src/libvaladoc/content/link.vala
similarity index 56%
copy from src/doclets/htmlhelpers/taglets/headline.vala
copy to src/libvaladoc/content/link.vala
index 117d522..2f9abbb 100755
--- a/src/doclets/htmlhelpers/taglets/headline.vala
+++ b/src/libvaladoc/content/link.vala
@@ -1,42 +1,44 @@
-/*
+/* link.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public class Valadoc.Content.Link : ContentElement, Inline {
+	public string url { get; set; }
+	public string label { get; set; }
 
-public class Valadoc.Html.HeadlineDocElement : Valadoc.HeadlineDocElement {
-	private string title;
-	private int lvl;
-
-	public override bool parse (string title, int lvl) {
-		this.title = title;
-		this.lvl = lvl;
-		return true;
+	internal Link () {
+		base ();
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("\n\n<h%d>%s</h%d>\n", this.lvl, this.title, this.lvl);
-		return true;
+	public override void configure (Settings settings, ResourceLocator locator) {
 	}
-}
 
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+	}
 
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_link (this);
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/listelement.vala b/src/libvaladoc/content/list.vala
similarity index 50%
rename from src/doclets/htmlhelpers/taglets/listelement.vala
rename to src/libvaladoc/content/list.vala
index 8b44ff8..59987bf 100755
--- a/src/doclets/htmlhelpers/taglets/listelement.vala
+++ b/src/libvaladoc/content/list.vala
@@ -1,50 +1,49 @@
-/*
+/* list.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public class Valadoc.Content.List : ContentElement, Block {
+	public Gee.List<ListItem> items { get { return _items; } }
+	
+	private Gee.List<ListItem> _items;
 
-public class Valadoc.Html.ListEntryDocElement : Valadoc.ListEntryDocElement {
-	private Gee.ArrayList<DocElement> content;
-
-	public override bool parse ( ListType type, long lvl, Gee.ArrayList<DocElement> content ) {
-		this.content = content;
-		return true;
+	internal List () {
+		base ();
+		_items = new ArrayList<ListItem> ();
 	}
 
-	public override bool write ( void* res, int max, int index ) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		int _max = this.content.size;
-		int _index = 0;
-
-		file.printf ( "\t<li>" );
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// Check the list consistency in terms of successive item levels ?
 
-		foreach ( DocElement element in this.content ) {
-			element.write ( res, _max, _index );
-			_index++;
+		// Check individual list items
+		foreach (ListItem element in _items) {
+			element.check (api_root, container, reporter);
 		}
+	}
 
-		file.printf ( "</li>\n" );
-		return true;
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_list (this);
 	}
 }
-
-
diff --git a/src/libvaladoc/content/listitem.vala b/src/libvaladoc/content/listitem.vala
new file mode 100755
index 0000000..9b11a4b
--- /dev/null
+++ b/src/libvaladoc/content/listitem.vala
@@ -0,0 +1,57 @@
+/* listitem.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 Gee;
+
+public class Valadoc.Content.ListItem : InlineContent {
+	public enum Bullet {
+		NONE,
+		UNORDERED,
+		ORDERED,
+		ORDERED_LATIN,
+		ORDERED_CAPITAL,
+		ORDERED_NUMBER,
+		ORDERED_LOWER_CASE
+	}
+
+	public Bullet bullet { get; set; }
+	public int level { get; set; }
+
+	internal ListItem () {
+		base ();
+		_bullet = Bullet.UNORDERED;
+		_level = 0;
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// TODO report error if level == 0 ?
+
+		// Check inline content
+		base.check (api_root, container, reporter);
+	}
+
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_list_item (this);
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/headline.vala b/src/libvaladoc/content/page.vala
similarity index 61%
copy from src/doclets/htmlhelpers/taglets/headline.vala
copy to src/libvaladoc/content/page.vala
index 117d522..2580bf4 100755
--- a/src/doclets/htmlhelpers/taglets/headline.vala
+++ b/src/libvaladoc/content/page.vala
@@ -1,42 +1,35 @@
-/*
+/* page.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
-
-public class Valadoc.Html.HeadlineDocElement : Valadoc.HeadlineDocElement {
-	private string title;
-	private int lvl;
-
-	public override bool parse (string title, int lvl) {
-		this.title = title;
-		this.lvl = lvl;
-		return true;
+public class Valadoc.Content.Page : BlockContent {
+	internal Page () {
+		base ();
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("\n\n<h%d>%s</h%d>\n", this.lvl, this.title, this.lvl);
-		return true;
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_page (this);
 	}
 }
-
-
diff --git a/src/doclets/htmlhelpers/taglets/paragraph.vala b/src/libvaladoc/content/paragraph.vala
similarity index 52%
copy from src/doclets/htmlhelpers/taglets/paragraph.vala
copy to src/libvaladoc/content/paragraph.vala
index 42981a3..138c4c3 100755
--- a/src/doclets/htmlhelpers/taglets/paragraph.vala
+++ b/src/libvaladoc/content/paragraph.vala
@@ -1,50 +1,44 @@
-/*
+/* paragraph.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public class Valadoc.Content.Paragraph : InlineContent, Block, StyleAttributes {
+	public HorizontalAlign? horizontal_align { get; set; }
+	public VerticalAlign? vertical_align { get; set; }
+	public string? style { get; set; }
 
-public class Valadoc.Html.ParagraphDocElement : Valadoc.ParagraphDocElement {
-	private ArrayList<DocElement> content;
-
-	public override bool parse (ArrayList<DocElement> content) {
-		this.content = content;
-		return true;
+	internal Paragraph () {
+		base ();
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		int _max = this.content.size;
-		int _index = 0;
-
-		file.printf ("<p>");
-
-		foreach (DocElement element in this.content) {
-			element.write (res, _max, _index);
-			_index++;
-		}
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// Check inline content
+		base.check (api_root, container, reporter);
+	}
 
-		file.printf ("</p>");
-		return true;
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_paragraph (this);
 	}
 }
-
-
diff --git a/src/libvaladoc/html/attribute.vala b/src/libvaladoc/content/resourcelocator.vala
similarity index 69%
copy from src/libvaladoc/html/attribute.vala
copy to src/libvaladoc/content/resourcelocator.vala
index 7d8e89e..b188cb1 100755
--- a/src/libvaladoc/html/attribute.vala
+++ b/src/libvaladoc/content/resourcelocator.vala
@@ -1,36 +1,29 @@
-/*
+/* resourcelocator.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2009 Florian Brosch
- * 
+ * 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 Gee;
 
-
-public class Valadoc.Html.Attribute {
-	private string name;
-	private string val;
-
-	public Attribute (string name, string val) {
-		this.name = name;
-		this.val = val;
-	}
-
-	public string to_string (string path) {
-		return " %s=\"%s\"".printf (this.name, this.val);
-	}
+public interface Valadoc.ResourceLocator : Object {
+	public abstract string resolve (string path);
 }
-
diff --git a/src/doclets/htmlhelpers/taglets/headline.vala b/src/libvaladoc/content/sourcecode.vala
similarity index 55%
copy from src/doclets/htmlhelpers/taglets/headline.vala
copy to src/libvaladoc/content/sourcecode.vala
index 117d522..4be3aa2 100755
--- a/src/doclets/htmlhelpers/taglets/headline.vala
+++ b/src/libvaladoc/content/sourcecode.vala
@@ -1,42 +1,48 @@
-/*
+/* sourcecode.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public class Valadoc.Content.SourceCode : ContentElement, Block {
+	public enum Language {
+		GENIE,
+		VALA,
+		C
+	}
 
-public class Valadoc.Html.HeadlineDocElement : Valadoc.HeadlineDocElement {
-	private string title;
-	private int lvl;
+	public string code { get; set; }
+	public Language language { get; set; }
 
-	public override bool parse (string title, int lvl) {
-		this.title = title;
-		this.lvl = lvl;
-		return true;
+	internal SourceCode () {
+		base ();
+		_language = Language.VALA;
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("\n\n<h%d>%s</h%d>\n", this.lvl, this.title, this.lvl);
-		return true;
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
 	}
-}
-
 
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_source_code (this);
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/headline.vala b/src/libvaladoc/content/styleattributes.vala
similarity index 58%
copy from src/doclets/htmlhelpers/taglets/headline.vala
copy to src/libvaladoc/content/styleattributes.vala
index 117d522..09283b9 100755
--- a/src/doclets/htmlhelpers/taglets/headline.vala
+++ b/src/libvaladoc/content/styleattributes.vala
@@ -1,42 +1,43 @@
-/*
+/* styleattributes.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
-
-public class Valadoc.Html.HeadlineDocElement : Valadoc.HeadlineDocElement {
-	private string title;
-	private int lvl;
-
-	public override bool parse (string title, int lvl) {
-		this.title = title;
-		this.lvl = lvl;
-		return true;
-	}
-
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("\n\n<h%d>%s</h%d>\n", this.lvl, this.title, this.lvl);
-		return true;
-	}
+public enum Valadoc.Content.HorizontalAlign {
+	LEFT,
+	RIGHT,
+	CENTER
 }
 
+public enum Valadoc.Content.VerticalAlign {
+	TOP,
+	MIDDLE,
+	BOTTOM
+}
 
+public interface Valadoc.Content.StyleAttributes : ContentElement {
+	public abstract HorizontalAlign? horizontal_align { get; set; }
+	public abstract VerticalAlign? vertical_align { get; set; }
+	public abstract string? style { get; set; }
+}
diff --git a/src/doclets/htmlhelpers/taglets/constants.vala b/src/libvaladoc/content/symbollink.vala
similarity index 51%
copy from src/doclets/htmlhelpers/taglets/constants.vala
copy to src/libvaladoc/content/symbollink.vala
index df71288..e5ab034 100755
--- a/src/doclets/htmlhelpers/taglets/constants.vala
+++ b/src/libvaladoc/content/symbollink.vala
@@ -1,45 +1,46 @@
-/*
+/* link.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public class Valadoc.Content.SymbolLink : ContentElement, Inline {
+	public DocumentedElement symbol { get; set; }
+	public string label { get; set; }
 
-public class Valadoc.Html.CodeConstantDocElement : Valadoc.CodeConstantDocElement {
-	private string constant;
-
-	public override bool parse (string constant) {
-		this.constant = constant;
-		return true;
+	internal SymbolLink (DocumentedElement? symbol = null, string? label = null) {
+		base ();
+		_symbol = symbol;
+		_label = label;
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("<font class=\"%s\">%s</font>", css_content_literal, this.constant);
-		return true;
+	public override void configure (Settings settings, ResourceLocator locator) {
 	}
-}
 
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+	}
 
-[ModuleInit]
-public GLib.Type register_plugin (Gee.HashMap<string, Type> taglets) {
-	return typeof (Valadoc.Html.CodeConstantDocElement);
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_symbol_link (this);
+	}
 }
-
diff --git a/src/libvaladoc/content/table.vala b/src/libvaladoc/content/table.vala
new file mode 100755
index 0000000..a5187d2
--- /dev/null
+++ b/src/libvaladoc/content/table.vala
@@ -0,0 +1,51 @@
+/* table.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 Gee;
+
+public class Valadoc.Content.Table : ContentElement, Block {
+	public Gee.List<Gee.List<TableCell>> cells { get { return _cells; } }
+
+	private Gee.List<Gee.List<TableCell>> _cells;
+
+	internal Table () {
+		base ();
+		_cells = new ArrayList<Gee.List<TableCell>> ();
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// Check the table consistency in term of row/column number
+
+		// Check individual cells
+		foreach (var row in _cells) {
+			foreach (var cell in row) {
+				cell.check (api_root, container, reporter);
+			}
+		}
+	}
+
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_table (this);
+	}
+}
diff --git a/src/libvaladoc/content/tablecell.vala b/src/libvaladoc/content/tablecell.vala
new file mode 100755
index 0000000..d816d34
--- /dev/null
+++ b/src/libvaladoc/content/tablecell.vala
@@ -0,0 +1,48 @@
+/* tablecell.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 Gee;
+
+public class Valadoc.Content.TableCell : InlineContent, StyleAttributes {
+	public HorizontalAlign? horizontal_align { get; set; }
+	public VerticalAlign? vertical_align { get; set; }
+	public string? style { get; set; }
+	public int colspan { get; set; }
+	public int rowspan { get; set; }
+
+	internal TableCell () {
+		base ();
+		_colspan = 1;
+		_rowspan = 1;
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// Check inline content
+		base.check (api_root, container, reporter);
+	}
+
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_table_cell (this);
+	}
+}
diff --git a/src/libvaladoc/html/attribute.vala b/src/libvaladoc/content/taglet.vala
similarity index 69%
copy from src/libvaladoc/html/attribute.vala
copy to src/libvaladoc/content/taglet.vala
index 7d8e89e..098d0f0 100755
--- a/src/libvaladoc/html/attribute.vala
+++ b/src/libvaladoc/content/taglet.vala
@@ -1,36 +1,30 @@
-/*
+/* taglet.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2009 Florian Brosch
- * 
+ * 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 Gee;
 
+public interface Valadoc.Content.Taglet : ContentElement {
 
-public class Valadoc.Html.Attribute {
-	private string name;
-	private string val;
-
-	public Attribute (string name, string val) {
-		this.name = name;
-		this.val = val;
-	}
-
-	public string to_string (string path) {
-		return " %s=\"%s\"".printf (this.name, this.val);
-	}
+	public abstract Rule? get_parser_rule (Rule run_rule);
 }
-
diff --git a/src/doclets/htmlhelpers/taglets/paragraph.vala b/src/libvaladoc/content/text.vala
similarity index 55%
rename from src/doclets/htmlhelpers/taglets/paragraph.vala
rename to src/libvaladoc/content/text.vala
index 42981a3..c749b1a 100755
--- a/src/doclets/htmlhelpers/taglets/paragraph.vala
+++ b/src/libvaladoc/content/text.vala
@@ -1,50 +1,46 @@
-/*
+/* text.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public class Valadoc.Content.Text : ContentElement, Inline {
+	public string content { get; set; }
 
-public class Valadoc.Html.ParagraphDocElement : Valadoc.ParagraphDocElement {
-	private ArrayList<DocElement> content;
-
-	public override bool parse (ArrayList<DocElement> content) {
-		this.content = content;
-		return true;
+	construct {
+		_content = "";
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		int _max = this.content.size;
-		int _index = 0;
-
-		file.printf ("<p>");
-
-		foreach (DocElement element in this.content) {
-			element.write (res, _max, _index);
-			_index++;
+	internal Text (string? text = null) {
+		if (text != null) {
+			_content = text;
 		}
-
-		file.printf ("</p>");
-		return true;
 	}
-}
 
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+	}
 
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_text (this);
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/constant.vala b/src/libvaladoc/documentation/documentation.vala
similarity index 65%
rename from src/doclets/htmlhelpers/taglets/constant.vala
rename to src/libvaladoc/documentation/documentation.vala
index 85ba9d6..7d36140 100755
--- a/src/doclets/htmlhelpers/taglets/constant.vala
+++ b/src/libvaladoc/documentation/documentation.vala
@@ -17,23 +17,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 using GLib;
 using Gee;
 
-
-public class Valadoc.Html.CodeConstantDocElement : Valadoc.CodeConstantDocElement {
-	private string constant;
-
-	public override bool parse (string constant) {
-		this.constant = constant;
-		return true;
-	}
-
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("<font class=\"%s\">%s</font>", css_content_literal, this.constant);
-		return true;
-	}
+public interface Valadoc.Documentation : Object {
+	public abstract string? get_filename ();
 }
-
diff --git a/src/libvaladoc/documentation/errorreporter.vala b/src/libvaladoc/documentation/errorreporter.vala
index 7c02458..82f76cd 100755
--- a/src/libvaladoc/documentation/errorreporter.vala
+++ b/src/libvaladoc/documentation/errorreporter.vala
@@ -63,8 +63,17 @@ public class Valadoc.ErrorReporter : Object {
 	private inline void msg ( ErrorType type, string file, long line, long startpos, long endpos, string errline, string msg ) {
 		this.stream.printf ( "%s:%lu.%lu-%lu.%lu: %s: %s\n", file, line, startpos, line, endpos, (type == ErrorType.ERROR)? "error" : "warning", msg );
 		if (startpos <= endpos) {
-			this.stream.printf ( "\t%s\n", errline );
-			this.stream.printf ( "\t%s%s\n", string.nfill ((uint)startpos, ' '), string.nfill( (uint)(endpos-startpos), '^' ) );
+			this.stream.printf ( "%s\n", errline );
+			for (int i = 0; i < errline.length; i++) {
+				if (errline[i] == '\t') {
+					this.stream.printf ("\t");
+				} else if (i >= startpos - 1 && i < endpos - 1) {
+					this.stream.printf ("^");
+				} else {
+					this.stream.printf (" ");
+				}
+			}
+			this.stream.printf ("\n");
 		}
 	}
 
diff --git a/src/libvaladoc/documentation/moduleloader.vala b/src/libvaladoc/documentation/moduleloader.vala
index ff96f90..891fbdb 100755
--- a/src/libvaladoc/documentation/moduleloader.vala
+++ b/src/libvaladoc/documentation/moduleloader.vala
@@ -29,24 +29,7 @@ public static delegate  void Valadoc.TagletRegisterFunction (ModuleLoader loader
 public class Valadoc.ModuleLoader : Object {
 	public Doclet doclet;
 
-	public Gee.HashMap<string, GLib.Type> taglets;
-	public GLib.Type bold;
-	public GLib.Type center;
-	public GLib.Type headline;
-	public GLib.Type image;
-	public GLib.Type italic;
-	public GLib.Type link;
-	public GLib.Type list;
-	public GLib.Type list_element;
-	public GLib.Type notification;
-	public GLib.Type right;
-	public GLib.Type source;
-	public GLib.Type source_inline;
-	public GLib.Type @string;
-	public GLib.Type table;
-	public GLib.Type table_cell;
-	public GLib.Type underline;
-	public GLib.Type paragraph;
+	public Gee.HashMap<string, GLib.Type> taglets = new Gee.HashMap<string, Type> (GLib.str_hash, GLib.str_equal);
 
 	private Module docletmodule;
 	private Type doclettype;
@@ -56,8 +39,11 @@ public class Valadoc.ModuleLoader : Object {
 		if ( tmp == false ) {
 			return false;
 		}
+		return true;
+	}
 
-		return this.load_taglets ( path );
+	public Content.Taglet create_taglet (string keyword) {
+		return (Content.Taglet) GLib.Object.new (taglets.get (keyword));
 	}
 
 	private bool load_doclet ( string path ) {
@@ -78,48 +64,4 @@ public class Valadoc.ModuleLoader : Object {
 		this.doclet = (Doclet)GLib.Object.new (doclettype);
 		return true;
 	}
-
-	private bool load_taglets (string fulldirpath) {
-		try {
-			taglets = new Gee.HashMap<string, Type> (GLib.str_hash, GLib.str_equal);
-			Gee.ArrayList<Module*> modules = new Gee.ArrayList<weak Module*> ( );
-
-			string pluginpath = build_filename(fulldirpath, "taglets");
-			size_t modulesuffixlen = Module.SUFFIX.size() + 1;
-
-			void* function;
-
-			GLib.Dir dir = GLib.Dir.open (pluginpath);
-
-			taglets.set ("toto", typeof (Type));
-			taglets.unset ("toto");
-
-			for (weak string entry = dir.read_name(); entry != null ; entry = dir.read_name()) {
-				if (!entry.has_suffix("." + Module.SUFFIX))
-					continue;
-
-				string tagletpath = build_filename (pluginpath, entry);
-				Module* module = Module.open (tagletpath, ModuleFlags.BIND_LAZY);
-				if (module == null) {
-					taglets = null;
-					return false;
-				}
-
-				module->symbol("register_plugin", out function);
-				Valadoc.TagletRegisterFunction tagletregisterfkt = (Valadoc.TagletRegisterFunction) function;
-				if (function == null) {
-					taglets = null;
-					return false;
-				}
-
-				tagletregisterfkt (this);
-			}
-			return true;
-		}
-		catch (FileError err) {
-			taglets = null;
-			return false;
-		}
-	}
 }
-
diff --git a/src/libvaladoc/documentation/wiki.vala b/src/libvaladoc/documentation/wiki.vala
index 76d25a5..f539239 100755
--- a/src/libvaladoc/documentation/wiki.vala
+++ b/src/libvaladoc/documentation/wiki.vala
@@ -19,7 +19,10 @@
 
 
 public class Valadoc.WikiPage : Object, Documentation {
-	private Gee.ArrayList<DocElement> content;
+	public Content.Page documentation {
+		protected set;
+		get;
+	}
 
 	public string documentation_str {
 		private set;
@@ -56,31 +59,8 @@ public class Valadoc.WikiPage : Object, Documentation {
 		}
 	}
 
-	public bool parse ( Parser docparser ) {
-		docparser.parse_wikipage ( this );
-		return true;
-	}
-
-	public void add_content (Gee.ArrayList<DocElement> content) {
-		this.content = content;
-	}
-
-	public bool write (void* res) {
-		if ( this.content == null )
-			return true;
-
-		int max = this.content.size;
-		bool tmp = false;
-		int i = 0;
-
-		foreach ( DocElement tag in this.content ) {
-			tmp = tag.write ( res, max, i );
-			if ( tmp == false )
-				return false;
-
-			i++;
-		}
-
+	public bool parse (DocumentationParser docparser) {
+		documentation = docparser.parse_wikipage ( this );
 		return true;
 	}
 }
@@ -113,7 +93,7 @@ public class Valadoc.WikiPageTree : Object {
 		return null;
 	}
 
-	private void create_tree_from_path (Parser docparser, string path, string? nameoffset = null) throws GLib.FileError {
+	private void create_tree_from_path (DocumentationParser docparser, string path, string? nameoffset = null) throws GLib.FileError {
 		Dir dir = Dir.open (path);
 
 		for (string? curname = dir.read_name(); curname!=null ; curname = dir.read_name()) {
@@ -129,7 +109,7 @@ public class Valadoc.WikiPageTree : Object {
 		}
 	}
 
-	public void create_tree ( Parser docparser ) throws GLib.FileError {
+	public void create_tree ( DocumentationParser docparser ) throws GLib.FileError {
 		try {
 			weak string path = this.settings.wiki_directory;
 			if (path == null) {
diff --git a/src/libvaladoc/parser/commentscanner.vala b/src/libvaladoc/parser/commentscanner.vala
new file mode 100644
index 0000000..aa74ad7
--- /dev/null
+++ b/src/libvaladoc/parser/commentscanner.vala
@@ -0,0 +1,69 @@
+/* commentscanner.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>
+ */
+
+public class Valadoc.CommentScanner : WikiScanner {
+
+	public CommentScanner (Settings settings) {
+		base (settings);
+	}
+
+	private bool in_line_start;
+	private bool past_star;
+	private int start_column;
+
+	public override void reset () {
+		base.reset ();
+
+		in_line_start = true;
+		past_star = false;
+		start_column = 0;
+	}
+
+	public override int get_line_start_column () {
+		return start_column;
+	}
+
+	protected override void accept (unichar c) throws ParserError {
+		if (in_line_start) {
+			start_column++;
+			if (c == '*') {
+				past_star = true;
+			} else if (past_star) {
+				past_star = false;
+				if (c == '\n') {
+					base.accept (c);
+					in_line_start = true;
+					start_column = 0;
+				} else if (c == ' ') {
+					in_line_start = false;
+				}
+			}
+		} else {
+			base.accept (c);
+			if (c == '\n') {
+				in_line_start = true;
+				start_column = 0;
+			}
+		}
+	}
+}
diff --git a/src/libvaladoc/parser/documentationparser.vala b/src/libvaladoc/parser/documentationparser.vala
new file mode 100644
index 0000000..f0b70f3
--- /dev/null
+++ b/src/libvaladoc/parser/documentationparser.vala
@@ -0,0 +1,518 @@
+/* documentationparser.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 Gee;
+using Valadoc.Content;
+
+public class Valadoc.DocumentationParser : Object, ResourceLocator {
+
+	public DocumentationParser (Settings settings, ErrorReporter reporter, Tree tree, ModuleLoader modules) {
+		_settings = settings;
+		_reporter = reporter;
+		_tree = tree;
+		_modules = modules;
+
+		_factory = new ContentFactory (_settings, this, _modules);
+
+		_wiki_scanner = new WikiScanner (_settings);
+		_wiki_parser = new Parser (_settings, _wiki_scanner, _reporter);
+		_wiki_scanner.set_parser (_wiki_parser);
+
+		_comment_scanner = new CommentScanner (_settings);
+		_comment_parser = new Parser (_settings, _comment_scanner, _reporter);
+		_comment_scanner.set_parser (_comment_parser);
+
+		init_rules ();
+	}
+
+	private Settings _settings;
+	private ErrorReporter _reporter;
+	private Tree _tree;
+	private ModuleLoader _modules;
+
+	private ContentFactory _factory;
+	private WikiScanner _wiki_scanner;
+	private CommentScanner _comment_scanner;
+	private Parser _wiki_parser;
+	private Parser _comment_parser;
+	
+	private Parser _parser;
+	private WikiScanner _scanner;
+
+	public Comment? parse (DocumentedElement element) {
+		if (element.documentation != null) {
+			return element.documentation;
+		}
+
+		var comment = element.vcomment as Vala.Comment;
+		if (comment == null) {
+			return null;
+		}
+
+		weak string content = element.vcomment.content;
+		var source_ref = comment.source_reference;
+		try {
+			Comment doc_comment = parse_comment (content, source_ref.file.filename, source_ref.first_line, source_ref.first_column);
+			doc_comment.check (_tree, element, _reporter);
+			return doc_comment;
+		} catch (ParserError error) {
+			return null;
+		}
+	}
+
+	public Page? parse_wikipage (WikiPage page) {
+		if (page.documentation != null) {
+			return page.documentation;
+		}
+
+		if (page.documentation_str == null) {
+			return null;
+		}
+
+		try {
+			Page documentation = parse_wiki (page.documentation_str, page.get_filename ());
+			documentation.check (_tree, null, _reporter);
+			return documentation;
+		} catch (ParserError error) {
+			return null;
+		}
+	}
+
+	private Comment parse_comment (string content, string filename, int first_line, int first_column) throws ParserError {
+		_parser = _comment_parser;
+		_scanner = _comment_scanner;
+		_stack.clear ();
+		_comment_parser.parse (content, filename, first_line, first_column);
+		return (Comment) pop ();
+	}
+
+	private Page parse_wiki (string content, string filename) throws ParserError {
+		_parser = _wiki_parser;
+		_scanner = _wiki_scanner;
+		_stack.clear ();
+		_wiki_parser.parse (content, filename, 0, 0);
+		return (Page) pop ();
+	}
+
+	public string resolve (string path) {
+		return path;
+	}
+
+	private ArrayList<Object> _stack = new ArrayList<Object> ();
+
+	private void push (Object element) {
+		_stack.add (element);
+	}
+
+	private Object peek () {
+		assert (_stack.size > 0);
+		return _stack.get (_stack.size - 1);
+	}
+
+	private Object pop () {
+		Object node = peek ();
+		_stack.remove_at (_stack.size - 1);
+		return node;
+	}
+
+	private Rule multiline_run;
+
+	private void init_rules () {
+		// Inline rules
+
+		StubRule run = new StubRule ();
+		run.set_name ("Run");
+
+		TokenType.Action add_text = (token) => {
+			var text = peek () as Text;
+			if (text == null) {
+				push (text = _factory.create_text ());
+			}
+			text.content += token.to_string ();
+		};
+
+		TokenType word = TokenType.any_word ().action (add_text);
+		TokenType space = TokenType.SPACE.action (add_text);
+
+		Rule text =
+			Rule.seq ({
+				word,
+				Rule.option ({ space }),
+				Rule.option ({
+					Rule.many ({
+						Rule.one_of ({
+							word,
+							TokenType.STAR.action (add_text),
+							TokenType.SHARP.action (add_text),
+							TokenType.LESS_THAN.action (add_text),
+							TokenType.GREATER_THAN.action (add_text),
+							TokenType.ALIGN_RIGHT.action (add_text),
+							TokenType.ALIGN_CENTER.action (add_text)
+						}),
+						Rule.option ({ space })
+					})
+				})
+			})
+			.set_name ("Text")
+			.set_start (() => { push (_factory.create_text ()); });
+
+		Rule run_with_spaces =
+			Rule.seq ({
+				Rule.many ({
+					Rule.option ({
+						Rule.many ({ TokenType.SPACE })
+					}),
+					run
+				})
+			})
+			.set_name ("RunWithSpaces");
+
+		multiline_run = Rule.many ({
+				run_with_spaces,
+				TokenType.EOL.action (() => { ((InlineContent) peek ()).content.add (_factory.create_text (" ")); })
+			})
+			.set_name ("MultiLineRun");
+
+		Rule inline_taglet =
+			Rule.seq ({
+				TokenType.OPEN_BRACE,
+				TokenType.AROBASE,
+				TokenType.any_word ().action ((token) => {
+					var taglet = _factory.create_taglet (token.to_string ());
+					if (!(taglet is Inline)) {
+						_parser.error ("Invalid taglet in this context: %s".printf (token.to_string ()));
+					}
+					push (taglet);
+					Rule? taglet_rule = taglet.get_parser_rule (multiline_run);
+					if (taglet_rule != null) {
+						_parser.push_rule (Rule.seq ({ TokenType.SPACE, taglet_rule }));
+					}
+				}),
+				TokenType.CLOSED_BRACE
+			})
+			.set_name ("InlineTaglet");
+
+		Rule bold =
+			Rule.seq ({ TokenType.SINGLE_QUOTE_2, run, TokenType.SINGLE_QUOTE_2 })
+				.set_name ("Bold")
+				.set_start (() => { push (_factory.create_highlighted (Highlighted.Style.BOLD)); });
+		Rule italic =
+			Rule.seq ({ TokenType.SLASH_2, run, TokenType.SLASH_2 })
+				.set_name ("Italic")
+				.set_start (() => { push (_factory.create_highlighted (Highlighted.Style.ITALIC)); });
+		Rule underlined =
+			Rule.seq ({ TokenType.UNDERSCORE_2, run, TokenType.UNDERSCORE_2 })
+				.set_name ("Underlined")
+				.set_start (() => { push (_factory.create_highlighted (Highlighted.Style.UNDERLINED)); });
+		Rule monospace =
+			Rule.seq ({ TokenType.BACK_QUOTE, run, TokenType.BACK_QUOTE })
+				.set_name ("Monospace")
+				.set_start (() => { push (_factory.create_highlighted (Highlighted.Style.MONOSPACED)); });
+
+		Rule embedded =
+			Rule.seq ({
+				TokenType.DOUBLE_OPEN_BRACE.action (() => { _scanner.set_url_escape_mode (true); }),
+				TokenType.any_word (),
+				Rule.option ({
+					TokenType.PIPE.action (() => { _scanner.set_url_escape_mode (false); }),
+					run
+				}),
+				TokenType.DOUBLE_CLOSED_BRACE.action (() => { _scanner.set_url_escape_mode (false); })
+			})
+			.set_name ("Embedded")
+			.set_start (() => { push (_factory.create_embedded ()); });
+		Rule link =
+			Rule.seq ({
+				TokenType.DOUBLE_OPEN_BRACKET.action (() => { _scanner.set_url_escape_mode (true); }),
+				TokenType.any_word (),
+				Rule.option ({
+					TokenType.PIPE.action (() => { _scanner.set_url_escape_mode (false); }),
+					run
+				}),
+				TokenType.DOUBLE_CLOSED_BRACKET.action (() => { _scanner.set_url_escape_mode (false); })
+			})
+			.set_name ("Link")
+			.set_start (() => { push (_factory.create_link ()); });
+
+		run.set_rule (
+			Rule.many ({
+				Rule.one_of ({
+					text, inline_taglet, bold, italic, underlined, monospace, embedded, link
+				})
+				.set_reduce (() => { ((InlineContent) peek ()).content.add ((Inline) pop ()); }),
+				Rule.option ({ space })
+				.set_reduce (() => { ((InlineContent) peek ()).content.add ((Inline) pop ()); })
+			})
+			.set_name ("Run")
+		);
+
+		// Block rules
+
+		Rule paragraph =
+			Rule.seq ({
+				Rule.option ({
+					Rule.one_of ({
+						TokenType.ALIGN_CENTER.action (() => { ((Paragraph) peek ()).horizontal_align = HorizontalAlign.RIGHT; }),
+						TokenType.ALIGN_RIGHT.action (() => { ((Paragraph) peek ()).horizontal_align = HorizontalAlign.RIGHT; })
+					})
+				}),
+				Rule.many ({
+					run,
+					TokenType.EOL.action (() => { ((Paragraph) peek ()).content.add (_factory.create_text (" ")); })
+				})
+			})
+			.set_name ("Paragraph")
+			.set_start (() => { push (_factory.create_paragraph ()); })
+			.set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+		Rule source_code =
+			Rule.seq ({
+				TokenType.TRIPLE_OPEN_BRACE.action ((token) => { _scanner.set_code_escape_mode (true); }),
+				TokenType.any_word ().action ((token) => { ((SourceCode) peek ()).code = token.to_string (); }),
+				TokenType.TRIPLE_CLOSED_BRACE.action ((token) => { _scanner.set_code_escape_mode (false); }),
+				TokenType.EOL
+			})
+			.set_name ("SourceCode")
+			.set_start (() => { push (_factory.create_source_code ()); })
+			.set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+		Rule list_item =
+			Rule.seq ({
+				Rule.many ({
+					TokenType.SPACE.action ((token) => { ((ListItem) peek ()).level++; })
+				}),
+				Rule.one_of ({
+					TokenType.STAR.action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.UNORDERED; }),
+					TokenType.SHARP.action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED; }),
+					TokenType.str (".").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.NONE; }),
+					TokenType.str ("I.").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED_LATIN; }),
+					TokenType.str ("A.").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED_CAPITAL; }),
+					TokenType.str ("1.").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED_NUMBER; }),
+					TokenType.str ("a.").action ((token) => { ((ListItem) peek ()).bullet = ListItem.Bullet.ORDERED_LOWER_CASE; })
+				}),
+				run,
+				TokenType.EOL
+			})
+			.set_name ("ListItem")
+			.set_start (() => { push (_factory.create_list_item ()); })
+			.set_reduce (() => { ((Content.List) peek ()).items.add ((ListItem) pop ()); });
+		Rule list =
+			Rule.seq ({
+				Rule.many ({
+					list_item
+				}),
+				TokenType.EOL
+			})
+			.set_name ("List")
+			.set_start (() => { push (_factory.create_list ()); })
+			.set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+		Rule table_cell_attributes =
+			Rule.seq ({
+				TokenType.LESS_THAN,
+				Rule.option ({
+					Rule.one_of ({
+						Rule.seq ({
+							Rule.option ({
+								Rule.one_of ({
+									TokenType.ALIGN_RIGHT.action ((token) => { ((TableCell) peek ()).horizontal_align = HorizontalAlign.RIGHT; }),
+									TokenType.ALIGN_CENTER.action ((token) => { ((TableCell) peek ()).horizontal_align = HorizontalAlign.CENTER; })
+								})
+							}),
+							Rule.option ({
+								Rule.one_of ({
+									TokenType.ALIGN_TOP.action ((token) => { ((TableCell) peek ()).vertical_align = VerticalAlign.TOP; }),
+									TokenType.ALIGN_BOTTOM.action ((token) => { ((TableCell) peek ()).vertical_align = VerticalAlign.BOTTOM; })
+								})
+							})
+						}),
+						TokenType.any_word ().action ((token) => { ((TableCell) peek ()).style = token.to_string (); })
+					})
+				}),
+				Rule.option ({
+					Rule.one_of ({
+						Rule.seq ({
+							TokenType.PIPE,
+							TokenType.any_number ().action ((token) => { ((TableCell) peek ()).colspan = token.to_int (); })
+						}),
+						Rule.seq ({
+							TokenType.MINUS,
+							TokenType.any_number ().action ((token) => { ((TableCell) peek ()).rowspan = token.to_int (); })
+						})
+					})
+				}),
+				TokenType.GREATER_THAN
+			})
+			.set_name ("CellAttributes");
+		Rule table_cell =
+			Rule.seq ({
+				Rule.seq ({
+					Rule.option ({
+						table_cell_attributes
+					}),
+					run_with_spaces,
+					Rule.option ({
+						Rule.many ({ TokenType.SPACE })
+					})
+				}),
+				TokenType.DOUBLE_PIPE
+			})
+			.set_name ("Cell")
+			.set_start (() => { push (_factory.create_table_cell ()); })
+			.set_reduce (() => { ((ArrayList<TableCell>) peek ()).add ((TableCell) pop ()); });
+		Rule table_row =
+			Rule.seq ({
+				TokenType.DOUBLE_PIPE,
+				Rule.many ({
+					table_cell
+				}),
+				TokenType.EOL
+			})
+			.set_name ("Row")
+			.set_start (() => { push (new ArrayList<TableCell> ()); })
+			.set_reduce (() => { ((Table) peek ()).cells.add ((ArrayList<TableCell>) pop ()); });
+		Rule table =
+			Rule.seq ({
+				Rule.many ({
+					table_row
+				})
+			})
+			.set_name ("Table")
+			.set_start (() => { push (_factory.create_table ()); })
+			.set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+		Rule headline =
+			Rule.one_of ({
+				Rule.seq ({
+					TokenType.EQUAL_1.action ((token) => { ((Headline) peek ()).level = 1; }),
+					run,
+					TokenType.EQUAL_1,
+					TokenType.EOL
+				}),
+				Rule.seq ({
+					TokenType.EQUAL_2.action ((token) => { ((Headline) peek ()).level = 2; }),
+					run,
+					TokenType.EQUAL_2,
+					TokenType.EOL
+				}),
+				Rule.seq ({
+					TokenType.EQUAL_3.action ((token) => { ((Headline) peek ()).level = 3; }),
+					run,
+					TokenType.EQUAL_3,
+					TokenType.EOL
+				}),
+				Rule.seq ({
+					TokenType.EQUAL_4.action ((token) => { ((Headline) peek ()).level = 4; }),
+					run,
+					TokenType.EQUAL_4,
+					TokenType.EOL
+				}),
+				Rule.seq ({
+					TokenType.EQUAL_5.action ((token) => { ((Headline) peek ()).level = 5; }),
+					run,
+					TokenType.EQUAL_5,
+					TokenType.EOL
+				})
+			})
+			.set_name ("Headline")
+			.set_start (() => { push (_factory.create_headline ()); })
+			.set_reduce (() => { ((BlockContent) peek ()).content.add ((Block) pop ()); });
+
+		Rule blocks =
+			Rule.one_of ({
+				source_code,
+				list,
+				table,
+				headline,
+				paragraph
+			})
+			.set_name ("Blocks");
+
+		Rule page =
+			Rule.seq ({
+				blocks,
+				Rule.option ({
+					Rule.many ({
+						TokenType.EOL,
+						Rule.option ({ blocks })
+					})
+				})
+			})
+			.set_name ("Page")
+			.set_start (() => { push (_factory.create_page ()); });
+
+		Rule description =
+			Rule.seq ({
+				blocks,
+				Rule.option ({
+					Rule.many ({
+						TokenType.EOL,
+						Rule.option ({ blocks })
+					})
+				})
+			})
+			.set_name ("Description");
+
+		Rule taglet =
+			Rule.seq ({
+				TokenType.AROBASE,
+				TokenType.any_word ().action ((token) => {
+					var taglet = _factory.create_taglet (token.to_string ());
+					if (!(taglet is Block)) {
+						_parser.error ("Invalid taglet in this context", token);
+					}
+					push (taglet);
+					Rule? taglet_rule = taglet.get_parser_rule (multiline_run);
+					if (taglet_rule != null) {
+						_parser.push_rule (Rule.seq ({ TokenType.SPACE, taglet_rule }));
+					}
+				}),
+				Rule.option ({
+					Rule.many ({ TokenType.EOL })
+				})
+			})
+			.set_name ("Taglet")
+			.set_reduce (() => { ((Comment) peek ()).taglets.add ((Taglet) pop ()); });
+
+		Rule comment =
+			Rule.seq ({
+				TokenType.EOL,
+				description,
+				Rule.option ({
+					Rule.many ({ taglet })
+				})
+			})
+			.set_name ("Comment")
+			.set_start (() => { push (_factory.create_comment ()); });
+
+		_comment_parser.set_root_rule (comment);
+		_wiki_parser.set_root_rule (page);
+	}
+
+	private void dump_stack () {
+		message ("Dumping stack");
+		foreach (Object object in _stack) {
+			message ("%s", object.get_type ().name ());
+		}
+	}
+}
diff --git a/src/libvaladoc/parser/manyrule.vala b/src/libvaladoc/parser/manyrule.vala
new file mode 100644
index 0000000..d3d0673
--- /dev/null
+++ b/src/libvaladoc/parser/manyrule.vala
@@ -0,0 +1,108 @@
+/* parser.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 Gee;
+
+internal class Valadoc.ManyRule : Rule {
+
+	public ManyRule (Object scheme) {
+		_scheme = scheme;
+	}
+
+	private Object _scheme;
+
+	private class State : Object {
+		public bool started = false;
+		public bool done_one = false;
+	}
+
+	public override bool is_optional () {
+		return is_optional_rule (_scheme);
+	}
+
+	public override bool starts_with_token (Token token) {
+		if (has_start_token (_scheme, token)) {
+			return true;
+		}
+		return false;
+	}
+
+	public override bool accept_token (Token token, ParserCallback parser, Rule.Forward forward) throws ParserError {
+		var state = parser.get_rule_state () as State;
+		if (state == null) {
+			state = new State ();
+			parser.set_rule_state (state);
+		}
+
+		if (!state.started) {
+			do_start (parser);
+			state.started = true;
+		}
+
+		if (state.done_one && parser.would_parent_accept_token (token)) {
+			do_reduce (parser);
+			return false;
+		}
+		if (parser.would_parent_reduce_to_rule (token, this)) {
+			do_reduce (parser);
+			return false;
+		}
+
+		bool handled;
+		if (try_to_apply (_scheme, token, parser, out handled)) {
+			state.done_one = true;
+			return handled;
+		}
+		if (parser.would_parent_accept_token (token)) {
+			do_reduce (parser);
+			return false;
+		}
+
+		if (_scheme is TokenType) {
+			parser.error ("expected %s".printf (((TokenType) _scheme).to_pretty_string ()), token);
+		} else {
+			parser.error ("unexpected token", token);
+		}
+		assert_not_reached ();
+	}
+
+	public override bool would_accept_token (Token token, Object? state) {
+		if (has_start_token (_scheme, token)) {
+			return true;
+		}
+		return false;
+	}
+
+	public override bool would_reduce (Token token, Object? rule_state) {
+		var state = rule_state as State;
+		return state.done_one || is_optional_rule (_scheme);
+	}
+
+	public override string to_string (Object? rule_state) {
+		var state = rule_state as State;
+		if (state == null) {
+			state = new State ();
+		}
+		return "%-15s%-15s(started=%s;done_one=%s)".printf (name != null ? name : " ", "[many]", state.started.to_string (), state.done_one.to_string ());
+	}
+}
diff --git a/src/libvaladoc/parser/oneofrule.vala b/src/libvaladoc/parser/oneofrule.vala
new file mode 100644
index 0000000..3613e00
--- /dev/null
+++ b/src/libvaladoc/parser/oneofrule.vala
@@ -0,0 +1,94 @@
+/* parser.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 Gee;
+
+internal class Valadoc.OneOfRule : Rule {
+
+	public OneOfRule (Object[] scheme) {
+		_scheme = scheme;
+	}
+
+	private Object[] _scheme;
+
+	private class State : Object {
+		public int selected = -1;
+	}
+
+	public override bool is_optional () {
+		return false;
+	}
+
+	public override bool starts_with_token (Token token) {
+		foreach (Object? scheme_element in _scheme) {
+			if (has_start_token (scheme_element, token)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public override bool accept_token (Token token, ParserCallback parser, Rule.Forward forward) throws ParserError {
+		var state = parser.get_rule_state () as State;
+		if (state == null) {
+			state = new State ();
+			parser.set_rule_state (state);
+		}
+
+		if (state.selected == -1) {
+			do_start (parser);
+
+			bool handled;
+			for (int i = 0; i < _scheme.length; i++) {
+				Object? scheme_element = _scheme[i];
+				if (try_to_apply (scheme_element, token, parser, out handled)) {
+					state.selected = i;
+					return handled;
+				}
+			}
+		} else {
+			do_reduce (parser);
+			return false;
+		}
+
+		parser.error ("unexpected token", token);
+		assert_not_reached ();
+	}
+
+	public override bool would_accept_token (Token token, Object? state) {
+		return false;
+	}
+
+	public override bool would_reduce (Token token, Object? rule_state) {
+		var state = rule_state as State;
+		return state.selected != -1;
+	}
+
+	public override string to_string (Object? rule_state) {
+		var state = rule_state as State;
+		if (state == null) {
+			state = new State ();
+		}
+		return "%-15s%-15s(selected=%d/%d)".printf (name != null ? name : " ", "[one-of]", state.selected, _scheme.length);
+	}
+}
diff --git a/src/libvaladoc/parser/optionalrule.vala b/src/libvaladoc/parser/optionalrule.vala
new file mode 100644
index 0000000..656cf4f
--- /dev/null
+++ b/src/libvaladoc/parser/optionalrule.vala
@@ -0,0 +1,85 @@
+/* parser.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 Gee;
+
+internal class Valadoc.OptionalRule : Rule {
+
+	public OptionalRule (Object scheme) {
+		_scheme = scheme;
+	}
+
+	private Object _scheme;
+
+	private class State : Object {
+		public bool started = false;
+	}
+
+	public override bool is_optional () {
+		return true;
+	}
+
+	public override bool starts_with_token (Token token) {
+		return has_start_token (_scheme, token);
+	}
+
+	public override bool accept_token (Token token, ParserCallback parser, Rule.Forward forward) throws ParserError {
+		var state = parser.get_rule_state () as State;
+		if (state == null) {
+			state = new State ();
+			parser.set_rule_state (state);
+		}
+
+		if (!state.started) {
+			do_start (parser);
+			state.started = true;
+
+			bool handled;
+			if (try_to_apply (_scheme, token, parser, out handled)) {
+				return handled;
+			} else {
+				do_reduce (parser);
+				return false;
+			}
+		} else {
+			do_reduce (parser);
+			return false;
+		}
+	}
+
+	public override bool would_accept_token (Token token, Object? state) {
+		return false;
+	}
+
+	public override bool would_reduce (Token token, Object? state) {
+		return true;
+	}
+
+	public override string to_string (Object? rule_state) {
+		var state = rule_state as State;
+		if (state == null) {
+			state = new State ();
+		}
+		return "%-15s%-15s(started=%s)".printf (name != null ? name : " ", "[option]", state.started.to_string ());
+	}
+}
diff --git a/src/libvaladoc/parser/parser.vala b/src/libvaladoc/parser/parser.vala
new file mode 100644
index 0000000..ade9ec1
--- /dev/null
+++ b/src/libvaladoc/parser/parser.vala
@@ -0,0 +1,286 @@
+/* parser.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 Gee;
+
+public errordomain Valadoc.ParserError {
+	INTERNAL_ERROR,
+	UNEXPECTED_TOKEN
+}
+
+public class Valadoc.Parser : ParserCallback {
+
+	public Parser (Settings settings, Scanner scanner, ErrorReporter reporter) {
+		_settings = settings;
+		_scanner = scanner;
+		_reporter = reporter;
+
+		TokenType.init_token_types ();
+	}
+
+	private Settings _settings;
+	private Scanner _scanner;
+	private ErrorReporter _reporter;
+	private Rule _root_rule;
+
+	private string _filename;
+	private int _first_line;
+	private int _first_column;
+	private Token _current_token;
+
+	private ArrayList<Rule> rule_stack = new ArrayList<Rule> ();
+	private ArrayList<Object?> rule_state_stack = new ArrayList<Object?> ();
+
+	public void set_root_rule (Rule root_rule) {
+		_root_rule = root_rule;
+	}
+
+	public void parse (string content, string filename, int first_line, int first_column) throws ParserError {
+		_filename = filename;
+		_first_line = first_line;
+		_first_column = first_column;
+
+		rule_stack.clear ();
+		rule_state_stack.clear ();
+
+		try {
+			push_rule (_root_rule);
+			_scanner.reset ();
+			_scanner.scan (content);
+			_scanner.end ();
+
+			if (rule_stack.size != 0) {
+				error ("Rule stack is not empty!");
+			}
+		} catch (ParserError e) {
+			#if DEBUG
+				log_error (e.message);
+			#endif
+			// Set an in_error boolean, try to recover
+			// And only throw the error at the end of parse ?
+			throw e;
+		}
+	}
+
+	public void accept_token (Token token) throws ParserError {
+		#if HARD_DEBUG
+			debug ("Incomming token: %s", token.to_pretty_string ());
+		#endif
+
+		_current_token = token;
+		int rule_depth = rule_stack.size;
+		Rule.Forward forward = Rule.Forward.NONE;
+		Rule? rule = peek_rule ();
+		if (rule == null) {
+			throw new ParserError.INTERNAL_ERROR ("Rule stack is empty!");
+		}
+		while (rule != null) {
+			if (rule.accept_token (token, this, forward)) {
+				break;
+			}
+
+			// Check for invalid recursion
+			if (rule_depth != rule_stack.size && peek_rule () == rule) {
+				error ("Parser state error");
+				break;
+			}
+			rule = peek_rule ();
+
+			// Rule stack size have changed
+			// Check for propagation
+			forward = rule_depth > rule_stack.size ? Rule.Forward.CHILD
+			                                       : Rule.Forward.PARENT;
+			rule_depth = rule_stack.size;
+		}
+	}
+
+	private Rule? peek_rule (int offset = -1) {
+		assert (offset < 0);
+		if (rule_stack.size + offset < 0) {
+			return null;
+		}
+		return rule_stack.get (rule_stack.size + offset);
+	}
+
+	private Rule pop_rule () {
+		int last_index = rule_stack.size - 1;
+		Rule rule = rule_stack.get (last_index);
+		rule_stack.remove_at (last_index);
+		rule_state_stack.remove_at (last_index);
+		return rule;
+	}
+
+	public void push_rule (Rule rule) {
+		rule_stack.add (rule);
+		rule_state_stack.add (null);
+
+		#if HARD_DEBUG
+			debug ("Pushed at  %2d: %s", rule_stack.size - 1, rule.to_string (null));
+		#endif
+	}
+
+	private Object? peek_state (int offset = -1) {
+		assert (offset < 0);
+		if (rule_state_stack.size + offset < 0) {
+			return null;
+		}
+		return rule_state_stack.get (rule_state_stack.size + offset);
+	}
+
+	public Object? get_rule_state () {
+		return peek_state ();
+	}
+
+	public void set_rule_state (Object state) {
+		int last_index = rule_stack.size - 1;
+		rule_state_stack.set (last_index, state);
+	}
+
+	public void reduce () {
+		pop_rule ();
+
+		#if HARD_DEBUG
+			Rule? parent_rule = peek_rule ();
+			if (parent_rule != null) {
+				debug ("Reduced to %2d: %s", rule_stack.size - 1, parent_rule.to_string (peek_state ()));
+			}
+		#endif
+	}
+
+	public bool would_parent_accept_token (Token token) {
+		int offset = -2;
+		Rule? parent_rule = peek_rule (offset);
+		Object? state = peek_state (offset);
+		while (parent_rule != null) {
+			#if VERY_HARD_DEBUG
+				debug ("WouldAccept - Offset %d; Index %d: %s", offset, rule_stack.size + offset, parent_rule.to_string (state));
+			#endif
+			if (parent_rule.would_accept_token (token, state)) {
+				#if VERY_HARD_DEBUG
+					debug ("WouldAccept - Yes");
+				#endif
+				return true;
+			}
+			if (!parent_rule.would_reduce (token, state)) {
+				#if VERY_HARD_DEBUG
+					debug ("WouldAccept - No");
+				#endif
+				return false;
+			}
+			offset--;
+			parent_rule = peek_rule (offset);
+			state = peek_state (offset);
+		}
+		#if VERY_HARD_DEBUG
+			debug ("WouldAccept - No");
+		#endif
+		return false;
+	}
+
+	public bool would_parent_reduce_to_rule (Token token, Rule rule) {
+		int offset = -2;
+		Rule? parent_rule = peek_rule (offset);
+		Object? state = peek_state (offset);
+		while (parent_rule != null) {
+			#if VERY_HARD_DEBUG
+				debug ("WouldReduce - Offset %d; Index %d: %s", offset, rule_stack.size + offset, parent_rule.to_string (state));
+			#endif
+			if (!parent_rule.would_reduce (token, state)) {
+				break;
+			}
+			offset--;
+			parent_rule = peek_rule (offset);
+			state = peek_state (offset);
+		}
+		if ((parent_rule != null && parent_rule.would_accept_token (token, state))
+			|| (parent_rule == null && TokenType.EOF.matches (token))) {
+			#if VERY_HARD_DEBUG
+				debug ("WouldReduce - Yes");
+			#endif
+			return true;
+		}
+		#if VERY_HARD_DEBUG
+			debug ("WouldReduce - No");
+		#endif
+		return false;
+	}
+
+	public void warning (string message, Token? token = null) {
+		string error_message = message + (token != null ? ": " + token.to_pretty_string () : "");
+		_reporter.warning (_filename,
+		                   get_line (token),
+		                   get_start_column (token),
+		                   get_end_column (token),
+		                   _scanner.get_line_content (),
+		                   error_message);
+	}
+
+	public void error (string message, Token? token = null) throws ParserError {
+		string error_message = message + (token != null ? ": " + token.to_pretty_string () : "");
+		_reporter.error (_filename, get_line (token),
+		                 get_start_column (token),
+		                 get_end_column (token),
+		                 _scanner.get_line_content (),
+		                 error_message);
+		throw new ParserError.UNEXPECTED_TOKEN (error_message);
+	}
+
+	private int get_line (Token? token) {
+		if (token == null) {
+			token = _current_token;
+		}
+		return token.begin.line + _first_line;
+	}
+
+	private int get_start_column (Token? token) {
+		if (token == null) {
+			token = _current_token;
+		}
+		if (token.begin.line == 0) {
+			return token.begin.column + _first_column + 1;
+		} else {
+			return token.begin.column + 1;
+		}
+	}
+
+	private int get_end_column (Token? token) {
+		if (token == null) {
+			token = _current_token;
+		}
+		if (token.end.line == 0) {
+			return token.end.column + _first_column + 1;
+		} else {
+			return token.end.column + 1;
+		}
+	}
+
+#if DEBUG
+	private void log_error (string message) {
+		stderr.printf ("An error occured while parsing: %s\n", message);
+		stderr.printf ("\nDumping rule stack:\n");
+		for (int i = 0; i < rule_stack.size; i++) {
+			stderr.printf ("\t%2d: %s\n", i, rule_stack[i].to_string (rule_state_stack[i]));
+		}
+	}
+#endif
+}
diff --git a/src/doclets/htmlhelpers/taglets/center.vala b/src/libvaladoc/parser/parsercallback.vala
old mode 100755
new mode 100644
similarity index 52%
rename from src/doclets/htmlhelpers/taglets/center.vala
rename to src/libvaladoc/parser/parsercallback.vala
index 36204c4..6747262
--- a/src/doclets/htmlhelpers/taglets/center.vala
+++ b/src/libvaladoc/parser/parsercallback.vala
@@ -1,50 +1,38 @@
-/*
+/* parser.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
 
+public interface Valadoc.ParserCallback {
+	public abstract Object? get_rule_state ();
+	public abstract void set_rule_state (Object state);
 
-public class Valadoc.Html.CenterDocElement : Valadoc.CenterDocElement {
-	private Gee.ArrayList<DocElement> content;
-
-	public override bool parse ( Gee.ArrayList<DocElement> content ) {
-		this.content = content;
-		return true;
-	}
-
-	public override bool write ( void* res, int max, int index ) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		int _max = this.content.size;
-		int _index = 0;
+	public abstract void push_rule (Rule rule);
+	public abstract void reduce ();
 
-		file.printf ( "<div align=\"center\">" );
+	public abstract bool would_parent_accept_token (Token token);
+	public abstract bool would_parent_reduce_to_rule (Token token, Rule rule);
 
-		foreach ( DocElement element in this.content ) {
-			element.write ( res, _max, _index );
-			_index++;
-		}
-
-		file.printf ( "</div>" );
-		return true;
-	}
+	public abstract void warning (string message, Token? token = null);
+	public abstract void error (string message, Token? token = null) throws ParserError;
 }
-
-
diff --git a/src/libvaladoc/parser/rule.vala b/src/libvaladoc/parser/rule.vala
new file mode 100644
index 0000000..980c2d1
--- /dev/null
+++ b/src/libvaladoc/parser/rule.vala
@@ -0,0 +1,151 @@
+/* parser.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 Gee;
+
+public abstract class Valadoc.Rule : Object {
+
+	public static Rule seq (Object?[] scheme) {
+		return new SequenceRule (scheme);
+	}
+
+	public static Rule one_of (Object?[] scheme) {
+		return new OneOfRule (scheme);
+	}
+
+	public static Rule many (Object?[] scheme) {
+		if (scheme.length == 1) {
+			return new ManyRule (scheme[0]);
+		} else {
+			return new ManyRule (new SequenceRule (scheme));
+		}
+	}
+
+	public static Rule option (Object?[] scheme) {
+		if (scheme.length == 1) {
+			return new OptionalRule (scheme[0]);
+		} else {
+			return new OptionalRule (new SequenceRule (scheme));
+		}
+	}
+
+	protected Rule () {
+	}
+
+	private string? _name = null;
+	private Action _start_action;
+	private Action _reduce_action;
+
+	public string name { get { return _name; } }
+
+	public Rule set_name (string name) {
+		_name = name;
+		return this;
+	}
+
+	public delegate void Action () throws ParserError;
+
+	public Rule set_start (Action action) {
+		_start_action = action;
+		return this;
+	}
+
+	public Rule set_reduce (Action action) {
+		_reduce_action = action;
+		return this;
+	}
+
+	public enum Forward {
+		NONE, PARENT, CHILD
+	}
+
+	public abstract bool is_optional ();
+	public abstract bool starts_with_token (Token token);
+	public abstract bool accept_token (Token token, ParserCallback parser, Rule.Forward forward) throws ParserError;
+	public abstract bool would_accept_token (Token token, Object? state);
+	public abstract bool would_reduce (Token token, Object? state);
+
+	public abstract string to_string (Object? state);
+
+	protected bool is_optional_rule (Object? scheme_element) {
+		Rule? scheme_rule = scheme_element as Rule;
+		if (scheme_rule != null) {
+			return scheme_rule.is_optional ();
+		}
+		return false;
+	}
+
+	protected bool has_start_token (Object? scheme_element, Token token) {
+		TokenType? scheme_token_type = scheme_element as TokenType;
+		if (scheme_token_type != null) {
+			return scheme_token_type.matches (token);
+		}
+		Rule? scheme_rule = scheme_element as Rule;
+		if (scheme_rule != null) {
+			return scheme_rule.starts_with_token (token);
+		}
+		return false;
+	}
+
+	protected bool try_to_apply (Object? scheme_element, Token token, ParserCallback parser, out bool handled) throws ParserError {
+		#if VERY_HARD_DEBUG
+			{
+				TokenType? scheme_token = scheme_element as TokenType;
+				Rule? scheme_rule = scheme_element as Rule;
+				if (scheme_token != null) {
+					message ("TryToApply: token='%s'; scheme_token='%s'", token.to_string (), scheme_token.to_string ());
+				} else if (scheme_rule != null) {
+					message ("TryToApply: token='%s'; scheme_rule='%s'", token.to_string (), scheme_rule.to_string (parser.get_rule_state ()));
+				} else {
+					assert (scheme_element != null);
+				}
+			}
+		#endif
+		TokenType? scheme_token_type = scheme_element as TokenType;
+		if (scheme_token_type != null && scheme_token_type.matches (token)) {
+			scheme_token_type.do_action (token);
+			handled = true;
+			return true;
+		}
+		Rule? scheme_rule = scheme_element as Rule;
+		if (scheme_rule != null && scheme_rule.starts_with_token (token)) {
+			parser.push_rule (scheme_rule);
+			handled = false;
+			return true;
+		}
+		return false;
+	}
+
+	protected void do_start (ParserCallback parser) throws ParserError {
+		if (_start_action != null) {
+			_start_action ();
+		}
+	}
+
+	protected void do_reduce (ParserCallback parser) throws ParserError {
+		if (_reduce_action != null) {
+			_reduce_action ();
+		}
+		parser.reduce ();
+	}
+}
diff --git a/src/libvaladoc/html/attribute.vala b/src/libvaladoc/parser/scanner.vala
old mode 100755
new mode 100644
similarity index 60%
rename from src/libvaladoc/html/attribute.vala
rename to src/libvaladoc/parser/scanner.vala
index 7d8e89e..be583ed
--- a/src/libvaladoc/html/attribute.vala
+++ b/src/libvaladoc/parser/scanner.vala
@@ -1,36 +1,37 @@
-/*
+/* commentscanner.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2009 Florian Brosch
- * 
+ * 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 Gee;
+public interface Valadoc.Scanner : Object {
 
+	public abstract void set_parser (Parser parser);
 
-public class Valadoc.Html.Attribute {
-	private string name;
-	private string val;
+	public abstract void reset ();
 
-	public Attribute (string name, string val) {
-		this.name = name;
-		this.val = val;
-	}
+	public abstract void scan (string content) throws ParserError;
 
-	public string to_string (string path) {
-		return " %s=\"%s\"".printf (this.name, this.val);
-	}
-}
+	public abstract void end () throws ParserError;
+
+	public abstract void stop ();
 
+	public abstract string get_line_content ();
+}
diff --git a/src/libvaladoc/parser/sequencerule.vala b/src/libvaladoc/parser/sequencerule.vala
new file mode 100644
index 0000000..7989afb
--- /dev/null
+++ b/src/libvaladoc/parser/sequencerule.vala
@@ -0,0 +1,129 @@
+/* parser.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 Gee;
+
+internal class Valadoc.SequenceRule : Rule {
+
+	public SequenceRule (Object[] scheme) {
+		_scheme = scheme;
+	}
+
+	private Object[] _scheme;
+
+	private class State : Object {
+		public int index = 0;
+	}
+
+	public override bool is_optional () {
+		return false;
+	}
+
+	public override bool starts_with_token (Token token) {
+		return test_token (0, token);
+	}
+
+	private bool test_token (int from_index, Token token) {
+		int i = from_index;
+		while (i < _scheme.length) {
+			if (has_start_token (_scheme[i], token)) {
+				return true;
+			}
+			if (!is_optional_rule (_scheme[i])) {
+				break;
+			}
+			i++;
+		}
+		return false;
+	}
+
+	private bool test_reduce (int from_index, Token token) {
+		int i = from_index;
+		while (i < _scheme.length) {
+			if (!is_optional_rule (_scheme[i])) {
+				return false;
+			}
+			i++;
+		}
+		return true;
+	}
+
+	public override bool accept_token (Token token, ParserCallback parser, Rule.Forward forward) throws ParserError {
+		var state = parser.get_rule_state () as State;
+		if (state == null) {
+			state = new State ();
+			parser.set_rule_state (state);
+		}
+
+		if (state.index == 0) {
+			do_start (parser);
+		} else if (state.index == _scheme.length) {
+			do_reduce (parser);
+			return false;
+		}
+
+		Object? scheme_element = null;
+		bool handled;
+		do {
+			scheme_element = _scheme[state.index];
+			if (try_to_apply (scheme_element, token, parser, out handled)) {
+				state.index++;
+				return handled;
+			}
+			if (!is_optional_rule (scheme_element)) {
+				break;
+			}
+			state.index++;
+		} while (state.index < _scheme.length);
+
+		if (state.index == _scheme.length) {
+			do_reduce (parser);
+			return false;
+		}
+
+		if (scheme_element is TokenType) {
+			parser.error ("expected %s".printf (((TokenType) scheme_element).to_pretty_string ()), token);
+		} else {
+			parser.error ("unexpected token", token);
+		}
+		assert_not_reached ();
+	}
+
+	public override bool would_accept_token (Token token, Object? rule_state) {
+		var state = rule_state as State;
+		return test_token (state.index, token);
+	}
+
+	public override bool would_reduce (Token token, Object? rule_state) {
+		var state = rule_state as State;
+		return state.index == _scheme.length || test_reduce (state.index, token);
+	}
+
+	public override string to_string (Object? rule_state) {
+		var state = rule_state as State;
+		if (state == null) {
+			state = new State ();
+		}
+		return "%-15s%-15s(index=%d/%d)".printf (name != null ? name : " ", "[seq]", state.index, _scheme.length);
+	}
+}
diff --git a/src/libvaladoc/parser/sourcelocation.vala b/src/libvaladoc/parser/sourcelocation.vala
new file mode 100644
index 0000000..0a461c1
--- /dev/null
+++ b/src/libvaladoc/parser/sourcelocation.vala
@@ -0,0 +1,36 @@
+/* sourcelocation.vala
+ *
+ * Copyright (C) 2008  Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library 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
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ * 	Jürg Billeter <j bitron ch>
+ */
+
+using GLib;
+
+/**
+ * Represents a position in a source file.
+ */
+public struct Valadoc.SourceLocation {
+	public int line;
+	public int column;
+
+	public SourceLocation (int _line, int _column) {
+		line = _line;
+		column = _column;
+	}
+}
diff --git a/src/libvaladoc/parser/stubrule.vala b/src/libvaladoc/parser/stubrule.vala
new file mode 100644
index 0000000..e9a6f28
--- /dev/null
+++ b/src/libvaladoc/parser/stubrule.vala
@@ -0,0 +1,61 @@
+/* parser.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 Gee;
+
+public class Valadoc.StubRule : Rule {
+
+	public StubRule () {
+	}
+
+	private Rule _rule;
+
+	public Rule set_rule (Rule rule) {
+		_rule = rule;
+		return this;
+	}
+
+	public override bool is_optional () {
+		return _rule.is_optional ();
+	}
+
+	public override bool starts_with_token (Token token) {
+		return _rule.starts_with_token (token);
+	}
+
+	public override bool accept_token (Token token, ParserCallback parser, Rule.Forward forward) throws ParserError {
+		return _rule.accept_token (token, parser, forward);
+	}
+
+	public override bool would_accept_token (Token token, Object? state) {
+		return _rule.would_accept_token (token, state);
+	}
+
+	public override bool would_reduce (Token token, Object? state) {
+		return _rule.would_reduce (token, state);
+	}
+
+	public override string to_string (Object? state) {
+		return _rule.to_string (state);
+	}
+}
diff --git a/src/libvaladoc/parser/token.vala b/src/libvaladoc/parser/token.vala
new file mode 100644
index 0000000..23654c7
--- /dev/null
+++ b/src/libvaladoc/parser/token.vala
@@ -0,0 +1,103 @@
+/* parser.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 Gee;
+
+public class Valadoc.Token : Object {
+
+	public Token.from_type (TokenType type, SourceLocation begin, SourceLocation end) {
+		_type = type;
+		_begin = begin;
+		_end = end;
+	}
+
+	public Token.from_word (string word, SourceLocation begin, SourceLocation end) {
+		_word = word;
+		_begin = begin;
+		_end = end;
+	}
+
+	private TokenType? _type = null;
+	private string? _word = null;
+	private SourceLocation _begin;
+	private SourceLocation _end;
+
+	public bool is_word {
+		get {
+			return _word != null;
+		}
+	}
+
+	public bool is_number {
+		get {
+			if (_word == null || _word.length == 0) {
+				return false;
+			} else if (_word[0] == '0' && _word.length > 1) {
+				return false;
+			} 
+			for (int i = 0; i < _word.length; i++) {
+				if (_word[i] < '0' || _word[i] > '9') {
+					return false;
+				}
+			}
+			return true;
+		}
+	}
+
+	public string? word {
+		get {
+			return _word;
+		}
+	}
+
+	public TokenType? token_type {
+		get {
+			return _type;
+		}
+	}
+
+	public SourceLocation begin {
+		get {
+			return _begin;
+		}
+	}
+
+	public SourceLocation end {
+		get {
+			return _end;
+		}
+	}
+
+	public string to_string () {
+		return _word == null ? _type.to_string () : _word;
+	}
+
+	public string to_pretty_string () {
+		return _word == null ? _type.to_pretty_string () : _word;
+	}
+
+	public int to_int () {
+		assert (is_number);
+		return _word.to_int ();
+	}
+}
diff --git a/src/libvaladoc/parser/tokentype.vala b/src/libvaladoc/parser/tokentype.vala
new file mode 100644
index 0000000..5edaf4b
--- /dev/null
+++ b/src/libvaladoc/parser/tokentype.vala
@@ -0,0 +1,183 @@
+/* parser.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 Gee;
+
+public class Valadoc.TokenType : Object {
+
+	public static TokenType ANY;
+	public static TokenType ANY_WORD;
+	public static TokenType ANY_NUMBER;
+	public static TokenType EOF;
+	public static TokenType EOL;
+ 	public static TokenType AROBASE;
+	public static TokenType SPACE;
+	public static TokenType TAB;
+	public static TokenType EQUAL_1;
+	public static TokenType EQUAL_2;
+	public static TokenType EQUAL_3;
+	public static TokenType EQUAL_4;
+	public static TokenType EQUAL_5;
+	public static TokenType MINUS;
+	public static TokenType STAR;
+	public static TokenType SHARP;
+	public static TokenType LESS_THAN;
+	public static TokenType GREATER_THAN;
+	public static TokenType ALIGN_TOP;
+	public static TokenType ALIGN_BOTTOM;
+	public static TokenType SINGLE_QUOTE_2;
+	public static TokenType SLASH_2;
+	public static TokenType UNDERSCORE_2;
+	public static TokenType BACK_QUOTE;
+	public static TokenType OPEN_BRACE;
+	public static TokenType CLOSED_BRACE;
+	public static TokenType DOUBLE_OPEN_BRACE;
+	public static TokenType DOUBLE_CLOSED_BRACE;
+	public static TokenType TRIPLE_OPEN_BRACE;
+	public static TokenType TRIPLE_CLOSED_BRACE;
+	public static TokenType DOUBLE_OPEN_BRACKET;
+	public static TokenType DOUBLE_CLOSED_BRACKET;
+	public static TokenType PIPE;
+	public static TokenType DOUBLE_PIPE;
+	public static TokenType ALIGN_RIGHT;
+	public static TokenType ALIGN_CENTER;
+
+	private static bool initialized = false;
+
+	internal static void init_token_types () {
+		if (!initialized) {
+			ANY = new TokenType.basic ("<any>");
+			ANY_WORD = new TokenType.basic ("<any-word>");
+			ANY_NUMBER = new TokenType.basic ("<any-number>");
+			EOF = new TokenType.basic ("\0", "<end-of-file>");
+			EOL = new TokenType.basic ("\n", "<end-of-line>");
+			AROBASE = new TokenType.basic ("@");
+			SPACE = new TokenType.basic (" ", "<space>");
+			TAB = new TokenType.basic ("\t", "<tab>");
+			EQUAL_1 = new TokenType.basic ("=");
+			EQUAL_2 = new TokenType.basic ("==");
+			EQUAL_3 = new TokenType.basic ("====");
+			EQUAL_4 = new TokenType.basic ("=====");
+			EQUAL_5 = new TokenType.basic ("======");
+			MINUS = new TokenType.basic ("-");
+			STAR = new TokenType.basic ("*");
+			SHARP = new TokenType.basic ("#");
+			LESS_THAN = new TokenType.basic ("<");
+			GREATER_THAN = new TokenType.basic (">");
+			ALIGN_TOP = new TokenType.basic ("^");
+			ALIGN_BOTTOM = new TokenType.basic ("v");
+			SINGLE_QUOTE_2 = new TokenType.basic ("''");
+			SLASH_2 = new TokenType.basic ("//");
+			UNDERSCORE_2 = new TokenType.basic ("__");
+			BACK_QUOTE = new TokenType.basic ("`");
+			OPEN_BRACE = new TokenType.basic ("{");
+			CLOSED_BRACE = new TokenType.basic ("}");
+			DOUBLE_OPEN_BRACE = new TokenType.basic ("{{");
+			DOUBLE_CLOSED_BRACE = new TokenType.basic ("}}");
+			TRIPLE_OPEN_BRACE = new TokenType.basic ("{{{");
+			TRIPLE_CLOSED_BRACE = new TokenType.basic ("}}}");
+			DOUBLE_OPEN_BRACKET = new TokenType.basic ("[[");
+			DOUBLE_CLOSED_BRACKET = new TokenType.basic ("]]");
+			PIPE = new TokenType.basic ("|");
+			DOUBLE_PIPE = new TokenType.basic ("||");
+			ALIGN_RIGHT = new TokenType.basic ("))");
+			ALIGN_CENTER = new TokenType.basic (")(");
+			initialized = true;
+		}
+	}
+
+	private static int EXACT_WORD = -1;
+
+	public static TokenType str (string str) {
+		return new TokenType (str, EXACT_WORD, null);
+	}
+
+	public static TokenType any () {
+		return ANY;
+	}
+
+	public static TokenType any_word () {
+		return ANY_WORD;
+	}
+
+	public static TokenType any_number () {
+		return ANY_NUMBER;
+	}
+
+	private TokenType (string string_value, int basic_value, Action? action) {
+		_string_value = string_value;
+		_basic_value = basic_value;
+		_action = action;
+	}
+
+	private TokenType.basic (string string_value, string? pretty_string = null) {
+		_string_value = string_value;
+		_pretty_string = pretty_string;
+		_basic_value = ++_last_basic_value;
+	}
+
+	private static int _last_basic_value = -1;
+
+	private string _string_value;
+	private string? _pretty_string;
+	private int _basic_value = -1;
+	private Action? _action = null;
+
+	public delegate void Action (Token token) throws ParserError;
+
+	public TokenType action (Action action) {
+		return new TokenType (_string_value, _basic_value, action);
+	}
+
+	public void do_action (Token matched_token) throws ParserError {
+		if (_action != null) {
+			_action (matched_token);
+		}
+	}
+
+	public bool matches (Token token) {
+		if (_basic_value == ANY._basic_value) {
+			return true;
+		} else if (_basic_value == ANY_WORD._basic_value && token.is_word) {
+			return true;
+		} else if (_basic_value == ANY_NUMBER._basic_value && token.is_number) {
+			return true;
+		} else if (_basic_value == EXACT_WORD && token.is_word && token.word == _string_value) {
+			return true;
+		} else if (token.token_type != null && token.token_type._basic_value == _basic_value) {
+			return true;
+		}
+		return false;
+	}
+
+	public string to_string () {
+		return _string_value;
+	}
+
+	public string to_pretty_string () {
+		if (_pretty_string != null) {
+			return _pretty_string;
+		}
+		return _string_value;
+	}
+}
diff --git a/src/libvaladoc/parser/wikiscanner.vala b/src/libvaladoc/parser/wikiscanner.vala
new file mode 100644
index 0000000..1784ccd
--- /dev/null
+++ b/src/libvaladoc/parser/wikiscanner.vala
@@ -0,0 +1,395 @@
+/* commentscanner.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>
+ */
+
+public class Valadoc.WikiScanner : Object, Scanner {
+
+	public WikiScanner (Settings settings) {
+		_settings = settings;
+	}
+
+	private Settings _settings;
+	private Parser _parser;
+
+	private string _content;
+	private int _index;
+	private bool _stop;
+	private int _last_index;
+	private int _last_line;
+	private int _last_column;
+	private int _line;
+	private int _column;
+	private bool _url_escape_mode;
+	private bool _code_escape_mode;
+	private unichar _last_char;
+	private int _skip;
+	private StringBuilder _current_string = new StringBuilder ();
+
+	public void set_parser (Parser parser) {
+		_parser = parser;
+	}
+
+	public virtual void reset () {
+		_stop = false;
+		_last_index = 0;
+		_last_line = 0;
+		_last_column = 0;
+		_line = 0;
+		_column = 0;
+		_url_escape_mode = false;
+		_code_escape_mode = false;
+		_last_char = 0;
+		_skip = 0;
+		_current_string.erase (0, -1);
+	}
+
+	public void scan (string _content) throws ParserError {
+		this._content = _content;
+		for (_index = 0; !_stop && _index < _content.length; _index++) {
+			unichar c = _content[_index];
+			accept (c);
+		}
+	}
+
+	public void end () throws ParserError {
+		emit_token (TokenType.EOF);
+	}
+
+	public virtual void stop () {
+		_stop = true;
+	}
+
+	public void set_url_escape_mode (bool escape_mode) {
+		_url_escape_mode = escape_mode;
+	}
+
+	public void set_code_escape_mode (bool escape_mode) {
+		_code_escape_mode = escape_mode;
+	}
+
+	public int get_line () {
+		return _line;
+	}
+
+	public virtual string get_line_content () {
+		int i = _index;
+		while (i > 0 && _content[i-1] != '\n') {
+			i--;
+		}
+		StringBuilder builder = new StringBuilder ();
+		while (i < _content.length && _content[i] != '\n') {
+			unichar c = _content[i++];
+			if (c == '\t') {
+				builder.append (" ");
+			} else {
+				builder.append_unichar (c);
+			}
+		}
+		return builder.str;
+	}
+
+	protected unichar get_next_char (int offset = 1) {
+		return _content[_index + offset];
+	}
+
+	protected virtual void accept (unichar c) throws ParserError {
+		_column++;
+		if (_skip == 0) {
+			if (_code_escape_mode) {
+				switch (c) {
+				case '}':
+					if (get_next_char (1) == c && get_next_char (2) == c) {
+						_code_escape_mode = false; // This is a temporary hack
+						emit_token (TokenType.TRIPLE_CLOSED_BRACE);
+						_skip = 2;
+					} else {
+						append_char (c);
+					}
+					return;
+				default:
+					append_char (c);
+					return;
+				}
+			} else if (_url_escape_mode) {
+				switch (c) {
+				// Reserved characters
+				case ';':
+				case '/':
+				case '?':
+				case ':':
+				case '@':
+				case '#':
+				case '=':
+				case '&':
+				// Special characters
+				case '$':
+				case '-':
+				case '_':
+				case '.':
+				case '+':
+				case '!':
+				case '*':
+				case '\'':
+				case '(':
+				case ')':
+				case ',':
+					append_char (c);
+					return;
+				default:
+					break;
+				}
+			}
+
+			switch (c) {
+			case '@':
+				if (get_next_char () == '@') {
+					append_char (c);
+					_skip = 1;
+				} else {
+					emit_token (TokenType.AROBASE);
+				}
+				break;
+
+			case '{':
+				look_for_three (c,
+				                TokenType.OPEN_BRACE,
+				                TokenType.DOUBLE_OPEN_BRACE,
+				                TokenType.TRIPLE_OPEN_BRACE);
+				break;
+
+			case '}':
+				look_for_three (c,
+				                TokenType.CLOSED_BRACE,
+				                TokenType.DOUBLE_CLOSED_BRACE,
+				                TokenType.TRIPLE_CLOSED_BRACE);
+				break;
+
+			case '[':
+				look_for_two_or_append (c, TokenType.DOUBLE_OPEN_BRACKET);
+				break;
+
+			case ']':
+				look_for_two_or_append (c, TokenType.DOUBLE_CLOSED_BRACKET);
+				break;
+
+			case '|':
+				look_for_two (c,
+				              TokenType.PIPE,
+				              TokenType.DOUBLE_PIPE);
+				break;
+
+			case ')':
+				if (get_next_char () == ')') {
+					emit_token (TokenType.ALIGN_RIGHT);
+					_skip = 1;
+				} else if (get_next_char () == '(') {
+					emit_token (TokenType.ALIGN_CENTER);
+					_skip = 1;
+				} else {
+					append_char (c);
+				}
+				break;
+
+			case '*':
+				emit_token (TokenType.STAR);
+				break;
+
+			case '#':
+				emit_token (TokenType.SHARP);
+				break;
+				
+			case '-':
+				if (_last_char.isalnum () || get_next_char ().isalnum ()) {
+					append_char (c);
+				} else {
+					emit_token (TokenType.MINUS);
+				}
+				break;
+
+			case '=':
+				look_for_five (c,
+	                           TokenType.EQUAL_1,
+	                           TokenType.EQUAL_2,
+	                           TokenType.EQUAL_3,
+	                           TokenType.EQUAL_4,
+	                           TokenType.EQUAL_5);
+				break;
+
+			case '<':
+				emit_token (TokenType.LESS_THAN);
+				break;
+
+			case '>':
+				emit_token (TokenType.GREATER_THAN);
+				break;
+
+			case '^':
+				emit_token (TokenType.ALIGN_TOP);
+				break;
+
+			case 'v':
+				unichar next_char = get_next_char ();
+				if (_last_char.isalnum () || _last_char == ' '
+					|| next_char.isalnum () || next_char == ' ') {
+					append_char (c);
+				} else {
+					emit_token (TokenType.ALIGN_BOTTOM);
+				}
+				break;
+
+			case '\'':
+				look_for_two_or_append (c, TokenType.SINGLE_QUOTE_2);
+				break;
+
+			case '/':
+				look_for_two_or_append (c, TokenType.SLASH_2);
+				break;
+
+			case '_':
+				look_for_two_or_append (c, TokenType.UNDERSCORE_2);
+				break;
+
+			case '`':
+				emit_token (TokenType.BACK_QUOTE);
+				break;
+
+			case '\t':
+				emit_token (TokenType.TAB);
+				break;
+
+			case ' ':
+				emit_token (TokenType.SPACE);
+				break;
+
+			case '\r':
+				break;
+
+			case '\n':
+				emit_token (TokenType.EOL);
+				_line++;
+				_column = 0;
+				_last_column = 0;
+				break;
+
+			default:
+				append_char (c);
+				break;
+			}
+		} else {
+			_skip--;
+		}
+		_last_char = c;
+	}
+
+	private void append_char (unichar c) {
+		_current_string.append_unichar (c);
+	}
+
+	public virtual int get_line_start_column () {
+		return 0;
+	}
+
+	private SourceLocation get_begin () {
+		return SourceLocation (_last_line, get_line_start_column () + _last_column);
+	}
+
+	private SourceLocation get_end (int offset = 0) {
+		return SourceLocation (_line, get_line_start_column () + _column + offset);
+	}
+
+	private void emit_current_word () throws ParserError {
+		if (_current_string.len > 0) {
+			_parser.accept_token (new Token.from_word (_current_string.str, get_begin (), get_end (-1)));
+			_current_string.erase (0, -1);
+
+			_last_index = _index;
+			_last_line = _line;
+			_last_column = _column - 1;
+		}
+	}
+
+	private void emit_token (TokenType type) throws ParserError {
+		emit_current_word ();
+
+		_parser.accept_token (new Token.from_type (type, get_begin (), get_end (_skip)));
+
+		_last_index = _index;
+		_last_line = _line;
+		_last_column = _column;
+	}
+
+	private void look_for_two_or_append (unichar c, TokenType type) throws ParserError {
+		if (get_next_char () == c) {
+			emit_token (type);
+			_skip = 1;
+		} else {
+			append_char (c);
+		}
+	}
+
+	private void look_for_two (unichar c, TokenType one, TokenType two) throws ParserError {
+		if (get_next_char (1) == c) {
+			emit_token (two);
+			_skip = 1;
+		} else {
+			emit_token (one);
+		}
+	}
+
+	private void look_for_three (unichar c, TokenType one, TokenType two, TokenType three) throws ParserError {
+		if (get_next_char (1) == c) {
+			if (get_next_char (2) == c) {
+				emit_token (three);
+				_skip = 2;
+			} else {
+				emit_token (two);
+				_skip = 1;
+			}
+		} else {
+			emit_token (one);
+		}
+	}
+
+	private void look_for_five (unichar c, TokenType one, TokenType two, TokenType three, TokenType four, TokenType five) throws ParserError {
+		if (get_next_char (1) == c) {
+			if (get_next_char (2) == c) {
+				if (get_next_char (3) == c) {
+					if (get_next_char (4) == c) {
+						emit_token (five);
+						_skip = 4;
+					} else {
+						emit_token (four);
+						_skip = 3;
+					}
+				} else {
+					emit_token (three);
+					_skip = 2;
+				}
+			} else {
+				emit_token (two);
+				_skip = 1;
+			}
+		} else {
+			emit_token (one);
+		}
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/headline.vala b/src/libvaladoc/taglets/tagletdeprecated.vala
similarity index 57%
copy from src/doclets/htmlhelpers/taglets/headline.vala
copy to src/libvaladoc/taglets/tagletdeprecated.vala
index 117d522..7efc2bc 100755
--- a/src/doclets/htmlhelpers/taglets/headline.vala
+++ b/src/libvaladoc/taglets/tagletdeprecated.vala
@@ -1,42 +1,40 @@
-/*
+/* taglet.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
+using Valadoc.Content;
 
+public class Valadoc.Taglets.Deprecated : InlineContent, Taglet, Block {
+	public Rule? get_parser_rule (Rule run_rule) {
+		return run_rule;
+	}
 
-public class Valadoc.Html.HeadlineDocElement : Valadoc.HeadlineDocElement {
-	private string title;
-	private int lvl;
-
-	public override bool parse (string title, int lvl) {
-		this.title = title;
-		this.lvl = lvl;
-		return true;
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		base.check (api_root, container, reporter);
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("\n\n<h%d>%s</h%d>\n", this.lvl, this.title, this.lvl);
-		return true;
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_taglet (this);
 	}
 }
-
-
diff --git a/src/libvaladoc/taglets/tagletinheritdoc.vala b/src/libvaladoc/taglets/tagletinheritdoc.vala
new file mode 100755
index 0000000..f4ff918
--- /dev/null
+++ b/src/libvaladoc/taglets/tagletinheritdoc.vala
@@ -0,0 +1,64 @@
+/* tagletinheritdoc.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 Gee;
+using Valadoc.Content;
+
+public class Valadoc.Taglets.InheritDoc : InlineTaglet {
+	private DocumentedElement? _inherited;
+
+	public override Rule? get_parser_rule (Rule run_rule) {
+		return null;
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// TODO Check that the container is an override of an abstract symbol
+		// Also retrieve that abstract symbol _inherited
+
+		if (container is Method) {
+			_inherited = ((Method) container).base_method;
+		} else if (container is Property) {
+			_inherited = ((Property) container).base_property;
+		}
+
+		// TODO report error if inherited is null
+
+		// TODO postpone check after complete parse of the api tree comments
+		// And reenable that check
+		//base.check (api_root, container, reporter);
+	}
+
+	public override ContentElement produce_content () {
+		if (_inherited != null) {
+			Paragraph inherited_paragraph = _inherited.documentation.content.get (0) as Paragraph;
+
+			Highlighted paragraph = new Highlighted (Highlighted.Style.NONE);
+			foreach (var element in inherited_paragraph.content) {
+				paragraph.content.add (element);
+			}
+			return paragraph;
+		}
+		return new Text ("");
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/constants.vala b/src/libvaladoc/taglets/tagletinit.vala
old mode 100755
new mode 100644
similarity index 55%
copy from src/doclets/htmlhelpers/taglets/constants.vala
copy to src/libvaladoc/taglets/tagletinit.vala
index df71288..42d9147
--- a/src/doclets/htmlhelpers/taglets/constants.vala
+++ b/src/libvaladoc/taglets/tagletinit.vala
@@ -17,29 +17,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
-using GLib;
-using Gee;
-
-
-public class Valadoc.Html.CodeConstantDocElement : Valadoc.CodeConstantDocElement {
-	private string constant;
-
-	public override bool parse (string constant) {
-		this.constant = constant;
-		return true;
-	}
-
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("<font class=\"%s\">%s</font>", css_content_literal, this.constant);
-		return true;
+using Valadoc;
+
+namespace Valadoc.Taglets {
+	public void init (ModuleLoader loader) {
+		loader.taglets.set ("see", typeof (Valadoc.Taglets.See));
+		loader.taglets.set ("since", typeof (Valadoc.Taglets.Since));
+		loader.taglets.set ("link", typeof (Valadoc.Taglets.Link));
+		loader.taglets.set ("throws", typeof (Valadoc.Taglets.Throws));
+		loader.taglets.set ("return", typeof (Valadoc.Taglets.Return));
+		loader.taglets.set ("param", typeof (Valadoc.Taglets.Param));
+		loader.taglets.set ("deprecated", typeof (Valadoc.Taglets.Deprecated));
+		loader.taglets.set ("inheritDoc", typeof (Valadoc.Taglets.InheritDoc));
 	}
 }
-
-
-[ModuleInit]
-public GLib.Type register_plugin (Gee.HashMap<string, Type> taglets) {
-	return typeof (Valadoc.Html.CodeConstantDocElement);
-}
-
diff --git a/src/libvaladoc/taglets/tagletlink.vala b/src/libvaladoc/taglets/tagletlink.vala
new file mode 100755
index 0000000..9849560
--- /dev/null
+++ b/src/libvaladoc/taglets/tagletlink.vala
@@ -0,0 +1,55 @@
+/* taglet.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 Gee;
+using Valadoc.Content;
+
+public class Valadoc.Taglets.Link : InlineTaglet {
+	public string symbol_name { private set; get; }
+
+	private DocumentedElement _symbol;
+
+	public override Rule? get_parser_rule (Rule run_rule) {
+		return Rule.seq ({
+			TokenType.any_word ().action ((token) => { symbol_name = token.to_string (); })
+		});
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		_symbol = api_root.search_symbol_str (container, symbol_name);
+		if (_symbol == null) {
+			// TODO use ContentElement's source reference
+			reporter.simple_error ("%s does not exist".printf (symbol_name));
+		}
+
+		base.check (api_root, container, reporter);
+	}
+
+	public override ContentElement produce_content () {
+		var link = new Content.SymbolLink ();
+		link.symbol = _symbol;
+		link.label = symbol_name;
+		return link;
+	}
+}
diff --git a/src/libvaladoc/taglets/tagletparam.vala b/src/libvaladoc/taglets/tagletparam.vala
new file mode 100755
index 0000000..7864411
--- /dev/null
+++ b/src/libvaladoc/taglets/tagletparam.vala
@@ -0,0 +1,48 @@
+/* taglet.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 Gee;
+using Valadoc.Content;
+
+public class Valadoc.Taglets.Param : InlineContent, Taglet, Block {
+	public string parameter_name { private set; get; }
+
+	public Rule? get_parser_rule (Rule run_rule) {
+		return Rule.seq ({
+			TokenType.any_word ().action ((token) => { parameter_name = token.to_string (); }),
+			Rule.many ({ TokenType.SPACE }),
+			run_rule
+		});
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// TODO check for the existence of such a parameter
+
+		base.check (api_root, container, reporter);
+	}
+
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_taglet (this);
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/headline.vala b/src/libvaladoc/taglets/tagletreturn.vala
similarity index 55%
rename from src/doclets/htmlhelpers/taglets/headline.vala
rename to src/libvaladoc/taglets/tagletreturn.vala
index 117d522..c43c8d5 100755
--- a/src/doclets/htmlhelpers/taglets/headline.vala
+++ b/src/libvaladoc/taglets/tagletreturn.vala
@@ -1,42 +1,42 @@
-/*
+/* taglet.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
+using Valadoc.Content;
 
+public class Valadoc.Taglets.Return : InlineContent, Taglet, Block {
+	public Rule? get_parser_rule (Rule run_rule) {
+		return run_rule;
+	}
 
-public class Valadoc.Html.HeadlineDocElement : Valadoc.HeadlineDocElement {
-	private string title;
-	private int lvl;
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		// TODO check for the existence of a return type
 
-	public override bool parse (string title, int lvl) {
-		this.title = title;
-		this.lvl = lvl;
-		return true;
+		base.check (api_root, container, reporter);
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("\n\n<h%d>%s</h%d>\n", this.lvl, this.title, this.lvl);
-		return true;
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_taglet (this);
 	}
 }
-
-
diff --git a/src/libvaladoc/taglets/tagletsee.vala b/src/libvaladoc/taglets/tagletsee.vala
new file mode 100755
index 0000000..533a48c
--- /dev/null
+++ b/src/libvaladoc/taglets/tagletsee.vala
@@ -0,0 +1,49 @@
+/* taglet.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 Gee;
+using Valadoc.Content;
+
+public class Valadoc.Taglets.See : ContentElement, Taglet, Block {
+	public string symbol_name { private set; get; }
+	public DocumentedElement symbol { private set; get; }
+
+	public Rule? get_parser_rule (Rule run_rule) {
+		return Rule.seq ({
+			TokenType.any_word ().action ((token) => { symbol_name = token.to_string (); })
+		});
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		symbol = api_root.search_symbol_str (container, symbol_name);
+		if (symbol == null) {
+			// TODO use ContentElement's source reference
+			reporter.simple_error ("%s does not exist".printf (symbol_name));
+		}
+	}
+
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_taglet (this);
+	}
+}
diff --git a/src/doclets/htmlhelpers/taglets/constants.vala b/src/libvaladoc/taglets/tagletsince.vala
similarity index 55%
rename from src/doclets/htmlhelpers/taglets/constants.vala
rename to src/libvaladoc/taglets/tagletsince.vala
index df71288..e895c13 100755
--- a/src/doclets/htmlhelpers/taglets/constants.vala
+++ b/src/libvaladoc/taglets/tagletsince.vala
@@ -1,45 +1,43 @@
-/*
+/* taglet.vala
+ *
  * Valadoc - a documentation tool for vala.
- * Copyright (C) 2008 Florian Brosch
- * 
+ * 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 Gee;
+using Valadoc.Content;
 
+public class Valadoc.Taglets.Since : ContentElement, Taglet, Block {
+	public string version;
 
-public class Valadoc.Html.CodeConstantDocElement : Valadoc.CodeConstantDocElement {
-	private string constant;
-
-	public override bool parse (string constant) {
-		this.constant = constant;
-		return true;
+	public Rule? get_parser_rule (Rule run_rule) {
+		return Rule.seq ({
+			TokenType.any_word ().action ((token) => { version = token.to_string (); })
+		});
 	}
 
-	public override bool write (void* res, int max, int index) {
-		weak GLib.FileStream file = (GLib.FileStream)res;
-		file.printf ("<font class=\"%s\">%s</font>", css_content_literal, this.constant);
-		return true;
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
 	}
-}
 
-
-[ModuleInit]
-public GLib.Type register_plugin (Gee.HashMap<string, Type> taglets) {
-	return typeof (Valadoc.Html.CodeConstantDocElement);
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_taglet (this);
+	}
 }
-
diff --git a/src/libvaladoc/taglets/tagletthrows.vala b/src/libvaladoc/taglets/tagletthrows.vala
new file mode 100755
index 0000000..5fd7937
--- /dev/null
+++ b/src/libvaladoc/taglets/tagletthrows.vala
@@ -0,0 +1,53 @@
+/* taglet.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 Gee;
+using Valadoc.Content;
+
+public class Valadoc.Taglets.Throws : InlineContent, Taglet, Block {
+	public string error_domain_name { private set; get; }
+	public DocumentedElement error_domain { private set; get; }
+
+	public Rule? get_parser_rule (Rule run_rule) {
+		return Rule.seq ({
+			TokenType.any_word ().action ((token) => { error_domain_name = token.to_string (); }),
+			Rule.many ({ TokenType.SPACE }),
+			run_rule
+		});
+	}
+
+	public override void check (Tree api_root, DocumentedElement? container, ErrorReporter reporter) {
+		error_domain = api_root.search_symbol_str (container, error_domain_name);
+		if (error_domain == null) {
+			// TODO use ContentElement's source reference
+			reporter.simple_error ("%s does not exist".printf (error_domain_name));
+		}
+
+		base.check (api_root, container, reporter);
+	}
+
+	public override void accept (ContentVisitor visitor) {
+		visitor.visit_taglet (this);
+	}
+}
diff --git a/src/libvaladoc/testcomment.test b/src/libvaladoc/testcomment.test
new file mode 100644
index 0000000..9e6919d
--- /dev/null
+++ b/src/libvaladoc/testcomment.test
@@ -0,0 +1,48 @@
+*
+	 * This is a stupid { dumb} ''toto'' //''documentation''// comment
+	 * for everything I didn't comment until now
+	 *
+	 * __Another__ description //line//
+	 *
+	 * Yet another __description__ line, but this one __lasts__
+	 * along some [[http://live.gnome.org/valadoc/|The Valadoc Website]]
+	 * {{./img/an_image.png|An image}}
+	 * //lines//
+	 *
+	 * )) A right-aligned paragraph+ { link AType} that continues at the
+	 * next line
+	 *
+	 * )( Center-aligned stuff
+	 *
+	 * { inheritDoc}
+	 *
+	 * {{{
+	 *	if (toto) {
+	 *		do_bad_stuff (my_variable++);
+	 *	}
+	 * }}}
+	 *  * A list item
+	 *  * Another list item
+	 *    . No bullet
+	 *  * A list item
+	 *    * Another list item
+	 *
+	 * ||<header-3> Joint Header Cell ||
+	 * ||<header> Joint Cell || Cell3 ||
+	 * || Cell1 || <|2> Joint Cell ||
+	 *
+	 * == Header 2 ==
+	 * === Header 3 ===
+	 * One can write immediately after headers
+	 * 
+	 * ==== Header 4 ====
+	 *  A. Mixed with ordered items
+	 *    1. Another ordered items
+	 *
+	 * And some other data
+	 *
+	 * @param test a test parameter
+	 *             that continues here
+	 * @return the value it returns
+	 * 				and this is the @@last line
+	 
\ No newline at end of file
diff --git a/src/libvaladoc/testparser.sh b/src/libvaladoc/testparser.sh
new file mode 100755
index 0000000..46c8c51
--- /dev/null
+++ b/src/libvaladoc/testparser.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+DEBUG_FLAGS=""
+#DEBUG_FLAGS="$DEBUG_FLAGS -D DEBUG"
+#DEBUG_FLAGS="$DEBUG_FLAGS -D HARD_DEBUG"
+#DEBUG_FLAGS="$DEBUG_FLAGS -D VERY_HARD_DEBUG"
+
+COMMAND="./testparser testcomment.test"
+COMMAND="gdb -ex run -ex bt -ex finish -ex quit --args $COMMAND"
+
+valac -C $DEBUG_FLAGS -g -o testparser --pkg vala-1.0 \
+	parser/commentscanner.vala \
+	parser/documentationfactory.vala \
+	parser/documentationparser.vala \
+	parser/manyrule.vala \
+	parser/oneofrule.vala \
+	parser/parser.vala \
+	parser/parsercallback.vala \
+	parser/rule.vala \
+	parser/scanner.vala \
+	parser/sequencerule.vala \
+	parser/stubrule.vala \
+	parser/token.vala \
+	parser/wikiscanner.vala \
+	documentation/errorreporter.vala \
+	settings.vala \
+	testparser.vala \
+&& valac $DEBUG_FLAGS -g -o testparser --pkg vala-1.0 \
+	parser/commentscanner.vala \
+	parser/documentationfactory.vala \
+	parser/documentationparser.vala \
+	parser/manyrule.vala \
+	parser/oneofrule.vala \
+	parser/parser.vala \
+	parser/parsercallback.vala \
+	parser/rule.vala \
+	parser/scanner.vala \
+	parser/sequencerule.vala \
+	parser/stubrule.vala \
+	parser/token.vala \
+	parser/wikiscanner.vala \
+	documentation/errorreporter.vala \
+	settings.vala \
+	testparser.vala \
+&& $COMMAND
diff --git a/src/libvaladoc/testparser.vala b/src/libvaladoc/testparser.vala
new file mode 100644
index 0000000..fff2230
--- /dev/null
+++ b/src/libvaladoc/testparser.vala
@@ -0,0 +1,16 @@
+/** Just a test file for parser2 **/
+
+namespace Valadoc {
+	void main (string[] args) {
+		Settings settings = new Settings ();
+		ErrorReporter reporter = new ErrorReporter ();
+		DocumentationParser parser = new DocumentationParser(settings, reporter);
+
+		string filename = args[1];
+		string content;
+		if (FileUtils.get_contents (filename, out content)) {
+			Object root = parser.parse_comment (content, filename, 0, 0);
+			stdout.printf ("\n%s\n", ((Node) root).to_string ());
+		}
+	}
+}
diff --git a/src/valadoc/valadoc.vala b/src/valadoc/valadoc.vala
index 0558955..26ae78b 100755
--- a/src/valadoc/valadoc.vala
+++ b/src/valadoc/valadoc.vala
@@ -172,6 +172,7 @@ public class ValaDoc : Object {
 
 
 		ModuleLoader modules = new ModuleLoader ();
+		Taglets.init (modules);
 		bool tmp = modules.load (fulldirpath);
 		if (tmp == false) {
 			reporter.simple_error ("failed to load plugin");
@@ -180,7 +181,7 @@ public class ValaDoc : Object {
 
 
 		Valadoc.Tree doctree = new Valadoc.Tree (reporter, settings);
-		Valadoc.Parser docparser = new Valadoc.Parser (settings, reporter, doctree, modules);
+		Valadoc.DocumentationParser docparser = new Valadoc.DocumentationParser (settings, reporter, doctree, modules);
 		if (reporter.errors > 0) {
 			return quit (reporter);
 		}



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