summaryrefslogtreecommitdiff
path: root/src/yelp-db-pager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/yelp-db-pager.c')
-rw-r--r--src/yelp-db-pager.c605
1 files changed, 0 insertions, 605 deletions
diff --git a/src/yelp-db-pager.c b/src/yelp-db-pager.c
deleted file mode 100644
index 800ff5f0..00000000
--- a/src/yelp-db-pager.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * Copyright (C) 2003 Shaun McCance <shaunm@gnome.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Shaun McCance <shaunm@gnome.org>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/xinclude.h>
-#include <libxslt/xslt.h>
-#include <libxslt/templates.h>
-#include <libxslt/transform.h>
-#include <libxslt/extensions.h>
-#include <libxslt/xsltInternals.h>
-#include <libxslt/xsltutils.h>
-
-#include "yelp-error.h"
-#include "yelp-db-pager.h"
-#include "yelp-toc-pager.h"
-#include "yelp-settings.h"
-#include "yelp-debug.h"
-
-#define STYLESHEET_PATH DATADIR"/yelp/xslt/"
-#define DB_STYLESHEET STYLESHEET_PATH"db2html.xsl"
-
-#define BOOK_CHUNK_DEPTH 2
-#define ARTICLE_CHUNK_DEPTH 1
-
-#define EVENTS_PENDING while (yelp_pager_get_state (pager) <= YELP_PAGER_STATE_RUNNING && gtk_events_pending ()) gtk_main_iteration ();
-#define CANCEL_CHECK if (!main_running || yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) goto done;
-
-extern gboolean main_running;
-
-#define YELP_DB_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_DB_PAGER, YelpDBPagerPriv))
-
-struct _YelpDBPagerPriv {
- GtkTreeModel *sects;
- GHashTable *frags_hash;
-
- gint max_depth;
- gchar *root_id;
-};
-
-typedef struct _DBWalker DBWalker;
-struct _DBWalker {
- YelpDBPager *pager;
- gchar *page_id;
-
- xmlDocPtr doc;
- xmlNodePtr cur;
-
- GtkTreeIter *iter;
-
- gint depth;
- gint max_depth;
-
-};
-
-static void db_pager_class_init (YelpDBPagerClass *klass);
-static void db_pager_init (YelpDBPager *pager);
-static void db_pager_dispose (GObject *gobject);
-
-static void db_pager_cancel (YelpPager *pager);
-static xmlDocPtr db_pager_parse (YelpPager *pager);
-static gchar ** db_pager_params (YelpPager *pager);
-
-static const gchar * db_pager_resolve_frag (YelpPager *pager,
- const gchar *frag_id);
-static GtkTreeModel * db_pager_get_sections (YelpPager *pager);
-
-static void walker_walk_xml (DBWalker *walker);
-
-static gboolean node_is_chunk (DBWalker *walker);
-static gboolean node_is_division (DBWalker *walker);
-static gchar * node_get_title (DBWalker *walker,
- gchar *type);
-
-xmlNodePtr node_find_child (xmlNodePtr parent,
- gchar *child_name);
-
-static YelpPagerClass *parent_class;
-
-GType
-yelp_db_pager_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (YelpDBPagerClass),
- NULL,
- NULL,
- (GClassInitFunc) db_pager_class_init,
- NULL,
- NULL,
- sizeof (YelpDBPager),
- 0,
- (GInstanceInitFunc) db_pager_init,
- };
- type = g_type_register_static (YELP_TYPE_XSLT_PAGER,
- "YelpDBPager",
- &info, 0);
- }
- return type;
-}
-
-static void
-db_pager_class_init (YelpDBPagerClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass);
- YelpXsltPagerClass *xslt_class = YELP_XSLT_PAGER_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->dispose = db_pager_dispose;
-
- pager_class->cancel = db_pager_cancel;
-
- pager_class->resolve_frag = db_pager_resolve_frag;
- pager_class->get_sections = db_pager_get_sections;
-
- xslt_class->parse = db_pager_parse;
- xslt_class->params = db_pager_params;
-
- xslt_class->stylesheet = DB_STYLESHEET;
-
- g_type_class_add_private (klass, sizeof (YelpDBPagerPriv));
-}
-
-static void
-db_pager_init (YelpDBPager *pager)
-{
- pager->priv = YELP_DB_PAGER_GET_PRIVATE (pager);
-
- pager->priv->sects = NULL;
-
- pager->priv->frags_hash =
- g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
- pager->priv->root_id = NULL;
-}
-
-static void
-db_pager_dispose (GObject *object)
-{
- YelpDBPager *pager = YELP_DB_PAGER (object);
-
- g_object_unref (pager->priv->sects);
- g_hash_table_destroy (pager->priv->frags_hash);
-
- g_free (pager->priv->root_id);
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-/******************************************************************************/
-
-YelpPager *
-yelp_db_pager_new (YelpDocInfo *doc_info)
-{
- YelpDBPager *pager;
-
- g_return_val_if_fail (doc_info != NULL, NULL);
-
- pager = (YelpDBPager *) g_object_new (YELP_TYPE_DB_PAGER,
- "document-info", doc_info,
- NULL);
-
- g_hash_table_insert (pager->priv->frags_hash,
- g_strdup ("x-yelp-titlepage"),
- g_strdup ("x-yelp-titlepage"));
-
- if (!pager->priv->sects)
- pager->priv->sects =
- GTK_TREE_MODEL (gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_STRING));
-
- return (YelpPager *) pager;
-}
-
-static xmlDocPtr
-db_pager_parse (YelpPager *pager)
-{
- YelpDBPagerPriv *priv;
- YelpDocInfo *doc_info;
- gchar *filename = NULL;
-
- xmlParserCtxtPtr parserCtxt = NULL;
- xmlDocPtr doc = NULL;
-
- DBWalker *walker = NULL;
- xmlChar *id;
- GError *error = NULL;
-
- debug_print (DB_FUNCTION, "entering\n");
-
- doc_info = yelp_pager_get_doc_info (pager);
-
- g_return_val_if_fail (pager != NULL, NULL);
- g_return_val_if_fail (YELP_IS_DB_PAGER (pager), NULL);
- priv = YELP_DB_PAGER (pager)->priv;
-
- g_object_ref (pager);
-
- if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR)
- goto done;
-
- filename = yelp_doc_info_get_filename (doc_info);
-
- parserCtxt = xmlNewParserCtxt ();
- doc = xmlCtxtReadFile (parserCtxt,
- (const char *) filename, NULL,
- XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA |
- XML_PARSE_NOENT | XML_PARSE_NONET );
- if (doc == NULL) {
- g_set_error (&error, YELP_GERROR, YELP_ERROR_NO_DOC,
- _("The file ā€˜%sā€™ could not be parsed. Either the file "
- "does not exist, or it is not well-formed XML."),
- filename);
- yelp_pager_error (pager, error);
- goto done;
- }
-
- xmlXIncludeProcessFlags (doc,
- XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA |
- XML_PARSE_NOENT | XML_PARSE_NONET );
-
- walker = g_new0 (DBWalker, 1);
- walker->pager = YELP_DB_PAGER (pager);
- walker->doc = doc;
- walker->cur = xmlDocGetRootElement (walker->doc);
-
- if (!xmlStrcmp (xmlDocGetRootElement (doc)->name, BAD_CAST "book"))
- priv->max_depth = walker->max_depth = BOOK_CHUNK_DEPTH;
- else
- priv->max_depth = walker->max_depth = ARTICLE_CHUNK_DEPTH;
-
- id = xmlGetProp (walker->cur, BAD_CAST "id");
- if (id)
- priv->root_id = g_strdup ((gchar *) id);
- else {
- priv->root_id = g_strdup ("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 (walker->cur, BAD_CAST "id", BAD_CAST "index");
- }
-
- EVENTS_PENDING;
- CANCEL_CHECK;
-
- walker_walk_xml (walker);
-
- done:
- g_free (walker);
-
- g_free (filename);
-
- if (parserCtxt)
- xmlFreeParserCtxt (parserCtxt);
-
- g_object_unref (pager);
-
- return doc;
-}
-
-static gchar **
-db_pager_params (YelpPager *pager)
-{
- YelpDBPagerPriv *priv;
- gchar **params;
- gint params_i = 0;
- gint params_max = 20;
-
- debug_print (DB_FUNCTION, "entering\n");
-
- g_return_val_if_fail (pager != NULL, FALSE);
- g_return_val_if_fail (YELP_IS_DB_PAGER (pager), FALSE);
- priv = YELP_DB_PAGER (pager)->priv;
-
- if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR)
- return NULL;
-
- 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.extension";
- params[params_i++] = g_strdup ("\"\"");
- params[params_i++] = "db.chunk.info_basename";
- params[params_i++] = g_strdup ("\"x-yelp-titlepage\"");
- params[params_i++] = "db.chunk.max_depth";
- params[params_i++] = g_strdup_printf ("%i", priv->max_depth);
- params[params_i++] = "yelp.javascript";
- params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/yelp.js");
-
- params[params_i] = NULL;
-
- return params;
-}
-
-static void
-db_pager_cancel (YelpPager *pager)
-{
- YelpDBPagerPriv *priv = YELP_DB_PAGER (pager)->priv;
-
- debug_print (DB_FUNCTION, "entering\n");
-
- yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID);
-
- gtk_tree_store_clear (GTK_TREE_STORE (priv->sects));
- g_hash_table_foreach_remove (priv->frags_hash, (GHRFunc) gtk_true, NULL);
-
- g_free (priv->root_id);
- priv->root_id = NULL;
-
- YELP_PAGER_CLASS (parent_class)->cancel (pager);
-}
-
-static const gchar *
-db_pager_resolve_frag (YelpPager *pager, const gchar *frag_id)
-{
- YelpDBPager *db_pager;
- gchar *page_id = NULL;
-
- g_return_val_if_fail (pager != NULL, NULL);
- g_return_val_if_fail (YELP_IS_DB_PAGER (pager), NULL);
-
- db_pager = YELP_DB_PAGER (pager);
-
- if (frag_id)
- page_id = g_hash_table_lookup (db_pager->priv->frags_hash,
- frag_id);
- else
- page_id = db_pager->priv->root_id;
-
- return (const gchar *) page_id;
-}
-
-static GtkTreeModel *
-db_pager_get_sections (YelpPager *pager)
-{
- g_return_val_if_fail (pager != NULL, NULL);
- g_return_val_if_fail (YELP_IS_DB_PAGER (pager), NULL);
-
- return YELP_DB_PAGER (pager)->priv->sects;
-}
-
-/******************************************************************************/
-
-static void
-walker_walk_xml (DBWalker *walker)
-{
- static gint autoid = 0;
- gchar autoidstr[20];
- xmlChar *id = NULL;
- xmlChar *title = NULL;
- gchar *old_id = NULL;
- xmlNodePtr cur;
- xmlNodePtr old_cur;
- GtkTreeIter iter;
- GtkTreeIter *old_iter = NULL;
- YelpDBPagerPriv *priv = walker->pager->priv;
-
- /* check for the yelp:chunk-depth processing instruction and set
- * the max chunk depth accordingly */
- if (walker->depth == 0) {
- cur = walker->cur;
- for ( ; cur; cur = cur->prev)
- if (cur->type == XML_PI_NODE)
- if (!xmlStrcmp (cur->name,
- (const xmlChar *) "yelp:chunk-depth")) {
- gint max = atoi ((gchar *) cur->content);
- if (max)
- priv->max_depth = walker->max_depth = max;
- break;
- }
- }
-
- id = xmlGetProp (walker->cur, BAD_CAST "id");
- if (!id && walker->cur->parent->type == XML_DOCUMENT_NODE) {
- id = xmlStrdup (BAD_CAST "__yelp_toc");
- }
-
- if (node_is_chunk (walker)) {
- title = BAD_CAST node_get_title (walker, "titleabbrev");
- if (!title)
- title = BAD_CAST node_get_title (walker, "title");
-
- /* if id attribute is not present, autogenerate a
- * unique value, and insert it into the in-memory tree */
- if (!id) {
- g_snprintf (autoidstr, 20, "_auto-gen-id-%d", ++autoid);
- xmlNewProp (walker->cur, BAD_CAST "id", BAD_CAST autoidstr);
- id = xmlGetProp (walker->cur, BAD_CAST "id");
- }
-
- if (id) {
- gtk_tree_store_append (GTK_TREE_STORE (priv->sects),
- &iter, walker->iter);
-
- gtk_tree_store_set (GTK_TREE_STORE (priv->sects),
- &iter,
- YELP_PAGER_COLUMN_ID, id,
- YELP_PAGER_COLUMN_TITLE, title,
- -1);
-
- old_id = walker->page_id;
- walker->page_id = (gchar *) id;
-
- old_iter = walker->iter;
-
- if (walker->cur->parent->type != XML_DOCUMENT_NODE)
- walker->iter = &iter;
- }
- }
-
- while (gtk_events_pending ())
- gtk_main_iteration ();
- /* FIXME : check for cancel */
-
- old_cur = walker->cur;
- walker->depth++;
-
- if (id) {
- g_hash_table_insert (priv->frags_hash,
- g_strdup ((gchar *) id),
- g_strdup (walker->page_id));
- }
-
- cur = walker->cur->children;
- while (cur != NULL) {
- if (cur->type == XML_ELEMENT_NODE) {
- walker->cur = cur;
- walker_walk_xml (walker);
- }
- cur = cur->next;
- }
-
- walker->depth--;
- walker->cur = old_cur;
-
- if (node_is_chunk (walker) && id) {
- walker->iter = old_iter;
-
- walker->page_id = old_id;
- }
-
- if (id != NULL)
- xmlFree (id);
- if (title != NULL)
- xmlFree (title);
-}
-
-xmlNodePtr
-node_find_child (xmlNodePtr parent, gchar *child_name)
-{
- xmlNodePtr child = (xmlNodePtr) parent->children;
-
- while (child) {
- if (!xmlStrcmp (child->name, BAD_CAST child_name))
- break;
- child = child->next;
- }
- return child;
-}
-
-
-static gchar *
-node_get_title (DBWalker *walker, gchar *type)
-{
- gchar *title = NULL;
- xmlChar *node_name = (xmlChar *) walker->cur->name;
- xmlNodePtr child = NULL;
- xmlNodePtr title_node = NULL;
-
- if (xmlStrcmp (node_name, BAD_CAST "refentry")) {
- /*refentry is special cased below */
- title_node = node_find_child (walker->cur, type);
- if (!title_node) {
- /* Gotta look for some other way of getting the title */
- gchar *looking_for = g_strdup_printf ("%sinfo", node_name);
-
- child = node_find_child (walker->cur, looking_for);
- g_free (looking_for);
-
- if (child)
- title_node = node_find_child (child, type);
- }
- } else {
- /* Refentry */
- xmlNodePtr refentry = NULL;
- xmlNodePtr refmeta = NULL;
- xmlNodePtr refnamediv = NULL;
- xmlNodePtr child = walker->cur->children;
-
- while (child) {
- if (!xmlStrcmp (child->name, BAD_CAST "refmeta"))
- refmeta = child;
- else if (!xmlStrcmp (child->name, BAD_CAST "refentryinfo"))
- refentry = child;
- else if (!xmlStrcmp (child->name, BAD_CAST "refnamediv"))
- refnamediv = child;
- else if (!xmlStrncmp (child->name, BAD_CAST "refsect", 7))
- break;
- child = child->next;
-
- }
- if (refmeta) {
- xmlNodePtr tmp = node_find_child (refmeta, "refentrytitle");
- title_node = node_find_child (tmp, type);
- }
- if (!title_node && refentry) {
- title_node = node_find_child (refentry, type);
- }
- if (!title_node) {
- title_node = node_find_child (refnamediv, "refname");
- }
-
- }
- /* Something pretty seriously screwy happened
- * Try the fallback options
- */
- if (!title_node) {
- xmlNodePtr block = node_find_child (walker->cur, "blockinfo");
- if (block) {
- title_node = node_find_child (block, type);
- }
- if (!title_node) {
- xmlNodePtr obj = node_find_child (walker->cur, "objectinfo");
- if (obj)
- title_node = node_find_child (obj, type);
- }
- }
-
- title = (gchar *) xmlNodeGetContent (title_node);
-
- return title;
-}
-
-static gboolean
-node_is_chunk (DBWalker *walker)
-{
- if (walker->depth <= walker->max_depth) {
- if (node_is_division (walker))
- return TRUE;
- }
- return FALSE;
-}
-
-static gboolean
-node_is_division (DBWalker *walker)
-{
- xmlNodePtr node = walker->cur;
- 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") );
-}