[libgepub] Function to replace relative resources by epub://
- From: Daniel Garcia Moreno <danigm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgepub] Function to replace relative resources by epub://
- Date: Sat, 11 Jun 2016 10:05:54 +0000 (UTC)
commit d86cbb44bb1a8f5d00a411b591183cae71fd0d6f
Author: Daniel Garcia Moreno <danigm wadobo com>
Date: Sat Jun 11 11:59:37 2016 +0200
Function to replace relative resources by epub://
Resources like styles or images are linked inside the xml doc with a
relative path using as base the doc path.
To render these resources in widgets like webkit this new function replaces
with a the scheme, epub://, and converts these paths from relative to
absolute so we can find these resources easily with the get_resource
function.
TODO | 2 +
configure.ac | 2 +
libgepub/gepub-doc.c | 36 ++++++++++++++++++-----
libgepub/gepub-doc.h | 43 ++++++++++++++--------------
libgepub/gepub-utils.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
libgepub/gepub-utils.h | 5 ++-
tests/test-gepub.c | 12 ++++++++
7 files changed, 142 insertions(+), 31 deletions(-)
---
diff --git a/TODO b/TODO
index e69de29..6ff37cf 100644
--- a/TODO
+++ b/TODO
@@ -0,0 +1,2 @@
+ - support for multi-page display: get_current_next() or get_current_nth()
+ to the the page nth
diff --git a/configure.ac b/configure.ac
index 5bbf804..3a9d85a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,6 +17,7 @@ AC_PROG_INSTALL
AC_PROG_LIBTOOL
PKG_CHECK_MODULES(GEPUB,
+ libsoup-2.4
glib-2.0
gobject-2.0
gio-2.0
@@ -27,6 +28,7 @@ AC_SUBST(GEPUB_CFLAGS)
AC_SUBST(GEPUB_LIBS)
PKG_CHECK_MODULES(GEPUB_TESTS,
+ libsoup-2.4
glib-2.0
gobject-2.0
gtk+-3.0
diff --git a/libgepub/gepub-doc.c b/libgepub/gepub-doc.c
index 1729b16..001911f 100644
--- a/libgepub/gepub-doc.c
+++ b/libgepub/gepub-doc.c
@@ -467,6 +467,32 @@ gepub_doc_get_current (GepubDoc *doc, gsize *bufsize)
}
/**
+ * gepub_doc_get_current_with_epub_uris:
+ * @doc: a #GepubDoc
+ * @bufsize: (out): location to store the length in bytes of the contents
+ *
+ * Returns: (array length=bufsize) (transfer full): the current chapter
+ * data, with resource uris renamed so they have the epub:// prefix and all
+ * are relative to the root file
+ */
+guchar *
+gepub_doc_get_current_with_epub_uris (GepubDoc *doc, gsize *bufsize)
+{
+ guchar *content = gepub_doc_get_current (doc, bufsize);
+ guchar *replaced = NULL;
+ gchar *path = gepub_doc_get_current_path (doc);
+ // getting the basepath of the current xhtml loaded
+ gchar *base = g_path_get_dirname (path);
+
+ replaced = gepub_utils_replace_resources (content, bufsize, base);
+
+ g_free (path);
+ g_free (content);
+
+ return replaced;
+}
+
+/**
* gepub_doc_get_text:
* @doc: a #GepubDoc
*
@@ -615,18 +641,12 @@ gchar *gepub_doc_get_resource_path (GepubDoc *doc, gchar *id)
}
/**
- * gepub_doc_get_resource_path:
+ * gepub_doc_get_current_path:
* @doc: a #GepubDoc
*
* Returns: (transfer full): the current resource path
*/
gchar *gepub_doc_get_current_path (GepubDoc *doc)
{
- GepubResource *gres = g_hash_table_lookup (doc->resources, doc->spine->data);
- if (!gres) {
- // not found
- return NULL;
- }
-
- return g_strdup (gres->uri);
+ return gepub_doc_get_resource_path (doc, doc->spine->data);
}
diff --git a/libgepub/gepub-doc.h b/libgepub/gepub-doc.h
index b399545..cb03101 100644
--- a/libgepub/gepub-doc.h
+++ b/libgepub/gepub-doc.h
@@ -42,27 +42,28 @@ struct _GepubResource {
typedef struct _GepubResource GepubResource;
-GType gepub_doc_get_type (void) G_GNUC_CONST;
-
-GepubDoc *gepub_doc_new (const gchar *path);
-gchar *gepub_doc_get_content (GepubDoc *doc);
-gchar *gepub_doc_get_metadata (GepubDoc *doc, gchar *mdata);
-guchar *gepub_doc_get_resource (GepubDoc *doc, gchar *id, gsize *bufsize);
-guchar *gepub_doc_get_resource_v (GepubDoc *doc, gchar *v, gsize *bufsize);
-GHashTable *gepub_doc_get_resources (GepubDoc *doc);
-gchar *gepub_doc_get_resource_mime (GepubDoc *doc, gchar *v);
-gchar *gepub_doc_get_resource_mime_by_id (GepubDoc *doc, gchar *id);
-gchar *gepub_doc_get_current_mime (GepubDoc *doc);
-GList *gepub_doc_get_spine (GepubDoc *doc);
-GList *gepub_doc_get_text (GepubDoc *doc);
-GList *gepub_doc_get_text_by_id (GepubDoc *doc, gchar *id);
-void gepub_doc_free_text (GList *tlist);
-guchar *gepub_doc_get_current (GepubDoc *doc, gsize *bufsize);
-gboolean gepub_doc_go_next (GepubDoc *doc);
-gboolean gepub_doc_go_prev (GepubDoc *doc);
-gchar *gepub_doc_get_cover (GepubDoc *doc);
-gchar *gepub_doc_get_resource_path (GepubDoc *doc, gchar *id);
-gchar *gepub_doc_get_current_path (GepubDoc *doc);
+GType gepub_doc_get_type (void) G_GNUC_CONST;
+
+GepubDoc *gepub_doc_new (const gchar *path);
+gchar *gepub_doc_get_content (GepubDoc *doc);
+gchar *gepub_doc_get_metadata (GepubDoc *doc, gchar *mdata);
+guchar *gepub_doc_get_resource (GepubDoc *doc, gchar *id, gsize *bufsize);
+guchar *gepub_doc_get_resource_v (GepubDoc *doc, gchar *v, gsize *bufsize);
+GHashTable *gepub_doc_get_resources (GepubDoc *doc);
+gchar *gepub_doc_get_resource_mime (GepubDoc *doc, gchar *v);
+gchar *gepub_doc_get_resource_mime_by_id (GepubDoc *doc, gchar *id);
+gchar *gepub_doc_get_current_mime (GepubDoc *doc);
+GList *gepub_doc_get_spine (GepubDoc *doc);
+GList *gepub_doc_get_text (GepubDoc *doc);
+GList *gepub_doc_get_text_by_id (GepubDoc *doc, gchar *id);
+void gepub_doc_free_text (GList *tlist);
+guchar *gepub_doc_get_current (GepubDoc *doc, gsize *bufsize);
+guchar *gepub_doc_get_current_with_epub_uris (GepubDoc *doc, gsize *bufsize);
+gboolean gepub_doc_go_next (GepubDoc *doc);
+gboolean gepub_doc_go_prev (GepubDoc *doc);
+gchar *gepub_doc_get_cover (GepubDoc *doc);
+gchar *gepub_doc_get_resource_path (GepubDoc *doc, gchar *id);
+gchar *gepub_doc_get_current_path (GepubDoc *doc);
G_END_DECLS
diff --git a/libgepub/gepub-utils.c b/libgepub/gepub-utils.c
index b76d2ee..645224e 100644
--- a/libgepub/gepub-utils.c
+++ b/libgepub/gepub-utils.c
@@ -16,13 +16,59 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <libsoup/soup.h>
+
#include <libxml/tree.h>
+#include <libxml/parser.h>
#include <stdarg.h>
#include <string.h>
#include "gepub-utils.h"
#include "gepub-text-chunk.h"
+
+/**
+ * Replaces the attr value with epub:// prefix for the tagname. This
+ * function also makes the resource absolute based on the epub root
+ */
+static void
+set_epub_uri (xmlNode *node, gchar *path, gchar *tagname, gchar *attr)
+{
+ xmlNode *cur_node = NULL;
+ xmlNode *ret = NULL;
+ xmlChar *text = NULL;
+
+ SoupURI *baseURI;
+ gchar *basepath = g_strdup_printf ("epub://%s", path);
+
+ baseURI = soup_uri_new (basepath);
+ g_free (basepath);
+
+ for (cur_node = node; cur_node; cur_node = cur_node->next) {
+ if (cur_node->type == XML_ELEMENT_NODE ) {
+ text = xmlGetProp (cur_node, attr);
+ if (!strcmp (cur_node->name, tagname) && text) {
+ SoupURI *uri = soup_uri_new_with_base (baseURI, text);
+ gchar *value = soup_uri_to_string (uri, FALSE);
+
+ xmlSetProp (cur_node, attr, value);
+
+ soup_uri_free (uri);
+ g_free (value);
+ }
+ if (text) {
+ xmlFree (text);
+ text = NULL;
+ }
+ }
+
+ if (cur_node->children)
+ set_epub_uri (cur_node->children, path, tagname, attr);
+ }
+
+ soup_uri_free (baseURI);
+}
+
gboolean
gepub_utils_has_parent_tag (xmlNode *node, gchar *name, ...)
{
@@ -150,3 +196,30 @@ gepub_utils_get_text_elements (xmlNode *node)
return text_list;
}
+
+/**
+ * replacing epub media paths, for css, image and svg files, to be
+ * able to provide these files to webkit from the epub file
+ **/
+guchar *
+gepub_utils_replace_resources (guchar *content, gsize *bufsize, gchar *path)
+{
+ xmlDoc *doc = NULL;
+ xmlNode *root_element = NULL;
+ guchar *buffer;
+
+ doc = xmlRecoverDoc (content);
+ root_element = xmlDocGetRootElement (doc);
+
+ // replacing css resources
+ set_epub_uri (root_element, path, "link", "href");
+ // replacing images resources
+ set_epub_uri (root_element, path, "img", "src");
+ // replacing svg images resources
+ set_epub_uri (root_element, path, "image", "xlink:href");
+
+ xmlDocDumpFormatMemory (doc, (xmlChar**)&buffer, (int*)bufsize, 1);
+ xmlFreeDoc (doc);
+
+ return buffer;
+}
diff --git a/libgepub/gepub-utils.h b/libgepub/gepub-utils.h
index 0abe2e6..1d51607 100644
--- a/libgepub/gepub-utils.h
+++ b/libgepub/gepub-utils.h
@@ -22,8 +22,9 @@
#include <glib.h>
#include <libxml/tree.h>
-xmlNode * gepub_utils_get_element_by_tag (xmlNode *node, gchar *name);
+xmlNode * gepub_utils_get_element_by_tag (xmlNode *node, gchar *name);
xmlNode * gepub_utils_get_element_by_attr (xmlNode *node, gchar *attr, gchar *value);
-GList * gepub_utils_get_text_elements (xmlNode *node);
+GList * gepub_utils_get_text_elements (xmlNode *node);
+guchar * gepub_utils_replace_resources (guchar *content, gsize *bufsize, gchar *path);
#endif
diff --git a/tests/test-gepub.c b/tests/test-gepub.c
index e11b866..55c4bee 100644
--- a/tests/test-gepub.c
+++ b/tests/test-gepub.c
@@ -53,6 +53,17 @@ update_text (GepubDoc *doc)
}
void
+print_replaced_text (GepubDoc *doc)
+{
+ gsize s = 0;
+ guchar *content = NULL;
+ content = gepub_doc_get_current_with_epub_uris (doc, &s);
+
+ printf ("\n\nREPLACED:\n%s\n", content);
+ g_free (content);
+}
+
+void
button_pressed (GtkButton *button, GepubDoc *doc)
{
if (!strcmp (gtk_button_get_label (button), "prev")) {
@@ -61,6 +72,7 @@ button_pressed (GtkButton *button, GepubDoc *doc)
gepub_doc_go_next (doc);
}
update_text (doc);
+ print_replaced_text (doc);
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]