diff --git a/demo/talkatudemowindow.c b/demo/talkatudemowindow.c
--- a/demo/talkatudemowindow.c
+++ b/demo/talkatudemowindow.c
@@ -213,14 +213,6 @@
 	TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
 	static guint64 id = 0;
 
-	if(TALKATU_IS_HTML_BUFFER(input)) {
-		talkatu_message_set_content_type(TALKATU_MESSAGE(input),
-		                                 TALKATU_CONTENT_TYPE_HTML);
-	} else if(TALKATU_IS_MARKDOWN_BUFFER(input)) {
-		talkatu_message_set_content_type(TALKATU_MESSAGE(input),
-		                                 TALKATU_CONTENT_TYPE_MARKDOWN);
-	}
-
 	talkatu_message_set_id(TALKATU_MESSAGE(input), id++);
 
 	talkatu_history_write_message(
diff --git a/po/POTFILES b/po/POTFILES
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -19,6 +19,7 @@
 talkatu/talkatuhistoryrow.c
 talkatu/talkatuhistory.c
 talkatu/talkatuhtmlbuffer.c
+talkatu/talkatuhtmlrenderer.c
 talkatu/talkatuinput.c
 talkatu/talkatulinkdialog.c
 talkatu/talkatumarkdownbuffer.c
diff --git a/talkatu/meson.build b/talkatu/meson.build
--- a/talkatu/meson.build
+++ b/talkatu/meson.build
@@ -15,7 +15,8 @@
 	'talkatuhistory.h',
 	'talkatuhistoryrow.h',
 	'talkatuhtmlbuffer.h',
-	'talkatuhtmlparser.h',
+	'talkatuhtmlpangorenderer.h',
+	'talkatuhtmlrenderer.h',
 	'talkatuinput.h',
 	'talkatulinkdialog.h',
 	'talkatumarkdownbuffer.h',
@@ -46,7 +47,8 @@
 	'talkatuhistory.c',
 	'talkatuhistoryrow.c',
 	'talkatuhtmlbuffer.c',
-	'talkatuhtmlparser.c',
+	'talkatuhtmlpangorenderer.c',
+	'talkatuhtmlrenderer.c',
 	'talkatuinput.c',
 	'talkatulinkdialog.c',
 	'talkatumarkdownbuffer.c',
diff --git a/talkatu/reference/talkatu-docs.xml b/talkatu/reference/talkatu-docs.xml
--- a/talkatu/reference/talkatu-docs.xml
+++ b/talkatu/reference/talkatu-docs.xml
@@ -40,7 +40,7 @@
     <xi:include href="xml/talkatuhistory.xml"/>
     <xi:include href="xml/talkatuhistoryrow.xml"/>
 
-    <xi:include href="xml/talkatuhtmlparser.xml"/>
+    <xi:include href="xml/talkatuhtmlrenderer.xml"/>
 
     <xi:include href="xml/talkatuinput.xml"/>
 
diff --git a/talkatu/talkatuhistoryrow.c b/talkatu/talkatuhistoryrow.c
--- a/talkatu/talkatuhistoryrow.c
+++ b/talkatu/talkatuhistoryrow.c
@@ -21,6 +21,8 @@
 #include <gtk/gtk.h>
 
 #include <talkatu/talkatuhistoryrow.h>
+#include <talkatu/talkatuhtmlpangorenderer.h>
+#include <talkatu/talkatuhtmlrenderer.h>
 
 /**
  * SECTION:talkatuhistoryrow
@@ -100,6 +102,19 @@
 
 		if(content_type == TALKATU_CONTENT_TYPE_PANGO) {
 			gtk_label_set_markup(GTK_LABEL(row->content), contents);
+		} else if(content_type == TALKATU_CONTENT_TYPE_HTML) {
+			TalkatuHtmlRenderer *renderer = NULL;
+			TalkatuHtmlPangoRenderer *pr = NULL;
+
+			renderer = talkatu_html_pango_renderer_new();
+			pr = TALKATU_HTML_PANGO_RENDERER(renderer);
+
+			talkatu_html_renderer_render(renderer, contents);
+
+			gtk_label_set_markup(GTK_LABEL(row->content),
+			                     talkatu_html_pango_renderer_get_string(pr));
+
+			g_object_unref(G_OBJECT(renderer));
 		} else {
 			gtk_label_set_text(GTK_LABEL(row->content), contents);
 		}
diff --git a/talkatu/talkatuhtmlpangorenderer.h b/talkatu/talkatuhtmlpangorenderer.h
new file mode 100644
--- /dev/null
+++ b/talkatu/talkatuhtmlpangorenderer.h
@@ -0,0 +1,44 @@
+/*
+ * Talkatu - GTK widgets for chat applications
+ * Copyright (C) 2017-2021 Gary Kramlich <grim@reaperworld.com>
+ *
+ * This library 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, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION)
+#error "only <talkatu.h> may be included directly"
+#endif
+
+#ifndef TALKATU_HTML_PANGO_RENDERER_H
+#define TALKATU_HTML_PANGO_RENDERER_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <talkatu/talkatuhtmlrenderer.h>
+
+#define TALKATU_TYPE_HTML_PANGO_RENDERER (talkatu_html_pango_renderer_get_type())
+G_DECLARE_FINAL_TYPE(TalkatuHtmlPangoRenderer, talkatu_html_pango_renderer,
+                     TALKATU, HTML_PANGO_RENDERER, TalkatuHtmlRenderer)
+
+G_BEGIN_DECLS
+
+TalkatuHtmlRenderer *talkatu_html_pango_renderer_new(void);
+
+const gchar *talkatu_html_pango_renderer_get_string(TalkatuHtmlPangoRenderer *renderer);
+
+G_END_DECLS
+
+#endif /* TALKATU_HTML_PANGO_RENDERER_H */
+
diff --git a/talkatu/talkatuhtmlpangorenderer.c b/talkatu/talkatuhtmlpangorenderer.c
new file mode 100644
--- /dev/null
+++ b/talkatu/talkatuhtmlpangorenderer.c
@@ -0,0 +1,294 @@
+/*
+ * Talkatu - GTK widgets for chat applications
+ * Copyright (C) 2017-2021 Gary Kramlich <grim@reaperworld.com>
+ *
+ * This library 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, 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "talkatu/talkatuhtmlpangorenderer.h"
+
+typedef void (*TalkatuHtmlPangoRendererStartFunc)(TalkatuHtmlPangoRenderer *renderer,
+                                                  const gchar *name,
+                                                  const gchar **attribute_names,
+                                                  const gchar **attribute_values);
+typedef void (*TalkatuHtmlPangoRendererFinishFunc)(TalkatuHtmlPangoRenderer *renderer,
+                                                   const gchar *name);
+
+typedef struct {
+	TalkatuHtmlPangoRendererStartFunc start;
+	TalkatuHtmlPangoRendererFinishFunc finish;
+	const gchar *alias;
+} TalkatuHtmlPangoRendererElementFuncs;
+
+struct _TalkatuHtmlPangoRenderer {
+	TalkatuHtmlRenderer parent;
+
+	GString *str;
+
+	GHashTable *lookup;
+};
+
+G_DEFINE_TYPE(TalkatuHtmlPangoRenderer, talkatu_html_pango_renderer,
+              TALKATU_TYPE_HTML_RENDERER)
+
+/******************************************************************************
+ * TalkatuHtmlPangoRenderer Element Functions
+ *****************************************************************************/
+static void
+talkatu_html_pango_renderer_passthrough_start(TalkatuHtmlPangoRenderer *renderer,
+                                              const gchar *name,
+                                              const gchar **attribute_names,
+                                              const gchar **attribute_values)
+{
+	g_string_append_printf(renderer->str, "<%s>", name);
+}
+
+static void
+talkatu_html_pango_renderer_passthrough_finish(TalkatuHtmlPangoRenderer *renderer,
+                                               const gchar *name)
+{
+	g_string_append_printf(renderer->str, "</%s>", name);
+}
+
+static void
+talkatu_html_pango_renderer_code_start(TalkatuHtmlPangoRenderer *renderer,
+                                       const gchar *name,
+                                       const gchar **attribute_names,
+                                       const gchar **attribute_values)
+{
+	g_string_append(renderer->str, "<span font=\"monospace\">");
+}
+
+static void
+talkatu_html_pango_renderer_link_start(TalkatuHtmlPangoRenderer *renderer,
+                                       const gchar *name,
+                                       const gchar **attribute_names,
+                                       const gchar **attribute_values)
+{
+	gint i = 0;
+
+	g_string_append(renderer->str, "<a");
+
+	if(attribute_names != NULL) {
+		for(i = 0; attribute_names[i] != NULL; i++) {
+			if(g_ascii_strcasecmp(attribute_names[i], "href") == 0) {
+				g_string_append_printf(renderer->str,
+				                       " href=\"%s\"", attribute_values[i]);
+			}
+		}
+	}
+
+	g_string_append(renderer->str, ">");
+}
+
+static void
+talkatu_html_pango_renderer_font_start(TalkatuHtmlPangoRenderer *renderer,
+                                       const gchar *name,
+                                       const gchar **attribute_names,
+                                       const gchar **attribute_values)
+{
+	gint i = 0;
+
+	g_string_append(renderer->str, "<span");
+
+	if(attribute_names != NULL) {
+		for(i = 0; attribute_names[i] != NULL; i++) {
+			if(g_ascii_strcasecmp(attribute_names[i], "size") == 0) {
+				g_string_append_printf(renderer->str,
+				                       " font=\"%s\"", attribute_values[i]);
+			} else if(g_ascii_strcasecmp(attribute_names[i], "color") == 0) {
+				g_string_append_printf(renderer->str,
+				                       " foreground=\"%s\"", attribute_values[i]);
+			}
+		}
+	}
+
+	g_string_append(renderer->str, ">");
+}
+
+/******************************************************************************
+ * TalkatuHtmlRendererElementFuncs API
+ *****************************************************************************/
+TalkatuHtmlPangoRendererElementFuncs *
+talkatu_html_pango_renderer_element_funcs_new(TalkatuHtmlPangoRendererStartFunc start,
+                                              TalkatuHtmlPangoRendererFinishFunc finish,
+                                              const gchar *alias)
+{
+	TalkatuHtmlPangoRendererElementFuncs *funcs = NULL;
+
+	funcs = g_new(TalkatuHtmlPangoRendererElementFuncs, 1);
+	funcs->start = start;
+	funcs->finish = finish;
+	funcs->alias = alias;
+
+	return funcs;
+}
+
+TalkatuHtmlPangoRendererElementFuncs *
+talkatu_html_pango_renderer_element_funcs_new_passthrough(const gchar *alias) {
+	return talkatu_html_pango_renderer_element_funcs_new(
+		talkatu_html_pango_renderer_passthrough_start,
+		talkatu_html_pango_renderer_passthrough_finish,
+		alias
+	);
+}
+
+/******************************************************************************
+ * TalkatuHtmlRenderer Implementation
+ *****************************************************************************/
+static void
+talkatu_html_pango_renderer_reset(TalkatuHtmlRenderer *renderer) {
+	TalkatuHtmlPangoRenderer *pr = TALKATU_HTML_PANGO_RENDERER(renderer);
+
+	g_string_free(pr->str, TRUE);
+	pr->str = g_string_new("");
+}
+
+static void
+talkatu_html_pango_renderer_element_start(TalkatuHtmlRenderer *renderer,
+                                          const gchar *name,
+                                          const gchar **attribute_names,
+                                          const gchar **attribute_values)
+{
+	TalkatuHtmlPangoRenderer *pr = TALKATU_HTML_PANGO_RENDERER(renderer);
+	TalkatuHtmlPangoRendererElementFuncs *funcs = NULL;
+
+	funcs = g_hash_table_lookup(pr->lookup, name);
+	if(funcs != NULL && funcs->start != NULL) {
+		const gchar *real_name = (funcs->alias != NULL) ? funcs->alias : name;
+
+		funcs->start(pr, real_name, attribute_names, attribute_values);
+	}
+}
+
+static void
+talkatu_html_pango_renderer_element_finish(TalkatuHtmlRenderer *renderer,
+                                           const gchar *name)
+{
+	TalkatuHtmlPangoRenderer *pr = TALKATU_HTML_PANGO_RENDERER(renderer);
+	TalkatuHtmlPangoRendererElementFuncs *funcs = NULL;
+
+	funcs = g_hash_table_lookup(pr->lookup, name);
+	if(funcs != NULL && funcs->finish != NULL) {
+		const gchar *real_name = (funcs->alias != NULL) ? funcs->alias : name;
+
+		funcs->finish(pr, real_name);
+	}
+}
+
+static void
+talkatu_html_pango_renderer_text(TalkatuHtmlRenderer *renderer,
+                                 const gchar *text)
+{
+	TalkatuHtmlPangoRenderer *pr = TALKATU_HTML_PANGO_RENDERER(renderer);
+
+	g_string_append(pr->str, text);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+static void
+talkatu_html_pango_renderer_init(TalkatuHtmlPangoRenderer *renderer) {
+	TalkatuHtmlPangoRendererElementFuncs *funcs = NULL;
+
+	renderer->str = g_string_new("");
+
+	renderer->lookup = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+	                                         g_free);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new(
+		talkatu_html_pango_renderer_link_start,
+		talkatu_html_pango_renderer_passthrough_finish,
+		NULL
+	);
+	g_hash_table_insert(renderer->lookup, "a", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new_passthrough(NULL);
+	g_hash_table_insert(renderer->lookup, "b", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new(
+		talkatu_html_pango_renderer_code_start,
+		talkatu_html_pango_renderer_passthrough_finish,
+		"span"
+	);
+	g_hash_table_insert(renderer->lookup, "code", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new_passthrough(NULL);
+	g_hash_table_insert(renderer->lookup, "i", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new(
+		talkatu_html_pango_renderer_font_start,
+		talkatu_html_pango_renderer_passthrough_finish,
+		"span"
+	);
+	g_hash_table_insert(renderer->lookup, "font", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new_passthrough(NULL);
+	g_hash_table_insert(renderer->lookup, "s", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new_passthrough("s");
+	g_hash_table_insert(renderer->lookup, "strike", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new_passthrough(NULL);
+	g_hash_table_insert(renderer->lookup, "sub", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new_passthrough(NULL);
+	g_hash_table_insert(renderer->lookup, "sup", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new_passthrough(NULL);
+	g_hash_table_insert(renderer->lookup, "tt", funcs);
+
+	funcs = talkatu_html_pango_renderer_element_funcs_new_passthrough(NULL);
+	g_hash_table_insert(renderer->lookup, "u", funcs);
+}
+
+static void
+talkatu_html_pango_renderer_finalize(GObject *obj) {
+	TalkatuHtmlPangoRenderer *renderer = TALKATU_HTML_PANGO_RENDERER(obj);
+
+	g_string_free(renderer->str, TRUE);
+	g_hash_table_destroy(renderer->lookup);
+
+	G_OBJECT_CLASS(talkatu_html_pango_renderer_parent_class)->finalize(obj);
+}
+
+static void
+talkatu_html_pango_renderer_class_init(TalkatuHtmlPangoRendererClass *klass) {
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	TalkatuHtmlRendererClass *renderer_class = TALKATU_HTML_RENDERER_CLASS(klass);
+
+	obj_class->finalize = talkatu_html_pango_renderer_finalize;
+
+	renderer_class->reset = talkatu_html_pango_renderer_reset;
+	renderer_class->element_start = talkatu_html_pango_renderer_element_start;
+	renderer_class->element_finish = talkatu_html_pango_renderer_element_finish;
+	renderer_class->text = talkatu_html_pango_renderer_text;
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+TalkatuHtmlRenderer *
+talkatu_html_pango_renderer_new(void) {
+	return TALKATU_HTML_RENDERER(g_object_new(TALKATU_TYPE_HTML_PANGO_RENDERER,
+	                                          NULL));
+}
+
+const gchar *
+talkatu_html_pango_renderer_get_string(TalkatuHtmlPangoRenderer *renderer) {
+	g_return_val_if_fail(TALKATU_IS_HTML_PANGO_RENDERER(renderer), NULL);
+
+	return renderer->str->str;
+}
diff --git a/talkatu/talkatuhtmlparser.h b/talkatu/talkatuhtmlrenderer.h
rename from talkatu/talkatuhtmlparser.h
rename to talkatu/talkatuhtmlrenderer.h
--- a/talkatu/talkatuhtmlparser.h
+++ b/talkatu/talkatuhtmlrenderer.h
@@ -20,32 +20,39 @@
 #error "only <talkatu.h> may be included directly"
 #endif
 
-#ifndef TALKATU_HTML_H
-#define TALKATU_HTML_H
+#ifndef TALKATU_HTML_RENDERER_H
+#define TALKATU_HTML_RENDERER_H
 
 #include <glib.h>
 #include <glib-object.h>
 
-#define TALKATU_TYPE_HTML_PARSER (talkatu_html_parser_get_type())
-G_DECLARE_DERIVABLE_TYPE(TalkatuHtmlParser, talkatu_html_parser, TALKATU,
-                         HTML_PARSER, GObject)
+#define TALKATU_TYPE_HTML_RENDERER (talkatu_html_renderer_get_type())
+G_DECLARE_DERIVABLE_TYPE(TalkatuHtmlRenderer, talkatu_html_renderer, TALKATU,
+                         HTML_RENDERER, GObject)
 
-struct _TalkatuHtmlParserClass {
+struct _TalkatuHtmlRendererClass {
 	/*< private >*/
 	GObjectClass parent;
 
 	/*< public >*/
-	void (*element_start)(TalkatuHtmlParser *parser, const gchar *name, const gchar **attribute_names, const gchar **attribute_values, gpointer data);
-	void (*element_finish)(TalkatuHtmlParser *parser, const gchar *name, gpointer data);
-	void (*text)(TalkatuHtmlParser *parser, const gchar *text, gpointer data);
-	void (*comment)(TalkatuHtmlParser *parser, const gchar *comment, gpointer data);
+	void (*reset)(TalkatuHtmlRenderer *renderer);
+
+	void (*element_start)(TalkatuHtmlRenderer *renderer, const gchar *name, const gchar **attribute_names, const gchar **attribute_values);
+	void (*element_finish)(TalkatuHtmlRenderer *renderer, const gchar *name);
+	void (*text)(TalkatuHtmlRenderer *renderer, const gchar *text);
+	void (*comment)(TalkatuHtmlRenderer *renderer, const gchar *comment);
+
+	/*< private >*/
+	gpointer reserved[4];
 };
 
 G_BEGIN_DECLS
 
-void talkatu_html_parser_parse(TalkatuHtmlParser *parser, const gchar *html, gpointer data);
+void talkatu_html_renderer_render(TalkatuHtmlRenderer *renderer, const gchar *html);
+
+void talkatu_html_renderer_reset(TalkatuHtmlRenderer *renderer);
 
 G_END_DECLS
 
-#endif /* TALKATU_HTML_H */
+#endif /* TALKATU_HTML_RENDERER_H */
 
diff --git a/talkatu/talkatuhtmlparser.c b/talkatu/talkatuhtmlrenderer.c
rename from talkatu/talkatuhtmlparser.c
rename to talkatu/talkatuhtmlrenderer.c
--- a/talkatu/talkatuhtmlparser.c
+++ b/talkatu/talkatuhtmlrenderer.c
@@ -18,25 +18,28 @@
 
 #include <gumbo.h>
 
-#include "talkatuhtmlparser.h"
+#include "talkatuhtmlrenderer.h"
 
 /**
- * SECTION:talkatuhtmlparser
- * @Title: HTML Parsing
- * @Short_description: An Expat-like HTML Parser
+ * SECTION:talkatuhtmlrenderer
+ * @Title: HTML Renderer
+ * @Short_description: An Expat-like HTML Renderer
  *
- * #TalkatuHtmlParser is an abstract class that will parse HTML and call the
- * registered instance methods for each element.
+ * #TalkatuHtmlRenderer is an abstract class that will parse HTML and call the
+ * registered instance methods for each element allowing subclasses to render
+ * the HTML however they like.
  */
 
 /**
- * TALKATU_TYPE_HTML_PARSER:
+ * TALKATU_TYPE_HTML_RENDERER:
  *
- * The standard _get_type macro for #TalkatuHtmlParser.
+ * The standard _get_type macro for #TalkatuHtmlRenderer.
  */
 
 /**
- * TalkatuHtmlParserClass:
+ * TalkatuHtmlRendererClass:
+ * @reset: The method to call to reset the renderer.  This allows the renderer
+ *         to be reused.
  * @element_start: The method to call when an element is found.  The attribute
  *                 names and values are passed in as a %NULL terminated array of
  *                 strings.
@@ -56,7 +59,7 @@
 	 (node)->type == GUMBO_NODE_TEMPLATE)
 
 static GumboNode *
-talkatu_html_parser_find_next_sibling(GumboNode *node) {
+talkatu_html_renderer_find_next_sibling(GumboNode *node) {
 	GumboNode *next = NULL;
 
 	if(node->parent == NULL) {
@@ -81,12 +84,11 @@
  * Helper Implementations
  *****************************************************************************/
 static void
-talkatu_html_parser_element_start(TalkatuHtmlParser *parser,
-                                  const gchar *name,
-                                  GumboElement *element,
-                                  gpointer data)
+talkatu_html_renderer_element_start(TalkatuHtmlRenderer *renderer,
+                                    const gchar *name,
+                                    GumboElement *element)
 {
-	TalkatuHtmlParserClass *klass = TALKATU_HTML_PARSER_GET_CLASS(parser);
+	TalkatuHtmlRendererClass *klass = TALKATU_HTML_RENDERER_GET_CLASS(renderer);
 
 	if(klass->element_start) {
 		const gchar **names = NULL, **values = NULL;
@@ -112,7 +114,7 @@
 			values[i] = NULL;
 		}
 
-		klass->element_start(parser, name, names, values, data);
+		klass->element_start(renderer, name, names, values);
 
 		g_free(names);
 		g_free(values);
@@ -120,50 +122,48 @@
 }
 
 static void
-talkatu_html_parser_element_finish(TalkatuHtmlParser *parser,
-                                   const gchar *name,
-                                   gpointer data)
+talkatu_html_renderer_element_finish(TalkatuHtmlRenderer *renderer,
+                                     const gchar *name)
 {
-	TalkatuHtmlParserClass *klass = TALKATU_HTML_PARSER_GET_CLASS(parser);
+	TalkatuHtmlRendererClass *klass = TALKATU_HTML_RENDERER_GET_CLASS(renderer);
 
 	if(klass->element_finish) {
-		klass->element_finish(parser, name, data);
+		klass->element_finish(renderer, name);
 	}
 }
 
 static void
-talkatu_html_parser_text(TalkatuHtmlParser *parser, const gchar *text,
-                         gpointer data)
-{
-	TalkatuHtmlParserClass *klass = TALKATU_HTML_PARSER_GET_CLASS(parser);
+talkatu_html_renderer_text(TalkatuHtmlRenderer *renderer, const gchar *text) {
+	TalkatuHtmlRendererClass *klass = TALKATU_HTML_RENDERER_GET_CLASS(renderer);
 
 	if(klass->text) {
-		klass->text(parser, text, data);
+		klass->text(renderer, text);
 	}
 }
 
 static void
-talkatu_html_parser_comment(TalkatuHtmlParser *parser, const gchar *comment,
-                            gpointer data)
+talkatu_html_renderer_comment(TalkatuHtmlRenderer *renderer,
+                              const gchar *comment)
 {
-	TalkatuHtmlParserClass *klass = TALKATU_HTML_PARSER_GET_CLASS(parser);
+	TalkatuHtmlRendererClass *klass = TALKATU_HTML_RENDERER_GET_CLASS(renderer);
 
 	if(klass->comment) {
-		klass->comment(parser, comment, data);
+		klass->comment(renderer, comment);
 	}
 }
 
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
-G_DEFINE_ABSTRACT_TYPE(TalkatuHtmlParser, talkatu_html_parser, G_TYPE_OBJECT)
+G_DEFINE_ABSTRACT_TYPE(TalkatuHtmlRenderer, talkatu_html_renderer,
+                       G_TYPE_OBJECT)
 
 static void
-talkatu_html_parser_init(TalkatuHtmlParser *parser) {
+talkatu_html_renderer_init(TalkatuHtmlRenderer *renderer) {
 }
 
 static void
-talkatu_html_parser_class_init(TalkatuHtmlParserClass *klass) {
+talkatu_html_renderer_class_init(TalkatuHtmlRendererClass *klass) {
 }
 
 /******************************************************************************
@@ -171,18 +171,15 @@
  *****************************************************************************/
 
 /**
- * talkatu_html_parser_parse:
- * @parser: The #TalkatuHtmlParser instance.
- * @html: The HTML text to parse.
- * @data: User data to pass to all of the handler functions.
+ * talkatu_html_renderer_render:
+ * @renderer: The #TalkatuHtmlRenderer instance.
+ * @html: The HTML text to render.
  *
- * Starts parsing the given @html calling the #TalkatuHtmlParserClass functions
- * as necessary.
+ * Renders the given @html calling the #TalkatuHtmlRendererClass functions as
+ * necessary.
  */
 void
-talkatu_html_parser_parse(TalkatuHtmlParser *parser, const gchar *html,
-                          gpointer data)
-{
+talkatu_html_renderer_render(TalkatuHtmlRenderer *renderer, const gchar *html) {
 	GList *stack = NULL;
 	GumboOutput *output = NULL;
 
@@ -222,8 +219,8 @@
 			case GUMBO_NODE_ELEMENT:
 			case GUMBO_NODE_TEMPLATE:
 				tagname = gumbo_normalized_tagname(node->v.element.tag);
-				talkatu_html_parser_element_start(parser, tagname,
-				                                  &node->v.element, data);
+				talkatu_html_renderer_element_start(renderer, tagname,
+				                                    &node->v.element);
 
 				if(node->v.element.children.length > 0) {
 					/* if we have at least one child, we throw it on the stack
@@ -235,21 +232,21 @@
 					continue;
 				} else {
 					/* We have no children so we just call the finish method. */
-					talkatu_html_parser_element_finish(parser, tagname, data);
+					talkatu_html_renderer_element_finish(renderer, tagname);
 				}
 				break;
 			case GUMBO_NODE_CDATA:
 			case GUMBO_NODE_TEXT:
 			case GUMBO_NODE_WHITESPACE:
-				talkatu_html_parser_text(parser, node->v.text.text, data);
+				talkatu_html_renderer_text(renderer, node->v.text.text);
 				break;
 			case GUMBO_NODE_COMMENT:
-				talkatu_html_parser_comment(parser, node->v.text.text, data);
+				talkatu_html_renderer_comment(renderer, node->v.text.text);
 				break;
 		}
 
 		/* check if we have a sibling */
-		next = talkatu_html_parser_find_next_sibling(node);
+		next = talkatu_html_renderer_find_next_sibling(node);
 
 		/* remove the node from the stack */
 		stack = g_list_remove(stack, node);
@@ -266,7 +263,7 @@
 			GumboElement parent_element = node->parent->v.element;
 			tagname = gumbo_normalized_tagname(parent_element.tag);
 
-			talkatu_html_parser_element_finish(parser, tagname, data);
+			talkatu_html_renderer_element_finish(renderer, tagname);
 
 			/* while we still have elements on the list, pop them off until we
 			 * find one that still has children we haven't visited yet.
@@ -276,7 +273,7 @@
 
 				node = (GumboNode *)stack->data;
 
-				next = talkatu_html_parser_find_next_sibling(node);
+				next = talkatu_html_renderer_find_next_sibling(node);
 
 				if(next != NULL) {
 					/* we found a sibling, so drop the top most item and
@@ -292,7 +289,7 @@
 					element = node->parent->v.element;
 					tagname = gumbo_normalized_tagname(element.tag);
 
-					talkatu_html_parser_element_finish(parser, tagname, data);
+					talkatu_html_renderer_element_finish(renderer, tagname);
 				}
 
 				/* If this node doesn't have a sibling, then pop it off the
@@ -305,3 +302,21 @@
 
 	gumbo_destroy_output(&kGumboDefaultOptions, output);
 }
+
+/**
+ * talkatu_html_renderer_reset:
+ * @renderer: The #TalkatuHtmlRenderer instance.
+ *
+ * Resets @renderer back to a clean state so that it can render new HTML.
+ */
+void
+talkatu_html_renderer_reset(TalkatuHtmlRenderer *renderer) {
+	TalkatuHtmlRendererClass *klass = NULL;
+
+	g_return_if_fail(TALKATU_IS_HTML_RENDERER(renderer));
+
+	klass = TALKATU_HTML_RENDERER_GET_CLASS(renderer);
+	if(klass && klass->reset) {
+		klass->reset(renderer);
+	}
+}
diff --git a/talkatu/tests/meson.build b/talkatu/tests/meson.build
--- a/talkatu/tests/meson.build
+++ b/talkatu/tests/meson.build
@@ -17,10 +17,17 @@
 test('action-group', TEST_WRAPPER, args : e, is_parallel : false)
 
 e = executable(
-	'test-html-parser',
-	'talkatutesthtmlparser.c',
+	'test-html-pango-renderer',
+	'talkatutesthtmlpangorenderer.c',
 	dependencies : [talkatu_dep, GLIB]
 )
-test('html-parser', TEST_WRAPPER, args : e, is_parallel : false)
+test('html-pango-renderer', TEST_WRAPPER, args : e, is_parallel : false)
+
+e = executable(
+	'test-html-renderer',
+	'talkatutesthtmlrenderer.c',
+	dependencies : [talkatu_dep, GLIB]
+)
+test('html-renderer', TEST_WRAPPER, args : e, is_parallel : false)
 
 endif
diff --git a/talkatu/tests/talkatutesthtmlpangorenderer.c b/talkatu/tests/talkatutesthtmlpangorenderer.c
new file mode 100644
--- /dev/null
+++ b/talkatu/tests/talkatutesthtmlpangorenderer.c
@@ -0,0 +1,177 @@
+/*
+ * talkatu
+ * Copyright (C) 2017-2021 Gary Kramlich <grim@reaperworld.com>
+ *
+ * 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, or
+ * (at your option) any later version.
+ *
+ * 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 library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <talkatu.h>
+
+/******************************************************************************
+ * Tests
+ *****************************************************************************/
+static void
+test_talkatu_html_pango_renderer_simple(void) {
+	TalkatuHtmlRenderer *renderer = talkatu_html_pango_renderer_new();
+	const gchar *inp = "plain text";
+	const gchar *exp = "plain text";
+	const gchar *act = NULL;
+
+	talkatu_html_renderer_render(renderer, inp);
+	act = talkatu_html_pango_renderer_get_string(TALKATU_HTML_PANGO_RENDERER(renderer));
+
+	g_assert_cmpstr(act, ==, exp);
+
+	g_object_unref(G_OBJECT(renderer));
+}
+
+static void
+test_talkatu_html_pango_renderer_mixed(void) {
+	TalkatuHtmlRenderer *renderer = talkatu_html_pango_renderer_new();
+	const gchar *inp = \
+		"<html><head></head><body>" \
+		"<i><b>emphasis <u>underline</u></b> <strike>strike</strike> italic</i>" \
+		"</body></html>";
+	const gchar *exp = \
+		"<i><b>emphasis <u>underline</u></b> <s>strike</s> italic</i>";
+	const gchar *act = NULL;
+
+	talkatu_html_renderer_render(renderer, inp);
+	act = talkatu_html_pango_renderer_get_string(TALKATU_HTML_PANGO_RENDERER(renderer));
+
+	g_assert_cmpstr(act, ==, exp);
+
+	g_object_unref(G_OBJECT(renderer));
+}
+
+static void
+test_talkatu_html_pango_renderer_with_comment(void) {
+	TalkatuHtmlRenderer *renderer = talkatu_html_pango_renderer_new();
+	const gchar *inp = \
+		"Hello, <!--Darkness, my old friend, here to conquer the--> World!";
+	const gchar *exp = "Hello,  World!";
+	const gchar *act = NULL;
+
+	talkatu_html_renderer_render(renderer, inp);
+	act = talkatu_html_pango_renderer_get_string(TALKATU_HTML_PANGO_RENDERER(renderer));
+
+	g_assert_cmpstr(act, ==, exp);
+
+	g_object_unref(G_OBJECT(renderer));
+}
+
+static void
+test_talkatu_html_pango_renderer_with_attributes(void) {
+	TalkatuHtmlRenderer *renderer = talkatu_html_pango_renderer_new();
+	const gchar *inp = \
+		"<html><head></head><body>" \
+		"<font size=\"2\" color=\"#007f00\">talkatu</font>" \
+		"</body></html>";
+	const gchar *exp = "<span font=\"2\" foreground=\"#007f00\">talkatu</span>";
+	const gchar *act = NULL;
+
+	talkatu_html_renderer_render(renderer, inp);
+	act = talkatu_html_pango_renderer_get_string(TALKATU_HTML_PANGO_RENDERER(renderer));
+
+	g_assert_cmpstr(act, ==, exp);
+
+	g_object_unref(G_OBJECT(renderer));
+}
+
+static void
+test_talkatu_html_pango_renderer_with_nested_attributes(void) {
+	TalkatuHtmlRenderer *renderer = talkatu_html_pango_renderer_new();
+	const gchar *inp = \
+		"<html><head></head><body>" \
+		"<font size=\"2\" color=\"#007f00\">" \
+		"<a href=\"https://keep.imfreedom.org/talkatu/talkatu/\">talkatu</a>" \
+		"</font>" \
+		"</body></html>";
+	const gchar *exp = \
+		"<span font=\"2\" foreground=\"#007f00\">" \
+		"<a href=\"https://keep.imfreedom.org/talkatu/talkatu/\">talkatu</a>" \
+		"</span>";
+	const gchar *act = NULL;
+
+	talkatu_html_renderer_render(renderer, inp);
+	act = talkatu_html_pango_renderer_get_string(TALKATU_HTML_PANGO_RENDERER(renderer));
+
+	g_assert_cmpstr(act, ==, exp);
+
+	g_object_unref(G_OBJECT(renderer));
+}
+
+static void
+test_talkatu_html_pango_renderer_code(void) {
+	TalkatuHtmlRenderer *renderer = talkatu_html_pango_renderer_new();
+	const gchar *inp = \
+		"<html><head></head><body>" \
+		"<code>monkey</code>" \
+		"</body></html>";
+	const gchar *exp = \
+		"<span font=\"monospace\">monkey</span>";
+	const gchar *act = NULL;
+
+	talkatu_html_renderer_render(renderer, inp);
+	act = talkatu_html_pango_renderer_get_string(TALKATU_HTML_PANGO_RENDERER(renderer));
+
+	g_assert_cmpstr(act, ==, exp);
+
+	g_object_unref(G_OBJECT(renderer));
+}
+
+/******************************************************************************
+ * Main
+ *****************************************************************************/
+gint
+main(gint argc, gchar **argv) {
+	gint ret = 0;
+
+	g_test_init(&argc, &argv, NULL);
+
+	gtk_init(&argc, &argv);
+
+	talkatu_init();
+
+	g_test_add_func(
+		"/html-pango-renderer/simple",
+		test_talkatu_html_pango_renderer_simple);
+
+	g_test_add_func(
+		"/html-pango-renderer/mixed-children",
+		test_talkatu_html_pango_renderer_mixed);
+
+	g_test_add_func(
+		"/html-pango-renderer/with-comment",
+		test_talkatu_html_pango_renderer_with_comment);
+
+	g_test_add_func(
+		"/html-pango-renderer/with-attributes",
+		test_talkatu_html_pango_renderer_with_attributes);
+
+	g_test_add_func(
+		"/html-pango-renderer/with-nested-attributes",
+		test_talkatu_html_pango_renderer_with_nested_attributes);
+
+	g_test_add_func(
+		"/html-pango-renderer/code",
+		test_talkatu_html_pango_renderer_code);
+
+	ret = g_test_run();
+
+	talkatu_uninit();
+
+	return ret;
+}
+
diff --git a/talkatu/tests/talkatutesthtmlparser.c b/talkatu/tests/talkatutesthtmlrenderer.c
rename from talkatu/tests/talkatutesthtmlparser.c
rename to talkatu/tests/talkatutesthtmlrenderer.c
--- a/talkatu/tests/talkatutesthtmlparser.c
+++ b/talkatu/tests/talkatutesthtmlrenderer.c
@@ -19,158 +19,169 @@
 #include <talkatu.h>
 
 /******************************************************************************
- * TestTalkatuHtmlParser
+ * TestTalkatuHtmlRenderer
  *****************************************************************************/
-#define TEST_TALKATU_TYPE_HTML_PARSER (test_talkatu_html_parser_get_type())
-G_DECLARE_FINAL_TYPE(TestTalkatuHtmlParser, test_talkatu_html_parser,
-                     TEST_TALKATU, HTML_PARSER, TalkatuHtmlParser)
+#define TEST_TALKATU_TYPE_HTML_PARSER (test_talkatu_html_renderer_get_type())
+G_DECLARE_FINAL_TYPE(TestTalkatuHtmlRenderer, test_talkatu_html_renderer,
+                     TEST_TALKATU, HTML_RENDERER, TalkatuHtmlRenderer)
 
-struct _TestTalkatuHtmlParser {
-	TalkatuHtmlParser parent;
+struct _TestTalkatuHtmlRenderer {
+	TalkatuHtmlRenderer parent;
+
+	GString *str;
 };
 
 static void
-test_talkatu_html_parser_element_start(TalkatuHtmlParser *parser,
-                                       const gchar *name,
-                                       const gchar **attr_names,
-                                       const gchar **attr_values,
-                                       gpointer data)
+test_talkatu_html_renderer_element_start(TalkatuHtmlRenderer *renderer,
+                                         const gchar *name,
+                                         const gchar **attr_names,
+                                         const gchar **attr_values)
 {
-	GString *str = (GString *)data;
+	TestTalkatuHtmlRenderer *tr = TEST_TALKATU_HTML_RENDERER(renderer);
 
-	g_string_append_printf(str, "<%s", name);
+	g_string_append_printf(tr->str, "<%s", name);
 
 	if(attr_names != NULL) {
 		gint i = 0;
 
 		for(i = 0; attr_names[i] != NULL; i++) {
-			g_string_append_printf(str, " %s=\"", attr_names[i]);
+			g_string_append_printf(tr->str, " %s=\"", attr_names[i]);
 			if(attr_values[i] != NULL) {
-				g_string_append_printf(str, "%s", attr_values[i]);
+				g_string_append_printf(tr->str, "%s", attr_values[i]);
 			}
-			g_string_append_printf(str, "\"");
+			g_string_append_printf(tr->str, "\"");
 		}
 	}
 
-	g_string_append_printf(str, ">");
+	g_string_append_printf(tr->str, ">");
 }
 
 static void
-test_talkatu_html_parser_element_finish(TalkatuHtmlParser *parser,
-                                        const gchar *name,
-                                        gpointer data)
+test_talkatu_html_renderer_element_finish(TalkatuHtmlRenderer *renderer,
+                                          const gchar *name)
 {
-	g_string_append_printf((GString *)data, "</%s>", name);
+	TestTalkatuHtmlRenderer *tr = TEST_TALKATU_HTML_RENDERER(renderer);
+
+	g_string_append_printf(tr->str, "</%s>", name);
 }
 
 static void
-test_talkatu_html_parser_text(TalkatuHtmlParser *parser, const gchar *text,
-                              gpointer data)
+test_talkatu_html_renderer_text(TalkatuHtmlRenderer *renderer,
+                                const gchar *text)
 {
-	g_string_append_printf((GString *)data, "%s", text);
+	TestTalkatuHtmlRenderer *tr = TEST_TALKATU_HTML_RENDERER(renderer);
+
+	g_string_append_printf(tr->str, "%s", text);
 }
 
 static void
-test_talkatu_html_parser_comment(TalkatuHtmlParser *parser,
-                                 const gchar *comment, gpointer data)
+test_talkatu_html_renderer_comment(TalkatuHtmlRenderer *renderer,
+                                   const gchar *comment)
 {
-	g_string_append_printf((GString *)data, "<!--%s-->", comment);
+	TestTalkatuHtmlRenderer *tr = TEST_TALKATU_HTML_RENDERER(renderer);
+
+	g_string_append_printf(tr->str, "<!--%s-->", comment);
 }
 
-G_DEFINE_TYPE(TestTalkatuHtmlParser, test_talkatu_html_parser, TALKATU_TYPE_HTML_PARSER);
+G_DEFINE_TYPE(TestTalkatuHtmlRenderer, test_talkatu_html_renderer,
+              TALKATU_TYPE_HTML_RENDERER);
 
 static void
-test_talkatu_html_parser_init(TestTalkatuHtmlParser *parser) {
+test_talkatu_html_renderer_init(TestTalkatuHtmlRenderer *renderer) {
+	renderer->str = g_string_new("");
 }
 
 static void
-test_talkatu_html_parser_class_init(TestTalkatuHtmlParserClass *klass) {
-	TalkatuHtmlParserClass *parser_class = TALKATU_HTML_PARSER_CLASS(klass);
+test_talkatu_html_renderer_finalize(GObject *obj) {
+	TestTalkatuHtmlRenderer *tr = TEST_TALKATU_HTML_RENDERER(obj);
 
-	parser_class->element_start = test_talkatu_html_parser_element_start;
-	parser_class->element_finish = test_talkatu_html_parser_element_finish;
-	parser_class->text = test_talkatu_html_parser_text;
-	parser_class->comment = test_talkatu_html_parser_comment;
+	g_string_free(tr->str, TRUE);
+
+	G_OBJECT_CLASS(test_talkatu_html_renderer_parent_class)->finalize(obj);
 }
 
-TalkatuHtmlParser *
-test_talkatu_html_parser_new(void) {
-	return TALKATU_HTML_PARSER(g_object_new(TEST_TALKATU_TYPE_HTML_PARSER,
-	                                        NULL));
+static void
+test_talkatu_html_renderer_class_init(TestTalkatuHtmlRendererClass *klass) {
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	TalkatuHtmlRendererClass *renderer_class = TALKATU_HTML_RENDERER_CLASS(klass);
+
+	obj_class->finalize = test_talkatu_html_renderer_finalize;
+
+	renderer_class->element_start = test_talkatu_html_renderer_element_start;
+	renderer_class->element_finish = test_talkatu_html_renderer_element_finish;
+	renderer_class->text = test_talkatu_html_renderer_text;
+	renderer_class->comment = test_talkatu_html_renderer_comment;
+}
+
+TestTalkatuHtmlRenderer *
+test_talkatu_html_renderer_new(void) {
+	return TEST_TALKATU_HTML_RENDERER(g_object_new(TEST_TALKATU_TYPE_HTML_PARSER,
+	                                               NULL));
 }
 
 /******************************************************************************
  * Tests
  *****************************************************************************/
 static void
-test_talkatu_html_parser_simple(void) {
-	TalkatuHtmlParser *parser = test_talkatu_html_parser_new();
-	GString *str = g_string_new("");
+test_talkatu_html_renderer_simple(void) {
+	TestTalkatuHtmlRenderer *renderer = test_talkatu_html_renderer_new();
 	const gchar *exp = "<html><head></head><body>plain text</body></html>";
 
-	talkatu_html_parser_parse(parser, "plain text", str);
+	talkatu_html_renderer_render(TALKATU_HTML_RENDERER(renderer), "plain text");
 
-	g_assert_cmpstr(str->str, ==, exp);
+	g_assert_cmpstr(renderer->str->str, ==, exp);
 
-	g_string_free(str, TRUE);
-	g_object_unref(G_OBJECT(parser));
+	g_object_unref(G_OBJECT(renderer));
 }
 
 static void
-test_talkatu_html_parser_mixed(void) {
-	TalkatuHtmlParser *parser = test_talkatu_html_parser_new();
-	GString *str = g_string_new("");
+test_talkatu_html_renderer_mixed(void) {
+	TestTalkatuHtmlRenderer *renderer = test_talkatu_html_renderer_new();
 	const gchar *exp = \
 		"<html><head></head><body>" \
 		"<i><b>emphasis <u>underline</u></b> <strike>strike</strike> italic</i>" \
 		"</body></html>";
 
-	talkatu_html_parser_parse(parser, exp, str);
+	talkatu_html_renderer_render(TALKATU_HTML_RENDERER(renderer), exp);
 
-	g_assert_cmpstr(str->str, ==, exp);
+	g_assert_cmpstr(renderer->str->str, ==, exp);
 
-	g_string_free(str, TRUE);
-	g_object_unref(G_OBJECT(parser));
+	g_object_unref(G_OBJECT(renderer));
 }
 
 static void
-test_talkatu_html_parser_with_comment(void) {
-	TalkatuHtmlParser *parser = test_talkatu_html_parser_new();
-	GString *str = g_string_new("");
+test_talkatu_html_renderer_with_comment(void) {
+	TestTalkatuHtmlRenderer *renderer = test_talkatu_html_renderer_new();
 	const gchar *exp = \
 		"<html><head></head><body>" \
 		"Hello, <!--Darkness, my old friend, here to conquer the--> World!" \
 		"</body></html>";
 
-	talkatu_html_parser_parse(parser, exp, str);
+	talkatu_html_renderer_render(TALKATU_HTML_RENDERER(renderer), exp);
 
-	g_assert_cmpstr(str->str, ==, exp);
+	g_assert_cmpstr(renderer->str->str, ==, exp);
 
-	g_string_free(str, TRUE);
-	g_object_unref(G_OBJECT(parser));
+	g_object_unref(G_OBJECT(renderer));
 }
 
 static void
-test_talkatu_html_parser_with_attributes(void) {
-	TalkatuHtmlParser *parser = test_talkatu_html_parser_new();
-	GString *str = g_string_new("");
+test_talkatu_html_renderer_with_attributes(void) {
+	TestTalkatuHtmlRenderer *renderer = test_talkatu_html_renderer_new();
 	const gchar *exp = \
 		"<html><head></head><body>" \
 		"<font size=\"2\" color=\"#007f00\">talkatu</font>" \
 		"</body></html>";
 
-	talkatu_html_parser_parse(parser, exp, str);
+	talkatu_html_renderer_render(TALKATU_HTML_RENDERER(renderer), exp);
 
-	g_assert_cmpstr(str->str, ==, exp);
+	g_assert_cmpstr(renderer->str->str, ==, exp);
 
-	g_string_free(str, TRUE);
-	g_object_unref(G_OBJECT(parser));
+	g_object_unref(G_OBJECT(renderer));
 }
 
 static void
-test_talkatu_html_parser_with_nested_attributes(void) {
-	TalkatuHtmlParser *parser = test_talkatu_html_parser_new();
-	GString *str = g_string_new("");
+test_talkatu_html_renderer_with_nested_attributes(void) {
+	TestTalkatuHtmlRenderer *renderer = test_talkatu_html_renderer_new();
 	const gchar *exp = \
 		"<html><head></head><body>" \
 		"<font size=\"2\" color=\"#007f00\">" \
@@ -178,12 +189,11 @@
 		"</font>" \
 		"</body></html>";
 
-	talkatu_html_parser_parse(parser, exp, str);
+	talkatu_html_renderer_render(TALKATU_HTML_RENDERER(renderer), exp);
 
-	g_assert_cmpstr(str->str, ==, exp);
+	g_assert_cmpstr(renderer->str->str, ==, exp);
 
-	g_string_free(str, TRUE);
-	g_object_unref(G_OBJECT(parser));
+	g_object_unref(G_OBJECT(renderer));
 }
 
 /******************************************************************************
@@ -200,24 +210,24 @@
 	talkatu_init();
 
 	g_test_add_func(
-		"/html-parser/simple",
-		test_talkatu_html_parser_simple);
+		"/html-renderer/simple",
+		test_talkatu_html_renderer_simple);
 
 	g_test_add_func(
-		"/html-parser/mixed-children",
-		test_talkatu_html_parser_mixed);
+		"/html-renderer/mixed-children",
+		test_talkatu_html_renderer_mixed);
 
 	g_test_add_func(
-		"/html-parser/with-comment",
-		test_talkatu_html_parser_with_comment);
+		"/html-renderer/with-comment",
+		test_talkatu_html_renderer_with_comment);
 
 	g_test_add_func(
-		"/html-parser/with-attributes",
-		test_talkatu_html_parser_with_attributes);
+		"/html-renderer/with-attributes",
+		test_talkatu_html_renderer_with_attributes);
 
 	g_test_add_func(
-		"/html-parser/with-nested-attributes",
-		test_talkatu_html_parser_with_nested_attributes);
+		"/html-renderer/with-nested-attributes",
+		test_talkatu_html_renderer_with_nested_attributes);
 
 	ret = g_test_run();
 
