[yelp/mallard] Very basic display of Mallard index page



commit 752f2f834554eab6c297f72041dbb806a51a74a9
Author: Shaun McCance <shaunm shaunmlxlap localdomain>
Date:   Mon Jun 8 15:23:49 2009 -0500

    Very basic display of Mallard index page
---
 src/yelp-mallard.c |  741 +++++++++++++++++++---------------------------------
 1 files changed, 267 insertions(+), 474 deletions(-)

diff --git a/src/yelp-mallard.c b/src/yelp-mallard.c
index 82648e9..30a5f63 100644
--- a/src/yelp-mallard.c
+++ b/src/yelp-mallard.c
@@ -41,11 +41,32 @@
 
 #define YELP_MALLARD_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_MALLARD, YelpMallardPriv))
 
+typedef enum {
+    MALLARD_STATE_BLANK,
+    MALLARD_STATE_THINKING,
+    MALLARD_STATE_IDLE,
+    MALLARD_STATE_STOP
+} MallardState;
+
+typedef struct {
+    YelpMallard   *mallard;
+    gchar         *page_id;
+    gchar         *filename;
+    xmlDocPtr      xmldoc;
+    YelpTransform *transform;
+} MallardPageData;
+
 struct _YelpMallardPriv {
     gchar         *directory;
+    MallardState   state;
 
     GMutex        *mutex;
     GThread       *thread;
+    gboolean       thread_running;
+    gint           transforms_running;
+    GSList        *pending;
+
+    GHashTable    *pages_hash;
 };
 
 
@@ -66,12 +87,21 @@ static void           mallard_request         (YelpDocument        *document,
 static void           transform_func          (YelpTransform       *transform,
 					       YelpTransformSignal  signal,
 					       gpointer             func_data,
-					       YelpMallard         *mallard);
+					       MallardPageData     *page_data);
 static void           transform_page_func     (YelpTransform       *transform,
 					       gchar               *page_id,
-					       YelpMallard         *mallard);
+					       MallardPageData     *page_data);
 static void           transform_final_func    (YelpTransform       *transform,
-					       YelpMallard         *mallard);
+					       MallardPageData     *page_data);
+/* Other */
+static void           mallard_think           (YelpMallard         *mallard);
+static void           mallard_pending         (YelpMallard         *mallard);
+static void           mallard_try_run         (YelpMallard         *mallard,
+                                               gchar               *page_id);
+
+static void           mallard_page_data_walk  (MallardPageData     *page_data);
+static void           mallard_page_data_run   (MallardPageData     *page_data);
+static void           mallard_page_data_free  (MallardPageData     *page_data);
 
 
 static YelpDocumentClass *parent_class;
@@ -120,6 +150,13 @@ mallard_init (YelpMallard *mallard)
     priv = mallard->priv = YELP_MALLARD_GET_PRIVATE (mallard);
 
     priv->mutex = g_mutex_new ();
+
+    priv->thread_running = FALSE;
+    priv->transforms_running = 0;
+
+    priv->pages_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                              NULL,
+                                              (GDestroyNotify) mallard_page_data_free);
 }
 
 static void
@@ -131,18 +168,15 @@ mallard_try_dispose (GObject *object)
 
     priv = YELP_MALLARD (object)->priv;
 
-    /*
     g_mutex_lock (priv->mutex);
-    if (priv->process_running || priv->transform_running) {
-	priv->state = DOCBOOK_STATE_STOP;
-	g_idle_add ((GSourceFunc) docbook_try_dispose, object);
+    if (priv->thread_running || priv->transforms_running > 0) {
+	priv->state = MALLARD_STATE_STOP;
+	g_idle_add ((GSourceFunc) mallard_try_dispose, object);
 	g_mutex_unlock (priv->mutex);
     } else {
 	g_mutex_unlock (priv->mutex);
-	docbook_dispose (object);
+	mallard_dispose (object);
     }
-    */
-    mallard_dispose (object);
 }
 
 static void
@@ -154,6 +188,8 @@ mallard_dispose (GObject *object)
 
     g_mutex_free (mallard->priv->mutex);
 
+    g_hash_table_destroy (mallard->priv->pages_hash);
+
     G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
@@ -163,6 +199,7 @@ YelpDocument *
 yelp_mallard_new (gchar *directory)
 {
     YelpMallard *mallard;
+    YelpDocument *document;
 
     g_return_val_if_fail (directory != NULL, NULL);
 
@@ -172,56 +209,60 @@ yelp_mallard_new (gchar *directory)
     mallard = (YelpMallard *) g_object_new (YELP_TYPE_MALLARD, NULL);
     mallard->priv->directory = g_strdup (directory);
 
-    /*
-      FIXME: find pages, add
-    yelp_document_add_page_id (YELP_DOCUMENT (docbook), "x-yelp-titlepage", "x-yelp-titlepage");
-    */
+    document = (YelpDocument *) mallard;
+    yelp_document_set_root_id (document, "index");
+    yelp_document_add_page_id (document, "x-yelp-index", "index");
 
-    return (YelpDocument *) mallard;
+    return document;
 }
 
 
-#if 0
 static void
-docbook_request (YelpDocument     *document,
-		 gint              req_id,
-		 gboolean          handled,
-		 gchar            *page_id,
-		 YelpDocumentFunc  func,
-		 gpointer          user_data)
+mallard_request (YelpDocument     *document,
+                 gint              req_id,
+                 gboolean          handled,
+                 gchar            *page_id,
+                 YelpDocumentFunc  func,
+                 gpointer          user_data)
 {
-    YelpDocbook *docbook;
-    YelpDocbookPriv *priv;
+    YelpMallard *mallard;
+    YelpMallardPriv *priv;
     YelpError *error;
 
     debug_print (DB_FUNCTION, "entering\n");
     debug_print (DB_ARG, "  req_id  = %i\n", req_id);
     debug_print (DB_ARG, "  page_id = \"%s\"\n", page_id);
-    g_assert (document != NULL && YELP_IS_DOCBOOK (document));
+    g_assert (G_TYPE_CHECK_INSTANCE_TYPE ((document), YELP_TYPE_MALLARD));
+    g_assert (document != NULL && YELP_IS_MALLARD (document));
 
     if (handled) {
-	return;
+        return;
     }
 
-    docbook = YELP_DOCBOOK (document);
-    priv = docbook->priv;
+    mallard = YELP_MALLARD (document);
+    priv = mallard->priv;
 
     g_mutex_lock (priv->mutex);
 
+    if (priv->state == MALLARD_STATE_BLANK) {
+        priv->state = MALLARD_STATE_THINKING;
+        priv->thread_running = TRUE;
+        priv->thread = g_thread_create ((GThreadFunc) mallard_think,
+                                        mallard, FALSE, NULL);
+    }
+
     switch (priv->state) {
-    case DOCBOOK_STATE_BLANK:
-	priv->state = DOCBOOK_STATE_PARSING;
-	priv->process_running = TRUE;
-	priv->thread = g_thread_create ((GThreadFunc) docbook_process,
-					docbook, FALSE, NULL);
-	break;
-    case DOCBOOK_STATE_PARSING:
-	break;
-    case DOCBOOK_STATE_PARSED:
-    case DOCBOOK_STATE_STOP:
+    case MALLARD_STATE_THINKING:
+        priv->pending = g_slist_prepend (priv->pending, (gpointer) g_strdup (page_id));
+        break;
+    case MALLARD_STATE_IDLE:
+        mallard_try_run (mallard, page_id);
+        break;
+    case MALLARD_STATE_BLANK:
+    case MALLARD_STATE_STOP:
 	error = yelp_error_new (_("Page not found"),
 				_("The page %s was not found in the document %s."),
-				page_id, priv->filename);
+				page_id, priv->directory);
 	yelp_document_error_request (document, req_id, error);
 	break;
     }
@@ -230,506 +271,258 @@ docbook_request (YelpDocument     *document,
 }
 
 /******************************************************************************/
-/** YelpTransform *************************************************************/
 
 static void
-transform_func (YelpTransform       *transform,
-		YelpTransformSignal  signal,
-		gpointer             func_data,
-		YelpDocbook         *docbook)
+mallard_think (YelpMallard *mallard)
 {
-    YelpDocbookPriv *priv;
-    debug_print (DB_FUNCTION, "entering\n");
+    YelpMallardPriv *priv;
+    YelpError *error = NULL;
+    YelpDocument *document;
 
-    g_assert (docbook != NULL && YELP_IS_DOCBOOK (docbook));
+    GFile *gfile;
+    GFileEnumerator *children;
+    GFileInfo *pageinfo;
 
-    priv = docbook->priv;
+    debug_print (DB_FUNCTION, "entering\n");
 
-    g_assert (transform == priv->transform);
+    g_assert (mallard != NULL && YELP_IS_MALLARD (mallard));
+    g_object_ref (mallard);
+    priv = mallard->priv;
+    document = YELP_DOCUMENT (mallard);
 
-    if (priv->state == DOCBOOK_STATE_STOP) {
-	switch (signal) {
-	case YELP_TRANSFORM_CHUNK:
-	    g_free (func_data);
-	    break;
-	case YELP_TRANSFORM_ERROR:
-	    yelp_error_free ((YelpError *) func_data);
-	    break;
-	case YELP_TRANSFORM_FINAL:
-	    break;
-	}
-	yelp_transform_release (transform);
-	priv->transform = NULL;
-	priv->transform_running = FALSE;
-	return;
+    if (!g_file_test (priv->directory, G_FILE_TEST_IS_DIR)) {
+	error = yelp_error_new (_("Directory not found"),
+				_("The directory â??%sâ?? does not exist."),
+				priv->directory);
+	yelp_document_error_pending (document, error);
+	goto done;
     }
 
-    switch (signal) {
-    case YELP_TRANSFORM_CHUNK:
-	transform_page_func (transform, (gchar *) func_data, docbook);
-	break;
-    case YELP_TRANSFORM_ERROR:
-	yelp_document_error_pending (YELP_DOCUMENT (docbook), (YelpError *) func_data);
-	yelp_transform_release (transform);
-	priv->transform = NULL;
-	priv->transform_running = FALSE;
-	break;
-    case YELP_TRANSFORM_FINAL:
-	transform_final_func (transform, docbook);
-	break;
+    gfile = g_file_new_for_path (priv->directory);
+    children = g_file_enumerate_children (gfile,
+                                          G_FILE_ATTRIBUTE_STANDARD_NAME,
+                                          G_FILE_QUERY_INFO_NONE,
+                                          NULL, NULL);
+    while ((pageinfo = g_file_enumerator_next_file (children, NULL, NULL))) {
+        MallardPageData *page_data;
+        gchar *filename;
+        GFile *pagefile;
+        filename = g_file_info_get_attribute_as_string (pageinfo,
+                                                        G_FILE_ATTRIBUTE_STANDARD_NAME);
+        if (!g_str_has_suffix (filename, ".page")) {
+            g_free (filename);
+            g_object_unref (pageinfo);
+            continue;
+        }
+        page_data = g_new0 (MallardPageData, 1);
+        page_data->mallard = mallard;
+        pagefile = g_file_resolve_relative_path (gfile, filename);
+        page_data->filename = g_file_get_path (pagefile);
+        mallard_page_data_walk (page_data);
+        if (page_data->page_id == NULL) {
+            mallard_page_data_free (page_data);
+        } else {
+            g_mutex_lock (priv->mutex);
+            g_hash_table_insert (priv->pages_hash, page_data->page_id, page_data);
+            g_mutex_unlock (priv->mutex);
+        }
+        g_object_unref (pagefile);
+        g_free (filename);
+        g_object_unref (pageinfo);
     }
+
+    mallard_pending (mallard);
+
+ done:
+    g_object_unref (children);
+    g_object_unref (gfile);
+
+    priv->thread_running = FALSE;
+    g_object_unref (mallard);
 }
 
 static void
-transform_page_func (YelpTransform *transform,
-		     gchar         *page_id,
-		     YelpDocbook   *docbook)
+mallard_pending (YelpMallard *mallard)
 {
-    YelpDocbookPriv *priv;
-    gchar *content;
+    YelpMallardPriv *priv = mallard->priv;
 
-    debug_print (DB_FUNCTION, "entering\n");
-
-    priv = docbook->priv;
     g_mutex_lock (priv->mutex);
-
-    content = yelp_transform_eat_chunk (transform, page_id);
-    yelp_document_add_page (YELP_DOCUMENT (docbook), page_id, content);
-
-    g_free (page_id);
-
+    while (priv->pending) {
+        gchar *page_id;
+        page_id = (gchar *) priv->pending->data;
+        mallard_try_run (mallard, page_id);
+        g_free (page_id);
+        priv->pending = g_slist_delete_link (priv->pending, priv->pending);
+    }
     g_mutex_unlock (priv->mutex);
 }
 
 static void
-transform_final_func (YelpTransform *transform, YelpDocbook *docbook)
+mallard_try_run (YelpMallard *mallard,
+                 gchar       *page_id)
 {
-    YelpError *error;
-    YelpDocbookPriv *priv = docbook->priv;
+    /* We expect to be in a locked mutex when this function is called. */
+    MallardPageData *page_data;
 
-    debug_print (DB_FUNCTION, "entering\n");
-
-    g_mutex_lock (priv->mutex);
-
-    error = yelp_error_new (_("Page not found"),
-			    _("The requested page was not found in the document %s."),
-			    priv->filename);
-    yelp_document_final_pending (YELP_DOCUMENT (docbook), error);
-
-    yelp_transform_release (transform);
-    priv->transform = NULL;
-    priv->transform_running = FALSE;
-    priv->state = DOCBOOK_STATE_PARSED;
-
-    if (priv->xmldoc)
-	xmlFreeDoc (priv->xmldoc);
-    priv->xmldoc = NULL;
+    page_data = g_hash_table_lookup (mallard->priv->pages_hash, page_id);
+    if (page_data == NULL) {
+        printf ("FIXME: page not foun\n");
+        return;
+    }
 
-    g_mutex_unlock (priv->mutex);
+    mallard_page_data_run (page_data);
 }
 
-
 /******************************************************************************/
-/** Threaded ******************************************************************/
+/** MallardPageData ***********************************************************/
 
 static void
-docbook_process (YelpDocbook *docbook)
+mallard_page_data_walk (MallardPageData *page_data)
 {
-    YelpDocbookPriv *priv;
-    xmlDocPtr xmldoc = NULL;
-    xmlChar *id = NULL;
-    YelpError *error = NULL;
     xmlParserCtxtPtr parserCtxt = NULL;
-    YelpDocument *document;
-
-    gint  params_i = 0;
-    gint  params_max = 10;
-    gchar **params = NULL;
-
-    debug_print (DB_FUNCTION, "entering\n");
-
-    g_assert (docbook != NULL && YELP_IS_DOCBOOK (docbook));
-    g_object_ref (docbook);
-    priv = docbook->priv;
-    document = YELP_DOCUMENT (docbook);
-
-    if (!g_file_test (priv->filename, G_FILE_TEST_IS_REGULAR)) {
-	error = yelp_error_new (_("File not found"),
-				_("The file â??%sâ?? does not exist."),
-				priv->filename);
-	yelp_document_error_pending (document, error);
-	goto done;
-    }
+    xmlNodePtr cur;
+    xmlChar *id;
 
     parserCtxt = xmlNewParserCtxt ();
-    xmldoc = xmlCtxtReadFile (parserCtxt,
-			      (const char *) priv->filename, NULL,
-			      XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA |
-			      XML_PARSE_NOENT   | XML_PARSE_NONET   );
-
-    if (xmldoc == NULL) {
-	error = yelp_error_new (_("Could not parse file"),
-				_("The file â??%sâ?? could not be parsed because it is"
-				  " not a well-formed XML document."),
-				priv->filename);
-	yelp_document_error_pending (document, error);
-	goto done;
-    }
-
-    if (xmlXIncludeProcessFlags (xmldoc,
-				 XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA |
-				 XML_PARSE_NOENT   | XML_PARSE_NONET   )
-	< 0) {
-	error = yelp_error_new (_("Could not parse file"),
-				_("The file â??%sâ?? could not be parsed because"
-				  " one or more of its included files is not"
-				  " a well-formed XML document."),
-				priv->filename);
-	yelp_document_error_pending (document, error);
+    page_data->xmldoc = xmlCtxtReadFile (parserCtxt,
+                                         (const char *) page_data->filename, NULL,
+                                         XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA |
+                                         XML_PARSE_NOENT   | XML_PARSE_NONET   );
+    if (page_data->xmldoc == NULL)
 	goto done;
-    }
-
-    g_mutex_lock (priv->mutex);
-    if (!xmlStrcmp (xmlDocGetRootElement (xmldoc)->name, BAD_CAST "book"))
-	priv->max_depth = 2;
-    else
-	priv->max_depth = 1;
-
-    priv->xmldoc = xmldoc;
-    priv->xmlcur = xmlDocGetRootElement (xmldoc);
-
-    id = xmlGetProp (priv->xmlcur, BAD_CAST "id");
-    if (id) {
-	yelp_document_set_root_id (document, (gchar *) id);
-	yelp_document_add_page_id (document, "x-yelp-index", (gchar *) id);
-	yelp_document_add_prev_id (document, (gchar *) id, "x-yelp-titlepage");
-	yelp_document_add_next_id (document, "x-yelp-titlepage", (gchar *) id);
-    }
-    else {
-	yelp_document_set_root_id (document, "x-yelp-index");
-	yelp_document_add_page_id (document, "x-yelp-index", "x-yelp-index");
-	yelp_document_add_prev_id (document, "x-yelp-index", "x-yelp-titlepage");
-	yelp_document_add_next_id (document, "x-yelp-titlepage", "x-yelp-index");
-	/* add the id attribute to the root element with value "index"
-	 * so when we try to load the document later, it doesn't fail */
-	xmlNewProp (priv->xmlcur, BAD_CAST "id", BAD_CAST "x-yelp-index");
-    }
-    g_mutex_unlock (priv->mutex);
 
-    g_mutex_lock (priv->mutex);
-    if (priv->state == DOCBOOK_STATE_STOP) {
-	g_mutex_unlock (priv->mutex);
-	goto done;
-    }
-    g_mutex_unlock (priv->mutex);
+    cur = xmlDocGetRootElement (page_data->xmldoc);
+    id = xmlGetProp (cur, BAD_CAST "id");
+    if (id == NULL)
+        goto done;
+    page_data->page_id = g_strdup ((gchar *) id);
+    xmlFree (id);
 
-    docbook_walk (docbook);
+ done:
+    if (parserCtxt)
+	xmlFreeParserCtxt (parserCtxt);
+}
 
-    g_mutex_lock (priv->mutex);
-    if (priv->state == DOCBOOK_STATE_STOP) {
-	g_mutex_unlock (priv->mutex);
-	goto done;
-    }
-    priv->transform = yelp_transform_new (STYLESHEET,
-					  (YelpTransformFunc) transform_func,
-					  docbook);
-    priv->transform_running = TRUE;
+static void
+mallard_page_data_run (MallardPageData *page_data)
+{
+    gint  params_i = 0;
+    gint  params_max = 10;
+    gchar **params = NULL;
+    page_data->transform = yelp_transform_new (STYLESHEET,
+                                               (YelpTransformFunc) transform_func,
+                                               page_data);
+    page_data->mallard->priv->transforms_running++;
 
     params = g_new0 (gchar *, params_max);
     yelp_settings_params (&params, &params_i, &params_max);
-
-
-    if ((params_i + 10) >= params_max - 1) {
-	params_max += 20;
-	params = g_renew (gchar *, params, params_max);
-    }
-    params[params_i++] = "db.chunk.max_depth";
-    params[params_i++] = g_strdup_printf ("%i", docbook->priv->max_depth);
-
-    params[params_i] = NULL;
-
-    yelp_transform_start (priv->transform,
-			  priv->xmldoc,
+    params[params_i+1] = NULL;
+    yelp_transform_start (page_data->transform,
+			  page_data->xmldoc,
 			  params);
-    g_mutex_unlock (priv->mutex);
-
- done:
-    if (id)
-	xmlFree (id);
-    if (parserCtxt)
-	xmlFreeParserCtxt (parserCtxt);
-
-    priv->process_running = FALSE;
-    g_object_unref (docbook);
 }
 
+static void
+mallard_page_data_free (MallardPageData *page_data)
+{
+    g_free (page_data->page_id);
+    g_free (page_data->filename);
+    if (page_data->xmldoc)
+        xmlFreeDoc (page_data->xmldoc);
+    if (page_data->transform)
+	yelp_transform_release (page_data->transform);
+    g_free (page_data);
+}
 
 /******************************************************************************/
-/** Walker ********************************************************************/
+/** YelpTransform *************************************************************/
 
 static void
-docbook_walk (YelpDocbook *docbook)
+transform_func (YelpTransform       *transform,
+		YelpTransformSignal  signal,
+		gpointer             func_data,
+		MallardPageData     *page_data)
 {
-    static       gint autoid = 0;
-    gchar        autoidstr[20];
-    xmlChar     *id = NULL;
-    xmlChar     *title = NULL;
-    gchar       *old_page_id = NULL;
-    xmlNodePtr   cur, old_cur;
-    GtkTreeIter  iter;
-    GtkTreeIter *old_iter = NULL;
-    YelpDocbookPriv *priv = docbook->priv;
-    YelpDocument *document = YELP_DOCUMENT (docbook);
-
+    YelpMallardPriv *priv;
     debug_print (DB_FUNCTION, "entering\n");
-    debug_print (DB_DEBUG, "  priv->xmlcur->name: %s\n", priv->xmlcur->name);
-
-    /* check for the yelp:chunk-depth or db.chunk.max_depth processing
-     * instruction and set the max chunk depth accordingly.
-     */
-    if (priv->cur_depth == 0)
-	for (cur = priv->xmlcur; cur; cur = cur->prev)
-	    if (cur->type == XML_PI_NODE)
-		if (!xmlStrcmp (cur->name, (const xmlChar *) "yelp:chunk-depth") ||
-		    !xmlStrcmp (cur->name, (const xmlChar *) "db.chunk.max_depth")) {
-		    gint max = atoi ((gchar *) cur->content);
-		    if (max)
-			priv->max_depth = max;
-		    break;
-		}
-
-    id = xmlGetProp (priv->xmlcur, BAD_CAST "id");
-
-    if (docbook_walk_divisionQ (docbook) && !id) {
-	/* if id attribute is not present, autogenerate a
-	 * unique value, and insert it into the in-memory tree */
-	g_snprintf (autoidstr, 20, "_auto-gen-id-%d", ++autoid);
-	xmlNewProp (priv->xmlcur, BAD_CAST "id", BAD_CAST autoidstr);
-	id = xmlGetProp (priv->xmlcur, BAD_CAST "id"); 
-    }
 
-    if (docbook_walk_chunkQ (docbook)) {
-	title = BAD_CAST docbook_walk_get_title (docbook);
-
-	debug_print (DB_DEBUG, "  id: \"%s\"\n", id);
-	debug_print (DB_DEBUG, "  title: \"%s\"\n", title);
-
-	yelp_document_add_title (document, (gchar *) id, (gchar *) title);
-
-	gdk_threads_enter ();
-	gtk_tree_store_append (GTK_TREE_STORE (priv->sections),
-			       &iter,
-			       priv->sections_iter);
-	gtk_tree_store_set (GTK_TREE_STORE (priv->sections),
-			    &iter,
-			    YELP_DOCUMENT_COLUMN_ID, id,
-			    YELP_DOCUMENT_COLUMN_TITLE, title,
-			    -1);
-	gdk_threads_leave ();
-
-	if (priv->cur_prev_id) {
-	    yelp_document_add_prev_id (document, (gchar *) id, priv->cur_prev_id);
-	    yelp_document_add_next_id (document, priv->cur_prev_id, (gchar *) id);
-	    g_free (priv->cur_prev_id);
-	}
-	priv->cur_prev_id = g_strdup ((gchar *) id);
-
-	if (priv->cur_page_id)
-	    yelp_document_add_up_id (document, (gchar *) id, priv->cur_page_id);
-	old_page_id = priv->cur_page_id;
-	priv->cur_page_id = g_strdup ((gchar *) id);
+    g_assert (page_data != NULL && page_data->mallard != NULL &&
+              YELP_IS_MALLARD (page_data->mallard));
+    g_assert (transform == page_data->transform);
 
-	old_iter = priv->sections_iter;
-	if (priv->xmlcur->parent->type != XML_DOCUMENT_NODE)
-	    priv->sections_iter = &iter;
-    }
+    priv = page_data->mallard->priv;
 
-    old_cur = priv->xmlcur;
-    priv->cur_depth++;
-    if (id && !g_str_equal (id, "x-yelp-index"))
-	yelp_document_add_page_id (document, (gchar *) id, priv->cur_page_id);
-
-    for (cur = priv->xmlcur->children; cur; cur = cur->next) {
-	if (cur->type == XML_ELEMENT_NODE) {
-	    priv->xmlcur = cur;
-	    docbook_walk (docbook);
+    if (priv->state == MALLARD_STATE_STOP) {
+	switch (signal) {
+	case YELP_TRANSFORM_CHUNK:
+	    g_free (func_data);
+	    break;
+	case YELP_TRANSFORM_ERROR:
+	    yelp_error_free ((YelpError *) func_data);
+	    break;
+	case YELP_TRANSFORM_FINAL:
+	    break;
 	}
+	yelp_transform_release (transform);
+	page_data->transform = NULL;
+	priv->transforms_running--;
+	return;
     }
-    priv->cur_depth--;
-    priv->xmlcur = old_cur;
 
-    if (docbook_walk_chunkQ (docbook)) {
-	priv->sections_iter = old_iter;
-	g_free (priv->cur_page_id);
-	priv->cur_page_id = old_page_id;
+    switch (signal) {
+    case YELP_TRANSFORM_CHUNK:
+	transform_page_func (transform, (gchar *) func_data, page_data);
+	break;
+    case YELP_TRANSFORM_ERROR:
+	yelp_document_error_pending (YELP_DOCUMENT (page_data->mallard), (YelpError *) func_data);
+	yelp_transform_release (transform);
+	page_data->transform = NULL;
+	priv->transforms_running -= 1;
+	break;
+    case YELP_TRANSFORM_FINAL:
+	transform_final_func (transform, page_data);
+	break;
     }
+}
 
-    if (priv->cur_depth == 0) {
-	g_free (priv->cur_prev_id);
-	priv->cur_prev_id = NULL;
+static void
+transform_page_func (YelpTransform   *transform,
+		     gchar           *page_id,
+		     MallardPageData *page_data)
+{
+    YelpMallardPriv *priv;
+    gchar *content;
 
-	g_free (priv->cur_page_id);
-	priv->cur_page_id = NULL;
-    }
+    debug_print (DB_FUNCTION, "entering\n");
 
-    if (id != NULL)
-	xmlFree (id);
-    if (title != NULL)
-	xmlFree (title);
-}
+    priv = page_data->mallard->priv;
+    g_mutex_lock (priv->mutex);
 
-static gboolean
-docbook_walk_chunkQ (YelpDocbook *docbook)
-{
-    if (docbook->priv->cur_depth <= docbook->priv->max_depth
-	&& docbook_walk_divisionQ (docbook))
-	return TRUE;
-    else
-	return FALSE;
-}
+    content = yelp_transform_eat_chunk (transform, page_id);
+    yelp_document_add_page (YELP_DOCUMENT (page_data->mallard), page_id, content);
 
-static gboolean
-docbook_walk_divisionQ (YelpDocbook *docbook)
-{
-    xmlNodePtr node = docbook->priv->xmlcur;
-    return (!xmlStrcmp (node->name, (const xmlChar *) "appendix")     ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "article")      ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "book")         ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "bibliography") ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "chapter")      ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "colophon")     ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "glossary")     ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "index")        ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "part")         ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "preface")      ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "reference")    ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "refentry")     ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "refsect1")     ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "refsect2")     ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "refsect3")     ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "refsection")   ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "sect1")        ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "sect2")        ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "sect3")        ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "sect4")        ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "sect5")        ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "section")      ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "set")          ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "setindex")     ||
-	    !xmlStrcmp (node->name, (const xmlChar *) "simplesect")   );
+    g_free (page_id);
+
+    g_mutex_unlock (priv->mutex);
 }
 
-static gchar *
-docbook_walk_get_title (YelpDocbook *docbook)
+static void
+transform_final_func (YelpTransform *transform, MallardPageData *page_data)
 {
-    gchar *infoname = NULL;
-    xmlNodePtr child = NULL;
-    xmlNodePtr title = NULL;
-    xmlNodePtr title_tmp = NULL;
-    YelpDocbookPriv *priv = docbook->priv;
-
-    if (!xmlStrcmp (priv->xmlcur->name, BAD_CAST "refentry")) {
-	/* The title for a refentry element can come from the following:
-	 *   refmeta/refentrytitle
-	 *   refentryinfo/title[abbrev]
-	 *   refnamediv/refname
-	 * We take the first one we find.
-	 */
-	for (child = priv->xmlcur->children; child; child = child->next) {
-	    if (!xmlStrcmp (child->name, BAD_CAST "refmeta")) {
-		for (title = child->children; title; title = title->next) {
-		    if (!xmlStrcmp (title->name, BAD_CAST "refentrytitle"))
-			break;
-		}
-		if (title)
-		    goto done;
-	    }
-	    else if (!xmlStrcmp (child->name, BAD_CAST "refentryinfo")) {
-		for (title = child->children; title; title = title->next) {
-		    if (!xmlStrcmp (title->name, BAD_CAST "titleabbrev"))
-			break;
-		    else if (!xmlStrcmp (title->name, BAD_CAST "title"))
-			title_tmp = title;
-		}
-		if (title)
-		    goto done;
-		else if (title_tmp) {
-		    title = title_tmp;
-		    goto done;
-		}
-	    }
-	    else if (!xmlStrcmp (child->name, BAD_CAST "refnamediv")) {
-		for (title = child->children; title; title = title->next) {
-		    if (!xmlStrcmp (title->name, BAD_CAST "refname"))
-			break;
-		    else if (!xmlStrcmp (title->name, BAD_CAST "refpurpose")) {
-			title = NULL;
-			break;
-		    }
-		}
-		if (title)
-		    goto done;
-	    }
-	    else if (!xmlStrncmp (child->name, BAD_CAST "refsect", 7))
-		break;
-	}
-    }
-    else {
-	/* The title for other elements appears in the following:
-	 *   title[abbrev]
-	 *   *info/title[abbrev]
-	 *   blockinfo/title[abbrev]
-	 *   objectinfo/title[abbrev]
-	 * We take them in that order.
-	 */
-	xmlNodePtr infos[3] = {NULL, NULL, NULL};
-	int i;
-
-	infoname = g_strdup_printf ("%sinfo", priv->xmlcur->name);
-
-	for (child = priv->xmlcur->children; child; child = child->next) {
-	    if (!xmlStrcmp (child->name, BAD_CAST "titleabbrev")) {
-		title = child;
-		goto done;
-	    }
-	    else if (!xmlStrcmp (child->name, BAD_CAST "title"))
-		title_tmp = child;
-	    else if (!xmlStrcmp (child->name, BAD_CAST infoname))
-		infos[0] = child;
-	    else if (!xmlStrcmp (child->name, BAD_CAST "blockinfo"))
-		infos[1] = child;
-	    else if (!xmlStrcmp (child->name, BAD_CAST "objectinfo"))
-		infos[2] = child;
-	}
+    YelpMallardPriv *priv;
 
-	if (title_tmp) {
-	    title = title_tmp;
-	    goto done;
-	}
+    debug_print (DB_FUNCTION, "entering\n");
 
-	for (i = 0; i < 3; i++) {
-	    child = infos[i];
-	    if (child) {
-		for (title = child->children; title; title = title->next) {
-		    if (!xmlStrcmp (title->name, BAD_CAST "titleabbrev"))
-			goto done;
-		    else if (!xmlStrcmp (title->name, BAD_CAST "title"))
-			title_tmp = title;
-		}
-		if (title_tmp) {
-		    title = title_tmp;
-		    goto done;
-		}
-	    }
-	}
-    }
+    priv = page_data->mallard->priv;
+    g_mutex_lock (priv->mutex);
 
- done:
-    g_free (infoname);
+    yelp_transform_release (transform);
+    page_data->transform = NULL;
+    priv->transforms_running -= 1;
+
+    if (page_data->xmldoc)
+	xmlFreeDoc (page_data->xmldoc);
+    page_data->xmldoc = NULL;
 
-    if (title)
-	return (gchar *) xmlNodeGetContent (title);
-    else
-	return g_strdup (_("Unknown"));
+    g_mutex_unlock (priv->mutex);
 }
-#endif



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