summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun McCance <shaunm@gnome.org>2010-06-01 15:01:57 -0500
committerShaun McCance <shaunm@gnome.org>2010-06-01 15:02:42 -0500
commit78dbed19c11400d1f9b182acc01a7414dadd191f (patch)
treef65a7e470ef1843598d68bcb0ca5466480cdd515
parent6d2f282102a2992c6197b60feed41d6a73272400 (diff)
downloadyelp-78dbed19c11400d1f9b182acc01a7414dadd191f.tar.gz
[libyelp] Adding man page support, some formatting still off
-rw-r--r--configure.ac1
-rw-r--r--libyelp/Makefile.am4
-rw-r--r--libyelp/yelp-document.c70
-rw-r--r--libyelp/yelp-info-document.h1
-rw-r--r--libyelp/yelp-info-parser.c5
-rw-r--r--libyelp/yelp-man-document.c506
-rw-r--r--libyelp/yelp-man-document.h51
-rw-r--r--libyelp/yelp-man-parser.c (renamed from src/yelp-man-parser.c)126
-rw-r--r--libyelp/yelp-man-parser.h (renamed from src/yelp-man-parser.h)4
-rw-r--r--src/yelp-man.c490
-rw-r--r--src/yelp-man.h53
-rw-r--r--stylesheets/Makefile.am1
-rw-r--r--stylesheets/man2html.xsl.in (renamed from stylesheets/man2html.xsl)106
-rw-r--r--stylesheets/yelp-common.xsl.in2
14 files changed, 684 insertions, 736 deletions
diff --git a/configure.ac b/configure.ac
index c7854a00..3797fb03 100644
--- a/configure.ac
+++ b/configure.ac
@@ -201,6 +201,7 @@ stylesheets/db2html.xsl
stylesheets/db-title.xsl
stylesheets/info2html.xsl
stylesheets/mal2html.xsl
+stylesheets/man2html.xsl
stylesheets/toc2html.xsl
stylesheets/yelp-common.xsl
data/Makefile
diff --git a/libyelp/Makefile.am b/libyelp/Makefile.am
index 077630eb..01217d16 100644
--- a/libyelp/Makefile.am
+++ b/libyelp/Makefile.am
@@ -10,6 +10,8 @@ libyelp_la_SOURCES = \
yelp-location-entry.c \
yelp-magic-decompressor.c \
yelp-mallard-document.c \
+ yelp-man-document.c \
+ yelp-man-parser.c \
yelp-marshal.c \
yelp-settings.c \
yelp-simple-document.c \
@@ -23,6 +25,7 @@ EXTRA_DIST = \
yelp-debug.h \
yelp-error.h \
yelp-info-parser.h \
+ yelp-man-parser.h \
yelp-lzma-decompressor.h \
yelp-magic-decompressor.h \
yelp-marshal.list
@@ -53,6 +56,7 @@ libyelp_headers = \
yelp-info-document.h \
yelp-location-entry.h \
yelp-mallard-document.h \
+ yelp-man-document.h \
yelp-settings.h \
yelp-simple-document.h \
yelp-transform.h \
diff --git a/libyelp/yelp-document.c b/libyelp/yelp-document.c
index 45017775..1a1cbb65 100644
--- a/libyelp/yelp-document.c
+++ b/libyelp/yelp-document.c
@@ -30,9 +30,10 @@
#include "yelp-debug.h"
#include "yelp-document.h"
#include "yelp-error.h"
-#include "yelp-info-document.h"
#include "yelp-docbook-document.h"
+#include "yelp-info-document.h"
#include "yelp-mallard-document.h"
+#include "yelp-man-document.h"
#include "yelp-simple-document.h"
typedef struct _Request Request;
@@ -76,6 +77,8 @@ struct _YelpDocumentPriv {
Hash *prev_ids; /* Mapping of page IDs to "previous page" IDs */
Hash *next_ids; /* Mapping of page IDs to "next page" IDs */
Hash *up_ids; /* Mapping of page IDs to "up page" IDs */
+
+ GError *idle_error;
};
G_DEFINE_TYPE (YelpDocument, yelp_document, G_TYPE_OBJECT);
@@ -140,14 +143,14 @@ yelp_document_get_for_uri (YelpUri *uri)
YelpDocument *document = NULL;
if (documents == NULL)
- documents = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_object_unref);
+ documents = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_object_unref);
g_return_val_if_fail (yelp_uri_is_resolved (uri), NULL);
docuri = yelp_uri_get_document_uri (uri);
if (docuri == NULL)
- return NULL;
+ return NULL;
switch (yelp_uri_get_document_type (uri)) {
case YELP_URI_DOCUMENT_TYPE_TEXT:
@@ -170,38 +173,38 @@ yelp_document_get_for_uri (YelpUri *uri)
document = g_hash_table_lookup (documents, docuri);
if (document != NULL) {
- g_free (docuri);
- return g_object_ref (document);
+ g_free (docuri);
+ return g_object_ref (document);
}
switch (yelp_uri_get_document_type (uri)) {
case YELP_URI_DOCUMENT_TYPE_TEXT:
case YELP_URI_DOCUMENT_TYPE_HTML:
case YELP_URI_DOCUMENT_TYPE_XHTML:
- document = yelp_simple_document_new (uri);
- break;
+ document = yelp_simple_document_new (uri);
+ break;
case YELP_URI_DOCUMENT_TYPE_DOCBOOK:
- document = yelp_docbook_document_new (uri);
- break;
+ document = yelp_docbook_document_new (uri);
+ break;
case YELP_URI_DOCUMENT_TYPE_MALLARD:
- document = yelp_mallard_document_new (uri);
- break;
+ document = yelp_mallard_document_new (uri);
+ break;
case YELP_URI_DOCUMENT_TYPE_MAN:
- /* FIXME */
- break;
+ document = yelp_man_document_new (uri);
+ break;
case YELP_URI_DOCUMENT_TYPE_INFO:
- document = yelp_info_document_new (uri);
- break;
+ document = yelp_info_document_new (uri);
+ break;
case YELP_URI_DOCUMENT_TYPE_TOC:
- /* FIXME */
- break;
+ /* FIXME */
+ break;
case YELP_URI_DOCUMENT_TYPE_SEARCH:
- /* FIXME */
- break;
+ /* FIXME */
+ break;
case YELP_URI_DOCUMENT_TYPE_NOT_FOUND:
case YELP_URI_DOCUMENT_TYPE_EXTERNAL:
case YELP_URI_DOCUMENT_TYPE_ERROR:
- break;
+ break;
}
if (document != NULL) {
@@ -847,22 +850,19 @@ yelp_document_signal (YelpDocument *document,
g_mutex_unlock (document->priv->mutex);
}
-void
-yelp_document_error_pending (YelpDocument *document,
- const GError *error)
+static gboolean
+yelp_document_error_pending_idle (YelpDocument *document)
{
YelpDocumentPriv *priv = GET_PRIV (document);
GSList *cur;
Request *request;
- g_assert (document != NULL && YELP_IS_DOCUMENT (document));
-
g_mutex_lock (priv->mutex);
if (priv->reqs_pending) {
for (cur = priv->reqs_pending; cur; cur = cur->next) {
request = cur->data;
- request->error = yelp_error_copy ((GError *) error);
+ request->error = yelp_error_copy ((GError *) priv->idle_error);
request->idle_funcs++;
g_idle_add ((GSourceFunc) request_idle_error, request);
}
@@ -872,6 +872,22 @@ yelp_document_error_pending (YelpDocument *document,
}
g_mutex_unlock (priv->mutex);
+
+ g_object_unref (document);
+ return FALSE;
+}
+
+void
+yelp_document_error_pending (YelpDocument *document,
+ const GError *error)
+{
+ YelpDocumentPriv *priv = GET_PRIV (document);
+
+ g_assert (document != NULL && YELP_IS_DOCUMENT (document));
+
+ g_object_ref (document);
+ priv->idle_error = g_error_copy (error);
+ g_idle_add ((GSourceFunc) yelp_document_error_pending_idle, document);
}
/******************************************************************************/
diff --git a/libyelp/yelp-info-document.h b/libyelp/yelp-info-document.h
index 40139446..a3f4a7bd 100644
--- a/libyelp/yelp-info-document.h
+++ b/libyelp/yelp-info-document.h
@@ -36,7 +36,6 @@
typedef struct _YelpInfoDocument YelpInfoDocument;
typedef struct _YelpInfoDocumentClass YelpInfoDocumentClass;
-typedef struct _YelpInfoPriv YelpInfoPriv;
struct _YelpInfoDocument {
YelpDocument parent;
diff --git a/libyelp/yelp-info-parser.c b/libyelp/yelp-info-parser.c
index cbca0e47..33107948 100644
--- a/libyelp/yelp-info-parser.c
+++ b/libyelp/yelp-info-parser.c
@@ -224,11 +224,6 @@ static char
g_string_append_len (string, buf, bytes);
g_object_unref (stream);
- /*
- g_object_unref (converter);
- g_object_unref (file_stream);
- g_object_unref (file);
- */
str = string->str;
diff --git a/libyelp/yelp-man-document.c b/libyelp/yelp-man-document.c
new file mode 100644
index 00000000..14ac8cd0
--- /dev/null
+++ b/libyelp/yelp-man-document.c
@@ -0,0 +1,506 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2007-2010 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 <gtk/gtk.h>
+#include <libxml/tree.h>
+
+#include "yelp-error.h"
+#include "yelp-man-document.h"
+#include "yelp-man-parser.h"
+#include "yelp-transform.h"
+#include "yelp-settings.h"
+
+#define STYLESHEET DATADIR"/yelp/xslt/man2html.xsl"
+
+typedef enum {
+ MAN_STATE_BLANK, /* Brand new, run transform as needed */
+ MAN_STATE_PARSING, /* Parsing/transforming document, please wait */
+ MAN_STATE_PARSED, /* All done, if we ain't got it, it ain't here */
+ MAN_STATE_STOP /* Stop everything now, object to be disposed */
+} ManState;
+
+typedef struct _YelpManDocumentPrivate YelpManDocumentPrivate;
+struct _YelpManDocumentPrivate {
+ YelpUri *uri;
+ ManState state;
+
+ GMutex *mutex;
+ GThread *thread;
+
+ xmlDocPtr xmldoc;
+
+ gboolean process_running;
+ gboolean transform_running;
+
+ YelpTransform *transform;
+ guint chunk_ready;
+ guint finished;
+ guint error;
+};
+
+typedef struct _YelpLangEncodings YelpLangEncodings;
+struct _YelpLangEncodings {
+ gchar *language;
+ gchar *encoding;
+};
+/* http://www.w3.org/International/O-charset-lang.html */
+static const YelpLangEncodings langmap[] = {
+ { "C", "ISO-8859-1" },
+ { "af", "ISO-8859-1" },
+ { "ar", "ISO-8859-6" },
+ { "bg", "ISO-8859-5" },
+ { "be", "ISO-8859-5" },
+ { "ca", "ISO-8859-1" },
+ { "cs", "ISO-8859-2" },
+ { "da", "ISO-8859-1" },
+ { "de", "ISO-8859-1" },
+ { "el", "ISO-8859-7" },
+ { "en", "ISO-8859-1" },
+ { "eo", "ISO-8859-3" },
+ { "es", "ISO-8859-1" },
+ { "et", "ISO-8859-15" },
+ { "eu", "ISO-8859-1" },
+ { "fi", "ISO-8859-1" },
+ { "fo", "ISO-8859-1" },
+ { "fr", "ISO-8859-1" },
+ { "ga", "ISO-8859-1" },
+ { "gd", "ISO-8859-1" },
+ { "gl", "ISO-8859-1" },
+ { "hu", "ISO-8859-2" },
+ { "id", "ISO-8859-1" }, /* is this right */
+ { "mt", "ISO-8859-3" },
+ { "is", "ISO-8859-1" },
+ { "it", "ISO-8859-1" },
+ { "iw", "ISO-8859-8" },
+ { "ja", "EUC-JP" },
+ { "ko", "EUC-KR" },
+ { "lt", "ISO-8859-13" },
+ { "lv", "ISO-8859-13" },
+ { "mk", "ISO-8859-5" },
+ { "mt", "ISO-8859-3" },
+ { "no", "ISO-8859-1" },
+ { "pl", "ISO-8859-2" },
+ { "pt_BR", "ISO-8859-1" },
+ { "ro", "ISO-8859-2" },
+ { "ru", "KOI8-R" },
+ { "sl", "ISO-8859-2" },
+ { "sr", "ISO-8859-2" }, /* Latin, not cyrillic */
+ { "sk", "ISO-8859-2" },
+ { "sv", "ISO-8859-1" },
+ { "tr", "ISO-8859-9" },
+ { "uk", "ISO-8859-5" },
+ { "zh_CN", "BIG5" },
+ { "zh_TW", "BIG5" },
+ { NULL, NULL },
+};
+
+static void yelp_man_document_class_init (YelpManDocumentClass *klass);
+static void yelp_man_document_init (YelpManDocument *man);
+static void yelp_man_document_dispose (GObject *object);
+static void yelp_man_document_finalize (GObject *object);
+
+/* YelpDocument */
+static gboolean man_request_page (YelpDocument *document,
+ const gchar *page_id,
+ GCancellable *cancellable,
+ YelpDocumentCallback callback,
+ gpointer user_data);
+
+/* YelpTransform */
+static void transform_chunk_ready (YelpTransform *transform,
+ gchar *chunk_id,
+ YelpManDocument *man);
+static void transform_finished (YelpTransform *transform,
+ YelpManDocument *man);
+static void transform_error (YelpTransform *transform,
+ YelpManDocument *man);
+static void transform_finalized (YelpManDocument *man,
+ gpointer transform);
+
+/* Threaded */
+static void man_document_process (YelpManDocument *man);
+
+static void man_document_disconnect (YelpManDocument *man);
+
+
+G_DEFINE_TYPE (YelpManDocument, yelp_man_document, YELP_TYPE_DOCUMENT);
+#define GET_PRIV(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_MAN_DOCUMENT, YelpManDocumentPrivate))
+
+static void
+yelp_man_document_class_init (YelpManDocumentClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ YelpDocumentClass *document_class = YELP_DOCUMENT_CLASS (klass);
+
+ object_class->dispose = yelp_man_document_dispose;
+ object_class->finalize = yelp_man_document_finalize;
+
+ document_class->request_page = man_request_page;
+
+ g_type_class_add_private (klass, sizeof (YelpManDocumentPrivate));
+}
+
+static void
+yelp_man_document_init (YelpManDocument *man)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (man);
+
+ priv->state = MAN_STATE_BLANK;
+ priv->mutex = g_mutex_new ();
+}
+
+static void
+yelp_man_document_dispose (GObject *object)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (object);
+
+ if (priv->uri) {
+ g_object_unref (priv->uri);
+ priv->uri = NULL;
+ }
+
+ G_OBJECT_CLASS (yelp_man_document_parent_class)->dispose (object);
+}
+
+static void
+yelp_man_document_finalize (GObject *object)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (object);
+
+ if (priv->xmldoc)
+ xmlFreeDoc (priv->xmldoc);
+
+ g_mutex_free (priv->mutex);
+
+ G_OBJECT_CLASS (yelp_man_document_parent_class)->finalize (object);
+}
+
+/******************************************************************************/
+
+YelpDocument *
+yelp_man_document_new (YelpUri *uri)
+{
+ YelpManDocument *man;
+ YelpManDocumentPrivate *priv;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ man = (YelpManDocument *) g_object_new (YELP_TYPE_MAN_DOCUMENT, NULL);
+ priv = GET_PRIV (man);
+
+ priv->uri = g_object_ref (uri);
+
+ return (YelpDocument *) man;
+}
+
+
+/******************************************************************************/
+/** YelpDocument **************************************************************/
+
+static gboolean
+man_request_page (YelpDocument *document,
+ const gchar *page_id,
+ GCancellable *cancellable,
+ YelpDocumentCallback callback,
+ gpointer user_data)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (document);
+ gchar *docuri;
+ GError *error;
+ gboolean handled;
+
+ if (page_id == NULL)
+ page_id = "//index";
+
+ handled =
+ YELP_DOCUMENT_CLASS (yelp_man_document_parent_class)->request_page (document,
+ page_id,
+ cancellable,
+ callback,
+ user_data);
+ if (handled) {
+ return;
+ }
+
+ g_mutex_lock (priv->mutex);
+
+ switch (priv->state) {
+ case MAN_STATE_BLANK:
+ priv->state = MAN_STATE_PARSING;
+ priv->process_running = TRUE;
+ g_object_ref (document);
+ yelp_document_set_page_id (document, NULL, "//index");
+ yelp_document_set_page_id (document, "//index", "//index");
+ yelp_document_set_root_id (document, "//index", "//index");
+ priv->thread = g_thread_create ((GThreadFunc) man_document_process,
+ document, FALSE, NULL);
+ break;
+ case MAN_STATE_PARSING:
+ break;
+ case MAN_STATE_PARSED:
+ case MAN_STATE_STOP:
+ docuri = yelp_uri_get_document_uri (priv->uri);
+ error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
+ _("The page ‘%s’ was not found in the document ‘%s’."),
+ page_id, docuri);
+ g_free (docuri);
+ yelp_document_signal (document, page_id,
+ YELP_DOCUMENT_SIGNAL_ERROR,
+ error);
+ g_error_free (error);
+ break;
+ }
+
+ g_mutex_unlock (priv->mutex);
+}
+
+
+/******************************************************************************/
+/** YelpTransform *************************************************************/
+
+static void
+transform_chunk_ready (YelpTransform *transform,
+ gchar *chunk_id,
+ YelpManDocument *man)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (man);
+ gchar *content;
+
+ g_assert (transform == priv->transform);
+
+ if (priv->state == MAN_STATE_STOP) {
+ man_document_disconnect (man);
+ return;
+ }
+
+ content = yelp_transform_take_chunk (transform, chunk_id);
+ yelp_document_give_contents (YELP_DOCUMENT (man),
+ chunk_id,
+ content,
+ "application/xhtml+xml");
+
+ yelp_document_signal (YELP_DOCUMENT (man),
+ chunk_id,
+ YELP_DOCUMENT_SIGNAL_INFO,
+ NULL);
+ yelp_document_signal (YELP_DOCUMENT (man),
+ chunk_id,
+ YELP_DOCUMENT_SIGNAL_CONTENTS,
+ NULL);
+}
+
+static void
+transform_finished (YelpTransform *transform,
+ YelpManDocument *man)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (man);
+ gchar *docuri;
+ GError *error;
+
+ g_assert (transform == priv->transform);
+
+ if (priv->state == MAN_STATE_STOP) {
+ man_document_disconnect (man);
+ return;
+ }
+
+ man_document_disconnect (man);
+ priv->state = MAN_STATE_PARSED;
+
+ /* We want to free priv->xmldoc, but we can't free it before transform
+ is finalized. Otherwise, we could crash when YelpTransform frees
+ its libxslt resources.
+ */
+ g_object_weak_ref ((GObject *) transform,
+ (GWeakNotify) transform_finalized,
+ man);
+
+ docuri = yelp_uri_get_document_uri (priv->uri);
+ error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
+ _("The requested page was not found in the document ‘%s’."),
+ docuri);
+ g_free (docuri);
+ yelp_document_error_pending ((YelpDocument *) man, error);
+ g_error_free (error);
+}
+
+static void
+transform_error (YelpTransform *transform,
+ YelpManDocument *man)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (man);
+ GError *error;
+
+ g_assert (transform == priv->transform);
+
+ if (priv->state == MAN_STATE_STOP) {
+ man_document_disconnect (man);
+ return;
+ }
+
+ error = yelp_transform_get_error (transform);
+ yelp_document_error_pending ((YelpDocument *) man, error);
+ g_error_free (error);
+
+ man_document_disconnect (man);
+}
+
+static void
+transform_finalized (YelpManDocument *man,
+ gpointer transform)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (man);
+
+ if (priv->xmldoc)
+ xmlFreeDoc (priv->xmldoc);
+ priv->xmldoc = NULL;
+}
+
+
+/******************************************************************************/
+/** Threaded ******************************************************************/
+
+static void
+man_document_process (YelpManDocument *man)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (man);
+ GFile *file = NULL;
+ gchar *filepath = NULL;
+ GError *error;
+ gint params_i = 0;
+ gchar **params = NULL;
+ YelpManParser *parser;
+ const gchar *language, *encoding;
+
+ file = yelp_uri_get_file (priv->uri);
+ if (file == NULL) {
+ error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
+ _("The file does not exist."));
+ yelp_document_error_pending ((YelpDocument *) man, error);
+ g_error_free (error);
+ goto done;
+ }
+
+ filepath = g_file_get_path (file);
+ g_object_unref (file);
+ if (!g_file_test (filepath, G_FILE_TEST_IS_REGULAR)) {
+ error = g_error_new (YELP_ERROR, YELP_ERROR_NOT_FOUND,
+ _("The file ‘%s’ does not exist."),
+ filepath);
+ yelp_document_error_pending ((YelpDocument *) man, error);
+ g_error_free (error);
+ goto done;
+ }
+
+ /* FIXME: get the language */
+ language = "C";
+
+ /* default encoding if the language doesn't match below */
+ encoding = g_getenv("MAN_ENCODING");
+ if (encoding == NULL)
+ encoding = "ISO-8859-1";
+
+ if (language != NULL) {
+ gint i;
+ for (i = 0; langmap[i].language != NULL; i++) {
+ if (g_str_equal (language, langmap[i].language)) {
+ encoding = langmap[i].encoding;
+ break;
+ }
+ }
+ }
+
+ parser = yelp_man_parser_new ();
+ priv->xmldoc = yelp_man_parser_parse_file (parser, filepath, encoding);
+ yelp_man_parser_free (parser);
+
+ if (priv->xmldoc == NULL) {
+ error = g_error_new (YELP_ERROR, YELP_ERROR_PROCESSING,
+ _("The file ‘%s’ could not be parsed because it is"
+ " not a well-formed man page."),
+ filepath);
+ yelp_document_error_pending ((YelpDocument *) man, error);
+ }
+
+ g_mutex_lock (priv->mutex);
+ if (priv->state == MAN_STATE_STOP) {
+ g_mutex_unlock (priv->mutex);
+ goto done;
+ }
+
+ priv->transform = yelp_transform_new (STYLESHEET);
+ priv->chunk_ready =
+ g_signal_connect (priv->transform, "chunk-ready",
+ (GCallback) transform_chunk_ready,
+ man);
+ priv->finished =
+ g_signal_connect (priv->transform, "finished",
+ (GCallback) transform_finished,
+ man);
+ priv->error =
+ g_signal_connect (priv->transform, "error",
+ (GCallback) transform_error,
+ man);
+
+ params = yelp_settings_get_all_params (yelp_settings_get_default (), 0, &params_i);
+
+ priv->transform_running = TRUE;
+ yelp_transform_start (priv->transform,
+ priv->xmldoc,
+ NULL,
+ (const gchar * const *) params);
+ g_strfreev (params);
+ g_mutex_unlock (priv->mutex);
+
+ done:
+ g_free (filepath);
+ priv->process_running = FALSE;
+ g_object_unref (man);
+}
+
+static void
+man_document_disconnect (YelpManDocument *man)
+{
+ YelpManDocumentPrivate *priv = GET_PRIV (man);
+ if (priv->chunk_ready) {
+ g_signal_handler_disconnect (priv->transform, priv->chunk_ready);
+ priv->chunk_ready = 0;
+ }
+ if (priv->finished) {
+ g_signal_handler_disconnect (priv->transform, priv->finished);
+ priv->finished = 0;
+ }
+ if (priv->error) {
+ g_signal_handler_disconnect (priv->transform, priv->error);
+ priv->error = 0;
+ }
+ yelp_transform_cancel (priv->transform);
+ g_object_unref (priv->transform);
+ priv->transform = NULL;
+ priv->transform_running = FALSE;
+}
diff --git a/libyelp/yelp-man-document.h b/libyelp/yelp-man-document.h
new file mode 100644
index 00000000..2379f081
--- /dev/null
+++ b/libyelp/yelp-man-document.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2007-2010 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>
+ */
+
+#ifndef __YELP_MAN_DOCUMENT_H__
+#define __YELP_MAN_DOCUMENT_H__
+
+#include <glib-object.h>
+
+#include "yelp-document.h"
+
+#define YELP_TYPE_MAN_DOCUMENT (yelp_man_document_get_type ())
+#define YELP_MAN_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_MAN_DOCUMENT, YelpManDocument))
+#define YELP_MAN_DOCUMENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_MAN_DOCUMENT, YelpManDocumentClass))
+#define YELP_IS_MAN_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_MAN_DOCUMENT))
+#define YELP_IS_MAN_DOCUMENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_MAN_DOCUMENT))
+#define YELP_MAN_DOCUMENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_MAN_DOCUMENT, YelpManDocumentClass))
+
+typedef struct _YelpManDocument YelpManDocument;
+typedef struct _YelpManDocumentClass YelpManDocumentClass;
+
+struct _YelpManDocument {
+ YelpDocument parent;
+};
+
+struct _YelpManDocumentClass {
+ YelpDocumentClass parent_class;
+};
+
+GType yelp_man_document_get_type (void);
+YelpDocument * yelp_man_document_new (YelpUri *uri);
+
+#endif /* __YELP_MAN_DOCUMENT_H__ */
diff --git a/src/yelp-man-parser.c b/libyelp/yelp-man-parser.c
index 933b3589..ef1f4d66 100644
--- a/src/yelp-man-parser.c
+++ b/libyelp/yelp-man-parser.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
- * Copyright (C) 2003 Shaun McCance <shaunm@gnome.org>
+ * Copyright (C) 2003-2010 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
@@ -17,7 +17,7 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
- * Author: Shaun McCance <shaunm@gnome.org>
+ * Author: Shaun McCance <shaunm@gnome.org>
*/
#ifdef HAVE_CONFIG_H
@@ -29,9 +29,8 @@
#include <libxml/tree.h>
#include <string.h>
-#include "yelp-debug.h"
-#include "yelp-io-channel.h"
#include "yelp-man-parser.h"
+#include "yelp-magic-decompressor.h"
#define PARSER_CUR (g_utf8_get_char (parser->cur) != '\0' \
&& (parser->cur - parser->buffer < parser->length))
@@ -69,10 +68,9 @@ struct _YelpManParser {
xmlNodePtr ins; /* The insertion node */
xmlNodePtr th_node; /* The TH node, or NULL if it doesn't exist */
- GIOChannel *channel; /* GIOChannel for the entire document */
-
- gchar *buffer; /* The buffer, line at a time */
- gsize length; /* The buffer length */
+ GDataInputStream *stream; /* The GIO input stream to read from */
+ gchar *buffer; /* The buffer, line at a time */
+ gsize length; /* The buffer length */
gchar *anc; /* The anchor point in the document */
gchar *cur; /* Our current position in the document */
@@ -98,17 +96,18 @@ yelp_man_parser_parse_file (YelpManParser *parser,
gchar *file,
const gchar *encoding)
{
- GError *errormsg = NULL;
- /*gchar *ptr = NULL;*/
-
- g_return_val_if_fail (parser != NULL, NULL);
- g_return_val_if_fail (file != NULL, NULL);
- g_return_val_if_fail (encoding != NULL, NULL);
-
- parser->channel = yelp_io_channel_new_file (file, NULL);
-
- if (!parser->channel)
- return NULL;
+ GFile *gfile;
+ GConverter *converter;
+ GFileInputStream *file_stream;
+ GInputStream *stream;
+ gchar *line;
+ gsize len;
+
+ gfile = g_file_new_for_path (file);
+ file_stream = g_file_read (gfile, NULL, NULL);
+ converter = (GConverter *) yelp_magic_decompressor_new ();
+ stream = g_converter_input_stream_new ((GInputStream *) file_stream, converter);
+ parser->stream = g_data_input_stream_new (stream);
parser->doc = xmlNewDoc (BAD_CAST "1.0");
parser->ins = xmlNewNode (NULL, BAD_CAST "Man");
@@ -116,20 +115,14 @@ yelp_man_parser_parse_file (YelpManParser *parser,
parser->make_links = TRUE;
- while (g_io_channel_read_line (parser->channel,
- &(parser->buffer),
- &(parser->length),
- NULL, &errormsg)
- == G_IO_STATUS_NORMAL) {
-
+ while ((parser->buffer = g_data_input_stream_read_line (parser->stream, &(parser->length), NULL, NULL)) != NULL) {
/* 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;
- /* since our encoding is binary (NULL) in g_io_channel, then
- * our returned lined should end with \n. Therefore we are making the
+ /* 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 */
@@ -149,23 +142,13 @@ yelp_man_parser_parse_file (YelpManParser *parser,
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);
}
- if (errormsg)
- g_print ("Error in g_io_channel_read_line()\n");
-
- g_io_channel_shutdown (parser->channel, FALSE, NULL);
+ g_object_unref (parser->stream);
return parser->doc;
}
@@ -173,9 +156,6 @@ yelp_man_parser_parse_file (YelpManParser *parser,
void
yelp_man_parser_free (YelpManParser *parser)
{
- if (parser->channel)
- g_io_channel_unref (parser->channel);
-
g_free (parser);
}
@@ -381,20 +361,20 @@ macro_section_header_handler (YelpManParser *parser, gchar *macro, GSList *args)
{
static gint id = 0;
GIOStatus retval;
- GError **errormsg = NULL;
+ GError *error = 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");
+ str = g_data_input_stream_read_line (parser->stream, NULL, NULL, &error);
+ if (error) {
+ g_warning ("%s\n", error->message);
+ g_error_free (error);
}
- } else
+ }
+ else
str = args_concat_all (args);
for (ptr = macro_uc; *ptr != '\0'; ptr++)
@@ -459,11 +439,8 @@ macro_tp_handler (YelpManParser *parser, gchar *macro, GSList *args)
g_free (parser->buffer);
- if (g_io_channel_read_line (parser->channel,
- &(parser->buffer),
- &(parser->length),
- NULL, errormsg)
- == G_IO_STATUS_NORMAL) {
+ parser->buffer = g_data_input_stream_read_line (parser->stream, &(parser->length), NULL, NULL);
+ if (parser->buffer != NULL) {
parser->ins = parser_append_node (parser, "Tag");
parser_parse_line (parser);
parser->ins = parser->ins->parent;
@@ -609,7 +586,7 @@ macro_url_handler (YelpManParser *parser, gchar *macro, GSList *args)
tmpNode = parser_stack_pop_node (parser, "UR");
if (tmpNode == NULL)
- debug_print (DB_WARN, "Found unexpected tag: '%s'\n", macro);
+ g_warning ("Found unexpected tag: '%s'\n", macro);
else
parser->ins = tmpNode->parent;
} else
@@ -706,7 +683,7 @@ macro_mandoc_list_handler (YelpManParser *parser, gchar *macro, GSList *args)
tmpNode = parser_stack_pop_node (parser, "Bl");
if (tmpNode == NULL)
- debug_print (DB_WARN, "Found unexpected tag: '%s'\n", macro);
+ g_warning ("Found unexpected tag: '%s'\n", macro);
else
parser->ins = tmpNode->parent;
}
@@ -725,7 +702,7 @@ macro_verbatim_handler (YelpManParser *parser, gchar *macro, GSList *args)
tmpNode = parser_stack_pop_node (parser, "Verbatim");
if (tmpNode == NULL)
- debug_print (DB_WARN, "Found unexpected tag: '%s'\n", macro);
+ g_warning ("Found unexpected tag: '%s'\n", macro);
else
parser->ins = tmpNode->parent;
}
@@ -1269,7 +1246,7 @@ get_argument:
}
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_warning ("Found unexpected tag: '%s'\n", str);
g_free (str);
}
/* "ie" and "if" are conditional macros in groff
@@ -1454,7 +1431,7 @@ parser_append_given_text_handle_escapes (YelpManParser *parser, gchar *text, gbo
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_warning ("No rule matching the tag '%s'\n", str);
g_free (str);
anc = ptr;
@@ -1754,11 +1731,9 @@ parser_handle_row_options (YelpManParser *parser)
g_free (parser->buffer);
- } while (g_io_channel_read_line (parser->channel,
- &(parser->buffer),
- &(parser->length),
- NULL, NULL)
- == G_IO_STATUS_NORMAL);
+ } while ((parser->buffer =
+ g_data_input_stream_read_line (parser->stream, &(parser->length), NULL, NULL))
+ != NULL);
}
static void
@@ -1769,11 +1744,8 @@ parser_parse_table (YelpManParser *parser)
table_start = parser->ins;
- if (g_io_channel_read_line (parser->channel,
- &(parser->buffer),
- &(parser->length),
- NULL, NULL)
- == G_IO_STATUS_NORMAL) {
+ parser->buffer = g_data_input_stream_read_line (parser->stream, &(parser->length), NULL, NULL);
+ if (parser->buffer != NULL) {
parser->anc = parser->buffer;
parser->cur = parser->buffer;
@@ -1782,11 +1754,8 @@ parser_parse_table (YelpManParser *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->buffer = g_data_input_stream_read_line (parser->stream, &(parser->length), NULL, NULL);
+ if (parser->buffer != NULL) {
parser->anc = parser->buffer;
parser->cur = parser->buffer;
@@ -1798,12 +1767,7 @@ parser_parse_table (YelpManParser *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) {
-
+ while ((parser->buffer = g_data_input_stream_read_line (parser->stream, &(parser->length), NULL, NULL)) != NULL) {
parser->anc = parser->buffer;
parser->cur = parser->buffer;
@@ -1814,7 +1778,7 @@ parser_parse_table (YelpManParser *parser)
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");
+ g_warning ("Found unexpected tag: 'TE'\n");
else {
parser->ins = table_start;
diff --git a/src/yelp-man-parser.h b/libyelp/yelp-man-parser.h
index 26976d2a..1901f1b2 100644
--- a/src/yelp-man-parser.h
+++ b/libyelp/yelp-man-parser.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
- * Copyright (C) 2003 Shaun McCance <shaunm@gnome.org>
+ * Copyright (C) 2003-2010 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
@@ -17,7 +17,7 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
- * Author: Shaun McCance <shaunm@gnome.org>
+ * Author: Shaun McCance <shaunm@gnome.org>
*/
#ifndef __YELP_MAN_PARSER_H__
diff --git a/src/yelp-man.c b/src/yelp-man.c
deleted file mode 100644
index 1e6fc562..00000000
--- a/src/yelp-man.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * Copyright (C) 2007 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 <gtk/gtk.h>
-#include <libxml/tree.h>
-
-#include "yelp-error.h"
-#include "yelp-man.h"
-#include "yelp-man-parser.h"
-#include "yelp-transform.h"
-#include "yelp-debug.h"
-#include "yelp-settings.h"
-
-#define STYLESHEET DATADIR"/yelp/xslt/man2html.xsl"
-
-#define YELP_MAN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_MAN, YelpManPriv))
-
-typedef enum {
- MAN_STATE_BLANK, /* Brand new, run transform as needed */
- MAN_STATE_PARSING, /* Parsing/transforming document, please wait */
- MAN_STATE_PARSED, /* All done, if we ain't got it, it ain't here */
- MAN_STATE_STOP /* Stop everything now, object to be disposed */
-} ManState;
-
-struct _YelpManPriv {
- gchar *filename;
- ManState state;
-
- GMutex *mutex;
- GThread *thread;
-
- xmlDocPtr xmldoc;
-
- gboolean process_running;
- gboolean transform_running;
-
- YelpTransform *transform;
-};
-
-typedef struct _YelpLangEncodings YelpLangEncodings;
-struct _YelpLangEncodings {
- gchar *language;
- gchar *encoding;
-};
-/* http://www.w3.org/International/O-charset-lang.html */
-static const YelpLangEncodings langmap[] = {
- { "C", "ISO-8859-1" },
- { "af", "ISO-8859-1" },
- { "ar", "ISO-8859-6" },
- { "bg", "ISO-8859-5" },
- { "be", "ISO-8859-5" },
- { "ca", "ISO-8859-1" },
- { "cs", "ISO-8859-2" },
- { "da", "ISO-8859-1" },
- { "de", "ISO-8859-1" },
- { "el", "ISO-8859-7" },
- { "en", "ISO-8859-1" },
- { "eo", "ISO-8859-3" },
- { "es", "ISO-8859-1" },
- { "et", "ISO-8859-15" },
- { "eu", "ISO-8859-1" },
- { "fi", "ISO-8859-1" },
- { "fo", "ISO-8859-1" },
- { "fr", "ISO-8859-1" },
- { "ga", "ISO-8859-1" },
- { "gd", "ISO-8859-1" },
- { "gl", "ISO-8859-1" },
- { "hu", "ISO-8859-2" },
- { "id", "ISO-8859-1" }, /* is this right */
- { "mt", "ISO-8859-3" },
- { "is", "ISO-8859-1" },
- { "it", "ISO-8859-1" },
- { "iw", "ISO-8859-8" },
- { "ja", "EUC-JP" },
- { "ko", "EUC-KR" },
- { "lt", "ISO-8859-13" },
- { "lv", "ISO-8859-13" },
- { "mk", "ISO-8859-5" },
- { "mt", "ISO-8859-3" },
- { "no", "ISO-8859-1" },
- { "pl", "ISO-8859-2" },
- { "pt_BR", "ISO-8859-1" },
- { "ro", "ISO-8859-2" },
- { "ru", "KOI8-R" },
- { "sl", "ISO-8859-2" },
- { "sr", "ISO-8859-2" }, /* Latin, not cyrillic */
- { "sk", "ISO-8859-2" },
- { "sv", "ISO-8859-1" },
- { "tr", "ISO-8859-9" },
- { "uk", "ISO-8859-5" },
- { "zh_CN", "BIG5" },
- { "zh_TW", "BIG5" },
- { NULL, NULL },
-};
-
-static void man_class_init (YelpManClass *klass);
-static void man_init (YelpMan *man);
-static void man_try_dispose (GObject *object);
-static void man_dispose (GObject *object);
-
-/* YelpDocument */
-static void man_request (YelpDocument *document,
- gint req_id,
- gboolean handled,
- gchar *page_id,
- YelpDocumentFunc func,
- gpointer user_data);
-
-/* YelpTransform */
-static void transform_func (YelpTransform *transform,
- YelpTransformSignal signal,
- gpointer func_data,
- YelpMan *man);
-static void transform_page_func (YelpTransform *transform,
- gchar *page_id,
- YelpMan *man);
-static void transform_final_func (YelpTransform *transform,
- YelpMan *man);
-
-/* Threaded */
-static void man_process (YelpMan *man);
-
-static YelpDocumentClass *parent_class;
-
-GType
-yelp_man_get_type (void)
-{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (YelpManClass),
- NULL, NULL,
- (GClassInitFunc) man_class_init,
- NULL, NULL,
- sizeof (YelpMan),
- 0,
- (GInstanceInitFunc) man_init,
- };
- type = g_type_register_static (YELP_TYPE_DOCUMENT,
- "YelpMan",
- &info, 0);
- }
- return type;
-}
-
-static void
-man_class_init (YelpManClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- YelpDocumentClass *document_class = YELP_DOCUMENT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->dispose = man_try_dispose;
-
- document_class->request = man_request;
- document_class->cancel = NULL;
-
- g_type_class_add_private (klass, sizeof (YelpManPriv));
-}
-
-static void
-man_init (YelpMan *man)
-{
- YelpManPriv *priv;
-
- priv = man->priv = YELP_MAN_GET_PRIVATE (man);
-
- priv->state = MAN_STATE_BLANK;
-
- priv->mutex = g_mutex_new ();
-}
-
-static void
-man_try_dispose (GObject *object)
-{
- YelpManPriv *priv;
-
- g_assert (object != NULL && YELP_IS_MAN (object));
- priv = YELP_MAN (object)->priv;
- g_mutex_lock (priv->mutex);
- if (priv->process_running || priv->transform_running) {
- priv->state = MAN_STATE_STOP;
- g_idle_add ((GSourceFunc) man_try_dispose, object);
- g_mutex_unlock (priv->mutex);
- } else {
- g_mutex_unlock (priv->mutex);
- man_dispose (object);
- }
-}
-
-static void
-man_dispose (GObject *object)
-{
- YelpMan *man = YELP_MAN (object);
-
- g_free (man->priv->filename);
-
- if (man->priv->xmldoc)
- xmlFreeDoc (man->priv->xmldoc);
-
- g_mutex_free (man->priv->mutex);
-
- G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-/******************************************************************************/
-
-YelpDocument *
-yelp_man_new (gchar *filename)
-{
- YelpMan *man;
-
- g_return_val_if_fail (filename != NULL, NULL);
-
- man = (YelpMan *) g_object_new (YELP_TYPE_MAN, NULL);
- man->priv->filename = g_strdup (filename);
-
- debug_print (DB_FUNCTION, "entering\n");
- debug_print (DB_ARG, " filename = \"%s\"\n", filename);
-
- yelp_document_add_page_id (YELP_DOCUMENT (man), "x-yelp-index", "index");
-
- return (YelpDocument *) man;
-}
-
-
-/******************************************************************************/
-/** YelpDocument **************************************************************/
-
-static void
-man_request (YelpDocument *document,
- gint req_id,
- gboolean handled,
- gchar *page_id,
- YelpDocumentFunc func,
- gpointer user_data)
-{
- YelpMan *man;
- YelpManPriv *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_MAN (document));
-
- if (handled)
- return;
-
- man = YELP_MAN (document);
- priv = man->priv;
-
- g_mutex_lock (priv->mutex);
-
- switch (priv->state) {
- case MAN_STATE_BLANK:
- priv->state = MAN_STATE_PARSING;
- priv->process_running = TRUE;
- priv->thread = g_thread_create ((GThreadFunc) man_process, man, FALSE, NULL);
- break;
- case MAN_STATE_PARSING:
- break;
- case MAN_STATE_PARSED:
- case MAN_STATE_STOP:
- error = yelp_error_new (_("Page not found"),
- _("The page %s was not found in the document %s."),
- page_id, priv->filename);
- yelp_document_error_request (document, req_id, error);
- break;
- }
-
- g_mutex_unlock (priv->mutex);
-}
-
-
-/******************************************************************************/
-/** YelpTransform *************************************************************/
-
-static void
-transform_func (YelpTransform *transform,
- YelpTransformSignal signal,
- gpointer func_data,
- YelpMan *man)
-{
- YelpManPriv *priv;
-
- debug_print (DB_FUNCTION, "entering\n");
-
- g_assert (man != NULL && YELP_IS_MAN (man));
-
- priv = man->priv;
-
- g_assert (transform == priv->transform);
-
- if (priv->state == MAN_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;
- }
-
- switch (signal) {
- case YELP_TRANSFORM_CHUNK:
- transform_page_func (transform, (gchar *) func_data, man);
- break;
- case YELP_TRANSFORM_ERROR:
- yelp_document_error_pending (YELP_DOCUMENT (man), (YelpError *) func_data);
- yelp_transform_release (transform);
- priv->transform = NULL;
- priv->transform_running = FALSE;
- break;
- case YELP_TRANSFORM_FINAL:
- transform_final_func (transform, man);
- break;
- }
-}
-
-static void
-transform_page_func (YelpTransform *transform,
- gchar *page_id,
- YelpMan *man)
-{
- YelpManPriv *priv;
- gchar *content;
-
- debug_print (DB_FUNCTION, "entering\n");
-
- priv = man->priv;
- g_mutex_lock (priv->mutex);
-
- content = yelp_transform_eat_chunk (transform, page_id);
-
- yelp_document_add_page (YELP_DOCUMENT (man), page_id, content);
-
- g_free (page_id);
-
- g_mutex_unlock (priv->mutex);
-}
-
-static void
-transform_final_func (YelpTransform *transform, YelpMan *man)
-{
- YelpError *error;
- YelpManPriv *priv = man->priv;
-
- 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 (man), error);
-
- yelp_transform_release (transform);
- priv->transform = NULL;
- priv->transform_running = FALSE;
- priv->state = MAN_STATE_PARSED;
-
- if (priv->xmldoc)
- xmlFreeDoc (priv->xmldoc);
- priv->xmldoc = NULL;
-
- g_mutex_unlock (priv->mutex);
-}
-
-
-/******************************************************************************/
-/** Threaded ******************************************************************/
-
-static void
-man_process (YelpMan *man)
-{
- YelpManPriv *priv;
- const gchar *language;
- const gchar *encoding;
- YelpManParser *parser;
- YelpError *error = NULL;
- YelpDocument *document;
- gint i;
-
- gint params_i = 0;
- gint params_max = 10;
- gchar **params = NULL;
-
- debug_print (DB_FUNCTION, "entering\n");
-
- g_assert (man != NULL && YELP_IS_MAN (man));
- g_object_ref (man);
- priv = man->priv;
- document = YELP_DOCUMENT (man);
-
- 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;
- }
-
- /* FIXME: get the language */
- language = "C";
-
- /* default encoding if the language doesn't match below */
- encoding = g_getenv("MAN_ENCODING");
- if (encoding == NULL)
- encoding = "ISO-8859-1";
-
- if (language != NULL) {
- for (i = 0; langmap[i].language != NULL; i++) {
- if (g_str_equal (language, langmap[i].language)) {
- encoding = langmap[i].encoding;
- break;
- }
- }
- }
-
- parser = yelp_man_parser_new ();
- priv->xmldoc = yelp_man_parser_parse_file (parser, priv->filename, encoding);
- yelp_man_parser_free (parser);
-
- if (priv->xmldoc == NULL) {
- error = yelp_error_new (_("Could not parse file"),
- _("The file ‘%s’ could not be parsed because it is"
- " not a well-formed man page."),
- priv->filename);
- yelp_document_error_pending (document, error);
- }
-
- g_mutex_lock (priv->mutex);
- if (priv->state == MAN_STATE_STOP) {
- g_mutex_unlock (priv->mutex);
- goto done;
- }
-
- priv->transform = yelp_transform_new (STYLESHEET,
- (YelpTransformFunc) transform_func,
- man);
- priv->transform_running = TRUE;
-
- params = g_new0 (gchar *, params_max);
- yelp_settings_params (&params, &params_i, &params_max);
-
- params[params_i] = NULL;
-
- yelp_transform_start (priv->transform,
- priv->xmldoc,
- params);
- g_strfreev (params);
- g_mutex_unlock (priv->mutex);
-
- done:
- priv->process_running = FALSE;
- g_object_unref (man);
-}
diff --git a/src/yelp-man.h b/src/yelp-man.h
deleted file mode 100644
index 844c44ab..00000000
--- a/src/yelp-man.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * Copyright (C) 2007 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>
- */
-
-#ifndef __YELP_MAN_H__
-#define __YELP_MAN_H__
-
-#include <glib-object.h>
-
-#include "yelp-document.h"
-
-#define YELP_TYPE_MAN (yelp_man_get_type ())
-#define YELP_MAN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_MAN, YelpMan))
-#define YELP_MAN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_MAN, YelpManClass))
-#define YELP_IS_MAN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_MAN))
-#define YELP_IS_MAN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_MAN))
-#define YELP_MAN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_MAN, YelpManClass))
-
-typedef struct _YelpMan YelpMan;
-typedef struct _YelpManClass YelpManClass;
-typedef struct _YelpManPriv YelpManPriv;
-
-struct _YelpMan {
- YelpDocument parent;
- YelpManPriv *priv;
-};
-
-struct _YelpManClass {
- YelpDocumentClass parent_class;
-};
-
-GType yelp_man_get_type (void);
-YelpDocument * yelp_man_new (gchar *uri);
-
-#endif /* __YELP_MAN_H__ */
diff --git a/stylesheets/Makefile.am b/stylesheets/Makefile.am
index 996b0d07..f64d28fa 100644
--- a/stylesheets/Makefile.am
+++ b/stylesheets/Makefile.am
@@ -18,5 +18,6 @@ EXTRA_DIST= \
db-title.xsl.in \
info2html.xsl.in \
mal2html.xsl.in \
+ man2html.xsl.in \
toc2html.xsl.in \
yelp-common.xsl.in
diff --git a/stylesheets/man2html.xsl b/stylesheets/man2html.xsl.in
index e3dd0654..5a028edf 100644
--- a/stylesheets/man2html.xsl
+++ b/stylesheets/man2html.xsl.in
@@ -6,86 +6,40 @@
extension-element-prefixes="yelp"
version="1.0">
-<xsl:output method="html" encoding="UTF-8"/>
-
+<xsl:import href="@XSL_GETTEXT@"/>
+<xsl:import href="@XSL_COLOR@"/>
+<xsl:import href="@XSL_ICONS@"/>
+<xsl:import href="@XSL_HTML@"/>
<xsl:include href="yelp-common.xsl"/>
-<xsl:param name="stylesheet_path" select="''"/>
-<xsl:param name="linktrail"/>
-
-<xsl:param name="yelp.javascript"/>
-
-<xsl:param name="yelp.icon.blockquote"/>
-<xsl:param name="yelp.icon.caution"/>
-<xsl:param name="yelp.icon.important"/>
-<xsl:param name="yelp.icon.note"/>
-<xsl:param name="yelp.icon.programlisting"/>
-<xsl:param name="yelp.icon.tip"/>
-<xsl:param name="yelp.icon.warning"/>
-
-<xsl:param name="theme.color.text"/>
-<xsl:param name="theme.color.background"/>
-<xsl:param name="theme.color.text_light"/>
-<xsl:param name="theme.color.link"/>
-<xsl:param name="theme.color.link_visited"/>
-<xsl:param name="theme.color.gray_background"/>
-<xsl:param name="theme.color.gray_border"/>
-<xsl:param name="theme.color.blue_background"/>
-<xsl:param name="theme.color.blue_border"/>
-<xsl:param name="theme.color.red_background"/>
-<xsl:param name="theme.color.red_border"/>
-<xsl:param name="theme.color.yellow_background"/>
-<xsl:param name="theme.color.yellow_border"/>
-
-<xsl:template match="Man">
- <xsl:choose>
- <xsl:when test="element-available('yelp:document')">
- <yelp:document href="index">
- <xsl:call-template name="html"/>
- </yelp:document>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="html"/>
- </xsl:otherwise>
- </xsl:choose>
+<xsl:param name="html.basename" select="'//index'"/>
+
+<xsl:param name="linktrail" select="''"/>
+
+<xsl:template mode="html.title.mode" match="Man">
+ <xsl:value-of select="//TH/Title"/>
</xsl:template>
-<xsl:template name="html">
- <html>
- <head>
- <title>
- <xsl:value-of select="//TH/Title"/>
- </title>
- <style type="text/css">
- <xsl:call-template name="html.css"/>
- </style>
- <script type="text/javascript">
- <xsl:attribute name="src">
- <xsl:value-of select="concat('file://', $yelp.javascript)"/>
- </xsl:attribute>
- </script>
- </head>
- <body>
- <xsl:call-template name="html.linktrail"/>
- <div class="body">
- <xsl:apply-templates select="TH"/>
- <xsl:apply-templates select="SH"/>
- </div>
- </body>
- </html>
-</xsl:template>
-
-<xsl:template name="html.css">
- <xsl:call-template name="yelp.common.css"/>
- <xsl:text>
- div[class~="SH"] { margin-left: 1.2em; }
- div[class~="SS"] { margin-left: 1.6em; }
-
- span[class~="R"] { font-family: serif; }
- span[class~="Section"] { margin-left: 0.4em; }
-
- dd { padding-bottom: 10px; }
- </xsl:text>
+<xsl:template mode="html.css.mode" match="Man">
+ <xsl:param name="direction"/>
+ <xsl:param name="left"/>
+ <xsl:param name="right"/>
+<xsl:text>
+body { font-family: monospace; }
+div.SH { margin-</xsl:text><xsl:value-of select="$left"/><xsl:text>: 1.2em; }
+div.SS { margin-</xsl:text><xsl:value-of select="$left"/><xsl:text>: 1.6em; }
+span.Section { margin-</xsl:text><xsl:value-of select="$left"/><xsl:text>: 0.4em; }
+dd { padding-bottom: 10px; }
+</xsl:text>
+</xsl:template>
+
+<xsl:template mode="html.header.mode" match="Man">
+ <xsl:call-template name="html.linktrail"/>
+</xsl:template>
+
+<xsl:template mode="html.body.mode" match="Man">
+ <xsl:apply-templates select="TH"/>
+ <xsl:apply-templates select="SH"/>
</xsl:template>
<xsl:template name="html.linktrail">
diff --git a/stylesheets/yelp-common.xsl.in b/stylesheets/yelp-common.xsl.in
index 6d6f8919..306ce446 100644
--- a/stylesheets/yelp-common.xsl.in
+++ b/stylesheets/yelp-common.xsl.in
@@ -30,7 +30,7 @@
</xsl:otherwise>
</xsl:choose>
</xsl:param>
- <yelp:document href="{$node/@id}">
+ <yelp:document href="{$href}">
<xsl:call-template name="html.page">
<xsl:with-param name="node" select="$node"/>
</xsl:call-template>