From 752f2f834554eab6c297f72041dbb806a51a74a9 Mon Sep 17 00:00:00 2001 From: Shaun McCance Date: Mon, 8 Jun 2009 15:23:49 -0500 Subject: Very basic display of Mallard index page --- src/yelp-mallard.c | 741 +++++++++++++++++++---------------------------------- 1 file changed, 267 insertions(+), 474 deletions(-) diff --git a/src/yelp-mallard.c b/src/yelp-mallard.c index 82648e92..30a5f639 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 (¶ms, ¶ms_i, ¶ms_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 -- cgit v1.2.1