diff options
author | Wu Xiaotian <[email protected]> | 2019-01-29 17:50:46 +0800 |
---|---|---|
committer | Wu Xiaotian <[email protected]> | 2019-03-06 12:11:01 +0800 |
commit | 70a278d95023d368570b6285ae8e2c2e559220f0 (patch) | |
tree | 341d832e24a40760984793dc8bd5fede0df1fe0f /backend/epub/epub-document.c | |
parent | 2b66cf239e0094f385df95eec313b2c0249acb91 (diff) | |
download | atril-70a278d95023d368570b6285ae8e2c2e559220f0.tar.bz2 atril-70a278d95023d368570b6285ae8e2c2e559220f0.tar.xz |
drop current epub supportwip/libgepub
Diffstat (limited to 'backend/epub/epub-document.c')
-rw-r--r-- | backend/epub/epub-document.c | 1831 |
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; -} |