Index: src/yelp-man.c
===================================================================
--- src/yelp-man.c	(revision 2973)
+++ src/yelp-man.c	(working copy)
@@ -453,8 +453,10 @@
 
     parser = yelp_man_parser_new ();
     priv->xmldoc = yelp_man_parser_parse_file (parser, priv->filename, encoding);
+    printf ("Freeing\n");
     yelp_man_parser_free (parser);
 
+    printf ("Feed\n");
     if (priv->xmldoc == NULL) {
 	error = yelp_error_new (_("Could not parse file"),
 				_("The file ‘%s’ could not be parsed because it is"
@@ -469,6 +471,7 @@
 	goto done;
     }
 
+    printf ("parsing...\n");
     priv->transform = yelp_transform_new (STYLESHEET,
 					  (YelpTransformFunc) transform_func,
 					  man);
@@ -479,6 +482,7 @@
 
     params[params_i] = NULL;
 
+    printf ("starting...\n");
     yelp_transform_start (priv->transform,
 			  priv->xmldoc,
 			  params);
Index: src/yelp-window.c
===================================================================
--- src/yelp-window.c	(revision 2973)
+++ src/yelp-window.c	(working copy)
@@ -870,7 +870,7 @@
 {
     YelpError *error;
     YelpLoadData *data;
-
+    printf ("Recieved signal - %d\n", signal);
     switch (signal) {
     case YELP_DOCUMENT_SIGNAL_PAGE:
 	window_set_sections (window, yelp_document_get_sections (document));
@@ -879,6 +879,7 @@
 	data->window = window;
 	data->page = (YelpPage *) func_data;
 
+	printf ("Writing html\n");
 	window_write_html (data);
 
 	window->priv->current_request = -1;
@@ -2673,11 +2674,15 @@
     yelp_html_set_base_uri (html, uri);
     g_free (uri);
     yelp_html_open_stream (html, "application/xhtml+xml");
-    
+
+    printf ("Writing:\n");
     do {
 	yelp_page_read (data->page, contents, BUFFER_SIZE, &read, NULL);
+	printf ("%s", contents);
 	yelp_html_write (html, contents, read);
     } while (read == BUFFER_SIZE);
+    printf ("\n");
+    fflush (NULL);
     yelp_html_close (html);
     return FALSE;
 }
Index: src/yelp-man-parser.c
===================================================================
--- src/yelp-man-parser.c	(revision 2973)
+++ src/yelp-man-parser.c	(working copy)
@@ -23,7 +23,7 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
-
+#include <fcntl.h>
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <libxml/tree.h>
@@ -63,25 +63,35 @@
 					     gchar         *name);
 static void        parser_parse_table       (YelpManParser *parser);
 
+static void        yelp_man_parser_parse_stream (YelpManParser *parser);
+
+struct _StackElem {
+    gint level;
+    xmlNodePtr ptr;
+
+};
+
+
 typedef struct _StackElem StackElem;
 struct _YelpManParser {
     xmlDocPtr     doc;           /* The top-level XML document */
     xmlNodePtr    ins;           /* The insertion node */
+    xmlNodePtr    cur;           /* Current append point */
+    xmlNodePtr    indent;
 
     GIOChannel   *channel;       /* GIOChannel for the entire document */
 
-    gchar        *buffer;        /* The buffer, line at a time */
-    gsize         length;        /* The buffer length */
+    GHashTable   *font_mappings;
+    GSList       *node_stack;
+    GSList       *font_stack;
 
-    gchar        *anc;           /* The anchor point in the document */
-    gchar        *cur;           /* Our current position in the document */
+    GSList       *indent_stack;
+    gint         *indent_level;
 
-    gchar        *token;         /* see ignore flag; we ignore the parsing stream until
-				  * this string is found in the stream */
-    gboolean      make_links;    /* Allow auto-generated hyperlinks to be disabled. */
-    gboolean      ignore;        /* when true, ignore stream until "token" is found  */
-	
-    GSList       *nodeStack;
+    gchar        *cur_font;
+    gchar        *buffer;        /* The buffer, line at a time */
+    gsize         length;        /* The buffer length */
+    gchar        *troff_out;     /* The troff output */
 };
 
 YelpManParser *
@@ -99,7 +109,23 @@
 {
     GError *errormsg = NULL;
     /*gchar *ptr = NULL;*/
+    gchar **argv = NULL;
+    gint troff_stdin;
+    gint troff_stdout;
+    gint troff_stderr;
+    GPid pid;
+    gchar line[50];
+    GError *error = NULL;
+    gint s;
 
+    parser->troff_out = g_strdup ("# comment\n");
+    argv = g_new(gchar *, 5);
+    argv[0] = g_strdup ("troff");
+    argv[1] = g_strdup ("-man");
+    argv[2] = g_strdup ("-Thtml");
+    argv[3] = g_strdup ("-");
+    argv[4] = 0;
+
     g_return_val_if_fail (parser != NULL, NULL);
     g_return_val_if_fail (file != NULL, NULL);
     g_return_val_if_fail (encoding != NULL, NULL);
@@ -111,61 +137,57 @@
 
     parser->doc = xmlNewDoc (BAD_CAST "1.0");
     parser->ins = xmlNewNode (NULL, BAD_CAST "Man");
-	xmlDocSetRootElement (parser->doc, parser->ins);
+    parser->cur = NULL;
+    //xmlNewTextChild (parser->ins, NULL, BAD_CAST "p", NULL);
+    parser->indent = parser->ins;
+    xmlDocSetRootElement (parser->doc, parser->ins);
+    
+    parser->font_stack = NULL;
+    parser->node_stack = NULL;
 
-    parser->make_links = TRUE;
+    parser->font_mappings =  g_hash_table_new_full (g_str_hash, g_str_equal,
+						    NULL, NULL);
+    parser->cur_font = g_strdup ("R");
 
+    if (!g_spawn_async_with_pipes (NULL,
+                                   argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+				   NULL, NULL, &pid,
+				   &troff_stdin, &troff_stdout, &troff_stderr, &error)) {
+	printf ("Not spawned troff! - %s", error->message);
+	exit (55);
+    }
+    fcntl (troff_stdin, F_SETFL, O_SYNC);
     while (g_io_channel_read_line (parser->channel,
 				   &(parser->buffer),
 				   &(parser->length),
 				   NULL, &errormsg)
 	   == G_IO_STATUS_NORMAL) {
 
-	/* convert this line from the encoding indicated to UTF-8 */
-	if (!g_str_equal (encoding, "UTF-8")) {
-	    GError *converr = NULL;
-	    gchar *new_buffer = NULL;
-	    gsize bytes_written = 0;
+	write (troff_stdin, parser->buffer, parser->length);
+	
 
-	    /* since our encoding is binary (NULL) in g_io_channel, then
-	     * our returned lined should end with \n.  Therefore we are making the
-	     * assumption that there are no partial characters at the end of this
-	     * string, and therefore can use calls like g_convert() which do not
-	     * preserve state - someone tell me if I'm wrong here */
-	    new_buffer = g_convert (parser->buffer, parser->length, "UTF-8", 
-	                            encoding, NULL, &bytes_written, &converr);
-	    if (converr != NULL) {
-		g_print ("Error occurred converting %s to UTF-8: %s\n", 
-		         encoding, converr->message);
-		g_error_free (converr);
-		break;
-	    } else if (parser->buffer == NULL) {
-		g_print ("parser->buffer == NULL\n");
-		break;
-	    }
-
-	    g_free (parser->buffer);
-	    parser->buffer = new_buffer;
-	    parser->length = bytes_written;
-	}
-	    
-	/* for debugging, make sure line is valid UTF-8 */
-	/*if (!g_utf8_validate (parser->buffer, (gssize)parser->length, &ptr)) {
-	    g_print ("str = %s\n", parser->buffer);
-	    g_print ("str ptr = %p\n", parser->buffer);
-	    g_print ("invalid char = %p (%c)\n", ptr, *ptr);
-	}*/
-	    
-	parser_parse_line (parser);
-
 	g_free (parser->buffer);
     }
+    close (troff_stdin);
 
+    fcntl (troff_stdout, F_SETFL, O_SYNC);
+    fflush (NULL);
     if (errormsg)
 	g_print ("Error in g_io_channel_read_line()\n");
 
+    do {
+	s = read (troff_stdout, &line, 49);	//if (s != 63)
+	line[s] = '\0';
+	parser->troff_out = g_strconcat (parser->troff_out, line, NULL);
+    } while (s > 0);
+    //fprintf (stderr, "%s\n", parser->troff_out);
+
     g_io_channel_shutdown (parser->channel, FALSE, NULL);
 
+    yelp_man_parser_parse_stream (parser);
+
+    printf ("Returning...\n");
+    xmlDocDump (stdout, parser->doc);
     return parser->doc;
 }
 
@@ -178,1659 +200,342 @@
     g_free (parser);
 }
 
-/******************************************************************************/
+/****************/
 
-static void
-parser_parse_line (YelpManParser *parser) {
-    parser->anc = parser->buffer;
-    parser->cur = parser->buffer;
-    
-    /* check to see if we are ignoring input */
-    if (parser->ignore) {
-	gchar *ptr;
-	/* needs to be utf-8 compatible */
-	ptr = strstr (parser->buffer, parser->token);
-    	if (ptr != NULL) {
-	    while (PARSER_CUR) {
-		parser->cur = g_utf8_next_char (parser->cur);
-		parser->anc = parser->cur;
-	    }
-	    g_free (parser->token);
-	    parser->ignore = FALSE;
-	} else {
-	    /* return to get another line of input  */
-	    return;
-	}
-    } else {
-	switch (*(parser->buffer)) {
-	case '.':
-	    parser_handle_linetag (parser);
-    	    /* we are ignoring everything until parser->token, 
-     	     * so return and get next line */
-    	    if (parser->ignore)
-	        return;
-	    break;
-	case '\n':
-	    parser->ins = xmlDocGetRootElement (parser->doc);
-	    break;
-	case '\'':
-	    parser->cur = parser->buffer + parser->length - 1;
-	    parser->anc = parser->cur;
-	default:
-	    break;
-	}
-    }
-    
-    parser_read_until (parser, '\n');
-     
-    if (parser->cur != parser->anc)
-	parser_append_text (parser);
-    
-    if (PARSER_CUR) {
-	parser->cur = g_utf8_next_char (parser->cur);
-	parser_append_text (parser);
-    }
-}
-
-/* creates a single string from all the macro arguments */
-static gchar *
-args_concat_all (GSList *args)
+void
+parse_meta (YelpManParser *parser, gchar *line)
 {
-    GSList *ptr = NULL;
-    gchar **str_array = NULL;
-    gchar *retval = NULL;
-    gint i = 0;
-    
-    if (!args)
-	return NULL;
+    gchar *content = g_strdup(line+1);
 
-    str_array = g_malloc0 ((sizeof (gchar *)) * (g_slist_length (args)+1) );
-
-    ptr = args;
-    while (ptr && ptr->data) {
-	str_array[i++] = ptr->data;
-	ptr = g_slist_next (ptr);
-    }
+    g_strstrip(content);
     
-    str_array[i] = NULL;
+    if (*content == 'X') {
+	/* New node type */
+	gchar *tag = g_strdup (content + 1);
+	g_strstrip (tag);
 
-    retval = g_strjoinv (" ", str_array);
+	if (!strncmp (tag, "html-tag:", 9)) {
+	    /* Actual tag that's interesting */
+	    printf ("Tag: %s (%s)\n", tag, tag+9);
+	    if (!strncmp (tag+9, ".br", 3)) {
+		/* .br indicates a line break */
+		printf ("Adding .br\n");
+		parser->cur = xmlNewTextChild (parser->indent, NULL, BAD_CAST "p", NULL);
+		parser->cur_font = g_strdup ("R");
+		parser->node_stack = NULL;
+		parser->font_stack = NULL;
+	    } else if (!strncmp (tag+9, ".sp", 3)) {
+		/* Vertical spacing.  Ignore options arguments
+		   as we know best		   
+		*/
+		printf ("Adding .sp\n");
 
-    g_free (str_array);
+		parser->cur = xmlNewTextChild (parser->indent, NULL, BAD_CAST "p", NULL);
+		parser->cur_font = g_strdup ("R");
+		parser->node_stack = NULL;
+		parser->font_stack = NULL;
+	    } else if (!strncmp (tag+9, ".NH", 3)) {
+		/* New section title, I think */
+		printf ("Adding new section header\n");
+		parser->cur = xmlNewTextChild (parser->indent, NULL, BAD_CAST "header", NULL);
+		gchar *lev = g_strdup_printf ("%d", parser->indent_level);
+		printf ("Lev: %s - %d\n", lev, parser->indent_level);
+		xmlSetProp (parser->cur, BAD_CAST "indent", BAD_CAST g_strdup_printf ("%d", parser->indent_level));
+		parser->font_stack = NULL;
+		parser->node_stack = NULL;
+	    } else if (!strncmp (tag+9, ".in", 3)) {
+		/* Indent current sect */
+		printf ("Adding indented DIV\n");
+		gint num_val;
+		gchar *val = g_strdup (tag+12);
+		printf ("DIV\n");
+		g_strstrip (val);
+		num_val = atoi (val);
+		printf ("Num val: %d - %d\n", num_val, parser->indent_level);
 
-    return retval;
-}
+		GSList *list_ptr = parser->indent_stack;
 
-/* handler to ignore a macro by reading until the null character */
-static void
-macro_ignore_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{ 
-    while (PARSER_CUR) {
-	parser->cur = g_utf8_next_char (parser->cur);
-	parser->anc = parser->cur;
-    }
-}
+		if (num_val > parser->indent_level) {
+		    StackElem *elem;
+		    /* More indentation */
 
-static void
-macro_bold_small_italic_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    gchar *str = NULL;
+		    elem = g_new (StackElem, 1);
+		    elem->ptr = parser->indent;
+		    elem->level = parser->indent_level;
 
-    parser_ensure_P (parser);
-    parser->ins = parser_append_node (parser, macro);
-    
-    if (args && args->data) {
-	str = args_concat_all (args);
-	parser_append_given_text_handle_escapes (parser, str, TRUE);
-	g_free (str);
-    }
-    
-    parser->ins = parser->ins->parent;
-}
+		    parser->indent_stack = g_slist_prepend (parser->indent_stack, elem);
+		    
+		    parser->indent = xmlNewChild (parser->indent, NULL, "div", NULL);
+		    
+		    parser->cur_font = g_strdup ("R");
+		    xmlSetProp (parser->indent, BAD_CAST "indent", BAD_CAST val);
+		    parser->indent_level += num_val;
 
-static void
-macro_roman_bold_small_italic_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    GSList *ptr = NULL;
-    gchar a[2], b[2];
-    gboolean toggle = TRUE;
-    
-    a[0] = macro[0];
-    b[0] = macro[1];
-    a[1] = b[1] = '\0';
+		}
 
-    parser_ensure_P (parser);
+		gboolean found = FALSE;
+		while (list_ptr) {
+		    if (num_val == ((StackElem *) list_ptr->data)->level) {
+			found = TRUE;
+			break;
+		    } else if (num_val > ((StackElem *) list_ptr->data)->level) {
+			/* Gone too far - for now, just pretend like above */
+			found = TRUE;
+			break;
+		    }
+		    list_ptr = list_ptr->next;
+		}
+		if (found) {
+		    parser->indent = xmlNewChild (((StackElem *) list_ptr->data)->ptr, NULL, "div", NULL);
+		    
+		    parser->cur_font = g_strdup ("R");
+		    xmlSetProp (parser->indent, BAD_CAST "indent", BAD_CAST val);
+		    parser->indent_level = ((StackElem *)list_ptr->data)->level + num_val;
+		    parser->indent_stack = list_ptr;
+		} else {
+		    /* New top-level indent */
+		    parser->cur_font = g_strdup ("R");
+		    parser->indent = xmlNewChild (parser->ins, NULL, "div", NULL);
+		    parser->indent_level = num_val;
+		    xmlSetProp (parser->indent, BAD_CAST "indent", BAD_CAST val);
+		    parser->indent_stack = NULL;
 
-    ptr = args;
-    while (ptr && ptr->data) {
-	if (toggle)
-	    parser->ins = parser_append_node (parser, a);
-	else
-	    parser->ins = parser_append_node (parser, b);
-	
-	if (ptr->next) {
-	    gchar *tmp = ptr->next->data;
-	    
-	    if (tmp[0] == '(' && g_ascii_isdigit (tmp[1]) &&
-		(tmp[2] == ')' || (g_ascii_isalpha (tmp[2]) && tmp[3] == ')'))) {
-		tmp = g_strconcat (ptr->data, " ", tmp, NULL);
-		parser_append_given_text_handle_escapes (parser, tmp, TRUE);
-		g_free (tmp);
-		parser->ins = parser->ins->parent;
-		ptr = ptr->next->next;
-		continue;
-	    }  
-	}
+		}
+		parser->cur = xmlNewTextChild (parser->indent, NULL, 
+					       BAD_CAST g_strdup("p"), 
+					       NULL);
+	    }
 
-	parser_append_given_text_handle_escapes (parser, ptr->data, TRUE);
-	parser->ins = parser->ins->parent;
-	
-	toggle = (toggle) ? 0 : 1;
-	ptr = g_slist_next (ptr);
-    }
-}
-
-static void
-macro_new_paragraph_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    xmlNodePtr tmpNode;
-	
-    /* Clean up from 'lists'. If this is null we don't care. */
-    tmpNode = parser_stack_pop_node (parser, "IP");
-	
-    tmpNode = parser_stack_pop_node (parser, "P");
-    if (tmpNode != NULL) {
-	parser->ins = tmpNode->parent;
-    }
-
-    parser_ensure_P (parser);
-}
-
-static void
-macro_insert_self_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    parser_append_node (parser, macro);
-}
-
-static void
-macro_title_header_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    GSList *ptr = NULL;
-    gchar *fields[5] = { "Title", "Section", "Date", "Commentary", "Name" };
-    gint i;
-	
-    parser->ins = parser_append_node (parser, macro);
-
-    ptr = args;
-    for (i=0; i < 5; i++) {
-	if (ptr && ptr->data) {
-	    parser->ins = parser_append_node (parser, fields[i]);
-	    parser_append_given_text_handle_escapes (parser, ptr->data, FALSE);
-	    parser->ins = parser->ins->parent;	
-	    ptr = g_slist_next (ptr);
-	} else 
-	    break;
-    }
-
-    parser->ins = parser->ins->parent;
-}
-
-static void
-macro_section_header_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    static gint id = 0;
-    GIOStatus retval;
-    GError **errormsg = NULL;
-    gchar *str = NULL;
-    gchar *macro_uc = g_strdup (macro);
-    gchar *ptr;
-    gchar  idval[20];
-    
-    if (!args) {
-	retval = g_io_channel_read_line (parser->channel,
-				         &str,
-				         NULL, NULL, errormsg);
-	if (retval != G_IO_STATUS_NORMAL) {
-	    g_warning ("g_io_channel_read_line != G_IO_STATUS_NORMAL\n");
 	}
-    } else 
-	str = args_concat_all (args);
+    } else if (!strncmp (content, "font", 4)) {
+	/* New font mapping.  These are of the type like:
+	   X font num type
+	*/
+	gchar *cut = g_strdup (content+4);
+	gchar *num = NULL;
+	gchar *desc = NULL;
+	g_strstrip(cut);
 
-    for (ptr = macro_uc; *ptr != '\0'; ptr++)
-	/* FIXME: utf-8 */
-    	*ptr = g_ascii_toupper (*ptr);
-    
-    parser_stack_pop_node (parser, "IP");
-
-    g_snprintf (idval, 20, "%d", ++id);
-    
-    /* Sections should be their own, well, section */
-    parser->ins = xmlDocGetRootElement (parser->doc);
-    parser->ins = parser_append_node_attr (parser, macro_uc, "id", idval);
-    parser_append_given_text_handle_escapes (parser, str, FALSE);
-    parser->ins = parser->ins->parent;
-    
-    if (str)
-	g_free (str);
-}
-
-static void
-macro_spacing_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    parser->ins = parser_append_node (parser, macro);
-
-    if (args && args->data) {
-	parser->ins = parser_append_node (parser, "Count");
-	parser_append_given_text (parser, args->data);
-	parser->ins = parser->ins->parent;
-    }
-
-    parser->ins = parser->ins->parent;
-}
-	
-/* this is used to define or redefine a macro until ".." 
- * is reached. */
-static void
-macro_define_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-	parser->ignore = TRUE;
-	parser->token = g_strdup("..");
-}
-	
-static void
-macro_tp_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    xmlNodePtr tmpNode = NULL;
-    GError **errormsg = NULL;
-
-    tmpNode = parser_stack_pop_node (parser, "IP");
-
-    if (tmpNode != NULL)
-	parser->ins = tmpNode->parent;
-
-    parser->ins = parser_append_node (parser, "IP");
-
-    if (args && args->data) {
-        parser->ins = parser_append_node (parser, "Indent");
-	parser_append_given_text (parser, args->data);
-        parser->ins = parser->ins->parent;
-    }
-
-    g_free (parser->buffer);
-
-    if (g_io_channel_read_line (parser->channel,
-                                &(parser->buffer), 
-				&(parser->length), 
-				NULL, errormsg)
-            == G_IO_STATUS_NORMAL) {
-	parser->ins = parser_append_node (parser, "Tag");
-	parser_parse_line (parser);
-	parser->ins = parser->ins->parent;
-    }
-
-    parser_stack_push_node (parser, parser->ins);
-}
-	
-static void
-macro_ip_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    xmlNodePtr tmpNode;
-    
-    tmpNode = parser_stack_pop_node (parser, "IP");
-
-    if (tmpNode != NULL)
-	parser->ins = tmpNode->parent;
-
-    parser->ins = parser_append_node (parser, macro);
-
-    if (args && args->data) {
-	parser->ins = parser_append_node (parser, "Tag");
-	parser_append_given_text_handle_escapes (parser, args->data, TRUE);
-	parser->ins = parser->ins->parent;
-	    
-	if (args->next && args->next->data) {
-	    parser->ins = parser_append_node (parser, "Indent");
-	    parser_append_given_text_handle_escapes (parser, args->next->data, TRUE);
-	    parser->ins = parser->ins->parent;
+	desc = cut+strlen(cut)-1;
+	while (*desc != ' ') {
+	    desc--;
 	}
-    }
-
-    parser_stack_push_node (parser, parser->ins);
-}
+	desc++;
 	
-static void
-macro_hanging_paragraph_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    parser_stack_pop_node (parser, "IP");
+	num = g_strndup (cut, desc-cut);
+	g_strstrip (num);
 
-    parser->ins = parser_append_node (parser, macro);
+	g_hash_table_insert (parser->font_mappings, (gpointer) num,
+			     (gpointer) (g_strdup(desc)));
+	g_free (cut);
 
-    if (args && args->data) {
-	parser->ins = parser_append_node (parser, "Indent");
-	parser_append_given_text (parser, args->data);
-	parser->ins = parser->ins->parent;
     }
-}
 
-/* BSD mandoc macros
- * Since mandoc man pages are required to begin with Dd, Dt, Os,
- * we will use this to create the TH tag.
- */
-static void
-macro_mandoc_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    gchar *str = NULL;
-	
-    if (g_str_equal (macro, "Dd")) {
-	parser->ins = parser_append_node (parser, "TH");
-
-	str = args_concat_all (args);
-	
-	if (args && args->data) {
-            parser->ins = parser_append_node (parser, "Date");
-            parser_append_given_text (parser, str);
-            parser->ins = parser->ins->parent;
-        }
-
-	g_free (str);
-    } 
-    else if (g_str_equal (macro, "Dt")) {
-	if (args && args->data) {
-            parser->ins = parser_append_node (parser, "Title");
-            parser_append_given_text (parser, args->data);
-            parser->ins = parser->ins->parent;
-        }
-
-	if (args && args->next && args->next->data) {
-            parser->ins = parser_append_node (parser, "Section");
-            parser_append_given_text (parser, args->next->data);
-            parser->ins = parser->ins->parent;
-	}
-    } 
-    else if (g_str_equal (macro, "Os")) {
-	if (args && args->data) {
-            parser->ins = parser_append_node (parser, "Os");
-            parser_append_given_text (parser, args->data);
-            parser->ins = parser->ins->parent;
-        }
-
-	/* Leave the TH tag */
-	parser->ins = parser->ins->parent;
-    }    
 }
 
-static void
-macro_url_handler (YelpManParser *parser, gchar *macro, GSList *args)
+void
+parse_append_text (YelpManParser *parser, gchar *line)
 {
-    xmlNodePtr tmpNode = NULL;
-    
-    if (g_str_equal (macro, "UR")) {
-	/* If someone wants to do automatic hyperlink wizardry outside
-	 * for the parser, then this should instead generate a tag.
-         */
-	if (args && args->data) {
-	    if (g_str_equal (args->data, ":"))
-		parser->make_links = FALSE;
-	    else {
-		parser->ins = parser_append_node (parser, macro);
-	    
-		parser_stack_push_node (parser, parser->ins);
-	    
-		parser->ins = parser_append_node (parser, "URI");
-		parser_append_given_text (parser, args->data);
-		parser->ins = parser->ins->parent;
-	    }
-	}
-    } 
-    else if (g_str_equal (macro, "UE")) {
-	
-	if (parser->make_links) {
-	    tmpNode = parser_stack_pop_node (parser, "UR");
-
-	    if (tmpNode == NULL)
-		debug_print (DB_WARN, "Found unexpected tag: '%s'\n", macro);
-	    else
-		parser->ins = tmpNode->parent;
-	} else
-	    parser->make_links = TRUE;
-	
-    } 
-    else if (g_str_equal (macro, "UN")) {
-
-	if (args && args->data) {
-	    parser->ins = parser_append_node (parser, macro);
-	    parser_append_given_text (parser, args->data);
-	    parser->ins = parser->ins->parent;
-	}
-	
+    if (!parser->cur) {
+	printf ("ERRORING: No cur element - append\n");
+	return;
     }
-}
-
-/* relative margin indent; FIXME: this takes a parameter that tells
- * how many indents to do, which needs to be implemented to fix 
- * some man page formatting options */
-/*static void
-macro_rs_re_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    xmlNodePtr tmpNode;
-
-    if (g_str_equal (macro, "RS")) {
-	parser->ins = parser_append_node (parser, macro);
-
-	parser_stack_push_node (parser, parser->ins);
-
-	if (args && args->data) {
-            parser->ins = parser_append_node (parser, "Indent");
-            parser_append_given_text (parser, args->data);
-            parser->ins = parser->ins->parent;
-        }
-    } 
-    else if (g_str_equal (macro, "RE")) {
-	parser_stack_pop_node (parser, "IP");
-
-	tmpNode = parser_stack_pop_node (parser, "RS");
-
-	if (tmpNode == NULL)
-	    d (g_warning ("Found unexpected tag: '%s'\n", macro));
-	else
-	    parser->ins = tmpNode->parent;
-    }
-}*/
-
-static void
-macro_mandoc_list_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    xmlNodePtr tmpNode;
-
-    if (g_str_equal (macro, "Bl")) {
-       
-	parser->ins = parser_append_node (parser, macro);
-	    
-	if (args && args->data) {
-	    gchar *listtype = (gchar *)args->data;
-		
-	    if (g_str_equal (listtype, "-hang") ||
-		g_str_equal (listtype, "-ohang") ||
-		g_str_equal (listtype, "-tag") ||
-		g_str_equal (listtype, "-diag") ||
-		g_str_equal (listtype, "-inset")
-	       ) {
-		listtype++;
-		xmlNewProp (parser->ins, BAD_CAST "listtype", 
-		            BAD_CAST listtype);
-		/* TODO: check for -width, -offset, -compact */
-	    } else if (g_str_equal (listtype, "-column")) {
-		/* TODO: support this */;
-	    } else if (g_str_equal (listtype, "-item") ||
-		       g_str_equal (listtype, "-bullet") ||
-		       g_str_equal (listtype, "-hyphen") ||
-		       g_str_equal (listtype, "-dash")
-		      ) {
-		listtype++;
-		xmlNewProp (parser->ins, BAD_CAST "listtype", 
-		            BAD_CAST listtype);
-		/* TODO: check for -offset, -compact */
-	    }
-	}
-	    
-        parser_stack_push_node (parser, parser->ins);
-    }
-    else if (g_str_equal (macro, "El")) {
+    char *text = line;
+    printf ("Adding %s to %s\n", text, parser->cur->name);
+    text++;
+    xmlNodeAddContent (parser->cur, text);
+    //xmlNodeAddContent (parser->cur, " ");
     
-    	tmpNode = parser_stack_pop_node (parser, "It");
-
-	if (tmpNode != NULL)
-	    parser->ins = tmpNode->parent;
-
-        tmpNode = parser_stack_pop_node (parser, "Bl");
-
-        if (tmpNode == NULL)
-	    debug_print (DB_WARN, "Found unexpected tag: '%s'\n", macro);
-        else
-            parser->ins = tmpNode->parent;
-    }
 }
 
-static void
-macro_verbatim_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    xmlNodePtr tmpNode;
-    
-    if (g_str_equal (macro, "nf") || g_str_equal (macro, "Vb")) {
-	parser->ins = parser_append_node (parser, "Verbatim");
-	parser_stack_push_node (parser, parser->ins);
-    } 
-    else if (g_str_equal (macro, "fi") || g_str_equal (macro, "Ve")) {
-	tmpNode = parser_stack_pop_node (parser, "Verbatim");
+typedef struct {
+    gchar *comp_font;
+    gint   found_num;
+    gint   cur_num;
+} FontData;
 
-	if (tmpNode == NULL)
-	    debug_print (DB_WARN, "Found unexpected tag: '%s'\n", macro);
-	else
-	    parser->ins = tmpNode->parent;
+void
+parse_find_prev (gchar *font, FontData *data)
+{    
+    printf ("Comparing %s to %s (%d)\n", font, data->comp_font, data->found_num);
+    data->cur_num++;
+    if (data->found_num > -1)
+	return;
+    if (!font && g_str_equal (data->comp_font, "1")) {
+	printf ("Found!\n");
+	data->found_num = data->cur_num;
     }
-}
-
-static void
-macro_reference_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    if (g_str_equal (macro, "so")) {
-	gchar *basename = NULL;
-	gchar *link = NULL;
-	
-	if (args && args->data) {
-	    basename = g_strrstr((const gchar *)args->data, "/");
-
-	    if (basename) {
-		basename++;
-		link = g_strdup_printf ("man:%s", basename);
-	    } else {
-		link = g_strdup_printf ("man:%s", (const gchar *)args->data);
-		basename = (gchar *)args->data;
-	    }
-	    
-	    parser->ins = parser_append_node (parser, "TH");
-	    parser->ins = parser_append_node (parser, "Title");
-	    parser_append_given_text (parser, "REFERENCE");
-	    parser->ins = parser->ins->parent;
-	    parser->ins = parser->ins->parent;
-		
-	    parser->ins = parser_append_node_attr (parser, "SH", "id", "9999");
-	    parser_append_given_text (parser, "REFERENCE");
-	    parser->ins = parser->ins->parent;
-	    
-	    parser_append_given_text (parser, "See ");
-	    parser->ins = parser_append_node (parser, "UR");
-	    parser->ins = parser_append_node (parser, "URI");
-	    parser_append_given_text (parser, link);
-	    parser->ins = parser->ins->parent;
-	    parser_append_given_text (parser, basename);
-	    parser->ins = parser->ins->parent;
-
-	    g_free (link);
-	}
+    else if (font && 
+	g_str_equal (font, data->comp_font)) {
+	printf ("Found 1\n");
+	data->found_num = data->cur_num;
     }
 }
-	
-/* many mandoc macros have their arguments parsed so that other
- * macros can be called to operate on their arguments.  This table
- * indicates which macros are _parsed_ for other callable macros, 
- * and which are _callable_ from other macros: see mdoc(7) for more
- * details
- */
 
-#define MANDOC_NONE 0x01
-#define MANDOC_PARSED 0x01
-#define MANDOC_CALLABLE 0x02
-
-struct MandocMacro {
-    gchar *macro;
-    gint flags;
-};
-
-static struct MandocMacro manual_macros[] = {
-    { "Ad", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "An", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Ar", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Cd", MANDOC_NONE },
-    { "Cm", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Dv", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Er", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Ev", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Fa", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Fd", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Fl", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Fn", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Ic", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Li", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Nd", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Nm", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Op", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Ot", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Pa", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "St", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Tn", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Va", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Vt", MANDOC_PARSED | MANDOC_CALLABLE },
-    { "Xr", MANDOC_PARSED | MANDOC_CALLABLE },
-    { NULL, MANDOC_NONE }
-};
-
-static gboolean
-is_mandoc_manual_macro_parsed (gchar *macro)
+void
+parse_set_font (YelpManParser *parser, gchar *line)
 {
-    gint i;
-	
-    for (i=0; manual_macros[i].macro != NULL; i++) {
-        if (g_str_equal (macro, manual_macros[i].macro) &&
-	    (manual_macros[i].flags & MANDOC_PARSED) == MANDOC_PARSED
-	   ) {
-		return TRUE;
-	}
-    }
-
-    return FALSE;
-}
-
-static gboolean
-is_mandoc_manual_macro_callable (gchar *macro)
-{
-    gint i;
-	
-    for (i=0; manual_macros[i].macro != NULL; i++) {
-        if (g_str_equal (macro, manual_macros[i].macro) &&
-	    (manual_macros[i].flags & MANDOC_CALLABLE) == MANDOC_CALLABLE
-	   ) {
-		return TRUE;
-	}
-    }
-
-    return FALSE;
-}
-
-static void
-macro_mandoc_utility_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    GSList *ptr = NULL;
-    gchar *str = NULL;
-    gchar *manpage, *uri;
-
-    g_return_if_fail (macro != NULL);
+    gchar *font_num;
+    FontData *data;
+    /* 
+       Command format:
+       f<space?>num
+       Font type supported:
+       B: Boldify
+       BI: Bold and italics
+       CB: ???
+       CBI: ???
+       CI: ???
+       CR: ???
+       G: ???
+       I: Italics
+       M: ???
+       R: Regular
+       S: ???       
+     */
     
-    if (is_mandoc_manual_macro_parsed (macro)) {
-	parser->ins = parser_append_node (parser, macro);
-	
-	ptr = args;
-	while (ptr && ptr->data) {
-	    if (is_mandoc_manual_macro_callable ((gchar *)ptr->data)) {
-	    	macro_mandoc_utility_handler (parser, (gchar *)ptr->data, ptr->next);
-		break;
-	    } else {
-		parser_append_given_text_handle_escapes (parser, (gchar *)ptr->data, TRUE);
-	    }
-	    ptr = ptr->next;
-	    if (ptr && ptr->data)
-		parser_append_given_text (parser, " ");
-	}
-	
-	parser->ins = parser->ins->parent;
-    } else {
-	parser->ins = parser_append_node (parser, macro);
-	str = args_concat_all (args);
-	parser->ins = parser->ins->parent;
-    
-	g_free (str);
-    }
+    /* TODO: stack based instead of static 2 */
 
-    return;
-	
-    if (g_str_equal (macro, "Op")) {
-	    
-    } else if (g_str_equal (macro, "Nm")) {
-
-	if (str) {
-	    parser_ensure_P (parser);
-		
-	    parser->ins = parser_append_node (parser, "B");
-	    parser_append_given_text_handle_escapes (parser, str, TRUE);
-	    parser->ins = parser->ins->parent;
-        }
+    if (!parser->cur) {
+	printf ("ERRORING: No cur element (set font)\n");
     }
-    else if (g_str_equal (macro, "Nd")) {
-    
-	if (str) {
-	    parser_append_given_text (parser, " -- ");
-	    parser_append_given_text_handle_escapes (parser, str, TRUE);
-	}
-    }
-    else if (g_str_equal (macro, "Xr")) {
-	    
-	if (args && args->data && args->next && args->next->data) {
-	    
-	    manpage = g_strdup_printf ("%s(%s)", (gchar *)args->data, (gchar *)args->next->data);
-	    uri = g_strdup_printf ("man:%s", manpage);
-	    
-	    parser_ensure_P (parser);
-	    
-	    parser->ins = parser_append_node (parser, "UR");
-	    parser->ins = parser_append_node (parser, "URI");
-	    parser_append_given_text (parser, uri);
-	    parser->ins = parser->ins->parent;
-	    parser_append_given_text (parser, manpage);
-	    parser->ins = parser->ins->parent;
-	   
-	    ptr = args->next->next;
 
-	    while (ptr && ptr->data) {
-		parser_append_given_text (parser, ptr->data);
-		ptr = g_slist_next (ptr);
-	    }
-	    
-	    g_free (uri);
-	    g_free (manpage);
-	}
-    }
+    font_num = g_strdup (line+1);
 
-    g_free (str);
-}
+    g_strstrip (font_num);
 
-static void
-macro_mandoc_listitem_handler (YelpManParser *parser, gchar *macro, GSList *args)
-{
-    GSList *ptr = NULL;
-    xmlNodePtr tmpNode;
-    
-    tmpNode = parser_stack_pop_node (parser, "It");
+    data = g_new (FontData, 1);
 
-    if (tmpNode != NULL)
-	parser->ins = tmpNode->parent;
+    data->comp_font = g_hash_table_lookup (parser->font_mappings,
+					   (gpointer) font_num);
+    data->found_num = -1;
+    data->cur_num = 0;
 
-    parser->ins = parser_append_node (parser, macro);
+    if (parser->cur_font && !strcmp (font_num, parser->cur_font))
+	return;
 
-    if (args && args->data) {
-	parser->ins = parser_append_node (parser, "ItTag");
-	
-	ptr = args;
-	while (ptr && ptr->data) {
-	    if (is_mandoc_manual_macro_callable ((gchar *)ptr->data)) {
-	    	macro_mandoc_utility_handler (parser, (gchar *)ptr->data, ptr->next);
-		break;
-	    } else {
-		parser_append_given_text (parser, (gchar *)ptr->data);
-	    }
-	    ptr = ptr->next;
-	    if (ptr && ptr->data)
-		parser_append_given_text (parser, " ");
-	}
-	
-	parser->ins = parser->ins->parent;
-    }
 
-    parser_stack_push_node (parser, parser->ins);
-}
+    g_slist_foreach (parser->font_stack, parse_find_prev, data);    
 
-/* the handler functions for each macro all have this form:
- *   - the calling function, parser_handle_linetag owns the "macro", and "args"
- *     parameters, so do not free them.
- */
-typedef void (*MacroFunc)(YelpManParser *parser, gchar *macro, GSList *args);
-
-struct MacroHandler {
-    gchar *macro;
-    MacroFunc handler;
-};
-
-/* We are calling all of these macros, when in reality some of them are
- * requests (lowercase, defined by groff system), and some of them are
- * macros (varying case, defined by man/mdoc/ms/tbl extensions)
- *
- * A great resource to figure out what each of these does is the groff
- * info page.  Also groff(7), man(7), and mdoc(7) are useful as well.
- */
-static struct MacroHandler macro_handlers[] = {
-    { "\\\"", macro_ignore_handler },                /* groff: comment */ 
-    { "ad", macro_ignore_handler },                  /* groff: set adjusting mode */ 
-    { "Ad", macro_mandoc_utility_handler },          /* mandoc: Address */ 
-    { "An", macro_mandoc_utility_handler },          /* mandoc: Author name */ 
-    { "Ar", macro_mandoc_utility_handler },          /* mandoc: Command line argument */ 
-    { "B",  macro_bold_small_italic_handler },       /* man: set bold font */
-    { "Bd", macro_ignore_handler },                  /* mandoc: Begin-display block */
-    { "BI", macro_roman_bold_small_italic_handler }, /* man: bold italic font */
-    { "Bl", macro_mandoc_list_handler },             /* mandoc: begin list */
-    { "bp", macro_ignore_handler },                  /* groff: break page */ 
-    { "br", macro_insert_self_handler },             /* groff: line break */
-    { "BR", macro_roman_bold_small_italic_handler }, /* man: set bold roman font */
-    { "Cd", macro_mandoc_utility_handler },          /* mandoc: Configuration declaration */ 
-    { "Cm", macro_mandoc_utility_handler },          /* mandoc: Command line argument modifier */ 
-    { "ce", macro_ignore_handler },                  /* groff: center text */
-    { "Dd", macro_mandoc_handler },                  /* mandoc: Document date */
-    { "de", macro_define_handler },                  /* groff: define macro */
-    { "ds", macro_ignore_handler },                  /* groff: define string variable */
-    { "D1", macro_ignore_handler },                  /* mandoc: Indent and display one text line */
-    { "Dl", macro_ignore_handler },                  /* mandoc: Indent and display one line of literal text */
-    { "Dt", macro_mandoc_handler },                  /* mandoc: Document title */
-    { "Dv", macro_mandoc_utility_handler },          /* mandoc: Defined variable */ 
-    { "Ed", macro_ignore_handler },                  /* mandoc: End-display block */
-    { "El", macro_mandoc_list_handler },             /* mandoc: end list */ 
-    { "Er", macro_mandoc_utility_handler },          /* mandoc: Error number */ 
-    { "Ev", macro_mandoc_utility_handler },          /* mandoc: Environment variable */ 
-    { "Fa", macro_mandoc_utility_handler },          /* mandoc: Function argument */ 
-    { "Fd", macro_mandoc_utility_handler },          /* mandoc: Function declaration */ 
-    { "fi", macro_verbatim_handler },                /* groff: activate fill mode */
-    { "Fl", macro_mandoc_utility_handler },          /* mandoc: ? */ 
-    { "Fn", macro_mandoc_utility_handler },          /* mandoc: Function call */ 
-    { "ft", macro_ignore_handler },                  /* groff: change font */
-    { "HP", macro_hanging_paragraph_handler },       /* man: paragraph with hanging left indentation */
-    { "hy", macro_ignore_handler },                  /* groff: enable hyphenation */
-    { "I",  macro_bold_small_italic_handler },       /* man: set italic font */
-    { "Ic", macro_mandoc_utility_handler },          /* mandoc: Interactive Command */ 
-    { "ie", macro_ignore_handler },                  /* groff: else portion of if-else */
-    { "if", macro_ignore_handler },                  /* groff: if statement */
-    { "ig", macro_ignore_handler },                  /* groff: comment until '..' or '.END' */
-    { "ih", macro_ignore_handler },                  /* ? */
-    { "IX", macro_ignore_handler },                  /* ms: print index to stderr */
-    { "IB", macro_roman_bold_small_italic_handler }, /* man: set italic bold font */
-    { "IP", macro_ip_handler },                      /* man: indented paragraph */
-    { "IR", macro_roman_bold_small_italic_handler }, /* man: set italic roman font */
-    { "It", macro_mandoc_listitem_handler },         /* mandoc: item in list */
-    { "Li", macro_mandoc_utility_handler },          /* mandoc: Literal text */ 
-    { "LP", macro_new_paragraph_handler },           /* man: line break and left margin and indentation are reset */
-    { "na", macro_ignore_handler },                  /* groff: disable adjusting */
-    { "Nd", macro_mandoc_utility_handler },          /* mandoc: description of utility/program */
-    { "ne", macro_ignore_handler },                  /* groff: force space at bottom of page */
-    { "nf", macro_verbatim_handler },                /* groff: no fill mode */
-    { "nh", macro_ignore_handler },                  /* groff: disable hyphenation */
-    { "Nd", macro_mandoc_utility_handler },          /* mandoc: ? */
-    { "Nm", macro_mandoc_utility_handler },          /* mandoc: Command/utility/program name*/
-    { "Op", macro_mandoc_utility_handler },          /* mandoc: Option */
-    { "Os", macro_mandoc_handler },                  /* mandoc: Operating System */
-    { "Ot", macro_mandoc_utility_handler },          /* mandoc: Old style function type (Fortran) */
-    { "P",  macro_new_paragraph_handler },           /* man: line break and left margin and indentation are reset */
-    { "Pa", macro_mandoc_utility_handler },          /* mandoc: Pathname or filename */
-    { "PP", macro_new_paragraph_handler },           /* man: line break and left margin and indentation are reset */
-    { "Pp", macro_new_paragraph_handler },           /* man: line break and left margin and indentation are reset */
-    { "ps", macro_ignore_handler },                  /* groff: change type size */
-    { "RB", macro_roman_bold_small_italic_handler }, /* man: set roman bold font */
-    { "RE", macro_ignore_handler },                  /* man: move left margin back to NNN */
-    { "RI", macro_roman_bold_small_italic_handler }, /* man: set roman italic font */
-    { "RS", macro_ignore_handler },                  /* man: move left margin to right by NNN */
-    { "SH", macro_section_header_handler },          /* man: unnumbered section heading */
-    { "Sh", macro_section_header_handler },          /* man: unnumbered section heading */
-    { "SM", macro_bold_small_italic_handler },       /* man: set font size one SMaller */
-    { "so", macro_reference_handler },               /* groff: include file */
-    { "sp", macro_spacing_handler },                 /* groff: */
-    { "SS", macro_section_header_handler },          /* man: unnumbered subsection heading */
-    { "Ss", macro_section_header_handler },          /* man: unnumbered subsection heading */
-    { "St", macro_mandoc_utility_handler },          /* mandoc: Standards (-p1003.2, -p1003.1 or -ansiC) */
-    { "TH", macro_title_header_handler },            /* man: set title of man page */
-    { "TP", macro_tp_handler },                      /* man: set indented paragraph with label */
-    { "UR", macro_url_handler },                     /* man: URL start hyperlink */
-    { "UE", macro_url_handler },                     /* man: URL end hyperlink */
-    { "UN", macro_ignore_handler },                  /* ? */ 
-    { "TE", macro_ignore_handler },                  /* ms: table */
-    { "Tn", macro_mandoc_utility_handler },          /* mandoc: Trade or type name (small Caps). */
-    { "ti", macro_ignore_handler },                  /* groff: temporary indent */
-    { "tr", macro_ignore_handler },                  /* groff: translate characters */
-    { "TS", macro_ignore_handler },                  /* ms: table with optional header */
-    { "Va", macro_mandoc_utility_handler },          /* mandoc: Variable name */
-    { "Vb", macro_verbatim_handler },                /* pod2man: start of verbatim text */
-    { "Ve", macro_verbatim_handler },                /* pod2man: end of verbatim text */
-    { "Vt", macro_mandoc_utility_handler },          /* mandoc: Variable type (Fortran only) */
-    { "Xr", macro_mandoc_utility_handler },          /* mandoc: Manual page cross reference */
-    { NULL, NULL } 
-};
-
-static void
-parser_handle_linetag (YelpManParser *parser) {
-    gchar c, *str, *ptr, *arg;
-    GSList *arglist = NULL;
-    GSList *listptr = NULL;
-    MacroFunc handler_func = NULL;
-    
-    static GHashTable *macro_hash = NULL;
-
-    /* check if we've created the hash of macros yet.  If not, make it */
-    if (!macro_hash) {
+    if (data->found_num != -1) {
 	gint i;
-	    
-	macro_hash = g_hash_table_new (g_str_hash, g_str_equal);
 	
-	for (i=0; macro_handlers[i].macro != NULL; i++) {
-	    g_hash_table_insert (macro_hash, 
-	                         macro_handlers[i].macro, 
-	                         macro_handlers[i].handler);
-	}
-    }
-
-    /* FIXME: figure out a better way to handle these cases */
-    /* special case, if the line is simply ".\n" then return */
-    if (g_utf8_get_char (g_utf8_next_char (parser->cur)) == '\n') {
-    	parser->cur = g_utf8_next_char (parser->cur);
-    	parser->cur = g_utf8_next_char (parser->cur);
-	parser->anc = parser->cur;
-	return;
-    } 
-    /* special case, if the line is simply "..\n" then return */
-    else if (g_utf8_get_char (g_utf8_next_char(parser->cur)) == '.' && 
-	     g_utf8_get_char (g_utf8_next_char (g_utf8_next_char (parser->cur+2))) == '\n') {
-    	parser->cur = g_utf8_next_char (parser->cur);
-    	parser->cur = g_utf8_next_char (parser->cur);
-    	parser->cur = g_utf8_next_char (parser->cur);
-    	parser->anc = parser->cur;
-    }
-    
-    /* skip any spaces after the control character . */
-    while (PARSER_CUR && g_utf8_get_char (parser->cur) == ' ')
-	    parser->cur = g_utf8_next_char (parser->cur);
-    
-    while (PARSER_CUR
-	   && g_utf8_get_char (parser->cur) != ' '
-	   && ( (g_utf8_get_char (parser->cur) != '\\') || 
-	        (
-		 (g_utf8_get_char(parser->cur) == '\\') && 
-		 (g_utf8_get_char(g_utf8_next_char (parser->cur)) == '\"')
-		) 
-	      )
-	   && g_utf8_get_char (parser->cur) != '\n') {    
-	if (
-	    (g_utf8_get_char (parser->cur) == '\\') && 
-	    (g_utf8_get_char (g_utf8_next_char (parser->cur)) == '\"')
-	   ) {
-	    parser->cur = g_utf8_next_char (g_utf8_next_char (parser->cur));
-	    break;
-	}
-	parser->cur = g_utf8_next_char (parser->cur);
-    }
-
-    /* copy the macro/request into str */
-    c = *(parser->cur);
-    *(parser->cur) = '\0';
-    str = g_strdup (parser->anc + 1);  /* skip control character '.' by adding one */
-    *(parser->cur) = c;
-    parser->anc = parser->cur;
-    
-    /* FIXME: need to handle escaped characters */
-    /* perform argument parsing and store argument in a singly linked list */
-    while (PARSER_CUR && g_utf8_get_char (parser->cur) != '\n') { 
-	ptr = NULL;
-	arg = NULL;
+	for (i=0; i < data->found_num-1; i++) {
+	    printf ("Before: %p and %p", parser->font_stack, parser->node_stack);
+	    printf ("Data: %s && %s", parser->font_stack->data, parser->node_stack->data);
+	    parser->font_stack = parser->font_stack->next;
+	    parser->node_stack = parser->node_stack->next;
 	    
-	/* skip any whitespace */
-	while (PARSER_CUR && g_utf8_get_char (parser->cur) == ' ') {
-	    parser->cur = g_utf8_next_char (parser->cur);
-	    parser->anc = parser->cur;
 	}
-	
-get_argument:
-	/* search until we hit whitespace or an " */
-	while (PARSER_CUR && 
-               g_utf8_get_char (parser->cur) != '\n' &&
-	       g_utf8_get_char (parser->cur) != ' ' &&
-	       g_utf8_get_char (parser->cur) != '\"')
-		parser->cur = g_utf8_next_char (parser->cur);
 
-	/* this checks for escaped spaces */
-	if (PARSER_CUR && 
-	    ((parser->cur - parser->buffer) > 0) &&
-	    g_utf8_get_char (parser->cur) == ' ' &&
-	    g_utf8_get_char (g_utf8_prev_char (parser->cur)) == '\\') {
-		parser->cur = g_utf8_next_char (parser->cur);
-		goto get_argument;
-	}
-	
-	if (g_utf8_get_char (parser->cur) == '\n' && 
-	    (parser->cur == parser->anc))
-	    break;
-	
-	if (g_utf8_get_char (parser->cur) == '\"' && 
-	    g_utf8_get_char (g_utf8_prev_char (parser->cur)) == ' ') {
-	    /* quoted argument */
-	    ptr = strchr (parser->cur+1, '\"');
-	    if (ptr != NULL) {
-		c = *(ptr);
-		*(ptr) = '\0';
-		arg = g_strdup (parser->anc+1);
-		*(ptr) = c;
-		parser->cur = ptr;
-		parser->anc = ++parser->cur;
-	    } else {
-		/* unmatched double quote: include the " as part of the argument */
-		parser->cur++;
-		goto get_argument;
-	    }
-	} 
-	else if (*(parser->cur) == '\"') {
-	    /* quote in the middle of an argument */
-	    c = *(parser->cur+1);
-	    *(parser->cur+1) = '\0';
-	    arg = g_strdup (parser->anc);
-	    *(parser->cur+1) = c;
-	    parser->anc = ++parser->cur;
-	} 
-	else if (*(parser->cur) == ' ') {
-	    /* normal space separated argument */
-	    c = *(parser->cur);
-	    *(parser->cur) = '\0';
-	    arg = g_strdup (parser->anc);
-	    *(parser->cur) = c;
-	    parser->anc = ++parser->cur;
-	} 
-	else if (*(parser->cur) == '\n' && *(parser->cur-1) != ' ') {
-	    /* special case for EOL */
-	    c = *(parser->cur);
-	    *(parser->cur) = '\0';
-	    arg = g_strdup (parser->anc);
-	    *(parser->cur) = c;
-	    parser->anc = parser->cur;
-	} else
-	    ; /* FIXME: do we need to handle this case? */
+	parser->cur = (xmlNodePtr) parser->node_stack->data;
+	parser->cur_font = (gchar *) parser->font_stack->data;
+	if (parser->cur)
+	    printf ("Popping stack up to %s (font: %s)\n", parser->cur->name, font_num);
+	else
+	    printf ("Popping NULL!\n");
+    } else {
+	gchar *font;
 
-	arglist = g_slist_append (arglist, arg);
-    }
-    
-    /*g_print ("handling macro (%s)\n", str);
-    
-    listptr = arglist;
-    while (listptr && listptr->data) {
-	g_print ("   arg = %s\n", (gchar *)listptr->data);
-	listptr = g_slist_next (listptr);
-    }
-    */
-    
-    /* lookup the macro handler and call that function */
-    handler_func = g_hash_table_lookup (macro_hash, str);
-    if (handler_func)
-	(*handler_func) (parser, str, arglist);
-    
-    /* in case macro is not defined in hash table, ignore rest of line */
-    else
-	macro_ignore_handler (parser, str, arglist);
-
-    g_free (str);
-    
-    listptr = arglist;
-    while (listptr && listptr->data) {
-	g_free (listptr->data);
-	listptr = g_slist_next (listptr);
-    } 
-    
-    return;
-    
-    if (0) {
-    }
-    /* Table (tbl) macros */
-    else if (g_str_equal (str, "TS")) {
-	parser->ins = parser_append_node (parser, "TABLE");
-        g_free (str);
-
-	parser_stack_push_node (parser, parser->ins);
-	g_free (parser->buffer);
-	parser_parse_table (parser);
-    }
-    else if (g_str_equal (str, "TE")) {
-	/* We should only see this from within parser_parse_table */
-	debug_print (DB_WARN, "Found unexpected tag: '%s'\n", str);
-        g_free (str);
-    }
-    /* "ie" and "if" are conditional macros in groff
-     * "ds" is to define a variable; see groff(7)
-     * ignore anything between the \{ \}, otherwise ignore until
-     * the end of the linee*/
-    else if (g_str_equal (str, "ds") || g_str_equal (str, "ie")
-	                             || g_str_equal (str, "if")) {
-	/* skip any remaining spaces */
-	while (PARSER_CUR && (*parser->cur == ' '))
-	    parser->anc = ++parser->cur;
+	parser->node_stack = g_slist_prepend (parser->node_stack,
+					      parser->cur);
+	parser->font_stack = g_slist_prepend (parser->node_stack,
+					      parser->cur_font);
 	
-	/* skip the "stringvar" or "cond"; see groff(7) */
-	while (PARSER_CUR && (*parser->cur != ' '))
-	    parser->anc = ++parser->cur;
+	if (parser->cur)
+	    printf ("Pushing %s down stack (adding %s)\n", parser->cur->name, font_num);
+	else 
+	    printf ("WTF?\n");
 	
-	/* skip any remaining spaces */
-	while (PARSER_CUR && (*parser->cur == ' '))
-	    parser->anc = ++parser->cur;
-	
-	/* check to see if the next two characters are the
-	 * special "\{" sequence */
-	if (*parser->cur == '\\' && *(parser->cur+1) == '{') {
-	    parser->ignore = TRUE;
-	    parser->token = g_strdup ("\\}");
-	} else {
-	    /* otherwise just ignore till the end of the line */
-	    while (PARSER_CUR)
-	        parser->anc = ++parser->cur;
-	}
+	font = g_hash_table_lookup(parser->font_mappings, 
+				   (gpointer) font_num);
+	parser->cur_font = font;
+	printf ("Reparenting to %p\n", parser->node_stack->data);
+	parser->cur = xmlNewTextChild (parser->node_stack->data, NULL, 
+				       BAD_CAST g_strdup(font), 
+				       NULL);
+	printf ("CUR is %p\n", parser->cur);
     }
-    /* else conditional macro */
-    else if (g_str_equal (str, "el")) {
-	/* check to see if the next two characters are the
-	 * special "\{" sequence */
-	parser->ignore = 0;
-	if (*parser->cur == '\\' && *(parser->cur+1) == '{') {
-	    parser->ignore = TRUE;
-	    parser->token = g_strdup ("\\}");
-	} else {
-	    /* otherwise just ignore till the end of the line */
-	    while (PARSER_CUR)
-	        parser->anc = ++parser->cur;
-	}
-    }
-
 }
 
-static void
-parser_ensure_P (YelpManParser *parser)
+void
+parse_append_space (YelpManParser *parser)
 {
-    if (xmlStrEqual (parser->ins->name, BAD_CAST "Man")) {
-	parser->ins = parser_append_node (parser, "P");
-	parser_stack_push_node (parser, parser->ins);
-    }
-}
-
-static void
-parser_read_until (YelpManParser *parser,
-		   gchar          delim)
-{
-    gchar c;
-    
-    while (PARSER_CUR
-	   && g_utf8_get_char (parser->cur) != '\n'
-	   && g_utf8_get_char (parser->cur) != delim) {
-	    parser->cur = g_utf8_next_char (parser->cur);
-    }
-
-    if (parser->anc == parser->cur)
+    if (!parser->cur) {
+	printf ("ERRORING: No cur element\n");
 	return;
-    
-    c = *(parser->cur);
-    *(parser->cur) = '\0';
-    parser_append_given_text_handle_escapes (parser, parser->anc, TRUE);
-    *(parser->cur) = c;
-    
-    parser->anc = parser->cur;
-}
-
-static void
-parser_escape_tags (YelpManParser *parser,
-		    gchar        **tags,
-		    gint           ntags)
-{
-    gint i;
-    xmlNodePtr node = NULL;
-    xmlNodePtr cur  = parser->ins;
-    GSList *path = NULL;
- 
-    /* Find the top node we can escape from */
-    while (cur && cur != (xmlNodePtr)parser->doc && 
-	   cur->parent && cur->parent != (xmlNodePtr) parser->doc) {
-	for (i = 0; i < ntags; i++)
-	    if (!xmlStrcmp (cur->name, BAD_CAST tags[i])) {
-		node = cur;
-		break;
-	    }
-	path = g_slist_prepend (path, cur);
-	cur = cur->parent;
     }
+    printf ("Adding space to %s\n", parser->cur->name);
+    xmlNodeAddContent (parser->cur, " ");
 
-    /* Walk back down, reproducing nodes we aren't escaping */
-    if (node) {
-	GSList *c = path;
-	while (c && (xmlNodePtr) c->data != node)
-	    c = g_slist_next (c);
-
-	parser->ins = node->parent;
-	parser_ensure_P (parser);
-
-	while ((c = c->next)) {
-	    gboolean insert = TRUE;
-	    cur = (xmlNodePtr) c->data;
-
-	    for (i = 0; i < ntags; i++)
-		if (!xmlStrcmp (cur->name, BAD_CAST tags[i])) {
-		    insert = FALSE;
-		    break;
-		}
-	    if (insert)
-		parser->ins = parser_append_node (parser, (gchar *) cur->name);
-	}
-    }
 }
 
-static void
-parser_append_given_text_handle_escapes (YelpManParser *parser, gchar *text, gboolean make_links)
+void
+yelp_man_parser_parse_stream (YelpManParser *parser)
 {
-    gchar *escape[] = { "fI", "fB" };
-    gchar *baseptr, *ptr, *anc, *str;
-    gint c, len;
+    gchar *line = NULL;
+    gchar *ptr;
+    gchar *token;
 
-    g_return_if_fail (parser != NULL);
-   
-    if (!text)
-	return;
+    ptr = parser->troff_out;
 
-    baseptr = g_strdup (text);
-    ptr = baseptr;
-    anc = baseptr;
-    len = strlen (baseptr);
-    
-    while (ptr && *ptr != '\0') {
-    
-	if (*ptr == '\\') {
-	    
-	    c = *ptr;
-	    *ptr = '\0';
-	    parser_append_given_text (parser, anc);
-	    *ptr = c;
-	    
-	    anc = ++ptr;
+    do {
+	gchar *term;
+	gchar *comment;
+	gchar *token;
 	
-	    switch (*ptr) {
-	    case '\0':
-	        break;
-	    case '-':
-	    case '\\':
-	        ptr++;
-	        c = *ptr;
-	        *ptr = '\0';
-	        parser_append_given_text (parser, anc);
-	        *ptr = c;
-	        anc = ptr;
-	        break;
-	    case 'f':
-	        ptr++;
-	        if ((ptr - baseptr) > len || *ptr == '\0') break;
-	        ptr++;
-
-	        c = *(ptr);
-	        *(ptr) = '\0';
-	        str = g_strdup (anc);
-	        *(ptr) = c;
-
-	        parser_ensure_P (parser);
-	        parser_escape_tags (parser, escape, 2);
-
-	        /* the \f escape sequence changes the font - R is Roman, 
-	         * B is Bold, and I is italic */
-	        if (g_str_equal (str, "fI") || g_str_equal (str, "fB"))
-		    parser->ins = parser_append_node (parser, str);
-	        else if (!g_str_equal (str, "fR") && !g_str_equal (str, "fP"))
-		    debug_print (DB_WARN, "No rule matching the tag '%s'\n", str);
-
-	        g_free (str);
-	        anc = ptr;
-	        break;
-	    case '(':
-	        ptr++;
-	        if ((ptr - baseptr) > len || *ptr == '\0') break;
-	        ptr++;
-	        if ((ptr - baseptr) > len || *ptr == '\0') break;
-	        ptr++;
-
-	        c = *(ptr);
-	        *(ptr) = '\0';
-	        str = g_strdup (anc);
-	        *(ptr) = c;
-
-	        if (g_str_equal (str, "(co"))
-		    parser_append_given_text (parser, "©");
-	        else if (g_str_equal (str, "(bu"))
-		    parser_append_given_text (parser, "•");
-	        else if (g_str_equal (str, "(em"))
-		    parser_append_given_text (parser, "—");
-
-	        g_free (str);
-	        anc = ptr;
-	        break;
-	    case '*':
-	        ptr++;
-	        if ((ptr - baseptr) > len || *ptr == '\0') break;
-
-	        if (*(ptr) == 'R') {
-		    parser_append_given_text (parser, "®");
-		    ptr++;
-		} else if (*(ptr) == '=') {
-		    parser_append_given_text (parser, "--");
-		    ptr++;
-	        } else if (*(ptr) == '(') {
-		    ptr++;
-		    if ((ptr - baseptr) > len || *ptr == '\0') break;
-		    ptr++;
-		    if ((ptr - baseptr) > len || *ptr == '\0') break;
-		    ptr++;
-		    
-		    c = *(ptr);
-		    *(ptr) = '\0';
-		    str = g_strdup (anc);
-		    *(ptr) = c;
-
-		    if (g_str_equal (str, "*(Tm"))
-		        parser_append_given_text (parser, "™");
-		    else if (g_str_equal (str, "*(lq"))
-		        parser_append_given_text (parser, "“");
-		    else if (g_str_equal (str, "*(rq"))
-		        parser_append_given_text (parser, "”");
-
-		    g_free (str);
-	        }
-	    
-	        anc = ptr;
-	        break;
-	    case 'e':
-	        anc = ++ptr;
-	        parser_append_given_text (parser, "\\");
-	        break;
-	    case '&':
-	        anc = ++ptr;
-	        break;
-	    case 's':
-	        /* this handles (actually ignores) the groff macros \s[+-][0-9] */
-	        ptr++;
-	        if (*(ptr) == '+' || *(ptr) == '-') {
-		    ptr++;
-		    if (g_ascii_isdigit (*ptr)) {
-			    ptr++;
-		    }
-	        } else if (g_ascii_isdigit (*ptr)) {
-		    ptr++;
-	        }
-	        anc = ptr;
-	        break;
-	    case '"':
-	        /* Marks comments till end of line. so we can ignore it. */
-	        while (ptr && *ptr != '\0')
-		    ptr++;
-	        anc = ptr;
-	        break;
-	    case '^':
-	    case '|':
-	        /* 1/12th and 1/16th em respectively - ignore this and simply output a space */
-	        anc = ++ptr;
-	        break;
-	    default:
-	        ptr++;
-		c = *(ptr);
-		*(ptr) = '\0';
-		parser_append_given_text (parser, anc);
-		*(ptr) = c;
-
-		anc++;
-		break;
-	    }
-	    
+	term = strchr (ptr, '\n');
+	if (term) {
+	    line = g_strndup (ptr, term - ptr);
+	    ptr = term+1;
+	} else {
+	    line = g_strdup (ptr);
+	    ptr = NULL;
 	}
-        else if ((make_links) && (*ptr == '(')) {
-	    gchar *space_pos;
-	    gchar *url;
-	    gchar  c;
-	    gchar *name_end;
-            gchar *num_start;
-            gchar *num_end;
 
-	   
-	    space_pos = ptr;
-	    
-	    while (space_pos != anc && *(space_pos - 1) != ' ') {
-		space_pos--;
-	    }
-	    name_end = space_pos;
-	    
-	    if (space_pos != ptr &&
-	        g_ascii_isdigit(*(ptr+1)) &&
-		(*(ptr+2) == ')' || (g_ascii_isalpha (*(ptr+2)) && *(ptr+3) == ')'))) {
-                num_start = ptr;
-		if (*(ptr+2) == ')')
-		    num_end = ptr + 2;
-                else
-		    num_end = ptr + 3;
-	    
-		ptr+=3;
-	    
-		parser_ensure_P (parser);
-	    
-		ptr = space_pos;
-	    
-		c = (*ptr);
-		*ptr = '\0';
-		parser_append_given_text (parser, anc);
-		*ptr = c;
-		anc = ptr;
-		ptr = num_start;
-
-		c = *name_end;
-		*name_end = '\0';
-                *num_end = '\0';
-		url = g_strdup_printf ("man:%s(%s)", anc, num_start + 1);
-
-	    
-		parser->ins = parser_append_node (parser, "UR");
-	
-		parser->ins = parser_append_node (parser, "URI");
-		parser_append_given_text (parser, url);
-		parser->ins = parser->ins->parent;
-	    
-		parser_append_given_text (parser, anc);
-		parser->ins = parser->ins->parent;
-	    
-		*name_end = c;
-                *num_end = ')';
-		anc = ptr;
-	    
-		g_free (url);
-
+	comment = strchr (line, '#');
+	if (comment && ((comment-1) != '\\')) {
+	    if (comment != line) {
+		gchar *new_line;
+		
+		new_line = g_strndup (line, comment - line);
+		g_free (line);
+		line = new_line;
 	    } else {
-		ptr++;
-	    }    
+		continue;
+	    }
 	}
-	else {
-	    ptr++;
-	}	
 
-    } /* end while */
-
-    c = *(ptr);
-    *(ptr) = '\0';
-    parser_append_given_text (parser, anc);
-    *(ptr) = c;
-   
-    g_free (baseptr); 
-}
-
-static xmlNodePtr
-parser_append_text (YelpManParser *parser)
-{
-    xmlNodePtr  node;
-    gchar       c;
-
-    if (parser->anc == parser->cur)
-	return NULL;
-
-    c = *(parser->cur);
-    *(parser->cur) = '\0';
-
-    if (g_utf8_get_char (parser->anc) != '\n')
-	parser_ensure_P (parser);
-
-    node = xmlNewText (BAD_CAST parser->anc);
-    xmlAddChild (parser->ins, node);
-
-    *(parser->cur) = c;
-
-    parser->anc = parser->cur;
-
-    return node;
-}
-
-static xmlNodePtr
-parser_append_given_text (YelpManParser *parser,
-			  gchar         *text)
-{
-    xmlNodePtr  node;
-
-    parser_ensure_P (parser);
-
-    node = xmlNewText (BAD_CAST text);
-    xmlAddChild (parser->ins, node);
-
-    return node;
-}
-
-static xmlNodePtr
-parser_append_node (YelpManParser *parser,
-		    gchar         *name)
-{
-    if (!name)
-	return NULL;
-	
-    return xmlNewChild (parser->ins, NULL, BAD_CAST name, NULL);
-}
-
-static xmlNodePtr
-parser_append_node_attr (YelpManParser *parser,
-			 gchar         *name,
-			 gchar         *attr,
-			 gchar         *value)
-{
-    xmlNodePtr node = NULL;
-    
-    node = xmlNewChild (parser->ins, NULL, BAD_CAST name, NULL);
-    xmlNewProp (node, BAD_CAST attr, BAD_CAST value);
-
-    return node;
-}
-
-static void        
-parser_stack_push_node (YelpManParser *parser,
-			xmlNodePtr     node)
-{
-    parser->nodeStack = g_slist_prepend (parser->nodeStack, node);
-}
-
-static xmlNodePtr  
-parser_stack_pop_node (YelpManParser *parser,
-		       gchar         *name)
-{
-    xmlNodePtr popped;
-
-    if (parser->nodeStack == NULL)
-	return NULL;
-   
-    popped = (xmlNodePtr) parser->nodeStack->data;
-    
-    if (!xmlStrEqual (BAD_CAST name, popped->name))
-	return NULL;
-	
-    parser->nodeStack = g_slist_remove (parser->nodeStack, popped);
-    return popped;
-}
-
-/*
- *  Table (tbl) macro package parsing
- */
-
-static void
-parser_handle_table_options (YelpManParser *parser)
-{
-    /* FIXME: do something with the options */
-    g_free (parser->buffer);
-
-    return;
-}
-
-static void
-parser_handle_row_options (YelpManParser *parser)
-{
-    /* FIXME: do something with these options */
-
-    do {
-	parser->anc = parser->buffer;
-	parser->cur = parser->buffer;
-	
-	parser_read_until (parser, '.');
-	
-	if (*(parser->cur) == '.') {
-	    g_free (parser->buffer);
-	    break;
+	if (*line == 'w') {
+	    /* Add a white-space char */
+	    parse_append_space (parser);
+	    token = line+1;
+	} else {
+	    token = line;
 	}
-	
-	g_free (parser->buffer);
 
-    } while (g_io_channel_read_line (parser->channel,
-				     &(parser->buffer),
-				     &(parser->length),
-				     NULL, NULL)
-	     == G_IO_STATUS_NORMAL);
-}
-
-static void
-parser_parse_table (YelpManParser *parser)
-{
-    xmlNodePtr table_start;
-    gboolean empty_row;
-
-    table_start = parser->ins;
-
-    if (g_io_channel_read_line (parser->channel,
-				&(parser->buffer),
-				&(parser->length),
-				NULL, NULL)
-	== G_IO_STATUS_NORMAL) {
-	parser->anc = parser->buffer;
-	parser->cur = parser->buffer;
-	
-	parser_read_until (parser, ';');
-
-	if (*(parser->cur) == ';') {
-	    parser_handle_table_options (parser);
-
-	    if (g_io_channel_read_line (parser->channel,
-					&(parser->buffer),
-					&(parser->length),
-					NULL, NULL)
-		== G_IO_STATUS_NORMAL) {
-		parser->anc = parser->buffer;
-		parser->cur = parser->buffer;
-	    
-		parser_read_until (parser, '\n');
-	    } else
-		return;
+	if (*token == 'x') {
+	    /* Meta-data to set fonts et. al. */
+	    parse_meta (parser, token);
+	} else if (*token == 't') {
+	    /* append text to current token */
+	    parse_append_text (parser, token);
+	} else if (*token == 'f') {
+	    /* Set new font type */
+	    parse_set_font (parser, token);
+	} else if (*token == 'C') {
+	    /* Print a special character */
+	    parse_append_text (parser, token+1);
+	} else if (*token == 'n' ) {
+	    /* Line break.  Since we can have varying
+	       width, instead, we add a space
+	    */
+	    parse_append_space (parser);
 	}
 
-	parser_handle_row_options (parser);
-
-	/* Now this is where we go through all the rows */
-	while (g_io_channel_read_line (parser->channel,
-				       &(parser->buffer),
-				       &(parser->length),
-				       NULL, NULL)
-	       == G_IO_STATUS_NORMAL) {
-	    
-	    parser->anc = parser->buffer;
-	    parser->cur = parser->buffer;
-	    
-	    empty_row = FALSE;
-
-	    switch (*(parser->buffer)) {
-	    case '.':
-		if (*(parser->buffer + 1) == 'T'
-		    && *(parser->buffer + 2) == 'E') {
-		    if (parser_stack_pop_node (parser, "TABLE") == NULL)
-			debug_print (DB_WARN, "Found unexpected tag: 'TE'\n");
-		    else {
-			parser->ins = table_start;
-			
-			parser->anc = parser->buffer + 3;
-			parser->cur = parser->buffer + 3;
-			return;
-		    }
-		} else if (*(parser->buffer + 1) == 'T'
-			   && *(parser->buffer + 2) == 'H') {
-		    /* Do nothing */
-		    empty_row = TRUE;
-		} else {
-		    parser_handle_linetag (parser);
-		    break;
-		}
-	    case '\n':
-		empty_row = TRUE;
-		break;
-	    default:
-		break;
-	    }
-	    
-	    if (!empty_row) {
-		parser->ins = parser_append_node (parser, "ROW");
-		while (PARSER_CUR && *(parser->cur) != '\n') {
-		    parser_read_until (parser, '\t');
-		    parser->ins = parser_append_node (parser, "CELL");
-		    parser_append_text (parser);
-		    parser->ins = parser->ins->parent;
-		    parser->anc++;
-		    parser->cur++;
-		}
-	    }
-
-	    g_free (parser->buffer);
-
-	    parser->ins = table_start;
-	}
-    }
+	//printf ("Line: %s\n", line);
+	g_free (line);
+	//printf ("Line free\n");
+    } while (ptr);
+    //    printf ("Out\n");
 }
Index: stylesheets/man2html.xsl
===================================================================
--- stylesheets/man2html.xsl	(revision 2973)
+++ stylesheets/man2html.xsl	(working copy)
@@ -53,7 +53,7 @@
 <xsl:template name="html">
   <html>
     <head>
-      <title>
+      <!--<title>
         <xsl:value-of select="//TH/Title"/>
       </title>
       <style type="text/css">
@@ -63,13 +63,13 @@
         <xsl:attribute name="src">
           <xsl:value-of select="concat('file://', $yelp.javascript)"/>
         </xsl:attribute>
-      </script>
+      </script>-->
     </head>
     <body>
       <xsl:call-template name="html.linktrail"/>
       <div class="body">
-        <xsl:apply-templates select="TH"/>
-        <xsl:apply-templates select="SH"/>
+        <xsl:apply-templates/><!-- select="node()[*]"/>-->
+        <!--<xsl:apply-templates select="SH"/>-->
       </div>
     </body>
   </html>
@@ -132,7 +132,7 @@
 <xsl:template match="Count" />
 <xsl:template match="sp" />
 
-<xsl:template match="B | fB">
+<xsl:template match="B">
   <b><xsl:apply-templates/></b>
 </xsl:template>
 
@@ -140,14 +140,10 @@
   <td><xsl:apply-templates/></td>
 </xsl:template>
 
-<xsl:template match="I | fI">
+<xsl:template match="I">
   <i><xsl:apply-templates/></i>
 </xsl:template>
 
-<xsl:template match="R | fR">
-  <span class="R"><xsl:apply-templates/></span>
-</xsl:template>
-
 <xsl:template match="Verbatim">
   <pre>
     <xsl:choose>
@@ -200,10 +196,28 @@
                        select="following-sibling::*[1][self::IP]"/>
 </xsl:template>
 
-<xsl:template match="P">
+<xsl:template match="div">
+  <xsl:element name="div">
+  <xsl:attribute name="style"><xsl:text>position: relative; left: </xsl:text><xsl:value-of select="@indent"/><xsl:text>px; width: 60%;</xsl:text></xsl:attribute>
+  <xsl:apply-templates/>
+</xsl:element>
+</xsl:template>
+
+<xsl:template match="p">
   <p><xsl:apply-templates/></p>
 </xsl:template>
 
+<xsl:template match="R">
+  <xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="header">
+  <xsl:element name="div">
+    <xsl:attribute name="style"><xsl:text>position: relative; left: -</xsl:text><xsl:value-of select="@indent"/><xsl:text>px;</xsl:text></xsl:attribute>
+  <h2><xsl:apply-templates/></h2>
+  </xsl:element>
+</xsl:template>
+
 <xsl:template match="ROW">
   <tr><xsl:apply-templates/></tr>
 </xsl:template>
