summaryrefslogtreecommitdiff
path: root/backend/epub/epub-document.c
diff options
context:
space:
mode:
Diffstat (limited to 'backend/epub/epub-document.c')
-rw-r--r--backend/epub/epub-document.c1831
1 files changed, 0 insertions, 1831 deletions
diff --git a/backend/epub/epub-document.c b/backend/epub/epub-document.c
deleted file mode 100644
index c0fa275b..00000000
--- a/backend/epub/epub-document.c
+++ /dev/null
@@ -1,1831 +0,0 @@
-/* this file is part of atril, a mate document viewer
- *
- * Copyright (C) 2014 Avishkar Gupta
- *
- * Author:
- * Avishkar Gupta <[email protected]>
- *
- * Atril 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.
- *
- * Atril 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "epub-document.h"
-#include "ev-file-helpers.h"
-#include "unzip.h"
-#include "ev-document-thumbnails.h"
-#include "ev-document-find.h"
-#include "ev-backends-manager.h"
-#include "ev-document-links.h"
-#include "ev-document-misc.h"
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/HTMLparser.h>
-#include <config.h>
-
-#include <glib/gi18n.h>
-#include <glib/gstdio.h>
-
-#include <gtk/gtk.h>
-
-/*For strcasestr(),strstr()*/
-#include <string.h>
-
-typedef enum _xmlParseReturnType
-{
- XML_ATTRIBUTE,
- XML_KEYWORD
-}xmlParseReturnType;
-
-typedef struct _contentListNode {
- gchar* key ;
- gchar* value ;
- gint index ;
-}contentListNode;
-
-typedef struct _linknode {
- gchar *pagelink;
- GList *children;
- gchar *linktext;
- guint page;
-}linknode;
-
-typedef struct _EpubDocumentClass EpubDocumentClass;
-
-struct _EpubDocumentClass
-{
- EvDocumentClass parent_class;
-};
-
-struct _EpubDocument
-{
- EvDocument parent_instance;
- /*Stores the path to the source archive*/
- gchar* archivename ;
- /*Stores the path of the directory where we unzipped the epub*/
- gchar* tmp_archive_dir ;
- /*Stores the contentlist in a sorted manner*/
- GList* contentList ;
- /* A variable to hold our epubDocument for unzipping*/
- unzFile epubDocument ;
- /*The (sub)directory that actually houses the document*/
- gchar* documentdir;
- /*Stores the table of contents*/
- GList *index;
- /*Document title, for the sidebar links*/
- gchar *docTitle;
-};
-
-static void epub_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface);
-static void epub_document_document_find_iface_init (EvDocumentFindInterface *iface);
-static void epub_document_document_links_iface_init (EvDocumentLinksInterface *iface);
-
-EV_BACKEND_REGISTER_WITH_CODE (EpubDocument, epub_document,
- {
- EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,
- epub_document_document_thumbnails_iface_init);
- EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
- epub_document_document_find_iface_init);
- EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_LINKS,
- epub_document_document_links_iface_init);
-
- } );
-
-static void
-epub_document_thumbnails_get_dimensions (EvDocumentThumbnails *document,
- EvRenderContext *rc,
- gint *width,
- gint *height)
-{
- gdouble page_width, page_height;
-
- page_width = 800;
- page_height = 1080;
-
- *width = MAX ((gint)(page_width * rc->scale + 0.5), 1);
- *height = MAX ((gint)(page_height * rc->scale + 0.5), 1);
-}
-
-static GdkPixbuf *
-epub_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document,
- EvRenderContext *rc,
- gboolean border)
-{
- cairo_surface_t *webpage;
- GdkPixbuf *thumbnailpix = NULL ;
- gint width,height;
- epub_document_thumbnails_get_dimensions (document, rc, &width, &height);
- webpage = ev_document_misc_surface_rotate_and_scale (rc->page->backend_page,
- width, height, 0);
- thumbnailpix = ev_document_misc_pixbuf_from_surface (webpage);
- return thumbnailpix;
-}
-
-static gboolean
-in_tag(const char* found)
-{
- const char* bracket = found ;
-
- /* Since the dump started with the body tag, the '<' will be the first
- * character in the haystack.
- */
- while (*bracket != '<') {
- bracket--;
- if (*bracket == '>') {
- /*We encounted a close brace before an open*/
- return FALSE ;
- }
- }
-
- return TRUE;
-}
-
-static int
-get_substr_count(const char * haystack,const char *needle,gboolean case_sensitive)
-{
- const char* tmp = haystack ;
- char* (*string_compare_function)(const char*,const char*);
- int count=0;
- if (case_sensitive) {
- string_compare_function = strstr ;
- }
- else {
- string_compare_function = strcasestr;
- }
-
- while ((tmp=string_compare_function(tmp,needle))) {
- if (!in_tag(tmp)) {
- count++;
- }
- tmp = tmp + strlen(needle);
- }
-
- return count;
-}
-
-static guint
-epub_document_check_hits(EvDocumentFind *document_find,
- EvPage *page,
- const gchar *text,
- gboolean case_sensitive)
-{
- gchar *filepath = g_filename_from_uri((gchar*)page->backend_page,NULL,NULL);
- htmlDocPtr htmldoc = xmlParseFile(filepath);
- htmlNodePtr htmltag = xmlDocGetRootElement(htmldoc);
- int count=0;
- htmlNodePtr bodytag = htmltag->xmlChildrenNode;
-
- while ( xmlStrcmp(bodytag->name,(xmlChar*)"body") ) {
- bodytag = bodytag->next;
- }
-
- xmlBufferPtr bodybuffer = xmlBufferCreate();
- xmlNodeDump(bodybuffer,htmldoc,bodytag,0,1);
-
- count = get_substr_count((char*)bodybuffer->content,text,case_sensitive);
-
- xmlBufferFree(bodybuffer);
- xmlFreeDoc(htmldoc);
- g_free (filepath);
-
- return count;
-}
-
-static gboolean
-epub_document_links_has_document_links(EvDocumentLinks *document_links)
-{
- EpubDocument *epub_document = EPUB_DOCUMENT(document_links);
-
- g_return_val_if_fail(EPUB_IS_DOCUMENT(epub_document), FALSE);
-
- if (!epub_document->index)
- return FALSE;
-
- return TRUE;
-}
-
-
-typedef struct _LinksCBStruct {
- GtkTreeModel *model;
- GtkTreeIter *parent;
-}LinksCBStruct;
-
-static void
-epub_document_make_tree_entry(linknode* ListData,LinksCBStruct* UserData)
-{
- GtkTreeIter tree_iter;
- EvLink *link = NULL;
- gboolean expand;
- char *title_markup;
-
- if (ListData->children) {
- expand=TRUE;
- }
- else {
- expand=FALSE;
- }
-
- EvLinkDest *ev_dest = NULL;
- EvLinkAction *ev_action;
-
- /* We shall use a EV_LINK_DEST_TYPE_PAGE for page links,
- * and a EV_LINK_DEST_TYPE_HLINK(custom) for refs on a page of type url#label
- * because we need both dest and page label for this.
- */
-
- if (g_strrstr(ListData->pagelink,"#") == NULL) {
- ev_dest = ev_link_dest_new_page(ListData->page);
- }
- else {
- ev_dest = ev_link_dest_new_hlink((gchar*)ListData->pagelink,ListData->page);
- }
-
- ev_action = ev_link_action_new_dest (ev_dest);
-
- link = ev_link_new((gchar*)ListData->linktext,ev_action);
-
- gtk_tree_store_append (GTK_TREE_STORE (UserData->model), &tree_iter,(UserData->parent));
- title_markup = g_strdup((gchar*)ListData->linktext);
-
- gtk_tree_store_set (GTK_TREE_STORE (UserData->model), &tree_iter,
- EV_DOCUMENT_LINKS_COLUMN_MARKUP, title_markup,
- EV_DOCUMENT_LINKS_COLUMN_LINK, link,
- EV_DOCUMENT_LINKS_COLUMN_EXPAND, expand,
- -1);
-
- if (ListData->children) {
- LinksCBStruct cbstruct;
- cbstruct.parent = &tree_iter;
- cbstruct.model = UserData->model;
- g_list_foreach (ListData->children,(GFunc)epub_document_make_tree_entry,&cbstruct);
- }
-
- g_free (title_markup);
- g_object_unref (link);
-}
-
-static GtkTreeModel *
-epub_document_links_get_links_model(EvDocumentLinks *document_links)
-{
- GtkTreeModel *model = NULL;
-
- g_return_val_if_fail (EPUB_IS_DOCUMENT (document_links), NULL);
-
- EpubDocument *epub_document = EPUB_DOCUMENT(document_links);
-
- model = (GtkTreeModel*) gtk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS,
- G_TYPE_STRING,
- G_TYPE_OBJECT,
- G_TYPE_BOOLEAN,
- G_TYPE_STRING);
-
- LinksCBStruct linkStruct;
- linkStruct.model = model;
- EvLink *link = ev_link_new(epub_document->docTitle,
- ev_link_action_new_dest(ev_link_dest_new_page(0)));
- GtkTreeIter parent;
-
- linkStruct.parent = &parent;
-
- gtk_tree_store_append (GTK_TREE_STORE (model), &parent,NULL);
-
- gtk_tree_store_set (GTK_TREE_STORE (model), &parent,
- EV_DOCUMENT_LINKS_COLUMN_MARKUP, epub_document->docTitle,
- EV_DOCUMENT_LINKS_COLUMN_LINK, link,
- EV_DOCUMENT_LINKS_COLUMN_EXPAND, TRUE,
- -1);
-
- g_object_unref(link);
-
- if (epub_document->index) {
- g_list_foreach (epub_document->index,(GFunc)epub_document_make_tree_entry,&linkStruct);
- }
-
- return model;
-}
-
-static EvMappingList *
-epub_document_links_get_links (EvDocumentLinks *document_links,
- EvPage *page)
-{
- /* TODO
- * ev_mapping_list_new()
- */
- return NULL;
-}
-
-static void
-epub_document_document_thumbnails_iface_init (EvDocumentThumbnailsInterface *iface)
-{
- iface->get_thumbnail = epub_document_thumbnails_get_thumbnail;
- iface->get_dimensions = epub_document_thumbnails_get_dimensions;
-}
-
-static void
-epub_document_document_find_iface_init (EvDocumentFindInterface *iface)
-{
- iface->check_for_hits = epub_document_check_hits;
-}
-
-static void
-epub_document_document_links_iface_init(EvDocumentLinksInterface *iface)
-{
- iface->has_document_links = epub_document_links_has_document_links;
- iface->get_links_model = epub_document_links_get_links_model;
- iface->get_links = epub_document_links_get_links;
-}
-
-static gboolean
-epub_document_save (EvDocument *document,
- const char *uri,
- GError **error)
-{
- EpubDocument *epub_document = EPUB_DOCUMENT (document);
-
- gchar *source_uri = g_filename_to_uri (epub_document->archivename, NULL, error);
- if (source_uri == NULL)
- return FALSE;
-
- return ev_xfer_uri_simple (source_uri, uri, error);
-}
-
-static int
-epub_document_get_n_pages (EvDocument *document)
-{
- EpubDocument *epub_document = EPUB_DOCUMENT (document);
-
- if (epub_document-> contentList == NULL)
- return 0;
-
- return g_list_length(epub_document->contentList);
-}
-
-/**
- * epub_remove_temporary_dir : Removes a directory recursively.
- * This function is same as comics_remove_temporary_dir
- * Returns:
- * 0 if it was successfully deleted,
- * -1 if an error occurred
- */
-static int
-epub_remove_temporary_dir (gchar *path_name)
-{
- GDir *content_dir;
- const gchar *filename;
- gchar *filename_with_path;
-
- if (g_file_test (path_name, G_FILE_TEST_IS_DIR)) {
- content_dir = g_dir_open (path_name, 0, NULL);
- filename = g_dir_read_name (content_dir);
- while (filename) {
- filename_with_path =
- g_build_filename (path_name,
- filename, NULL);
- epub_remove_temporary_dir (filename_with_path);
- g_free (filename_with_path);
- filename = g_dir_read_name (content_dir);
- }
- g_dir_close (content_dir);
- }
- /* Note from g_remove() documentation: on Windows, it is in general not
- * possible to remove a file that is open to some process, or mapped
- * into memory.*/
- return (g_remove (path_name));
-}
-
-
-static gboolean
-check_mime_type (const gchar* uri,
- GError** error);
-
-static gboolean
-open_xml_document (const gchar* filename);
-
-static gboolean
-set_xml_root_node (xmlChar* rootname);
-
-static xmlNodePtr
-xml_get_pointer_to_node (xmlChar* parserfor,
- xmlChar* attributename,
- xmlChar* attributevalue);
-static void
-xml_parse_children_of_node (xmlNodePtr parent,
- xmlChar* parserfor,
- xmlChar* attributename,
- xmlChar* attributevalue);
-
-static gboolean
-xml_check_attribute_value (xmlNode* node,
- xmlChar * attributename,
- xmlChar* attributevalue);
-
-static xmlChar*
-xml_get_data_from_node (xmlNodePtr node,
- xmlParseReturnType rettype,
- xmlChar* attributename);
-
-static void
-xml_free_doc();
-
-static void
-free_tree_nodes (gpointer data);
-
-/*Global variables for XML parsing*/
-static xmlDocPtr xmldocument ;
-static xmlNodePtr xmlroot ;
-static xmlNodePtr xmlretval ;
-
-/*
-**Functions to parse the xml files.
-**Open a XML document for reading
-*/
-static gboolean
-open_xml_document ( const gchar* filename )
-{
- xmldocument = xmlParseFile(filename);
-
- if ( xmldocument == NULL )
- {
- return FALSE ;
- }
- else
- {
- return TRUE ;
- }
-}
-
-/**
- *Check if the root value is same as rootname .
- *if supplied rootvalue = NULL ,just set root to rootnode .
-**/
-static gboolean
-set_xml_root_node(xmlChar* rootname)
-{
- xmlroot = xmlDocGetRootElement(xmldocument);
-
- if (xmlroot == NULL) {
-
- xmlFreeDoc(xmldocument);
- return FALSE;
- }
-
- if ( rootname == NULL )
- {
- return TRUE ;
- }
-
- if ( !xmlStrcmp(xmlroot->name,rootname))
- {
- return TRUE ;
- }
- else
- {
- return FALSE;
- }
-}
-
-static xmlNodePtr
-xml_get_pointer_to_node(xmlChar* parserfor,
- xmlChar* attributename,
- xmlChar* attributevalue )
-{
- xmlNodePtr topchild,children ;
-
- xmlretval = NULL ;
-
- if ( !xmlStrcmp( xmlroot->name, parserfor) )
- {
- return xmlroot ;
- }
-
- topchild = xmlroot->xmlChildrenNode ;
-
- while ( topchild != NULL )
- {
- if ( !xmlStrcmp(topchild->name,parserfor) )
- {
- if ( xml_check_attribute_value(topchild,attributename,attributevalue) == TRUE )
- {
- xmlretval = topchild;
- return xmlretval;
- }
- else
- {
- /*No need to parse children node*/
- topchild = topchild->next ;
- continue ;
- }
- }
-
- xml_parse_children_of_node(topchild , parserfor, attributename, attributevalue) ;
-
- topchild = topchild->next ;
- }
-
- return xmlretval ;
-}
-
-static void
-xml_parse_children_of_node(xmlNodePtr parent,
- xmlChar* parserfor,
- xmlChar* attributename,
- xmlChar* attributevalue )
-{
- xmlNodePtr child = parent->xmlChildrenNode ;
-
- while ( child != NULL )
- {
- if ( !xmlStrcmp(child->name,parserfor))
- {
- if ( xml_check_attribute_value(child,attributename,attributevalue) == TRUE )
- {
- xmlretval = child;
- return ;
- }
- else
- {
- /*No need to parse children node*/
- child = child->next ;
- continue ;
- }
- }
-
- /*return already if we have xmlretval set*/
- if ( xmlretval != NULL )
- {
- return ;
- }
-
- xml_parse_children_of_node(child,parserfor,attributename,attributevalue) ;
- child = child->next ;
- }
-}
-
-static void
-xml_free_doc()
-{
- xmlFreeDoc(xmldocument);
- xmldocument = NULL;
-}
-
-static gboolean
-xml_check_attribute_value(xmlNode* node,
- xmlChar * attributename,
- xmlChar* attributevalue)
-{
- xmlChar* attributefromfile ;
- if ( attributename == NULL || attributevalue == NULL )
- {
- return TRUE ;
- }
- else if ( !xmlStrcmp(( attributefromfile = xmlGetProp(node,attributename)),
- attributevalue) )
- {
- xmlFree(attributefromfile);
- return TRUE ;
- }
- xmlFree(attributefromfile);
- return FALSE ;
-}
-
-static xmlChar*
-xml_get_data_from_node(xmlNodePtr node,
- xmlParseReturnType rettype,
- xmlChar* attributename)
-{
- xmlChar* datastring ;
- if ( rettype == XML_ATTRIBUTE )
- datastring= xmlGetProp(node,attributename);
- else
- datastring= xmlNodeListGetString(xmldocument,node->xmlChildrenNode, 1);
-
- return datastring;
-}
-
-static gboolean
-check_mime_type(const gchar* uri,GError** error)
-{
- GError * err = NULL ;
- const gchar* mimeFromFile = ev_file_get_mime_type(uri,FALSE,&err);
-
- gchar* mimetypes[] = {"application/epub+zip","application/x-booki+zip"};
- int typecount = 2;
- if ( !mimeFromFile )
- {
- if (err) {
- g_propagate_error (error, err);
- }
- else {
- g_set_error_literal (error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("Unknown MIME Type"));
- }
- return FALSE;
- }
- else
- {
- int i=0;
- for (i=0; i < typecount ;i++) {
- if ( g_strcmp0(mimeFromFile, mimetypes[i]) == 0 ) {
- return TRUE;
- }
- }
-
- /*We didn't find a match*/
- g_set_error_literal (error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("Not an ePub document"));
-
- return FALSE;
- }
-}
-
-static gboolean
-extract_one_file(EpubDocument* epub_document,GError ** error)
-{
- GFile * outfile ;
- gsize writesize = 0;
- GString * gfilepath ;
- unz_file_info64 info ;
- gchar* directory;
- GString* dir_create;
- GFileOutputStream * outstream ;
-
- if ( unzOpenCurrentFile(epub_document->epubDocument) != UNZ_OK )
- {
- return FALSE ;
- }
-
- gboolean result = TRUE;
-
- gpointer currentfilename = g_malloc0(512);
- unzGetCurrentFileInfo64(epub_document->epubDocument,&info,currentfilename,512,NULL,0,NULL,0) ;
- directory = g_strrstr(currentfilename,"/") ;
-
- if ( directory != NULL )
- directory++;
-
- gfilepath = g_string_new(epub_document->tmp_archive_dir) ;
- g_string_append_printf(gfilepath,"/%s",(gchar*)currentfilename);
-
- /*if we encounter a directory, make a directory inside our temporary folder.*/
- if (directory != NULL && *directory == '\0')
- {
- g_mkdir(gfilepath->str,0777);
- goto out;
- }
- else if (directory != NULL && *directory != '\0' ) {
- gchar* createdir = currentfilename;
- /*Since a substring can't be longer than the parent string, allocating space equal to the parent's size should suffice*/
- gchar *createdirname = g_malloc0(strlen(currentfilename));
- /* Add the name of the directory and subdirectories,if any to a buffer and then create it */
- gchar *createdirnametemp = createdirname;
- while ( createdir != directory ) {
- (*createdirnametemp) = (*createdir);
- createdirnametemp++;
- createdir++;
- }
- (*createdirnametemp) = '\0';
-
- dir_create = g_string_new(epub_document->tmp_archive_dir);
- g_string_append_printf(dir_create,"/%s",createdirname);
- g_free(createdirname);
-
- g_mkdir_with_parents(dir_create->str,0777);
- g_string_free(dir_create,TRUE);
- }
-
- outfile = g_file_new_for_path(gfilepath->str);
- outstream = g_file_create(outfile,G_FILE_CREATE_PRIVATE,NULL,error);
- gpointer buffer = g_malloc0(512);
- while ( (writesize = unzReadCurrentFile(epub_document->epubDocument,buffer,512) ) != 0 )
- {
- if ( g_output_stream_write((GOutputStream*)outstream,buffer,writesize,NULL,error) == -1 )
- {
- result = FALSE;
- break;
- }
- }
- g_free(buffer);
- g_output_stream_close((GOutputStream*)outstream,NULL,error);
- g_object_unref(outfile) ;
- g_object_unref(outstream) ;
-
-out:
- unzCloseCurrentFile (epub_document->epubDocument) ;
- g_string_free(gfilepath,TRUE);
- g_free(currentfilename);
- return result;
-}
-
-static gboolean
-extract_epub_from_container (const gchar* uri,
- EpubDocument *epub_document,
- GError ** error)
-{
- GError *err = NULL;
- epub_document->archivename = g_filename_from_uri(uri,NULL,error);
-
- if ( !epub_document->archivename )
- {
- if (err) {
- g_propagate_error (error, err);
- }
- else {
- g_set_error_literal (error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("could not retrieve filename"));
- }
- return FALSE;
- }
-
- gchar *epubfilename = g_strrstr(epub_document->archivename,"/");
- if ( *epubfilename == '/' )
- epubfilename++ ;
-
- GString *temporary_sub_directory = g_string_new(epubfilename);
- g_string_append(temporary_sub_directory,"XXXXXX") ;
- epub_document->tmp_archive_dir = ev_mkdtemp(temporary_sub_directory->str, error);
- g_string_free(temporary_sub_directory, TRUE);
-
- if (!epub_document->tmp_archive_dir) {
- return FALSE;
- }
-
- epub_document->epubDocument = unzOpen64(epub_document->archivename);
- if ( epub_document->epubDocument == NULL )
- {
- if (err) {
- g_propagate_error (error, err);
- }
- else {
- g_set_error_literal (error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("could not open archive"));
- }
- return FALSE;
- }
-
- gboolean result = FALSE;
-
- if ( unzGoToFirstFile(epub_document->epubDocument) != UNZ_OK )
- {
- if (err) {
- g_propagate_error (error, err);
- }
- else {
- g_set_error_literal (error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("could not extract archive"));
- }
- goto out;
- }
-
- while ( TRUE )
- {
- if ( extract_one_file(epub_document,&err) == FALSE )
- {
- if (err) {
- g_propagate_error (error, err);
- }
- else {
- g_set_error_literal (error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("could not extract archive"));
- }
- goto out;
- }
-
- if ( unzGoToNextFile(epub_document->epubDocument) == UNZ_END_OF_LIST_OF_FILE ) {
- result = TRUE;
- break;
- }
- }
-
-out:
- unzClose(epub_document->epubDocument);
- return result;
-}
-
-static gchar*
-get_uri_to_content(const gchar* uri,GError ** error,EpubDocument *epub_document)
-{
- gchar* tmp_archive_dir = epub_document->tmp_archive_dir;
- GError *err = NULL ;
-
- gchar *containerpath = g_filename_from_uri(uri,NULL,&err);
- if ( !containerpath )
- {
- if (err) {
- g_propagate_error (error,err);
- }
- else {
- g_set_error_literal (error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("could not retrieve container file"));
- }
- return NULL ;
- }
-
- gboolean result = open_xml_document(containerpath);
- g_free (containerpath);
- if ( result == FALSE )
- {
- g_set_error_literal(error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("could not open container file"));
-
- return NULL ;
- }
-
- if ( set_xml_root_node((xmlChar*)"container") == FALSE) {
-
- g_set_error_literal(error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("container file is corrupt"));
- return NULL ;
- }
-
- xmlNodePtr rootfileNode = xml_get_pointer_to_node((xmlChar*)"rootfile",(xmlChar*)"media-type",(xmlChar*)"application/oebps-package+xml");
- if ( rootfileNode == NULL)
- {
- g_set_error_literal(error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("epub file is invalid or corrupt"));
- return NULL ;
- }
-
- xmlChar *relativepath = xml_get_data_from_node(rootfileNode,XML_ATTRIBUTE,(xmlChar*)"full-path") ;
- if ( relativepath == NULL )
- {
- g_set_error_literal(error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("epub file is corrupt, no container"));
- return NULL ;
- }
-
- gchar* documentfolder = g_strrstr((gchar*)relativepath,"/");
- if (documentfolder != NULL) {
- gchar* copybuffer = (gchar*)relativepath ;
- gchar* directorybuffer = g_malloc0(sizeof(gchar*)*100);
- gchar* writer = directorybuffer;
-
- while(copybuffer != documentfolder) {
- (*writer) = (*copybuffer);
- writer++;copybuffer++;
- }
- *writer = '\0';
-
- GString *documentdir = g_string_new(tmp_archive_dir);
- g_string_append_printf(documentdir,"/%s",directorybuffer);
- g_free(directorybuffer);
- epub_document->documentdir = g_string_free(documentdir,FALSE);
- }
- else
- {
- epub_document->documentdir = g_strdup(tmp_archive_dir);
- }
-
- GString *absolutepath = g_string_new(tmp_archive_dir);
- g_string_append_printf(absolutepath,"/%s",relativepath);
- g_free (relativepath);
-
- gchar *content_uri = g_filename_to_uri(absolutepath->str,NULL,&err);
- g_string_free(absolutepath,TRUE);
- if ( !content_uri ) {
- if (err) {
- g_propagate_error (error,err);
- }
- else
- {
- g_set_error_literal (error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("could not retrieve container file"));
- }
- return NULL ;
- }
- xml_free_doc();
- return content_uri ;
-}
-
-static gboolean
-link_present_on_page(const gchar* link,const gchar *page_uri)
-{
- gchar *res;
- if ((res=g_strrstr(link, page_uri)) != NULL) {
- return TRUE;
- }
- else {
- return FALSE;
- }
-}
-
-static void
-check_add_page_numbers(linknode *listdata, contentListNode *comparenode)
-{
- if (link_present_on_page(listdata->pagelink, comparenode->value)) {
- listdata->page = comparenode->index - 1;
- }
- if (listdata->children != NULL) {
- g_list_foreach(listdata->children,(GFunc)check_add_page_numbers,comparenode);
- }
-}
-
-static GList*
-setup_document_content_list(const gchar* content_uri, GError** error,gchar *documentdir)
-{
- GError *err = NULL;
- gint indexcounter = 1;
- xmlNodePtr manifest,spine,itemrefptr,itemptr;
- gboolean errorflag = FALSE;
-
- if ( open_xml_document(content_uri) == FALSE )
- {
- g_set_error_literal(error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("could not parse content manifest"));
-
- return FALSE ;
- }
- if ( set_xml_root_node((xmlChar*)"package") == FALSE) {
-
- g_set_error_literal(error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("content file is invalid"));
- return FALSE ;
- }
-
- if ( ( spine = xml_get_pointer_to_node((xmlChar*)"spine",NULL,NULL) )== NULL )
- {
- g_set_error_literal(error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("epub file has no spine"));
- return FALSE ;
- }
-
- if ( ( manifest = xml_get_pointer_to_node((xmlChar*)"manifest",NULL,NULL) )== NULL )
- {
- g_set_error_literal(error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("epub file has no manifest"));
- return FALSE ;
- }
-
- xmlretval = NULL ;
-
- /*Get first instance of itemref from the spine*/
- xml_parse_children_of_node(spine,(xmlChar*)"itemref",NULL,NULL);
-
- if ( xmlretval != NULL )
- itemrefptr = xmlretval ;
- else
- {
- errorflag=TRUE;
- }
-
- GList *newlist = NULL;
-
- /*Parse the spine for remaining itemrefs*/
- do
- {
- /*for the first time that we enter the loop, if errorflag is set we break*/
- if ( errorflag )
- {
- break;
- }
- if ( xmlStrcmp(itemrefptr->name,(xmlChar*)"itemref") == 0)
- {
- contentListNode *newnode = g_malloc0(sizeof(newnode));
- newnode->key = (gchar*)xml_get_data_from_node(itemrefptr,XML_ATTRIBUTE,(xmlChar*)"idref");
- if ( newnode->key == NULL )
- {
- g_free (newnode);
- errorflag = TRUE;
- break;
- }
- xmlretval=NULL ;
- xml_parse_children_of_node(manifest,(xmlChar*)"item",(xmlChar*)"id",(xmlChar*)newnode->key);
-
- if ( xmlretval != NULL )
- {
- itemptr = xmlretval ;
- }
- else
- {
- g_free (newnode->key);
- g_free (newnode);
- errorflag = TRUE;
- break;
- }
-
- GString* absolutepath = g_string_new(documentdir);
- gchar *relativepath = (gchar*)xml_get_data_from_node(itemptr,XML_ATTRIBUTE,(xmlChar*)"href");
- g_string_append_printf(absolutepath,"/%s",relativepath);
- g_free (relativepath);
-
- newnode->value = g_filename_to_uri(absolutepath->str,NULL,&err);
- g_string_free(absolutepath,TRUE);
-
- if ( newnode->value == NULL )
- {
- g_free (newnode->key);
- g_free (newnode);
- errorflag = TRUE;
- break;
- }
-
- newnode->index = indexcounter++ ;
-
- newlist = g_list_prepend(newlist, newnode);
- }
- itemrefptr = itemrefptr->next ;
- }
- while ( itemrefptr != NULL );
-
- if ( errorflag )
- {
- if ( err )
- {
- g_propagate_error(error,err);
- }
- else
- {
- g_set_error_literal(error,
- EV_DOCUMENT_ERROR,
- EV_DOCUMENT_ERROR_INVALID,
- _("Could not set up document tree for loading, some files missing"));
- }
- /*free any nodes that were set up and return empty*/
- g_list_free_full(newlist, (GDestroyNotify)free_tree_nodes);
- return NULL;
- }
-
- newlist = g_list_reverse(newlist);
- xml_free_doc();
- return newlist;
-
-}
-
-/* Callback function to free the contentlist.*/
-static void
-free_tree_nodes(gpointer data)
-{
- contentListNode* dataptr = data ;
- g_free(dataptr->value);
- g_free(dataptr->key);
- g_free(dataptr);
-}
-
-static void
-free_link_nodes(gpointer data)
-{
- linknode* dataptr = data ;
- g_free(dataptr->pagelink);
- g_free(dataptr->linktext);
-
- if (dataptr->children) {
- g_list_free_full(dataptr->children,(GDestroyNotify)free_link_nodes);
- }
- g_free(dataptr);
-}
-
-static gchar*
-get_toc_file_name(gchar *containeruri)
-{
- gchar *containerfilename = g_filename_from_uri(containeruri,NULL,NULL);
- open_xml_document(containerfilename);
- g_free (containerfilename);
-
- set_xml_root_node(NULL);
-
- xmlNodePtr manifest = xml_get_pointer_to_node((xmlChar*)"manifest",NULL,NULL);
- xmlNodePtr spine = xml_get_pointer_to_node((xmlChar*)"spine",NULL,NULL);
-
- xmlChar *ncx = xml_get_data_from_node(spine,XML_ATTRIBUTE,(xmlChar*)"toc");
-
- /*In an epub3, there is sometimes no toc, and we need to then use the nav file for this.*/
- if (ncx == NULL) {
- return NULL;
- }
-
- xmlretval = NULL;
- xml_parse_children_of_node(manifest,(xmlChar*)"item",(xmlChar*)"id",ncx);
-
- gchar* tocfilename = (gchar*)xml_get_data_from_node(xmlretval,XML_ATTRIBUTE,(xmlChar*)"href");
- xml_free_doc();
-
- return tocfilename;
-}
-
-static gchar*
-epub_document_get_nav_file(gchar* containeruri)
-{
- open_xml_document(containeruri);
- set_xml_root_node(NULL);
- xmlNodePtr manifest = xml_get_pointer_to_node((xmlChar*)"manifest",NULL,NULL);
- xmlretval = NULL;
- xml_parse_children_of_node(manifest,(xmlChar*)"item",(xmlChar*)"properties",(xmlChar*)"nav");
-
- gchar *uri = (gchar*)xml_get_data_from_node(xmlretval,XML_ATTRIBUTE, (xmlChar*)"href");
-
- xml_free_doc();
- return uri;
-}
-
-static GList*
-get_child_list(xmlNodePtr ol,gchar* documentdir)
-{
- GList *childlist = NULL;
- xmlNodePtr li = ol->xmlChildrenNode;
-
- while (li != NULL) {
- if (xmlStrcmp(li->name,(xmlChar*)"li")) {
- li = li->next;
- continue;
- }
- xmlNodePtr children = li->xmlChildrenNode;
- linknode *newlinknode = g_new0(linknode, 1);
- while (children != NULL) {
- if ( !xmlStrcmp(children->name,(xmlChar*)"a")) {
- newlinknode->linktext = (gchar*)xml_get_data_from_node(children,XML_KEYWORD,NULL);
- gchar* filename = (gchar*)xml_get_data_from_node(children,XML_ATTRIBUTE,(xmlChar*)"href");
- gchar *filepath = g_strdup_printf("%s/%s",documentdir,filename);
- newlinknode->pagelink = g_filename_to_uri(filepath,NULL,NULL);
- g_free(filename);
- g_free(filepath);
- newlinknode->children = NULL;
- childlist = g_list_prepend(childlist,newlinknode);
- }
- else if ( !xmlStrcmp(children->name,(xmlChar*)"ol")){
- newlinknode->children = get_child_list(children,documentdir);
- }
-
- children = children->next;
- }
-
- li = li->next;
- }
-
- return g_list_reverse(childlist);
-}
-
-/* For an epub3 style navfile */
-static GList*
-setup_index_from_navfile(gchar *tocpath)
-{
- GList *index = NULL;
- open_xml_document(tocpath);
- set_xml_root_node(NULL);
- xmlNodePtr nav = xml_get_pointer_to_node((xmlChar*)"nav",(xmlChar*)"id",(xmlChar*)"toc");
- xmlretval=NULL;
- xml_parse_children_of_node(nav,(xmlChar*)"ol", NULL,NULL);
- gchar *navdirend = g_strrstr(tocpath,"/");
- gchar *navdir = g_malloc0(strlen(tocpath));
- gchar *reader = tocpath;
- gchar *writer = navdir;
-
- while (reader != navdirend) {
- (*writer) = (*reader) ;
- writer++;reader++;
- }
- index = get_child_list(xmlretval,navdir);
- g_free(navdir);
- xml_free_doc();
- return index;
-}
-
-static GList*
-setup_document_index(EpubDocument *epub_document,gchar *containeruri)
-{
- GString *tocpath = g_string_new(epub_document->documentdir);
- gchar *tocfilename = get_toc_file_name(containeruri);
- GList *index = NULL;
-
- if (tocfilename == NULL) {
- tocfilename = epub_document_get_nav_file(containeruri);
-
- //Apparently, sometimes authors don't even care to add a TOC!! Guess standards are just guidelines.
-
- if (tocfilename == NULL) {
- //We didn't even find a nav file.The document has no TOC.
- g_string_free(tocpath,TRUE);
- return NULL;
- }
-
- g_string_append_printf (tocpath,"/%s",tocfilename);
- index = setup_index_from_navfile(tocpath->str);
- g_string_free(tocpath,TRUE);
- g_free (tocfilename);
- return index;
- }
-
- g_string_append_printf (tocpath,"/%s",tocfilename);
- g_free (tocfilename);
-
- GString *pagelink;
- open_xml_document(tocpath->str);
- g_string_free(tocpath,TRUE);
- set_xml_root_node((xmlChar*)"ncx");
-
- xmlNodePtr docTitle = xml_get_pointer_to_node((xmlChar*)"docTitle",NULL,NULL);
- xmlretval = NULL;
- xml_parse_children_of_node(docTitle,(xmlChar*)"text",NULL,NULL);
-
- while (epub_document->docTitle == NULL && xmlretval != NULL) {
- epub_document->docTitle = (gchar*)xml_get_data_from_node(xmlretval,XML_KEYWORD,NULL);
- xmlretval = xmlretval->next;
- }
- xmlNodePtr navMap = xml_get_pointer_to_node((xmlChar*)"navMap",NULL,NULL);
- xmlretval = NULL;
- xml_parse_children_of_node(navMap,(xmlChar*)"navPoint",NULL,NULL);
-
- xmlNodePtr navPoint = xmlretval;
-
- do {
-
- if ( !xmlStrcmp(navPoint->name,(xmlChar*)"navPoint")) {
- xmlretval = NULL;
- xml_parse_children_of_node(navPoint,(xmlChar*)"navLabel",NULL,NULL);
- xmlNodePtr navLabel = xmlretval;
- xmlretval = NULL;
- gchar *fragment=NULL,*end=NULL;
- GString *uri = NULL;
-
- xml_parse_children_of_node(navLabel,(xmlChar*)"text",NULL,NULL);
- linknode *newnode = g_new0(linknode,1);
- newnode->linktext = NULL;
- while (newnode->linktext == NULL) {
- newnode->linktext = (gchar*)xml_get_data_from_node(xmlretval,XML_KEYWORD,NULL);
- xmlretval = xmlretval->next;
- }
- xmlretval = NULL;
- xml_parse_children_of_node(navPoint,(xmlChar*)"content",NULL,NULL);
- pagelink = g_string_new(epub_document->documentdir);
- newnode->pagelink = (gchar*)xml_get_data_from_node(xmlretval,XML_ATTRIBUTE,(xmlChar*)"src");
- g_string_append_printf(pagelink,"/%s",newnode->pagelink);
- xmlFree(newnode->pagelink);
-
- gchar *escaped = g_strdup(pagelink->str);
-
- //unescaping any special characters
- pagelink->str = g_uri_unescape_string (escaped,NULL);
- g_free(escaped);
-
- if ((end = g_strrstr(pagelink->str,"#")) != NULL) {
- fragment = g_strdup(g_strrstr(pagelink->str,"#"));
- *end = '\0';
- }
- uri = g_string_new(g_filename_to_uri(pagelink->str,NULL,NULL));
- g_string_free(pagelink,TRUE);
-
- if (fragment) {
- g_string_append(uri,fragment);
- }
-
- newnode->pagelink = g_strdup(uri->str);
- g_string_free(uri,TRUE);
- index = g_list_prepend(index,newnode);
- }
-
- navPoint = navPoint->next;
-
- } while(navPoint != NULL);
-
- xml_free_doc();
-
- return g_list_reverse(index);
-}
-
-static EvDocumentInfo*
-epub_document_get_info(EvDocument *document)
-{
- EpubDocument *epub_document = EPUB_DOCUMENT(document);
- GError *error = NULL ;
- gchar* infofile ;
- xmlNodePtr metanode ;
- GString* buffer ;
- gchar* archive_dir = epub_document->tmp_archive_dir;
-
- GString* containerpath = g_string_new(epub_document->tmp_archive_dir);
- g_string_append_printf(containerpath,"/META-INF/container.xml");
- gchar* containeruri = g_filename_to_uri(containerpath->str,NULL,&error);
- g_string_free (containerpath, TRUE);
- if ( error )
- {
- return NULL ;
- }
-
- gchar* uri = get_uri_to_content (containeruri,&error,epub_document);
- g_free (containeruri);
- if ( error )
- {
- return NULL ;
- }
-
- EvDocumentInfo* epubinfo = g_new0 (EvDocumentInfo, 1);
-
- epubinfo->fields_mask = EV_DOCUMENT_INFO_TITLE |
- EV_DOCUMENT_INFO_FORMAT |
- EV_DOCUMENT_INFO_AUTHOR |
- EV_DOCUMENT_INFO_SUBJECT |
- EV_DOCUMENT_INFO_KEYWORDS |
- EV_DOCUMENT_INFO_LAYOUT |
- EV_DOCUMENT_INFO_CREATOR |
- EV_DOCUMENT_INFO_LINEARIZED |
- EV_DOCUMENT_INFO_PERMISSIONS |
- EV_DOCUMENT_INFO_N_PAGES ;
-
- infofile = g_filename_from_uri(uri,NULL,&error);
- g_free (uri);
- if ( error )
- {
- return epubinfo;
- }
-
- open_xml_document(infofile);
- g_free (infofile);
-
- set_xml_root_node((xmlChar*)"package");
-
- metanode = xml_get_pointer_to_node((xmlChar*)"title",NULL,NULL);
- if ( metanode == NULL )
- epubinfo->title = NULL ;
- else
- epubinfo->title = (char*)xml_get_data_from_node(metanode,XML_KEYWORD,NULL);
-
- metanode = xml_get_pointer_to_node((xmlChar*)"creator",NULL,NULL);
- if ( metanode == NULL )
- epubinfo->author = g_strdup("unknown");
- else
- epubinfo->author = (char*)xml_get_data_from_node(metanode,XML_KEYWORD,NULL);
-
- metanode = xml_get_pointer_to_node((xmlChar*)"subject",NULL,NULL);
- if ( metanode == NULL )
- epubinfo->subject = g_strdup("unknown");
- else
- epubinfo->subject = (char*)xml_get_data_from_node(metanode,XML_KEYWORD,NULL);
-
- buffer = g_string_new((gchar*)xml_get_data_from_node (xmlroot,XML_ATTRIBUTE,(xmlChar*)"version"));
- g_string_prepend(buffer,"epub ");
- epubinfo->format = g_string_free(buffer,FALSE);
-
- /*FIXME: Add more of these as you write the corresponding modules*/
-
- epubinfo->layout = EV_DOCUMENT_LAYOUT_SINGLE_PAGE;
-
- metanode = xml_get_pointer_to_node((xmlChar*)"publisher",NULL,NULL);
- if ( metanode == NULL )
- epubinfo->creator = g_strdup("unknown");
- else
- epubinfo->creator = (char*)xml_get_data_from_node(metanode,XML_KEYWORD,NULL);
-
- /* number of pages */
- epubinfo->n_pages = epub_document_get_n_pages(document);
-
- /*Copying*/
- epubinfo->permissions = EV_DOCUMENT_PERMISSIONS_OK_TO_COPY;
- /*TODO : Add a function to get date*/
-
- if (xmldocument)
- xml_free_doc();
- return epubinfo ;
-}
-
-static EvPage*
-epub_document_get_page(EvDocument *document,
- gint index)
-{
- EpubDocument *epub_document = EPUB_DOCUMENT(document);
- EvPage* page = ev_page_new(index);
- contentListNode *listptr = g_list_nth_data (epub_document->contentList,index);
- page->backend_page = g_strdup(listptr->value);
- return page ;
-}
-
-static void
-change_to_night_sheet(contentListNode *nodedata,gpointer user_data)
-{
- gchar *filename = g_filename_from_uri(nodedata->value,NULL,NULL);
- open_xml_document(filename);
- set_xml_root_node(NULL);
- xmlNodePtr head =xml_get_pointer_to_node((xmlChar*)"head",NULL,NULL);
- gchar *class = NULL;
- xmlretval = NULL;
- xml_parse_children_of_node(head,(xmlChar*)"link",(xmlChar*)"rel",(xmlChar*)"stylesheet");
-
- xmlNodePtr day = xmlretval;
- if ( (class = (gchar*)xml_get_data_from_node(day,XML_ATTRIBUTE,(xmlChar*)"class")) == NULL) {
- xmlSetProp(day,(xmlChar*)"class",(xmlChar*)"day");
- }
- g_free(class);
- xmlSetProp(day,(xmlChar*)"rel",(xmlChar*)"alternate stylesheet");
- xmlretval = NULL;
- xml_parse_children_of_node(head,(xmlChar*)"link",(xmlChar*)"class",(xmlChar*)"night");
- xmlSetProp(xmlretval,(xmlChar*)"rel",(xmlChar*)"stylesheet");
- xmlSaveFormatFile (filename, xmldocument, 0);
- xml_free_doc();
- g_free(filename);
-}
-
-static void
-change_to_day_sheet(contentListNode *nodedata,gpointer user_data)
-{
- gchar *filename = g_filename_from_uri(nodedata->value,NULL,NULL);
- open_xml_document(filename);
- set_xml_root_node(NULL);
- xmlNodePtr head =xml_get_pointer_to_node((xmlChar*)"head",NULL,NULL);
-
- xmlretval = NULL;
- xml_parse_children_of_node(head,(xmlChar*)"link",(xmlChar*)"rel",(xmlChar*)"stylesheet");
-
- xmlNodePtr day = xmlretval;
- xmlSetProp(day,(xmlChar*)"rel",(xmlChar*)"alternate stylesheet");
-
- xmlretval = NULL;
- xml_parse_children_of_node(head,(xmlChar*)"link",(xmlChar*)"class",(xmlChar*)"day");
- xmlSetProp(xmlretval,(xmlChar*)"rel",(xmlChar*)"stylesheet");
- xmlSaveFormatFile (filename, xmldocument, 0);
- xml_free_doc();
- g_free(filename);
-}
-
-static gchar*
-epub_document_get_alternate_stylesheet(gchar *docuri)
-{
- gchar *filename = g_filename_from_uri(docuri,NULL,NULL);
- open_xml_document(filename);
- g_free(filename);
-
- set_xml_root_node(NULL);
-
- xmlNodePtr head= xml_get_pointer_to_node((xmlChar*)"head",NULL,NULL);
-
- xmlretval = NULL;
-
- xml_parse_children_of_node(head,(xmlChar*)"link",(xmlChar*)"class",(xmlChar*)"night");
-
- if (xmlretval != NULL) {
- return (gchar*)xml_get_data_from_node(xmlretval,XML_ATTRIBUTE,(xmlChar*)"href");
- }
- xml_free_doc();
- return NULL;
-}
-
-static void
-add_night_sheet(contentListNode *listdata,gchar *sheet)
-{
- gchar *sheeturi = g_filename_to_uri(sheet,NULL,NULL);
- open_xml_document(listdata->value);
-
- set_xml_root_node(NULL);
- xmlNodePtr head = xml_get_pointer_to_node((xmlChar*)"head",NULL,NULL);
-
- xmlNodePtr link = xmlNewTextChild(head,NULL,(xmlChar*)"link",NULL);
- xmlAttrPtr href = xmlNewProp(link,(xmlChar*)"href",(xmlChar*)sheeturi);
- xmlAttrPtr rel = xmlNewProp(link,(xmlChar*)"rel",(xmlChar*)"alternate stylesheet");
- xmlAttrPtr class = xmlNewProp(link,(xmlChar*)"class",(xmlChar*)"night");
-
- xmlSaveFormatFile (listdata->value, xmldocument, 0);
- xml_free_doc();
- g_free(sheeturi);
-}
-
-static void
-epub_document_check_add_night_sheet(EvDocument *document)
-{
- EpubDocument *epub_document = EPUB_DOCUMENT(document);
-
- g_return_if_fail(EPUB_IS_DOCUMENT(epub_document));
-
- /*
- * We'll only check the first page for a supplied night mode stylesheet.
- * Odds are, if this one has it, all others have it too.
- */
- contentListNode *node = epub_document->contentList->data;
- gchar* stylesheetfilename = epub_document_get_alternate_stylesheet((gchar*)node->value) ;
-
- if (stylesheetfilename == NULL) {
- gchar *style = "body {color:rgb(255,255,255);\
- background-color:rgb(0,0,0);\
- text-align:justify;\
- line-spacing:1.8;\
- margin-top:0px;\
- margin-bottom:4px;\
- margin-right:50px;\
- margin-left:50px;\
- text-indent:3em;}\
- h1, h2, h3, h4, h5, h6\
- {color:white;\
- text-align:center;\
- font-style:italic;\
- font-weight:bold;}";
-
- gchar *csspath = g_strdup_printf("%s/atrilnightstyle.css",epub_document->documentdir);
-
-
- GFile *styles = g_file_new_for_path (csspath);
- GOutputStream *outstream = (GOutputStream*)g_file_create(styles,G_FILE_CREATE_PRIVATE,NULL,NULL);
- if ( g_output_stream_write((GOutputStream*)outstream,style,strlen(style),NULL,NULL) == -1 )
- {
- return ;
- }
- g_output_stream_close((GOutputStream*)outstream,NULL,NULL);
- g_object_unref(styles) ;
- g_object_unref(outstream) ;
- //add this stylesheet to each document, for later.
- g_list_foreach(epub_document->contentList,(GFunc)add_night_sheet,csspath);
- g_free(csspath);
- }
- g_free(stylesheetfilename);
-}
-
-static void
-epub_document_toggle_night_mode(EvDocument *document,gboolean night)
-{
- EpubDocument *epub_document = EPUB_DOCUMENT(document);
-
- g_return_if_fail(EPUB_IS_DOCUMENT(epub_document));
- if (night)
- g_list_foreach(epub_document->contentList,(GFunc)change_to_night_sheet,NULL);
- else
- g_list_foreach(epub_document->contentList,(GFunc)change_to_day_sheet,NULL);
-}
-
-static gchar*
-epub_document_set_document_title(gchar *containeruri)
-{
- open_xml_document(containeruri);
- gchar *doctitle;
- set_xml_root_node(NULL);
-
- xmlNodePtr title = xml_get_pointer_to_node((xmlChar*)"title",NULL,NULL);
-
- doctitle = (gchar*)xml_get_data_from_node(title, XML_KEYWORD, NULL);
- xml_free_doc();
-
- return doctitle;
-}
-
-static void
-page_set_function(linknode *Link, GList *contentList)
-{
- GList *listiter = contentList;
- contentListNode *pagedata;
-
- guint flag=0;
- while (!flag) {
- pagedata = listiter->data;
- if (link_present_on_page(Link->pagelink, pagedata->value)) {
- flag=1;
- Link->page = pagedata->index - 1;
- }
- listiter = listiter->next;
- }
-
- if (Link->children) {
- g_list_foreach(Link->children,(GFunc)page_set_function,contentList);
- }
-}
-
-static void
-epub_document_set_index_pages(GList *index,GList *contentList)
-{
- g_return_if_fail (index != NULL);
- g_return_if_fail (contentList != NULL);
-
- g_list_foreach(index,(GFunc)page_set_function,contentList);
-}
-
-
-static void
-add_mathjax_script_node_to_file(gchar *filename, gchar *data)
-{
- xmlDocPtr mathdocument = xmlParseFile (filename);
- xmlNodePtr mathroot = xmlDocGetRootElement(mathdocument);
-
- if (mathroot == NULL)
- return;
-
- xmlNodePtr head = mathroot->children;
-
- while(head != NULL) {
- if (!xmlStrcmp(head->name,(xmlChar*)"head")) {
- break;
- }
- head = head->next;
- }
-
- if (xmlStrcmp(head->name,(xmlChar*)"head")) {
- return ;
- }
-
- xmlNodePtr script = xmlNewTextChild (head,NULL,(xmlChar*)"script",(xmlChar*)"");
- xmlNewProp(script,(xmlChar*)"type",(xmlChar*)"text/javascript");
- xmlNewProp(script,(xmlChar*)"src",(xmlChar*)data);
-
- xmlSaveFormatFile(filename, mathdocument, 0);
- xmlFreeDoc (mathdocument);
-}
-
-static void
-epub_document_add_mathJax(gchar* containeruri,gchar* documentdir)
-{
- gchar *containerfilename= g_filename_from_uri(containeruri,NULL,NULL);
- const gchar *backenddir = ev_backends_manager_get_backends_dir();
- GString *mathjaxdir = g_string_new("/usr/share/javascript/mathjax");
-
- gchar *mathjaxref = g_filename_to_uri(mathjaxdir->str,NULL,NULL);
- gchar *nodedata = g_strdup_printf("%s/MathJax.js?config=TeX-AMS-MML_SVG",mathjaxref);
-
- open_xml_document(containerfilename);
- set_xml_root_node(NULL);
- xmlNodePtr manifest = xml_get_pointer_to_node((xmlChar*)"manifest",NULL,NULL);
-
- xmlNodePtr item = manifest->xmlChildrenNode;
-
- while (item != NULL) {
- if (xmlStrcmp(item->name,(xmlChar*)"item")) {
- item = item->next;
- continue;
- }
-
- xmlChar *mathml = xml_get_data_from_node(item,XML_ATTRIBUTE, (xmlChar*)"properties");
-
- if (mathml != NULL &&
- !xmlStrcmp(mathml, (xmlChar*)"mathml") ) {
- gchar *href = (gchar*)xml_get_data_from_node(item, XML_ATTRIBUTE, (xmlChar*)"href");
- gchar *filename = g_strdup_printf("%s/%s",documentdir,href);
-
- add_mathjax_script_node_to_file(filename,nodedata);
- g_free(href);
- g_free(filename);
- }
- g_free(mathml);
- item = item->next;
- }
- xml_free_doc();
- g_free(mathjaxref);
- g_free(containerfilename);
- g_free(nodedata);
- g_string_free(mathjaxdir,TRUE);
-}
-
-static gboolean
-epub_document_load (EvDocument* document,
- const char* uri,
- GError** error)
-{
- EpubDocument *epub_document = EPUB_DOCUMENT(document);
- GError *err = NULL;
-
- if ( check_mime_type (uri, &err) == FALSE )
- {
- /*Error would've been set by the function*/
- g_propagate_error(error,err);
- return FALSE;
- }
-
- extract_epub_from_container (uri,epub_document,&err);
-
- if ( err )
- {
- g_propagate_error( error,err );
- return FALSE;
- }
-
- /*FIXME : can this be different, ever?*/
- GString *containerpath = g_string_new(epub_document->tmp_archive_dir);
- g_string_append_printf(containerpath,"/META-INF/container.xml");
- gchar *containeruri = g_filename_to_uri(containerpath->str,NULL,&err);
- g_string_free (containerpath, TRUE);
-
- if ( err )
- {
- g_propagate_error(error,err);
- return FALSE;
- }
-
- gchar *contentOpfUri = get_uri_to_content (containeruri,&err,epub_document);
- g_free (containeruri);
-
- if ( contentOpfUri == NULL )
- {
- g_propagate_error(error,err);
- return FALSE;
- }
-
- epub_document->docTitle = epub_document_set_document_title(contentOpfUri);
- epub_document->index = setup_document_index(epub_document,contentOpfUri);
-
- epub_document->contentList = setup_document_content_list (contentOpfUri,&err,epub_document->documentdir);
-
- if (epub_document->index != NULL && epub_document->contentList != NULL)
- epub_document_set_index_pages(epub_document->index, epub_document->contentList);
-
- epub_document_add_mathJax(contentOpfUri,epub_document->documentdir);
- g_free (contentOpfUri);
-
- if ( epub_document->contentList == NULL )
- {
- g_propagate_error(error,err);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-epub_document_init (EpubDocument *epub_document)
-{
- epub_document->archivename = NULL ;
- epub_document->tmp_archive_dir = NULL ;
- epub_document->contentList = NULL ;
- epub_document->documentdir = NULL;
- epub_document->index = NULL;
- epub_document->docTitle = NULL;
-}
-
-
-static void
-epub_document_finalize (GObject *object)
-{
- EpubDocument *epub_document = EPUB_DOCUMENT (object);
-
- if (epub_document->epubDocument != NULL) {
- if (epub_remove_temporary_dir (epub_document->tmp_archive_dir) == -1)
- g_warning (_("There was an error deleting ā€œ%sā€."),
- epub_document->tmp_archive_dir);
- }
-
- if ( epub_document->contentList ) {
- g_list_free_full(epub_document->contentList,(GDestroyNotify)free_tree_nodes);
- epub_document->contentList = NULL;
- }
-
- if (epub_document->index) {
- g_list_free_full(epub_document->index,(GDestroyNotify)free_link_nodes);
- epub_document->index = NULL;
- }
-
- if ( epub_document->tmp_archive_dir) {
- g_free (epub_document->tmp_archive_dir);
- epub_document->tmp_archive_dir = NULL;
- }
-
- if (epub_document->docTitle) {
- g_free(epub_document->docTitle);
- epub_document->docTitle = NULL;
- }
- if ( epub_document->archivename) {
- g_free (epub_document->archivename);
- epub_document->archivename = NULL;
- }
- if ( epub_document->documentdir) {
- g_free (epub_document->documentdir);
- epub_document->documentdir = NULL;
- }
- G_OBJECT_CLASS (epub_document_parent_class)->finalize (object);
-}
-
-
-static void
-epub_document_class_init (EpubDocumentClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- EvDocumentClass *ev_document_class = EV_DOCUMENT_CLASS (klass);
-
- gobject_class->finalize = epub_document_finalize;
- ev_document_class->load = epub_document_load;
- ev_document_class->save = epub_document_save;
- ev_document_class->get_n_pages = epub_document_get_n_pages;
- ev_document_class->get_info = epub_document_get_info;
- ev_document_class->get_page = epub_document_get_page;
- ev_document_class->toggle_night_mode = epub_document_toggle_night_mode;
- ev_document_class->check_add_night_sheet = epub_document_check_add_night_sheet;
-}