[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [krita] plugins/python/comics_project_management_tools: CPMT: Seperate the exporters into their own 
From:       Wolthera_van_Hövell_tot_Westerflier <null () kde ! org>
Date:       2018-02-28 21:02:58
Message-ID: E1er8sM-0001GP-9P () code ! kde ! org
[Download RAW message or body]

Git commit b4b661515cdecd2b0f27ba8706c35df330ea46fb by Wolthera van Hövell tot \
Westerflier. Committed on 28/02/2018 at 21:02.
Pushed by woltherav into branch 'master'.

CPMT: Seperate the exporters into their own files.

The main exporter was getting a bit long and hard to understand.

It still needs more cleanup, but now almost each type has their own file.

M  +4    -5    plugins/python/comics_project_management_tools/README.md
M  +34   -1053 plugins/python/comics_project_management_tools/comics_exporter.py
A  +418  -0    plugins/python/comics_project_management_tools/exporters/CPMT_ACBF_XML_Exporter.py
 A  +147  -0    plugins/python/comics_project_management_tools/exporters/CPMT_CoMet_XML_Exporter.py
 A  +96   -0    plugins/python/comics_project_management_tools/exporters/CPMT_Comic_Book_Info_Exporter.py
 A  +135  -0    plugins/python/comics_project_management_tools/exporters/CPMT_Comic_Rack_XML_Exporter.py
 A  +320  -0    plugins/python/comics_project_management_tools/exporters/CPMT_EPUB_exporter.py
 A  +6    -0    plugins/python/comics_project_management_tools/exporters/__init__.py

https://commits.kde.org/krita/b4b661515cdecd2b0f27ba8706c35df330ea46fb

diff --git a/plugins/python/comics_project_management_tools/README.md \
b/plugins/python/comics_project_management_tools/README.md index \
                0c0156c8d3d..cfd1fcf114c 100644
--- a/plugins/python/comics_project_management_tools/README.md
+++ b/plugins/python/comics_project_management_tools/README.md
@@ -211,13 +211,13 @@ Things I still want to do:
 * Make label removal just a list? (unsure)
 * PNG and JPEG export settings.
 * maybe use python minidom for acbf(or export in general), because then we can \
create a prettier xml file, which is necessary for helping people edit the files in \
question. [partialy done, epub still needs this] +* Implement basic POT translation \
thingy(POC done, needs proper scrapping and then matching systems)  
 ACBF list:
 
 * support getting text info from the vector layers. [Partially done]
 	- users can specify a name for text layers. (Waiting for stringfreeze to end)
 	- Don't forget text-rotation(Needs API)
-	- last two/five characters are used to determine language. (Maybe not a good \
                idea...>_>)
 	- maybe text-class can be used to determine type? (We'll proly need to use style \
sheets and comparing the text format to those)  + Speech (speech, dialogue)
 		+ Commentary (caption in american comics)
@@ -239,13 +239,12 @@ ACBF list:
             4. have acbf_textclass read from the desc.
     - Get page background color from the page if possible. (This might only work \
                with canvas color, though)
     - Jump: proly not gonna support this.
-    - text url anchors: don't have a sensible interface for this.
+    - text url anchors: don't have a sensible interface for this. (Might use it for \
                references only)
     - Font embedding: spec is super vague about this.
     - Style sheets: needs a very complex gui.
     - database reference: I am not sure if this is at all relevant for Krita? \
                Because it implies an already published comic.
     - acbf doc info should use author with first/nick/last/etc seperate as \
                well[partially done]
     - text-layer background color(maybe sample topleft of projection???)
 * 1.2 support:
-    - Role: designer
-    - Book-info: reading direction
-    - text type: Sound.
+    - Role: designer [needs gui still]
+    - text type: Sound.[needs gui still]
diff --git a/plugins/python/comics_project_management_tools/comics_exporter.py \
b/plugins/python/comics_project_management_tools/comics_exporter.py index \
                78d33be9891..285c7128b86 100644
--- a/plugins/python/comics_project_management_tools/comics_exporter.py
+++ b/plugins/python/comics_project_management_tools/comics_exporter.py
@@ -21,20 +21,17 @@ along with the CPMT.  If not, see <http://www.gnu.org/licenses/>.
 An exporter that take the comicsConfig and uses it to generate several files.
 """
 import sys
-import os
 from pathlib import Path
-import json
 import zipfile
 import xml.etree.ElementTree as ET
 from xml.dom import minidom
 import types
-import shutil
-import html
 import re
 from PyQt5.QtWidgets import QLabel, QProgressDialog, qApp  # For the progress \
                dialog.
-from PyQt5.QtCore import QElapsedTimer, QDate, QLocale, Qt, QRectF, QPointF, \
QByteArray, QBuffer +from PyQt5.QtCore import QElapsedTimer, QLocale, Qt, QRectF, \
QPointF  from PyQt5.QtGui import QImage, QTransform, QPainterPath
 from krita import *
+from . import exporters
 
 """
 The sizesCalculator is a convenience class for interpretting the resize \
configuration @@ -93,7 +90,6 @@ class comicsExporter():
     acbfPageData = []
     cometLocation = str()
     comicRackInfo = str()
-    comic_book_info_json_dump = str()
     pagesLocationList = {}
 
     # set of keys used to define specific export behaviour for this page.
@@ -118,7 +114,6 @@ class comicsExporter():
         self.acbfPageData = []
         self.cometLocation = str()
         self.comicRackInfo = str()
-        self.comic_book_info_json_dump = str()
 
     """
     Export everything according to config and get yourself a coffee.
@@ -151,316 +146,43 @@ class comicsExporter():
 
             # Export acbf metadata.
             if export_success:
-                export_success = self.export_to_acbf()
+                title = self.configDictionary["projectName"]
+                if "title" in self.configDictionary.keys():
+                    title = self.configDictionary["title"]
+                
+                self.acbfLocation = str(exportPath / "metadata"/ str(title + \
".acbf")) +                
+                locationStandAlone = str(exportPath / str(title + ".acbf"))
+                
+                export_success = exporters.ACBF.write_xml(self.configDictionary, \
self.acbfPageData, self.pagesLocationList["CBZ"], self.acbfLocation, \
locationStandAlone)  
             # Export and package CBZ and Epub.
             if export_success:
                 if "CBZ" in sizesList.keys():
-                    export_success = self.export_to_cbz()
+                    export_success = self.export_to_cbz(exportPath)
                     print("CPMT: Exported to CBZ", export_success)
                 if "EPUB" in sizesList.keys():
-                    export_success = self.export_to_epub()
+                    export_success = exporters.EPUB.export(self.configDictionary, \
self.projectURL, self.pagesLocationList["EPUB"])  print("CPMT: Exported to EPUB", \
export_success)  else:
             print("CPMT: Nothing to export, url not set.")
 
         return export_success
 
-    """
-    This calls up all the functions necessary for making a acbf.
-    """
-
-    def export_to_acbf(self):
-        self.write_acbf_meta_data()
-        return True
-
     """
     This calls up all the functions necessary for making a cbz.
     """
 
-    def export_to_cbz(self):
-        export_success = self.write_comet_meta_data()
-        export_success = self.write_comic_rack_info()
-        export_success = self.write_comic_book_info_json()
-        self.package_cbz()
-        return export_success
-
-    """
-    Create an epub folder, finally, package to a epubzip.
-    """
-
-    def export_to_epub(self):
-        path = Path(os.path.join(self.projectURL, \
                self.configDictionary["exportLocation"]))
-        exportPath = path / "EPUB-files"
-        metaInf = exportPath / "META-INF"
-        oebps = exportPath / "OEBPS"
-        imagePath = oebps / "Images"
-        stylesPath = oebps / "Styles"
-        textPath = oebps / "Text"
-        if exportPath.exists() is False:
-            exportPath.mkdir()
-            metaInf.mkdir()
-            oebps.mkdir()
-            imagePath.mkdir()
-            stylesPath.mkdir()
-            textPath.mkdir()
-
-        mimetype = open(str(Path(exportPath / "mimetype")), mode="w")
-        mimetype.write("application/epub+zip")
-        mimetype.close()
-
-        container = ET.ElementTree()
-        cRoot = ET.Element("container")
-        cRoot.set("version", "1.0")
-        cRoot.set("xmlns", "urn:oasis:names:tc:opendocument:xmlns:container")
-        container._setroot(cRoot)
-        rootFiles = ET.Element("rootfiles")
-        rootfile = ET.Element("rootfile")
-        rootfile.set("full-path", "OEBPS/content.opf")
-        rootfile.set("media-type", "application/oebps-package+xml")
-        rootFiles.append(rootfile)
-        cRoot.append(rootFiles)
-        container.write(str(Path(metaInf / "container.xml")), encoding="utf-8", \
                xml_declaration=True)
-
-        # copyimages to images
-        pagesList = []
-        if "EPUB" in self.pagesLocationList.keys():
-            coverNumber = \
                self.configDictionary["pages"].index(self.configDictionary["cover"])
-            for p in self.pagesLocationList["EPUB"]:
-                if os.path.exists(p):
-                    shutil.copy2(p, str(imagePath))
-                    pagesList.append(str(Path(imagePath / os.path.basename(p))))
-            if len(self.pagesLocationList["EPUB"]) >= coverNumber:
-                coverpageurl = pagesList[coverNumber]
-        else:
-            print("CPMT: Couldn't find the location for the epub files.")
-            return False
-
-        # for each image, make an xml file
-        htmlFiles = []
-        for i in range(len(pagesList)):
-            pageName = "Page" + str(i) + ".xhtml"
-            doc = ET.ElementTree()
-            html = ET.Element("html")
-            doc._setroot(html)
-            html.set("xmlns", "http://www.w3.org/1999/xhtml")
-            html.set("xmlns:epub", "http://www.idpf.org/2007/ops")
-
-            head = ET.Element("head")
-            html.append(head)
-
-            body = ET.Element("body")
-
-            img = ET.Element("img")
-            img.set("src", os.path.relpath(pagesList[i], str(textPath)))
-            body.append(img)
-
-            if pagesList[i] != coverpageurl:
-                pagenumber = ET.Element("p")
-                pagenumber.text = "Page " + str(i)
-                body.append(pagenumber)
-            html.append(body)
-
-            filename = str(Path(textPath / pageName))
-            doc.write(filename, encoding="utf-8", xml_declaration=True)
-            if pagesList[i] == coverpageurl:
-                coverpagehtml = os.path.relpath(filename, str(oebps))
-            htmlFiles.append(filename)
-
-        # opf file
-        opfFile = ET.ElementTree()
-        opfRoot = ET.Element("package")
-        opfRoot.set("version", "3.0")
-        opfRoot.set("unique-identifier", "BookId")
-        opfRoot.set("xmlns", "http://www.idpf.org/2007/opf")
-        opfFile._setroot(opfRoot)
-
-        # metadata
-        opfMeta = ET.Element("metadata")
-        opfMeta.set("xmlns:dc", "http://purl.org/dc/elements/1.1/")
-
-        if "language" in self.configDictionary.keys():
-            bookLang = ET.Element("dc:language")
-            bookLang.text = self.configDictionary["language"]
-            opfMeta.append(bookLang)
-        bookTitle = ET.Element("dc:title")
-        if "title" in self.configDictionary.keys():
-            bookTitle.text = str(self.configDictionary["title"])
-        else:
-            bookTitle.text = "Comic with no Name"
-        opfMeta.append(bookTitle)
-        if "authorList" in self.configDictionary.keys():
-            for authorE in range(len(self.configDictionary["authorList"])):
-                authorDict = self.configDictionary["authorList"][authorE]
-                authorType = "dc:creator"
-                if "role" in authorDict.keys():
-                    if str(authorDict["role"]).lower() in ["editor", "assistant \
                editor", "proofreader", "beta"]:
-                        authorType = "dc:contributor"
-                author = ET.Element(authorType)
-                authorName = []
-                if "last-name" in authorDict.keys():
-                    authorName.append(authorDict["last-name"])
-                if "first-name" in authorDict.keys():
-                    authorName.append(authorDict["first-name"])
-                if "initials" in authorDict.keys():
-                    authorName.append(authorDict["initials"])
-                if "nickname" in authorDict.keys():
-                    authorName.append("(" + authorDict["nickname"] + ")")
-                author.text = ", ".join(authorName)
-                opfMeta.append(author)
-                if "role" in authorDict.keys():
-                    author.set("id", "cre" + str(authorE))
-                    role = ET.Element("meta")
-                    role.set("refines", "cre" + str(authorE))
-                    role.set("scheme", "marc:relators")
-                    role.set("property", "role")
-                    role.text = str(authorDict["role"])
-                    opfMeta.append(role)
-
-        if "publishingDate" in self.configDictionary.keys():
-            date = ET.Element("dc:date")
-            date.text = self.configDictionary["publishingDate"]
-            opfMeta.append(date)
-        description = ET.Element("dc:description")
-        if "summary" in self.configDictionary.keys():
-            description.text = self.configDictionary["summary"]
-        else:
-            description.text = "There was no summary upon generation of this file."
-        opfMeta.append(description)
-
-        type = ET.Element("dc:type")
-        type.text = "Comic"
-        opfMeta.append(type)
-        if "publisherName" in self.configDictionary.keys():
-            publisher = ET.Element("dc:publisher")
-            publisher.text = self.configDictionary["publisherName"]
-            opfMeta.append(publisher)
-        if "isbn-number" in self.configDictionary.keys():
-            publishISBN = ET.Element("dc:identifier")
-            publishISBN.text = str("urn:isbn:") + \
                self.configDictionary["isbn-number"]
-            opfMeta.append(publishISBN)
-        if "license" in self.configDictionary.keys():
-            rights = ET.Element("dc:rights")
-            rights.text = self.configDictionary["license"]
-            opfMeta.append(rights)
-
-        if "genre" in self.configDictionary.keys():
-            for g in self.configDictionary["genre"]:
-                subject = ET.Element("dc:subject")
-                subject.text = g
-                opfMeta.append(subject)
-        if "characters" in self.configDictionary.keys():
-            for name in self.configDictionary["characters"]:
-                char = ET.Element("dc:subject")
-                char.text = name
-                opfMeta.append(char)
-        if "format" in self.configDictionary.keys():
-            for format in self.configDictionary["format"]:
-                f = ET.Element("dc:subject")
-                f.text = format
-                opfMeta.append(f)
-        if "otherKeywords" in self.configDictionary.keys():
-            for key in self.configDictionary["otherKeywords"]:
-                word = ET.Element("dc:subject")
-                word.text = key
-                opfMeta.append(word)
-
-        opfRoot.append(opfMeta)
-
-        opfManifest = ET.Element("manifest")
-        toc = ET.Element("item")
-        toc.set("id", "ncx")
-        toc.set("href", "toc.ncx")
-        toc.set("media-type", "application/x-dtbncx+xml")
-        opfManifest.append(toc)
-        for p in htmlFiles:
-            item = ET.Element("item")
-            item.set("id", os.path.basename(p))
-            item.set("href", os.path.relpath(p, str(oebps)))
-            item.set("media-type", "application/xhtml+xml")
-            opfManifest.append(item)
-        for p in pagesList:
-            item = ET.Element("item")
-            item.set("id", os.path.basename(p))
-            item.set("href", os.path.relpath(p, str(oebps)))
-            item.set("media-type", "image/png")
-            if os.path.basename(p) == os.path.basename(coverpageurl):
-                item.set("properties", "cover-image")
-            opfManifest.append(item)
-
-        opfRoot.append(opfManifest)
-
-        opfSpine = ET.Element("spine")
-        opfSpine.set("toc", "ncx")
-        for p in htmlFiles:
-            item = ET.Element("itemref")
-            item.set("idref", os.path.basename(p))
-            opfSpine.append(item)
-        opfRoot.append(opfSpine)
-
-        opfGuide = ET.Element("guide")
-        if coverpagehtml is not None and coverpagehtml.isspace() is False and \
                len(coverpagehtml) > 0:
-            item = ET.Element("reference")
-            item.set("type", "cover")
-            item.set("title", "Cover")
-            item.set("href", coverpagehtml)
-        opfRoot.append(opfGuide)
-
-        opfFile.write(str(Path(oebps / "content.opf")), encoding="utf-8", \
                xml_declaration=True)
-        # toc
-        tocDoc = ET.ElementTree()
-        ncx = ET.Element("ncx")
-        ncx.set("version", "2005-1")
-        ncx.set("xmlns", "http://www.daisy.org/z3986/2005/ncx/")
-        tocDoc._setroot(ncx)
-
-        tocHead = ET.Element("head")
-        metaID = ET.Element("meta")
-        metaID.set("content", "ID_UNKNOWN")
-        metaID.set("name", "dtb:uid")
-        tocHead.append(metaID)
-        metaDepth = ET.Element("meta")
-        metaDepth.set("content", str(0))
-        metaDepth.set("name", "dtb:depth")
-        tocHead.append(metaDepth)
-        metaTotal = ET.Element("meta")
-        metaTotal.set("content", str(0))
-        metaTotal.set("name", "dtb:totalPageCount")
-        tocHead.append(metaTotal)
-        metaMax = ET.Element("meta")
-        metaMax.set("content", str(0))
-        metaMax.set("name", "dtb:maxPageNumber")
-        tocHead.append(metaDepth)
-        ncx.append(tocHead)
-
-        docTitle = ET.Element("docTitle")
-        text = ET.Element("text")
+    def export_to_cbz(self, exportPath):
+        title = self.configDictionary["projectName"]
         if "title" in self.configDictionary.keys():
-            text.text = str(self.configDictionary["title"])
-        else:
-            text.text = "Comic with no Name"
-        docTitle.append(text)
-        ncx.append(docTitle)
-
-        navmap = ET.Element("navMap")
-        navPoint = ET.Element("navPoint")
-        navPoint.set("id", "navPoint-1")
-        navPoint.set("playOrder", "1")
-        navLabel = ET.Element("navLabel")
-        navLabelText = ET.Element("text")
-        navLabelText.text = "Start"
-        navLabel.append(navLabelText)
-        navContent = ET.Element("content")
-        navContent.set("src", os.path.relpath(htmlFiles[0], str(oebps)))
-        navPoint.append(navLabel)
-        navPoint.append(navContent)
-        navmap.append(navPoint)
-        ncx.append(navmap)
-
-        tocDoc.write(str(Path(oebps / "toc.ncx")), encoding="utf-8", \
                xml_declaration=True)
-
-        self.package_epub()
-        return True
+            title = self.configDictionary["title"]
+        self.cometLocation = str(exportPath / "metadata"/ str(title + " CoMet.xml"))
+        export_success = exporters.CoMet.write_xml(self.configDictionary, \
self.pagesLocationList["CBZ"], self.cometLocation) +        self.comicRackInfo = \
str(exportPath / "metadata"/ "ComicInfo.xml") +        export_success = \
exporters.comic_rack_xml.write_xml(self.configDictionary, \
self.pagesLocationList["CBZ"], self.comicRackInfo) +        \
self.package_cbz(exportPath) +        return export_success
 
     def save_out_pngs(self, sizesList):
         # A small fix to ensure crop to guides is set.
@@ -505,7 +227,7 @@ class comicsExporter():
                     progress.setLabelText(str(i18n("{pages} of {pagesTotal} done. \
\nTime passed: {passedString}:\n Estimated:{estimated}")).format(pages=p, \
pagesTotal=len(pagesList), passedString=passedString, estimated=estimatedString))  \
qApp.processEvents()  # Get the appropriate url and open the page.
-                url = os.path.join(self.projectURL, pagesList[p])
+                url = str(Path(self.projectURL)/ pagesList[p])
                 page = Application.openDocument(url)
                 page.waitForDone()
 
@@ -597,7 +319,7 @@ class comicsExporter():
                     if Path(exportPath / folderName).exists() is False:
                         Path.mkdir(exportPath / folderName)
                     # Get a nice and descriptive fle name.
-                    fn = os.path.join(str(Path(exportPath / folderName)), "page_" + \
format(p, "03d") + "_" + str(listScales[0]) + "x" + str(listScales[1]) + "." + \
w["FileType"]) +                    fn = str(Path(exportPath / folderName) / \
str("page_" + format(p, "03d") + "_" + str(listScales[0]) + "x" + str(listScales[1]) \
                + "." + w["FileType"]))
                     # Finally save and add the page to a list of pages. This will \
make it easy for the packaging function to  # find the pages and store them.
                     projection.exportImage(fn, InfoObject())
@@ -841,733 +563,11 @@ class comicsExporter():
                 for child in node.childNodes():
                     self.removeLayers(labels, node=child)
 
-    """
-    Write the Advanced Comic Book Data xml file.
-    
-    http://acbf.wikia.com/wiki/ACBF_Specifications
-    
-    """
-
-    def write_acbf_meta_data(self):
-        acbfGenreList = ["science_fiction", "fantasy", "adventure", "horror", \
"mystery", "crime", "military", "real_life", "superhero", "humor", "western", \
"manga", "politics", "caricature", "sports", "history", "biography", "education", \
"computer", "religion", "romance", "children", "non-fiction", "adult", "alternative", \
                "other", "artbook"]
-        acbfAuthorRolesList = ["Writer", "Adapter", "Artist", "Penciller", "Inker", \
"Colorist", "Letterer", "Cover Artist", "Photographer", "Editor", "Assistant Editor", \
                "Translator", "Other", "Designer"]
-        title = self.configDictionary["projectName"]
-        if "title" in self.configDictionary.keys():
-            title = self.configDictionary["title"]
-        location = str(os.path.join(self.projectURL, \
                self.configDictionary["exportLocation"], "metadata", title + \
                ".acbf"))
-        document = minidom.Document()
-        root = document.createElement("ACBF")
-        root.setAttribute("xmlns", "http://www.fictionbook-lib.org/xml/acbf/1.0")
-        document.appendChild(root)
-
-        meta = document.createElement("meta-data")
-
-        bookInfo = document.createElement("book-info")
-        if "authorList" in self.configDictionary.keys():
-            for authorE in range(len(self.configDictionary["authorList"])):
-                author = document.createElement("author")
-                authorDict = self.configDictionary["authorList"][authorE]
-                if "first-name" in authorDict.keys():
-                    authorN = document.createElement("first-name")
-                    \
                authorN.appendChild(document.createTextNode(str(authorDict["first-name"])))
                
-                    author.appendChild(authorN)
-                if "last-name" in authorDict.keys():
-                    authorN = document.createElement("last-name")
-                    \
                authorN.appendChild(document.createTextNode(str(authorDict["last-name"])))
                
-                    author.appendChild(authorN)
-                if "initials" in authorDict.keys():
-                    authorN = document.createElement("middle-name")
-                    \
                authorN.appendChild(document.createTextNode(str(authorDict["initials"])))
                
-                    author.appendChild(authorN)
-                if "nickname" in authorDict.keys():
-                    authorN = document.createElement("nickname")
-                    \
                authorN.appendChild(document.createTextNode(str(authorDict["nickname"])))
                
-                    author.appendChild(authorN)
-                if "homepage" in authorDict.keys():
-                    authorN = document.createElement("home-page")
-                    \
                authorN.appendChild(document.createTextNode(str(authorDict["homepage"])))
                
-                    author.appendChild(authorN)
-                if "email" in authorDict.keys():
-                    authorN = document.createElement("email")
-                    \
                authorN.appendChild(document.createTextNode(str(authorDict["email"])))
                
-                    author.appendChild(authorN)
-                if "role" in authorDict.keys():
-                    if str(authorDict["role"]).title() in acbfAuthorRolesList:
-                        author.setAttribute("activity", str(authorDict["role"]))
-                if "language" in authorDict.keys():
-                    author.setAttribute("lang", str(authorDict["language"]))
-                bookInfo.appendChild(author)
-        bookTitle = document.createElement("book-title")
-        if "title" in self.configDictionary.keys():
-            bookTitle.appendChild(document.createTextNode(str(self.configDictionary["title"])))
                
-        else:
-            bookTitle.appendChild(document.createTextNode(str("Comic with no \
                Name")))
-        bookInfo.appendChild(bookTitle)
-        extraGenres = []
-
-        if "genre" in self.configDictionary.keys():
-            for genre in self.configDictionary["genre"]:
-                genreModified = str(genre).lower()
-                genreModified.replace(" ", "_")
-                if genreModified in acbfGenreList:
-                    bookGenre = document.createElement("genre")
-                    \
                bookGenre.appendChild(document.createTextNode(str(genreModified)))
-                    bookInfo.appendChild(bookGenre)
-                else:
-                    extraGenres.appendChild(genre)
-        annotation = document.createElement("annotation")
-        if "summary" in self.configDictionary.keys():
-            paragraphList = str(self.configDictionary["summary"]).split("\n")
-            for para in paragraphList:
-                p = document.createElement("p")
-                p.appendChild(document.createTextNode(str(para)))
-                annotation.appendChild(p)
-        else:
-            p = document.createElement("p")
-            p.appendChild(document.createTextNode(str("There was no summary upon \
                generation of this file.")))
-            annotation.appendChild(p)
-        bookInfo.appendChild(annotation)
-
-        if "characters" in self.configDictionary.keys():
-            character = document.createElement("characters")
-            for name in self.configDictionary["characters"]:
-                char = document.createElement("name")
-                char.appendChild(document.createTextNode(str(name)))
-                character.appendChild(char)
-            bookInfo.appendChild(character)
-
-        keywords = document.createElement("keywords")
-        stringKeywordsList = []
-        for key in extraGenres:
-            stringKeywordsList.append(str(key))
-        if "otherKeywords" in self.configDictionary.keys():
-            for key in self.configDictionary["otherKeywords"]:
-                stringKeywordsList.append(str(key))
-        if "format" in self.configDictionary.keys():
-            for key in self.configDictionary["format"]:
-                stringKeywordsList.append(str(key))
-        keywords.appendChild(document.createTextNode(", ".join(stringKeywordsList)))
-        bookInfo.appendChild(keywords)
-
-        coverpageurl = ""
-        coverpage = document.createElement("coverpage")
-        if "pages" in self.configDictionary.keys():
-            if "cover" in self.configDictionary.keys():
-                pageList = []
-                pageList = self.configDictionary["pages"]
-                coverNumber = max([pageList.index(self.configDictionary["cover"]), \
                0])
-                image = document.createElement("image")
-                if len(self.pagesLocationList["CBZ"]) >= coverNumber:
-                    coverpageurl = self.pagesLocationList["CBZ"][coverNumber]
-                    image.setAttribute("href", os.path.basename(coverpageurl))
-                coverpage.appendChild(image)
-        bookInfo.appendChild(coverpage)
-
-        if "language" in self.configDictionary.keys():
-            language = document.createElement("languages")
-            textlayer = document.createElement("text-layer")
-            textlayer.setAttribute("lang", self.configDictionary["language"])
-            textlayer.setAttribute("show", "False")
-            textlayerNative = document.createElement("text-layer")
-            textlayerNative.setAttribute("lang", self.configDictionary["language"])
-            textlayerNative.setAttribute("show", "True")
-            language.appendChild(textlayer)
-            language.appendChild(textlayerNative)
-            bookInfo.appendChild(language)
-
-            bookTitle.setAttribute("lang", self.configDictionary["language"])
-            annotation.setAttribute("lang", self.configDictionary["language"])
-            keywords.setAttribute("lang", self.configDictionary["language"])
-        #database = document.createElement("databaseref")
-        # bookInfo.appendChild(database)
-
-        if "seriesName" in self.configDictionary.keys():
-            sequence = document.createElement("sequence")
-            sequence.setAttribute("title", self.configDictionary["seriesName"])
-            if "seriesVolume" in self.configDictionary.keys():
-                sequence.setAttribute("volume", \
                str(self.configDictionary["seriesVolume"]))
-            if "seriesNumber" in self.configDictionary.keys():
-                sequence.appendChild(document.createTextNode(str(self.configDictionary["seriesNumber"])))
                
-            else:
-                sequence.appendChild(document.createTextNode(str(0)))
-            bookInfo.appendChild(sequence)
-        contentrating = document.createElement("content-rating")
-
-        if "rating" in self.configDictionary.keys():
-            contentrating.appendChild(document.createTextNode(str(self.configDictionary["rating"])))
                
-        else:
-            contentrating.appendChild(document.createTextNode(str("Unrated.")))
-        if "ratingSystem" in self.configDictionary.keys():
-            contentrating.setAttribute("type", \
                self.configDictionary["ratingSystem"])
-        bookInfo.appendChild(contentrating)
-
-        if "readingDirection" in self.configDictionary.keys():
-            readingDirection = document.createElement("reading-direction")
-            if self.configDictionary["readingDirection"] is "rightToLeft":
-                readingDirection.appendChild(document.createTextNode(str("RTL")))
-            else:
-                readingDirection.appendChild(document.createTextNode(str("LTR")))
-            bookInfo.appendChild(readingDirection)
-        meta.appendChild(bookInfo)
-
-        publisherInfo = document.createElement("publish-info")
-        if "publisherName" in self.configDictionary.keys():
-            publisherName = document.createElement("publisher")
-            publisherName.appendChild(document.createTextNode(str(self.configDictionary["publisherName"])))
                
-            publisherInfo.appendChild(publisherName)
-        if "publishingDate" in self.configDictionary.keys():
-            publishingDate = document.createElement("publish-date")
-            publishingDate.setAttribute("value", \
                self.configDictionary["publishingDate"])
-            publishingDate.appendChild(document.createTextNode(QDate.fromString(self.configDictionary["publishingDate"], \
                Qt.ISODate).toString(Qt.SystemLocaleLongDate)))
-            publisherInfo.appendChild(publishingDate)
-        if "publisherCity" in self.configDictionary.keys():
-            publishCity = document.createElement("city")
-            publishCity.appendChild(document.createTextNode(str(self.configDictionary["publisherCity"])))
                
-            publisherInfo.appendChild(publishCity)
-        if "isbn-number" in self.configDictionary.keys():
-            publishISBN = document.createElement("isbn")
-            publishISBN.appendChild(document.createTextNode(str(self.configDictionary["isbn-number"])))
                
-            publisherInfo.appendChild(publishISBN)
-        if "license" in self.configDictionary.keys():
-            license = self.configDictionary["license"]
-            if license.isspace() is False and len(license) > 0:
-                publishLicense = document.createElement("license")
-                publishLicense.appendChild(document.createTextNode(str(self.configDictionary["license"])))
                
-                publisherInfo.appendChild(publishLicense)
-
-        meta.appendChild(publisherInfo)
-
-        documentInfo = document.createElement("document-info")
-        # TODO: ACBF apparantly uses first/middle/last/nick/email/homepage for the \
                document auhtor too...
-        #      The following code compensates for me not understanding this \
                initially. This still needs
-        #      adjustments in the gui.
-        if "acbfAuthor" in self.configDictionary.keys():
-            if isinstance(self.configDictionary["acbfAuthor"], list):
-                for e in self.configDictionary["acbfAuthor"]:
-                    acbfAuthor = document.createElement("author")
-                    authorDict = self.configDictionary["acbfAuthor"][e]
-                    if "first-name" in authorDict.keys():
-                        authorN = document.createElement("first-name")
-                        \
                authorN.appendChild(document.createTextNode(str(authorDict["first-name"])))
                
-                        acbfAuthor.appendChild(authorN)
-                    if "last-name" in authorDict.keys():
-                        authorN = document.createElement("last-name")
-                        \
                authorN.appendChild(document.createTextNode(str(authorDict["last-name"])))
                
-                        acbfAuthor.appendChild(authorN)
-                    if "initials" in authorDict.keys():
-                        authorN = document.createElement("middle-name")
-                        \
                authorN.appendChild(document.createTextNode(str(authorDict["initials"])))
                
-                        acbfAuthor.appendChild(authorN)
-                    if "nickname" in authorDict.keys():
-                        authorN = document.createElement("nickname")
-                        \
                authorN.appendChild(document.createTextNode(str(authorDict["nickname"])))
                
-                        acbfAuthor.appendChild(authorN)
-                    if "homepage" in authorDict.keys():
-                        authorN = document.createElement("homepage")
-                        \
                authorN.appendChild(document.createTextNode(str(authorDict["home-page"])))
                
-                        acbfAuthor.appendChild(authorN)
-                    if "email" in authorDict.keys():
-                        authorN = document.createElement("email")
-                        \
                authorN.appendChild(document.createTextNode(str(authorDict["email"])))
                
-                        acbfAuthor.appendChild(authorN)
-                    if "language" in authorDict.keys():
-                        acbfAuthor.setAttribute("lang", str(authorDict["language"]))
-                    documentInfo.appendChild(acbfAuthor)
-            else:
-                acbfAuthor = document.createElement("author")
-                acbfAuthorNick = document.createElement("nickname")
-                acbfAuthorNick.appendChild(document.createTextNode(str(self.configDictionary["acbfAuthor"])))
                
-                acbfAuthor.appendChild(acbfAuthorNick)
-                documentInfo.appendChild(acbfAuthor)
-        else:
-            acbfAuthor = document.createElement("author")
-            acbfAuthorNick = document.createElement("nickname")
-            acbfAuthorNick.appendChild(document.createTextNode(str("Anon")))
-            acbfAuthor.appendChild(acbfAuthorNick)
-            documentInfo.appendChild(acbfAuthor)
-
-        acbfDate = document.createElement("creation-date")
-        now = QDate.currentDate()
-        acbfDate.setAttribute("value", now.toString(Qt.ISODate))
-        acbfDate.appendChild(document.createTextNode(str(now.toString(Qt.SystemLocaleLongDate))))
                
-        documentInfo.appendChild(acbfDate)
-
-        if "acbfSource" in self.configDictionary.keys():
-            acbfSource = document.createElement("source")
-            acbfSourceP = document.createElement("p")
-            acbfSourceP.appendChild(document.createTextNode(str(self.configDictionary["acbfSource"])))
                
-            acbfSource.appendChild(acbfSourceP)
-            documentInfo.appendChild(acbfSource)
-
-        if "acbfID" in self.configDictionary.keys():
-            acbfID = document.createElement("id")
-            acbfID.appendChild(document.createTextNode(str(self.configDictionary["acbfID"])))
                
-            documentInfo.appendChild(acbfID)
-
-        if "acbfVersion" in self.configDictionary.keys():
-            acbfVersion = document.createElement("version")
-            acbfVersion.appendChild(document.createTextNode(str(self.configDictionary["acbfVersion"])))
                
-            documentInfo.appendChild(acbfVersion)
-
-        if "acbfHistory" in self.configDictionary.keys():
-            acbfHistory = document.createElement("history")
-            for h in self.configDictionary["acbfHistory"]:
-                p = document.createElement("p")
-                p.appendChild(document.createTextNode(str(h)))
-                acbfHistory.appendChild(p)
-            documentInfo.appendChild(acbfHistory)
-        meta.appendChild(documentInfo)
-
-        root.appendChild(meta)
-
-        body = document.createElement("body")
-
-        for p in range(0, len(self.pagesLocationList["CBZ"])):
-            page = self.pagesLocationList["CBZ"][p]
-            language = "en"
-            if "language" in self.configDictionary.keys():
-                language = self.configDictionary["language"]
-            textLayer = document.createElement("text-layer")
-            textLayer.setAttribute("lang", language)
-            pageData = self.acbfPageData[p]
-            transform = pageData["transform"]
-            frameList = []
-            for v in pageData["vector"]:
-                boundingBoxText = []
-                for point in v["boundingBox"]:
-                    offset = QPointF(transform["offsetX"], transform["offsetY"])
-                    pixelPoint = QPointF(point.x() * transform["resDiff"], point.y() \
                * transform["resDiff"])
-                    newPoint = pixelPoint - offset
-                    x = int(newPoint.x() * transform["scaleWidth"])
-                    y = int(newPoint.y() * transform["scaleHeight"])
-                    pointText = str(x) + "," + str(y)
-                    boundingBoxText.append(pointText)
-
-                if "text" in v.keys():
-                    textArea = document.createElement("text-area")
-                    textArea.setAttribute("points", " ".join(boundingBoxText))
-                    # TODO: Rotate will require proper global transform api as \
transform info is not written intotext.                        \
                #textArea.setAttribute("text-rotation", str(v["rotate"]))
-                    paragraph = minidom.parseString(v["text"])
-                    textArea.appendChild(paragraph.documentElement)
-                    textLayer.appendChild(textArea)
-                else:
-                    f = {}
-                    f["points"] = " ".join(boundingBoxText)
-                    frameList.append(f)
-            if page is not coverpageurl:
-                pg = document.createElement("page")
-                image = document.createElement("image")
-                image.setAttribute("href", os.path.basename(page))
-                pg.appendChild(image)
-                if "acbf_title" in pageData["keys"]:
-                    title = document.createElement("title")
-                    title.setAttribute("lang", language)
-                    \
                title.appendChild(document.createTextNode(str(pageData["title"])))
-                    pg.appendChild(title)
-                if "acbf_none" in pageData["keys"]:
-                    pg.setAttribute("transition", "none")
-                if "acbf_blend" in pageData["keys"]:
-                    pg.setAttribute("transition", "blend")
-                if "acbf_fade" in pageData["keys"]:
-                    pg.setAttribute("transition", "fade")
-                if "acbf_horizontal" in pageData["keys"]:
-                    pg.setAttribute("transition", "scroll_right")
-                if "acbf_vertical" in pageData["keys"]:
-                    pg.setAttribute("transition", "scroll_down")
-                for f in frameList:
-                    frame = document.createElement("frame")
-                    frame.setAttribute("points", f["points"])
-                    pg.appendChild(frame)
-                pg.appendChild(textLayer)
-                body.appendChild(pg)
-            else:
-                for f in frameList:
-                    frame = document.createElement("frame")
-                    frame.setAttribute("points", f["points"])
-                    coverpage.appendChild(frame)
-                coverpage.appendChild(textLayer)
-
-        root.appendChild(body)
-
-        f = open(location, 'w', newline="", encoding="utf-8")
-        f.write(document.toprettyxml(indent="  "))
-        f.close()
-        self.acbfLocation = location
-        success = True
-        success = self.createStandAloneACBF(document)
-        return success
-
-    def createStandAloneACBF(self, document):
-        title = self.configDictionary["projectName"]
-        if "title" in self.configDictionary.keys():
-            title = self.configDictionary["title"]
-        location = str(os.path.join(self.projectURL, \
                self.configDictionary["exportLocation"], title + ".acbf"))
-        root = document.getElementsByTagName("ACBF")[0]
-        meta = root.getElementsByTagName("meta-data")[0]
-        bookInfo = meta.getElementsByTagName("book-info")[0]
-        cover = bookInfo.getElementsByTagName("coverpage")[0]
-
-        body = root.getElementsByTagName("body")[0]
-        pages = body.getElementsByTagName("page")
-        if (cover):
-            pages.append(cover)
-
-        data = document.createElement("data")
-
-        # Covert pages to base64 strings.
-        for i in range(0, len(pages)):
-            image = pages[i].getElementsByTagName("image")[0]
-            href = image.getAttribute("href")
-            for p in self.pagesLocationList["CBZ"]:
-                if href in p:
-                    binary = document.createElement("binary")
-                    binary.setAttribute("id", href)
-                    imageFile = QImage()
-                    imageFile.load(p)
-                    imageData = QByteArray()
-                    buffer = QBuffer(imageData)
-                    imageFile.save(buffer, "PNG")
-                    # For now always embed as png.
-                    contentType = "image/png"
-                    binary.setAttribute("content-type", contentType)
-                    \
binary.appendChild(document.createTextNode(str(bytearray(imageData.toBase64()).decode("ascii"))))
                
-
-                    image.setAttribute("href", "#" + href)
-                    data.appendChild(binary)
-
-        root.appendChild(data)
-
-        f = open(location, 'w', newline="", encoding="utf-8")
-        f.write(document.toprettyxml(indent="  "))
-        f.close()
-        return True
-
-    """
-    Write a CoMet xml file to url
-    """
-
-    def write_comet_meta_data(self):
-        title = self.configDictionary["projectName"]
-        if "title" in self.configDictionary.keys():
-            title = self.configDictionary["title"]
-        location = str(os.path.join(self.projectURL, \
                self.configDictionary["exportLocation"], "metadata", title + " \
                CoMet.xml"))
-        document = minidom.Document()
-        root = document.createElement("comet")
-        root.setAttribute("xmlns:comet", "http://www.denvog.com/comet/")
-        root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
-        root.setAttribute("xsi:schemaLocation", "http://www.denvog.com \
                http://www.denvog.com/comet/comet.xsd")
-        document.appendChild(root)
-
-        title = document.createElement("title")
-        if "title" in self.configDictionary.keys():
-            title.appendChild(document.createTextNode(str(self.configDictionary["title"])))
                
-        else:
-            title.appendChild(document.createTextNode(str("Untitled Comic")))
-        root.appendChild(title)
-        description = document.createElement("description")
-        if "summary" in self.configDictionary.keys():
-            description.appendChild(document.createTextNode(str(self.configDictionary["summary"])))
                
-        else:
-            description.appendChild(document.createTextNode(str("There was no \
                summary upon generation of this file.")))
-        root.appendChild(description)
-        if "seriesName" in self.configDictionary.keys():
-            series = document.createElement("series")
-            series.appendChild(document.createTextNode(str(self.configDictionary["seriesName"])))
                
-            root.appendChild(series)
-            if "seriesNumber" in self.configDictionary.keys():
-                issue = document.createElement("issue")
-                issue.appendChild(document.createTextNode(str(self.configDictionary["seriesNumber"])))
                
-                root.appendChild(issue)
-            if "seriesVolume" in self.configDictionary.keys():
-                volume = document.createElement("volume")
-                volume.appendChild(document.createTextNode(str(self.configDictionary["seriesVolume"])))
                
-                root.appendChild(volume)
-
-        if "publisherName" in self.configDictionary.keys():
-            publisher = document.createElement("publisher")
-            publisher.appendChild(document.createTextNode(str(self.configDictionary["publisherName"])))
                
-            root.appendChild(publisher)
-
-        if "publishingDate" in self.configDictionary.keys():
-            date = document.createElement("date")
-            date.appendChild(document.createTextNode(str(self.configDictionary["publishingDate"])))
                
-            root.appendChild(date)
-
-        if "genre" in self.configDictionary.keys():
-            for genreE in self.configDictionary["genre"]:
-                genre = document.createElement("genre")
-                genre.appendChild(document.createTextNode(str(genreE)))
-                root.appendChild(genre)
-
-        if "characters" in self.configDictionary.keys():
-            for char in self.configDictionary["characters"]:
-                character = document.createElement("character")
-                character.appendChild(document.createTextNode(str(char)))
-                root.appendChild(character)
-
-        if "format" in self.configDictionary.keys():
-            format = document.createElement("format")
-            format.appendChild(document.createTextNode(str(",".join(self.configDictionary["format"]))))
                
-            root.appendChild(format)
-
-        if "language" in self.configDictionary.keys():
-            language = document.createElement("language")
-            language.appendChild(document.createTextNode(str(self.configDictionary["language"])))
                
-            root.appendChild(language)
-        if "rating" in self.configDictionary.keys():
-            rating = document.createElement("rating")
-            rating.appendChild(document.createTextNode(str(self.configDictionary["rating"])))
                
-            root.appendChild(rating)
-        #rights = document.createElement("rights")
-        if "pages" in self.configDictionary.keys():
-            pages = document.createElement("pages")
-            pages.appendChild(document.createTextNode(str(len(self.configDictionary["pages"]))))
                
-            root.appendChild(pages)
-
-        if "isbn-number" in self.configDictionary.keys():
-            identifier = document.createElement("identifier")
-            identifier.appendChild(document.createTextNode(str(self.configDictionary["isbn-number"])))
                
-            root.appendChild(identifier)
-
-        if "authorList" in self.configDictionary.keys():
-            for authorE in range(len(self.configDictionary["authorList"])):
-                author = document.createElement("creator")
-                authorDict = self.configDictionary["authorList"][authorE]
-                if "role" in authorDict.keys():
-                    if str(authorDict["role"]).lower() in ["writer", "penciller", \
                "editor", "assistant editor", "cover artist", "letterer", "inker", \
                "colorist"]:
-                        if str(authorDict["role"]).lower() is "cover artist":
-                            author = document.createElement("coverDesigner")
-                        elif str(authorDict["role"]).lower() is "assistant editor":
-                            author = document.createElement("editor")
-                        else:
-                            author = \
                document.createElement(str(authorDict["role"]).lower())
-                stringName = []
-                if "last-name" in authorDict.keys():
-                    stringName.append(authorDict["last-name"])
-                if "first-name" in authorDict.keys():
-                    stringName.append(authorDict["first-name"])
-                if "nickname" in authorDict.keys():
-                    stringName.append("(" + authorDict["nickname"] + ")")
-                author.appendChild(document.createTextNode(str(",".join(stringName))))
                
-                root.appendChild(author)
-
-        if "pages" in self.configDictionary.keys():
-            if "cover" in self.configDictionary.keys():
-                pageList = []
-                pageList = self.configDictionary["pages"]
-                coverNumber = pageList.index(self.configDictionary["cover"])
-                if len(self.pagesLocationList["CBZ"]) >= coverNumber:
-                    coverImage = document.createElement("coverImage")
-                    \
coverImage.appendChild(document.createTextNode(str(os.path.basename(self.pagesLocationList["CBZ"][coverNumber]))))
                
-                    root.appendChild(coverImage)
-        readingDirection = document.createElement("readingDirection")
-        readingDirection.appendChild(document.createTextNode(str("ltr")))
-        if "readingDirection" in self.configDictionary.keys():
-            if self.configDictionary["readingDirection"] is "rightToLeft":
-                readingDirection.appendChild(document.createTextNode(str("rtl")))
-        root.appendChild(readingDirection)
-
-        f = open(location, 'w', newline="", encoding="utf-8")
-        f.write(document.toprettyxml(indent="  "))
-        f.close()
-        self.cometLocation = location
-        return True
-    """
-    The comicrack information is sorta... incomplete, so no idea if the following is \
                right...
-    I can't check in any case: It is a windows application.
-    """
-
-    def write_comic_rack_info(self):
-        location = str(os.path.join(self.projectURL, \
                self.configDictionary["exportLocation"], "metadata", \
                "ComicInfo.xml"))
-        document = minidom.Document()
-        root = document.createElement("ComicInfo")
-        root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
-        root.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema")
-
-        title = document.createElement("Title")
-        if "title" in self.configDictionary.keys():
-            title.appendChild(document.createTextNode(str(self.configDictionary["title"])))
                
-        else:
-            title.appendChild(document.createTextNode(str("Untitled Comic")))
-        root.appendChild(title)
-        description = document.createElement("Summary")
-        if "summary" in self.configDictionary.keys():
-            description.appendChild(document.createTextNode(str(self.configDictionary["summary"])))
                
-        else:
-            description.appendChild(document.createTextNode(str("There was no \
                summary upon generation of this file.")))
-        root.appendChild(description)
-        if "seriesNumber" in self.configDictionary.keys():
-            number = document.createElement("Number")
-            number.appendChild(document.createTextNode(str(self.configDictionary["seriesNumber"])))
                
-            root.appendChild(number)
-
-        if "publishingDate" in self.configDictionary.keys():
-            date = QDate.fromString(self.configDictionary["publishingDate"], \
                Qt.ISODate)
-            publishYear = document.createElement("Year")
-            publishYear.appendChild(document.createTextNode(str(date.year())))
-            publishMonth = document.createElement("Month")
-            publishMonth.appendChild(document.createTextNode(str(date.month())))
-            root.appendChild(publishYear)
-            root.appendChild(publishMonth)
-
-        if "format" in self.configDictionary.keys():
-            for form in self.configDictionary["format"]:
-                formattag = document.createElement("Format")
-                formattag.appendChild(document.createTextNode(str(form)))
-                root.appendChild(formattag)
-        if "otherKeywords" in self.configDictionary.keys():
-            tags = document.createElement("Tags")
-            tags.appendChild(document.createTextNode(str(", \
                ".join(self.configDictionary["otherKeywords"]))))
-            root.appendChild(tags)
-
-        if "authorList" in self.configDictionary.keys():
-            for authorE in range(len(self.configDictionary["authorList"])):
-                author = document.createElement("Writer")
-                authorDict = self.configDictionary["authorList"][authorE]
-                if "role" in authorDict.keys():
-                    if str(authorDict["role"]).lower() in ["writer", "penciller", \
                "editor", "assistant editor", "cover artist", "letterer", "inker", \
                "colorist"]:
-                        if str(authorDict["role"]).lower() is "cover artist":
-                            author = document.createElement("CoverArtist")
-                        elif str(authorDict["role"]).lower() is "assistant editor":
-                            author = document.createElement("Editor")
-                        else:
-                            author = \
                document.createElement(str(authorDict["role"]).title())
-                stringName = []
-                if "last-name" in authorDict.keys():
-                    stringName.append(authorDict["last-name"])
-                if "first-name" in authorDict.keys():
-                    stringName.append(authorDict["first-name"])
-                if "nickname" in authorDict.keys():
-                    stringName.append("(" + authorDict["nickname"] + ")")
-                author.appendChild(document.createTextNode(str(",".join(stringName))))
                
-                root.appendChild(author)
-        if "publisherName" in self.configDictionary.keys():
-            publisher = document.createElement("Publisher")
-            publisher.appendChild(document.createTextNode(str(self.configDictionary["publisherName"])))
                
-            root.appendChild(publisher)
-
-        if "genre" in self.configDictionary.keys():
-            for genreE in self.configDictionary["genre"]:
-                genre = document.createElement("Genre")
-                genre.appendChild(document.createTextNode(str(genreE)))
-                root.appendChild(genre)
-        blackAndWhite = document.createElement("BlackAndWhite")
-        blackAndWhite.appendChild(document.createTextNode(str("No")))
-        root.appendChild(blackAndWhite)
-        readingDirection = document.createElement("Manga")
-        readingDirection.appendChild(document.createTextNode(str("No")))
-        if "readingDirection" in self.configDictionary.keys():
-            if self.configDictionary["readingDirection"] is "rightToLeft":
-                readingDirection.appendChild(document.createTextNode(str("Yes")))
-        root.appendChild(readingDirection)
-
-        if "characters" in self.configDictionary.keys():
-            for char in self.configDictionary["characters"]:
-                character = document.createElement("Character")
-                character.appendChild(document.createTextNode(str(char)))
-                root.appendChild(character)
-        if "pages" in self.configDictionary.keys():
-            pagecount = document.createElement("PageCount")
-            pagecount.appendChild(document.createTextNode(str(len(self.configDictionary["pages"]))))
                
-            root.appendChild(pagecount)
-        pages = document.createElement("Pages")
-        covernumber = 0
-        if "pages" in self.configDictionary.keys() and "cover" in \
                self.configDictionary.keys():
-            covernumber = \
                self.configDictionary["pages"].index(self.configDictionary["cover"])
-        for i in range(len(self.pagesLocationList["CBZ"])):
-            page = document.createElement("Page")
-            page.setAttribute("Image", str(i))
-            if i is covernumber:
-                page.setAttribute("Type", "FrontCover")
-            pages.appendChild(page)
-        root.appendChild(pages)
-        document.appendChild(root)
-        f = open(location, 'w', newline="", encoding="utf-8")
-        f.write(document.toprettyxml(indent="  "))
-        f.close()
-        self.comicRackInfo = location
-        return True
-    """
-    Another metadata format but then a json dump stored into the zipfile comment.
-    Doesn't seem to be supported much. :/
-    https://code.google.com/archive/p/comicbookinfo/wikis/Example.wiki
-    """
-
-    def write_comic_book_info_json(self):
-        self.comic_book_info_json_dump = str()
-
-        basedata = {}
-        metadata = {}
-        authorList = []
-        taglist = []
-
-        if "authorList" in self.configDictionary.keys():
-            for authorE in range(len(self.configDictionary["authorList"])):
-                author = {}
-
-                authorDict = self.configDictionary["authorList"][authorE]
-                stringName = []
-                if "last-name" in authorDict.keys():
-                    stringName.append(authorDict["last-name"])
-                if "first-name" in authorDict.keys():
-                    stringName.append(authorDict["first-name"])
-                if "nickname" in authorDict.keys():
-                    stringName.append("(" + authorDict["nickname"] + ")")
-                author["person"] = ",".join(stringName)
-                if "role" in authorDict.keys():
-                    author["role"] = str(authorDict["role"]).title()
-                authorList.append(author)
-        if "characters" in self.configDictionary.keys():
-            for character in self.configDictionary["characters"]:
-                taglist.append(character)
-        if "format" in self.configDictionary.keys():
-            for item in self.configDictionary["format"]:
-                taglist.append(item)
-        if "otherKeywords" in self.configDictionary.keys():
-            for item in self.configDictionary["otherKeywords"]:
-                taglist.append(item)
-
-        if "seriesName" in self.configDictionary.keys():
-            metadata["series"] = self.configDictionary["seriesName"]
-        if "title" in self.configDictionary.keys():
-            metadata["title"] = self.configDictionary["title"]
-        else:
-            metadata["title"] = "Unnamed comic"
-        if "publisherName" in self.configDictionary.keys():
-            metadata["publisher"] = self.configDictionary["publisherName"]
-        if "publishingDate" in self.configDictionary.keys():
-            date = QDate.fromString(self.configDictionary["publishingDate"], \
                Qt.ISODate)
-            metadata["publicationMonth"] = date.month()
-            metadata["publicationYear"] = date.year()
-        if "seriesNumber" in self.configDictionary.keys():
-            metadata["issue"] = self.configDictionary["seriesNumber"]
-        if "seriesVolume" in self.configDictionary.keys():
-            metadata["volume"] = self.configDictionary["seriesVolume"]
-        if "genre" in self.configDictionary.keys():
-            metadata["genre"] = self.configDictionary["genre"]
-        if "language" in self.configDictionary.keys():
-            metadata["language"] = \
                QLocale.languageToString(QLocale(self.configDictionary["language"]).language())
                
-
-        metadata["credits"] = authorList
-
-        metadata["tags"] = taglist
-        if "summary" in self.configDictionary.keys():
-            metadata["comments"] = self.configDictionary["summary"]
-        else:
-            metadata["comments"] = "File generated without summary"
-
-        basedata["appID"] = "Krita"
-        basedata["lastModified"] = \
                QDateTime.currentDateTimeUtc().toString(Qt.ISODate)
-        basedata["ComicBookInfo/1.0"] = metadata
-
-        self.comic_book_info_json_dump = json.dumps(basedata)
-        return True
-
     """
     package cbz puts all the meta-data and relevant files into an zip file ending \
with ".cbz"  """
 
-    def package_cbz(self):
+    def package_cbz(self, exportPath):
 
         # Use the project name if there's no title to avoid sillyness with unnamed \
zipfiles.  title = self.configDictionary["projectName"]
@@ -1575,43 +575,24 @@ class comicsExporter():
             title = self.configDictionary["title"]
 
         # Get the appropriate path.
-        url = os.path.join(self.projectURL, self.configDictionary["exportLocation"], \
title + ".cbz") +        url = str(exportPath / "metadata"/ str(title + ".cbz"))
 
         # Create a zip file.
         cbzArchive = zipfile.ZipFile(url, mode="w", compression=zipfile.ZIP_STORED)
 
         # Add all the meta data files.
-        cbzArchive.write(self.acbfLocation, os.path.basename(self.acbfLocation))
-        cbzArchive.write(self.cometLocation, os.path.basename(self.cometLocation))
-        cbzArchive.write(self.comicRackInfo, os.path.basename(self.comicRackInfo))
-        cbzArchive.comment = self.comic_book_info_json_dump.encode("utf-8")
+        cbzArchive.write(self.acbfLocation, Path(self.acbfLocation).name)
+        cbzArchive.write(self.cometLocation, Path(self.cometLocation).name)
+        cbzArchive.write(self.comicRackInfo, Path(self.comicRackInfo).name)
+        comic_book_info_json_dump = str()
+        comic_book_info_json_dump = \
exporters.comic_book_info.writeJson(self.configDictionary) +        \
cbzArchive.comment = comic_book_info_json_dump.encode("utf-8")  
         # Add the pages.
         if "CBZ" in self.pagesLocationList.keys():
             for page in self.pagesLocationList["CBZ"]:
-                if (os.path.exists(page)):
-                    cbzArchive.write(page, os.path.basename(page))
+                if (Path(page).exists()):
+                    cbzArchive.write(page, Path(page).name)
 
         # Close the zip file when done.
         cbzArchive.close()
-
-    """
-    package epub packages the whole epub folder and renames the zip file to .epub.
-    """
-
-    def package_epub(self):
-
-        # Use the project name if there's no title to avoid sillyness with unnamed \
                zipfiles.
-        title = self.configDictionary["projectName"]
-        if "title" in self.configDictionary.keys():
-            title = self.configDictionary["title"]
-
-        # Get the appropriate paths.
-        url = os.path.join(self.projectURL, self.configDictionary["exportLocation"], \
                title)
-        epub = os.path.join(self.projectURL, \
                self.configDictionary["exportLocation"], "EPUB-files")
-
-        # Make the archive.
-        shutil.make_archive(base_name=url, format="zip", root_dir=epub)
-
-        # Rename the archive to epub.
-        shutil.move(src=str(url + ".zip"), dst=str(url + ".epub"))
diff --git a/plugins/python/comics_project_management_tools/exporters/CPMT_ACBF_XML_Exporter.py \
b/plugins/python/comics_project_management_tools/exporters/CPMT_ACBF_XML_Exporter.py \
new file mode 100644 index 00000000000..5c7cc7e4a8b
--- /dev/null
+++ b/plugins/python/comics_project_management_tools/exporters/CPMT_ACBF_XML_Exporter.py
 @@ -0,0 +1,418 @@
+"""
+Copyright (c) 2018 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
+
+This file is part of the Comics Project Management Tools(CPMT).
+
+CPMT 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 3 of the License, or
+(at your option) any later version.
+
+CPMT 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 the CPMT.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+"""
+Write the Advanced Comic Book Data xml file.
+
+http://acbf.wikia.com/wiki/ACBF_Specifications
+
+"""
+
+import os
+from xml.dom import minidom
+from PyQt5.QtCore import QDate, Qt, QPointF, QByteArray, QBuffer
+from PyQt5.QtGui import QImage
+
+def write_xml(configDictionary = {}, pageData = [],  pagesLocationList = [], \
locationBasic = str(), locationStandAlone = str()): +    acbfGenreList = \
["science_fiction", "fantasy", "adventure", "horror", "mystery", "crime", "military", \
"real_life", "superhero", "humor", "western", "manga", "politics", "caricature", \
"sports", "history", "biography", "education", "computer", "religion", "romance", \
"children", "non-fiction", "adult", "alternative", "other", "artbook"] +    \
acbfAuthorRolesList = ["Writer", "Adapter", "Artist", "Penciller", "Inker", \
"Colorist", "Letterer", "Cover Artist", "Photographer", "Editor", "Assistant Editor", \
"Translator", "Other", "Designer"] +    document = minidom.Document()
+    root = document.createElement("ACBF")
+    root.setAttribute("xmlns", "http://www.fictionbook-lib.org/xml/acbf/1.0")
+    document.appendChild(root)
+
+    meta = document.createElement("meta-data")
+
+    bookInfo = document.createElement("book-info")
+    if "authorList" in configDictionary.keys():
+        for authorE in range(len(configDictionary["authorList"])):
+            author = document.createElement("author")
+            authorDict = configDictionary["authorList"][authorE]
+            if "first-name" in authorDict.keys():
+                authorN = document.createElement("first-name")
+                authorN.appendChild(document.createTextNode(str(authorDict["first-name"])))
 +                author.appendChild(authorN)
+            if "last-name" in authorDict.keys():
+                authorN = document.createElement("last-name")
+                authorN.appendChild(document.createTextNode(str(authorDict["last-name"])))
 +                author.appendChild(authorN)
+            if "initials" in authorDict.keys():
+                authorN = document.createElement("middle-name")
+                authorN.appendChild(document.createTextNode(str(authorDict["initials"])))
 +                author.appendChild(authorN)
+            if "nickname" in authorDict.keys():
+                authorN = document.createElement("nickname")
+                authorN.appendChild(document.createTextNode(str(authorDict["nickname"])))
 +                author.appendChild(authorN)
+            if "homepage" in authorDict.keys():
+                authorN = document.createElement("home-page")
+                authorN.appendChild(document.createTextNode(str(authorDict["homepage"])))
 +                author.appendChild(authorN)
+            if "email" in authorDict.keys():
+                authorN = document.createElement("email")
+                authorN.appendChild(document.createTextNode(str(authorDict["email"])))
 +                author.appendChild(authorN)
+            if "role" in authorDict.keys():
+                if str(authorDict["role"]).title() in acbfAuthorRolesList:
+                    author.setAttribute("activity", str(authorDict["role"]))
+            if "language" in authorDict.keys():
+                author.setAttribute("lang", str(authorDict["language"]))
+            bookInfo.appendChild(author)
+    bookTitle = document.createElement("book-title")
+    if "title" in configDictionary.keys():
+        bookTitle.appendChild(document.createTextNode(str(configDictionary["title"])))
 +    else:
+        bookTitle.appendChild(document.createTextNode(str("Comic with no Name")))
+    bookInfo.appendChild(bookTitle)
+    extraGenres = []
+
+    if "genre" in configDictionary.keys():
+        for genre in configDictionary["genre"]:
+            genreModified = str(genre).lower()
+            genreModified.replace(" ", "_")
+            if genreModified in acbfGenreList:
+                bookGenre = document.createElement("genre")
+                bookGenre.appendChild(document.createTextNode(str(genreModified)))
+                bookInfo.appendChild(bookGenre)
+            else:
+                extraGenres.appendChild(genre)
+    annotation = document.createElement("annotation")
+    if "summary" in configDictionary.keys():
+        paragraphList = str(configDictionary["summary"]).split("\n")
+        for para in paragraphList:
+            p = document.createElement("p")
+            p.appendChild(document.createTextNode(str(para)))
+            annotation.appendChild(p)
+    else:
+        p = document.createElement("p")
+        p.appendChild(document.createTextNode(str("There was no summary upon \
generation of this file."))) +        annotation.appendChild(p)
+    bookInfo.appendChild(annotation)
+
+    if "characters" in configDictionary.keys():
+        character = document.createElement("characters")
+        for name in configDictionary["characters"]:
+            char = document.createElement("name")
+            char.appendChild(document.createTextNode(str(name)))
+            character.appendChild(char)
+        bookInfo.appendChild(character)
+
+    keywords = document.createElement("keywords")
+    stringKeywordsList = []
+    for key in extraGenres:
+        stringKeywordsList.append(str(key))
+    if "otherKeywords" in configDictionary.keys():
+        for key in configDictionary["otherKeywords"]:
+            stringKeywordsList.append(str(key))
+    if "format" in configDictionary.keys():
+        for key in configDictionary["format"]:
+            stringKeywordsList.append(str(key))
+    keywords.appendChild(document.createTextNode(", ".join(stringKeywordsList)))
+    bookInfo.appendChild(keywords)
+
+    coverpageurl = ""
+    coverpage = document.createElement("coverpage")
+    if "pages" in configDictionary.keys():
+        if "cover" in configDictionary.keys():
+            pageList = []
+            pageList = configDictionary["pages"]
+            coverNumber = max([pageList.index(configDictionary["cover"]), 0])
+            image = document.createElement("image")
+            if len(pagesLocationList) >= coverNumber:
+                coverpageurl = pagesLocationList[coverNumber]
+                image.setAttribute("href", os.path.basename(coverpageurl))
+            coverpage.appendChild(image)
+    bookInfo.appendChild(coverpage)
+
+    if "language" in configDictionary.keys():
+        language = document.createElement("languages")
+        textlayer = document.createElement("text-layer")
+        textlayer.setAttribute("lang", configDictionary["language"])
+        textlayer.setAttribute("show", "False")
+        textlayerNative = document.createElement("text-layer")
+        textlayerNative.setAttribute("lang", configDictionary["language"])
+        textlayerNative.setAttribute("show", "True")
+        language.appendChild(textlayer)
+        language.appendChild(textlayerNative)
+        bookInfo.appendChild(language)
+
+        bookTitle.setAttribute("lang", configDictionary["language"])
+        annotation.setAttribute("lang", configDictionary["language"])
+        keywords.setAttribute("lang", configDictionary["language"])
+    #database = document.createElement("databaseref")
+    # bookInfo.appendChild(database)
+
+    if "seriesName" in configDictionary.keys():
+        sequence = document.createElement("sequence")
+        sequence.setAttribute("title", configDictionary["seriesName"])
+        if "seriesVolume" in configDictionary.keys():
+            sequence.setAttribute("volume", str(configDictionary["seriesVolume"]))
+        if "seriesNumber" in configDictionary.keys():
+            sequence.appendChild(document.createTextNode(str(configDictionary["seriesNumber"])))
 +        else:
+            sequence.appendChild(document.createTextNode(str(0)))
+        bookInfo.appendChild(sequence)
+    contentrating = document.createElement("content-rating")
+
+    if "rating" in configDictionary.keys():
+        contentrating.appendChild(document.createTextNode(str(configDictionary["rating"])))
 +    else:
+        contentrating.appendChild(document.createTextNode(str("Unrated.")))
+    if "ratingSystem" in configDictionary.keys():
+        contentrating.setAttribute("type", configDictionary["ratingSystem"])
+    bookInfo.appendChild(contentrating)
+
+    if "readingDirection" in configDictionary.keys():
+        readingDirection = document.createElement("reading-direction")
+        if configDictionary["readingDirection"] is "rightToLeft":
+            readingDirection.appendChild(document.createTextNode(str("RTL")))
+        else:
+            readingDirection.appendChild(document.createTextNode(str("LTR")))
+        bookInfo.appendChild(readingDirection)
+    meta.appendChild(bookInfo)
+
+    publisherInfo = document.createElement("publish-info")
+    if "publisherName" in configDictionary.keys():
+        publisherName = document.createElement("publisher")
+        publisherName.appendChild(document.createTextNode(str(configDictionary["publisherName"])))
 +        publisherInfo.appendChild(publisherName)
+    if "publishingDate" in configDictionary.keys():
+        publishingDate = document.createElement("publish-date")
+        publishingDate.setAttribute("value", configDictionary["publishingDate"])
+        publishingDate.appendChild(document.createTextNode(QDate.fromString(configDictionary["publishingDate"], \
Qt.ISODate).toString(Qt.SystemLocaleLongDate))) +        \
publisherInfo.appendChild(publishingDate) +    if "publisherCity" in \
configDictionary.keys(): +        publishCity = document.createElement("city")
+        publishCity.appendChild(document.createTextNode(str(configDictionary["publisherCity"])))
 +        publisherInfo.appendChild(publishCity)
+    if "isbn-number" in configDictionary.keys():
+        publishISBN = document.createElement("isbn")
+        publishISBN.appendChild(document.createTextNode(str(configDictionary["isbn-number"])))
 +        publisherInfo.appendChild(publishISBN)
+    if "license" in configDictionary.keys():
+        license = configDictionary["license"]
+        if license.isspace() is False and len(license) > 0:
+            publishLicense = document.createElement("license")
+            publishLicense.appendChild(document.createTextNode(str(configDictionary["license"])))
 +            publisherInfo.appendChild(publishLicense)
+
+    meta.appendChild(publisherInfo)
+
+    documentInfo = document.createElement("document-info")
+    # TODO: ACBF apparantly uses first/middle/last/nick/email/homepage for the \
document auhtor too... +    #      The following code compensates for me not \
understanding this initially. This still needs +    #      adjustments in the gui.
+    if "acbfAuthor" in configDictionary.keys():
+        if isinstance(configDictionary["acbfAuthor"], list):
+            for e in configDictionary["acbfAuthor"]:
+                acbfAuthor = document.createElement("author")
+                authorDict = configDictionary["acbfAuthor"][e]
+                if "first-name" in authorDict.keys():
+                    authorN = document.createElement("first-name")
+                    \
authorN.appendChild(document.createTextNode(str(authorDict["first-name"]))) +         \
acbfAuthor.appendChild(authorN) +                if "last-name" in authorDict.keys():
+                    authorN = document.createElement("last-name")
+                    \
authorN.appendChild(document.createTextNode(str(authorDict["last-name"]))) +          \
acbfAuthor.appendChild(authorN) +                if "initials" in authorDict.keys():
+                    authorN = document.createElement("middle-name")
+                    \
authorN.appendChild(document.createTextNode(str(authorDict["initials"]))) +           \
acbfAuthor.appendChild(authorN) +                if "nickname" in authorDict.keys():
+                    authorN = document.createElement("nickname")
+                    \
authorN.appendChild(document.createTextNode(str(authorDict["nickname"]))) +           \
acbfAuthor.appendChild(authorN) +                if "homepage" in authorDict.keys():
+                    authorN = document.createElement("homepage")
+                    \
authorN.appendChild(document.createTextNode(str(authorDict["home-page"]))) +          \
acbfAuthor.appendChild(authorN) +                if "email" in authorDict.keys():
+                    authorN = document.createElement("email")
+                    \
authorN.appendChild(document.createTextNode(str(authorDict["email"]))) +              \
acbfAuthor.appendChild(authorN) +                if "language" in authorDict.keys():
+                    acbfAuthor.setAttribute("lang", str(authorDict["language"]))
+                documentInfo.appendChild(acbfAuthor)
+        else:
+            acbfAuthor = document.createElement("author")
+            acbfAuthorNick = document.createElement("nickname")
+            acbfAuthorNick.appendChild(document.createTextNode(str(configDictionary["acbfAuthor"])))
 +            acbfAuthor.appendChild(acbfAuthorNick)
+            documentInfo.appendChild(acbfAuthor)
+    else:
+        acbfAuthor = document.createElement("author")
+        acbfAuthorNick = document.createElement("nickname")
+        acbfAuthorNick.appendChild(document.createTextNode(str("Anon")))
+        acbfAuthor.appendChild(acbfAuthorNick)
+        documentInfo.appendChild(acbfAuthor)
+
+    acbfDate = document.createElement("creation-date")
+    now = QDate.currentDate()
+    acbfDate.setAttribute("value", now.toString(Qt.ISODate))
+    acbfDate.appendChild(document.createTextNode(str(now.toString(Qt.SystemLocaleLongDate))))
 +    documentInfo.appendChild(acbfDate)
+
+    if "acbfSource" in configDictionary.keys():
+        acbfSource = document.createElement("source")
+        acbfSourceP = document.createElement("p")
+        acbfSourceP.appendChild(document.createTextNode(str(configDictionary["acbfSource"])))
 +        acbfSource.appendChild(acbfSourceP)
+        documentInfo.appendChild(acbfSource)
+
+    if "acbfID" in configDictionary.keys():
+        acbfID = document.createElement("id")
+        acbfID.appendChild(document.createTextNode(str(configDictionary["acbfID"])))
+        documentInfo.appendChild(acbfID)
+
+    if "acbfVersion" in configDictionary.keys():
+        acbfVersion = document.createElement("version")
+        acbfVersion.appendChild(document.createTextNode(str(configDictionary["acbfVersion"])))
 +        documentInfo.appendChild(acbfVersion)
+
+    if "acbfHistory" in configDictionary.keys():
+        acbfHistory = document.createElement("history")
+        for h in configDictionary["acbfHistory"]:
+            p = document.createElement("p")
+            p.appendChild(document.createTextNode(str(h)))
+            acbfHistory.appendChild(p)
+        documentInfo.appendChild(acbfHistory)
+    meta.appendChild(documentInfo)
+
+    root.appendChild(meta)
+
+    body = document.createElement("body")
+
+    for p in range(0, len(pagesLocationList)):
+        page = pagesLocationList[p]
+        language = "en"
+        if "language" in configDictionary.keys():
+            language = configDictionary["language"]
+        textLayer = document.createElement("text-layer")
+        textLayer.setAttribute("lang", language)
+        data = pageData[p]
+        transform = data["transform"]
+        frameList = []
+        for v in data["vector"]:
+            boundingBoxText = []
+            for point in v["boundingBox"]:
+                offset = QPointF(transform["offsetX"], transform["offsetY"])
+                pixelPoint = QPointF(point.x() * transform["resDiff"], point.y() * \
transform["resDiff"]) +                newPoint = pixelPoint - offset
+                x = int(newPoint.x() * transform["scaleWidth"])
+                y = int(newPoint.y() * transform["scaleHeight"])
+                pointText = str(x) + "," + str(y)
+                boundingBoxText.append(pointText)
+
+            if "text" in v.keys():
+                textArea = document.createElement("text-area")
+                textArea.setAttribute("points", " ".join(boundingBoxText))
+                # TODO: Rotate will require proper global transform api as transform \
info is not written intotext.                        \
#textArea.setAttribute("text-rotation", str(v["rotate"])) +                paragraph \
= minidom.parseString(v["text"]) +                \
textArea.appendChild(paragraph.documentElement) +                \
textLayer.appendChild(textArea) +            else:
+                f = {}
+                f["points"] = " ".join(boundingBoxText)
+                frameList.append(f)
+        if page is not coverpageurl:
+            pg = document.createElement("page")
+            image = document.createElement("image")
+            image.setAttribute("href", os.path.basename(page))
+            pg.appendChild(image)
+            if "acbf_title" in data["keys"]:
+                title = document.createElement("title")
+                title.setAttribute("lang", language)
+                title.appendChild(document.createTextNode(str(data["title"])))
+                pg.appendChild(title)
+            if "acbf_none" in data["keys"]:
+                pg.setAttribute("transition", "none")
+            if "acbf_blend" in data["keys"]:
+                pg.setAttribute("transition", "blend")
+            if "acbf_fade" in data["keys"]:
+                pg.setAttribute("transition", "fade")
+            if "acbf_horizontal" in data["keys"]:
+                pg.setAttribute("transition", "scroll_right")
+            if "acbf_vertical" in data["keys"]:
+                pg.setAttribute("transition", "scroll_down")
+            for f in frameList:
+                frame = document.createElement("frame")
+                frame.setAttribute("points", f["points"])
+                pg.appendChild(frame)
+            pg.appendChild(textLayer)
+            body.appendChild(pg)
+        else:
+            for f in frameList:
+                frame = document.createElement("frame")
+                frame.setAttribute("points", f["points"])
+                coverpage.appendChild(frame)
+            coverpage.appendChild(textLayer)
+
+    root.appendChild(body)
+
+    f = open(locationBasic, 'w', newline="", encoding="utf-8")
+    f.write(document.toprettyxml(indent="  "))
+    f.close()
+    success = True
+    success = createStandAloneACBF(configDictionary, document, locationStandAlone, \
pagesLocationList) +    return success
+
+def createStandAloneACBF(configDictionary, document, location, pagesLocationList = \
[]): +    title = configDictionary["projectName"]
+    if "title" in configDictionary.keys():
+        title = configDictionary["title"]
+    root = document.getElementsByTagName("ACBF")[0]
+    meta = root.getElementsByTagName("meta-data")[0]
+    bookInfo = meta.getElementsByTagName("book-info")[0]
+    cover = bookInfo.getElementsByTagName("coverpage")[0]
+
+    body = root.getElementsByTagName("body")[0]
+    pages = body.getElementsByTagName("page")
+    if (cover):
+        pages.append(cover)
+
+    data = document.createElement("data")
+
+    # Covert pages to base64 strings.
+    for i in range(0, len(pages)):
+        image = pages[i].getElementsByTagName("image")[0]
+        href = image.getAttribute("href")
+        for p in pagesLocationList:
+            if href in p:
+                binary = document.createElement("binary")
+                binary.setAttribute("id", href)
+                imageFile = QImage()
+                imageFile.load(p)
+                imageData = QByteArray()
+                buffer = QBuffer(imageData)
+                imageFile.save(buffer, "PNG")
+                # For now always embed as png.
+                contentType = "image/png"
+                binary.setAttribute("content-type", contentType)
+                binary.appendChild(document.createTextNode(str(bytearray(imageData.toBase64()).decode("ascii"))))
 +
+                image.setAttribute("href", "#" + href)
+                data.appendChild(binary)
+
+    root.appendChild(data)
+
+    f = open(location, 'w', newline="", encoding="utf-8")
+    f.write(document.toprettyxml(indent="  "))
+    f.close()
+    return True
diff --git a/plugins/python/comics_project_management_tools/exporters/CPMT_CoMet_XML_Exporter.py \
b/plugins/python/comics_project_management_tools/exporters/CPMT_CoMet_XML_Exporter.py \
new file mode 100644 index 00000000000..3f8c4370f15
--- /dev/null
+++ b/plugins/python/comics_project_management_tools/exporters/CPMT_CoMet_XML_Exporter.py
 @@ -0,0 +1,147 @@
+"""
+Copyright (c) 2018 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
+
+This file is part of the Comics Project Management Tools(CPMT).
+
+CPMT 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 3 of the License, or
+(at your option) any later version.
+
+CPMT 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 the CPMT.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+"""
+Write a CoMet xml file to url
+"""
+
+import os
+from xml.dom import minidom
+
+def write_xml(configDictionary = {}, pagesLocationList = [], location = str()):
+    document = minidom.Document()
+    root = document.createElement("comet")
+    root.setAttribute("xmlns:comet", "http://www.denvog.com/comet/")
+    root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
+    root.setAttribute("xsi:schemaLocation", "http://www.denvog.com \
http://www.denvog.com/comet/comet.xsd") +    document.appendChild(root)
+
+    title = document.createElement("title")
+    if "title" in configDictionary.keys():
+        title.appendChild(document.createTextNode(str(configDictionary["title"])))
+    else:
+        title.appendChild(document.createTextNode(str("Untitled Comic")))
+    root.appendChild(title)
+    description = document.createElement("description")
+    if "summary" in configDictionary.keys():
+        description.appendChild(document.createTextNode(str(configDictionary["summary"])))
 +    else:
+        description.appendChild(document.createTextNode(str("There was no summary \
upon generation of this file."))) +    root.appendChild(description)
+    if "seriesName" in configDictionary.keys():
+        series = document.createElement("series")
+        series.appendChild(document.createTextNode(str(configDictionary["seriesName"])))
 +        root.appendChild(series)
+        if "seriesNumber" in configDictionary.keys():
+            issue = document.createElement("issue")
+            issue.appendChild(document.createTextNode(str(configDictionary["seriesNumber"])))
 +            root.appendChild(issue)
+        if "seriesVolume" in configDictionary.keys():
+            volume = document.createElement("volume")
+            volume.appendChild(document.createTextNode(str(configDictionary["seriesVolume"])))
 +            root.appendChild(volume)
+
+    if "publisherName" in configDictionary.keys():
+        publisher = document.createElement("publisher")
+        publisher.appendChild(document.createTextNode(str(configDictionary["publisherName"])))
 +        root.appendChild(publisher)
+
+    if "publishingDate" in configDictionary.keys():
+        date = document.createElement("date")
+        date.appendChild(document.createTextNode(str(configDictionary["publishingDate"])))
 +        root.appendChild(date)
+
+    if "genre" in configDictionary.keys():
+        for genreE in configDictionary["genre"]:
+            genre = document.createElement("genre")
+            genre.appendChild(document.createTextNode(str(genreE)))
+            root.appendChild(genre)
+
+    if "characters" in configDictionary.keys():
+        for char in configDictionary["characters"]:
+            character = document.createElement("character")
+            character.appendChild(document.createTextNode(str(char)))
+            root.appendChild(character)
+
+    if "format" in configDictionary.keys():
+        format = document.createElement("format")
+        format.appendChild(document.createTextNode(str(",".join(configDictionary["format"]))))
 +        root.appendChild(format)
+
+    if "language" in configDictionary.keys():
+        language = document.createElement("language")
+        language.appendChild(document.createTextNode(str(configDictionary["language"])))
 +        root.appendChild(language)
+    if "rating" in configDictionary.keys():
+        rating = document.createElement("rating")
+        rating.appendChild(document.createTextNode(str(configDictionary["rating"])))
+        root.appendChild(rating)
+    #rights = document.createElement("rights")
+    if "pages" in configDictionary.keys():
+        pages = document.createElement("pages")
+        pages.appendChild(document.createTextNode(str(len(configDictionary["pages"]))))
 +        root.appendChild(pages)
+
+    if "isbn-number" in configDictionary.keys():
+        identifier = document.createElement("identifier")
+        identifier.appendChild(document.createTextNode(str(configDictionary["isbn-number"])))
 +        root.appendChild(identifier)
+
+    if "authorList" in configDictionary.keys():
+        for authorE in range(len(configDictionary["authorList"])):
+            author = document.createElement("creator")
+            authorDict = configDictionary["authorList"][authorE]
+            if "role" in authorDict.keys():
+                if str(authorDict["role"]).lower() in ["writer", "penciller", \
"editor", "assistant editor", "cover artist", "letterer", "inker", "colorist"]: +     \
if str(authorDict["role"]).lower() is "cover artist": +                        author \
= document.createElement("coverDesigner") +                    elif \
str(authorDict["role"]).lower() is "assistant editor": +                        \
author = document.createElement("editor") +                    else:
+                        author = \
document.createElement(str(authorDict["role"]).lower()) +            stringName = []
+            if "last-name" in authorDict.keys():
+                stringName.append(authorDict["last-name"])
+            if "first-name" in authorDict.keys():
+                stringName.append(authorDict["first-name"])
+            if "nickname" in authorDict.keys():
+                stringName.append("(" + authorDict["nickname"] + ")")
+            author.appendChild(document.createTextNode(str(",".join(stringName))))
+            root.appendChild(author)
+
+    if "pages" in configDictionary.keys():
+        if "cover" in configDictionary.keys():
+            pageList = []
+            pageList = configDictionary["pages"]
+            coverNumber = pageList.index(configDictionary["cover"])
+            if len(pagesLocationList) >= coverNumber:
+                coverImage = document.createElement("coverImage")
+                coverImage.appendChild(document.createTextNode(str(os.path.basename(pagesLocationList[coverNumber]))))
 +                root.appendChild(coverImage)
+    readingDirection = document.createElement("readingDirection")
+    readingDirection.appendChild(document.createTextNode(str("ltr")))
+    if "readingDirection" in configDictionary.keys():
+        if configDictionary["readingDirection"] is "rightToLeft":
+            readingDirection.appendChild(document.createTextNode(str("rtl")))
+    root.appendChild(readingDirection)
+
+    f = open(location, 'w', newline="", encoding="utf-8")
+    f.write(document.toprettyxml(indent="  "))
+    f.close()
+    return True
diff --git a/plugins/python/comics_project_management_tools/exporters/CPMT_Comic_Book_Info_Exporter.py \
b/plugins/python/comics_project_management_tools/exporters/CPMT_Comic_Book_Info_Exporter.py
 new file mode 100644
index 00000000000..eed2022b01c
--- /dev/null
+++ b/plugins/python/comics_project_management_tools/exporters/CPMT_Comic_Book_Info_Exporter.py
 @@ -0,0 +1,96 @@
+"""
+Copyright (c) 2018 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
+
+This file is part of the Comics Project Management Tools(CPMT).
+
+CPMT 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 3 of the License, or
+(at your option) any later version.
+
+CPMT 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 the CPMT.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+"""
+Another metadata format but then a json dump stored into the zipfile comment.
+The logic here being that the zipfile information can be read quicker.
+Doesn't seem to be supported much. :/
+https://code.google.com/archive/p/comicbookinfo/wikis/Example.wiki
+"""
+
+import json
+from PyQt5.QtCore import QDateTime, QDate, Qt, QLocale
+
+def writeJson(configDictionary = {}):
+    basedata = {}
+    metadata = {}
+    authorList = []
+    taglist = []
+
+    if "authorList" in configDictionary.keys():
+        for authorE in range(len(configDictionary["authorList"])):
+            author = {}
+
+            authorDict = configDictionary["authorList"][authorE]
+            stringName = []
+            if "last-name" in authorDict.keys():
+                stringName.append(authorDict["last-name"])
+            if "first-name" in authorDict.keys():
+                stringName.append(authorDict["first-name"])
+            if "nickname" in authorDict.keys():
+                stringName.append("(" + authorDict["nickname"] + ")")
+            author["person"] = ",".join(stringName)
+            if "role" in authorDict.keys():
+                author["role"] = str(authorDict["role"]).title()
+            authorList.append(author)
+
+    if "characters" in configDictionary.keys():
+        for character in configDictionary["characters"]:
+            taglist.append(character)
+    if "format" in configDictionary.keys():
+        for item in configDictionary["format"]:
+            taglist.append(item)
+    if "otherKeywords" in configDictionary.keys():
+        for item in configDictionary["otherKeywords"]:
+            taglist.append(item)
+
+    if "seriesName" in configDictionary.keys():
+        metadata["series"] = configDictionary["seriesName"]
+    if "title" in configDictionary.keys():
+        metadata["title"] = configDictionary["title"]
+    else:
+        metadata["title"] = "Unnamed comic"
+    if "publisherName" in configDictionary.keys():
+        metadata["publisher"] = configDictionary["publisherName"]
+    if "publishingDate" in configDictionary.keys():
+        date = QDate.fromString(configDictionary["publishingDate"], Qt.ISODate)
+        metadata["publicationMonth"] = date.month()
+        metadata["publicationYear"] = date.year()
+    if "seriesNumber" in configDictionary.keys():
+        metadata["issue"] = configDictionary["seriesNumber"]
+    if "seriesVolume" in configDictionary.keys():
+        metadata["volume"] = configDictionary["seriesVolume"]
+    if "genre" in configDictionary.keys():
+        metadata["genre"] = configDictionary["genre"]
+    if "language" in configDictionary.keys():
+        metadata["language"] = \
QLocale.languageToString(QLocale(configDictionary["language"]).language()) +
+    metadata["credits"] = authorList
+
+    metadata["tags"] = taglist
+    if "summary" in configDictionary.keys():
+        metadata["comments"] = configDictionary["summary"]
+    else:
+        metadata["comments"] = "File generated without summary"
+
+    basedata["appID"] = "Krita"
+    basedata["lastModified"] = QDateTime.currentDateTimeUtc().toString(Qt.ISODate)
+    basedata["ComicBookInfo/1.0"] = metadata
+
+    return json.dumps(basedata)
diff --git a/plugins/python/comics_project_management_tools/exporters/CPMT_Comic_Rack_XML_Exporter.py \
b/plugins/python/comics_project_management_tools/exporters/CPMT_Comic_Rack_XML_Exporter.py
 new file mode 100644
index 00000000000..32643f8c194
--- /dev/null
+++ b/plugins/python/comics_project_management_tools/exporters/CPMT_Comic_Rack_XML_Exporter.py
 @@ -0,0 +1,135 @@
+"""
+Copyright (c) 2018 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
+
+This file is part of the Comics Project Management Tools(CPMT).
+
+CPMT 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 3 of the License, or
+(at your option) any later version.
+
+CPMT 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 the CPMT.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+"""
+The comicrack information is sorta... incomplete, so no idea if the following is \
right... +I can't check in any case: It is a windows application.
+"""
+
+from xml.dom import minidom
+from PyQt5.QtCore import QDate, Qt
+
+def write_xml(configDictionary = {}, pagesLocationList = [],  location = str()):
+    document = minidom.Document()
+    root = document.createElement("ComicInfo")
+    root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
+    root.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema")
+
+    title = document.createElement("Title")
+    if "title" in configDictionary.keys():
+        title.appendChild(document.createTextNode(str(configDictionary["title"])))
+    else:
+        title.appendChild(document.createTextNode(str("Untitled Comic")))
+    root.appendChild(title)
+    description = document.createElement("Summary")
+    if "summary" in configDictionary.keys():
+        description.appendChild(document.createTextNode(str(configDictionary["summary"])))
 +    else:
+        description.appendChild(document.createTextNode(str("There was no summary \
upon generation of this file."))) +    root.appendChild(description)
+    if "seriesNumber" in configDictionary.keys():
+        number = document.createElement("Number")
+        number.appendChild(document.createTextNode(str(configDictionary["seriesNumber"])))
 +        root.appendChild(number)
+
+    if "publishingDate" in configDictionary.keys():
+        date = QDate.fromString(configDictionary["publishingDate"], Qt.ISODate)
+        publishYear = document.createElement("Year")
+        publishYear.appendChild(document.createTextNode(str(date.year())))
+        publishMonth = document.createElement("Month")
+        publishMonth.appendChild(document.createTextNode(str(date.month())))
+        root.appendChild(publishYear)
+        root.appendChild(publishMonth)
+
+    if "format" in configDictionary.keys():
+        for form in configDictionary["format"]:
+            formattag = document.createElement("Format")
+            formattag.appendChild(document.createTextNode(str(form)))
+            root.appendChild(formattag)
+    if "otherKeywords" in configDictionary.keys():
+        tags = document.createElement("Tags")
+        tags.appendChild(document.createTextNode(str(", \
".join(configDictionary["otherKeywords"])))) +        root.appendChild(tags)
+
+    if "authorList" in configDictionary.keys():
+        for authorE in range(len(configDictionary["authorList"])):
+            author = document.createElement("Writer")
+            authorDict = configDictionary["authorList"][authorE]
+            if "role" in authorDict.keys():
+                if str(authorDict["role"]).lower() in ["writer", "penciller", \
"editor", "assistant editor", "cover artist", "letterer", "inker", "colorist"]: +     \
if str(authorDict["role"]).lower() is "cover artist": +                        author \
= document.createElement("CoverArtist") +                    elif \
str(authorDict["role"]).lower() is "assistant editor": +                        \
author = document.createElement("Editor") +                    else:
+                        author = \
document.createElement(str(authorDict["role"]).title()) +            stringName = []
+            if "last-name" in authorDict.keys():
+                stringName.append(authorDict["last-name"])
+            if "first-name" in authorDict.keys():
+                stringName.append(authorDict["first-name"])
+            if "nickname" in authorDict.keys():
+                stringName.append("(" + authorDict["nickname"] + ")")
+            author.appendChild(document.createTextNode(str(",".join(stringName))))
+            root.appendChild(author)
+    if "publisherName" in configDictionary.keys():
+        publisher = document.createElement("Publisher")
+        publisher.appendChild(document.createTextNode(str(configDictionary["publisherName"])))
 +        root.appendChild(publisher)
+
+    if "genre" in configDictionary.keys():
+        for genreE in configDictionary["genre"]:
+            genre = document.createElement("Genre")
+            genre.appendChild(document.createTextNode(str(genreE)))
+            root.appendChild(genre)
+    blackAndWhite = document.createElement("BlackAndWhite")
+    blackAndWhite.appendChild(document.createTextNode(str("No")))
+    root.appendChild(blackAndWhite)
+    readingDirection = document.createElement("Manga")
+    readingDirection.appendChild(document.createTextNode(str("No")))
+    if "readingDirection" in configDictionary.keys():
+        if configDictionary["readingDirection"] is "rightToLeft":
+            readingDirection.appendChild(document.createTextNode(str("Yes")))
+    root.appendChild(readingDirection)
+
+    if "characters" in configDictionary.keys():
+        for char in configDictionary["characters"]:
+            character = document.createElement("Character")
+            character.appendChild(document.createTextNode(str(char)))
+            root.appendChild(character)
+    if "pages" in configDictionary.keys():
+        pagecount = document.createElement("PageCount")
+        pagecount.appendChild(document.createTextNode(str(len(configDictionary["pages"]))))
 +        root.appendChild(pagecount)
+    pages = document.createElement("Pages")
+    covernumber = 0
+    if "pages" in configDictionary.keys() and "cover" in configDictionary.keys():
+        covernumber = configDictionary["pages"].index(configDictionary["cover"])
+    for i in range(len(pagesLocationList)):
+        page = document.createElement("Page")
+        page.setAttribute("Image", str(i))
+        if i is covernumber:
+            page.setAttribute("Type", "FrontCover")
+        pages.appendChild(page)
+    root.appendChild(pages)
+    document.appendChild(root)
+    f = open(location, 'w', newline="", encoding="utf-8")
+    f.write(document.toprettyxml(indent="  "))
+    f.close()
+    return True
diff --git a/plugins/python/comics_project_management_tools/exporters/CPMT_EPUB_exporter.py \
b/plugins/python/comics_project_management_tools/exporters/CPMT_EPUB_exporter.py new \
file mode 100644 index 00000000000..25d0259b2a6
--- /dev/null
+++ b/plugins/python/comics_project_management_tools/exporters/CPMT_EPUB_exporter.py
@@ -0,0 +1,320 @@
+"""
+Copyright (c) 2018 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
+
+This file is part of the Comics Project Management Tools(CPMT).
+
+CPMT 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 3 of the License, or
+(at your option) any later version.
+
+CPMT 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 the CPMT.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+"""
+Create an epub folder, finally, package to a epubzip.
+"""
+
+import shutil
+import os
+from pathlib import Path
+import xml.etree.ElementTree as ET
+
+def export(configDictionary = {}, projectURL = str(), pagesLocationList = []):
+    path = Path(os.path.join(projectURL, configDictionary["exportLocation"]))
+    exportPath = path / "EPUB-files"
+    metaInf = exportPath / "META-INF"
+    oebps = exportPath / "OEBPS"
+    imagePath = oebps / "Images"
+    stylesPath = oebps / "Styles"
+    textPath = oebps / "Text"
+    if exportPath.exists() is False:
+        exportPath.mkdir()
+        metaInf.mkdir()
+        oebps.mkdir()
+        imagePath.mkdir()
+        stylesPath.mkdir()
+        textPath.mkdir()
+
+    mimetype = open(str(Path(exportPath / "mimetype")), mode="w")
+    mimetype.write("application/epub+zip")
+    mimetype.close()
+
+    container = ET.ElementTree()
+    cRoot = ET.Element("container")
+    cRoot.set("version", "1.0")
+    cRoot.set("xmlns", "urn:oasis:names:tc:opendocument:xmlns:container")
+    container._setroot(cRoot)
+    rootFiles = ET.Element("rootfiles")
+    rootfile = ET.Element("rootfile")
+    rootfile.set("full-path", "OEBPS/content.opf")
+    rootfile.set("media-type", "application/oebps-package+xml")
+    rootFiles.append(rootfile)
+    cRoot.append(rootFiles)
+    container.write(str(Path(metaInf / "container.xml")), encoding="utf-8", \
xml_declaration=True) +
+    # copyimages to images
+    pagesList = []
+    if len(pagesLocationList)>0:
+        coverNumber = configDictionary["pages"].index(configDictionary["cover"])
+        for p in pagesLocationList:
+            if os.path.exists(p):
+                shutil.copy2(p, str(imagePath))
+                pagesList.append(str(Path(imagePath / os.path.basename(p))))
+        if len(pagesLocationList) >= coverNumber:
+            coverpageurl = pagesList[coverNumber]
+    else:
+        print("CPMT: Couldn't find the location for the epub files.")
+        return False
+
+    # for each image, make an xml file
+    htmlFiles = []
+    for i in range(len(pagesList)):
+        pageName = "Page" + str(i) + ".xhtml"
+        doc = ET.ElementTree()
+        html = ET.Element("html")
+        doc._setroot(html)
+        html.set("xmlns", "http://www.w3.org/1999/xhtml")
+        html.set("xmlns:epub", "http://www.idpf.org/2007/ops")
+
+        head = ET.Element("head")
+        html.append(head)
+
+        body = ET.Element("body")
+
+        img = ET.Element("img")
+        img.set("src", os.path.relpath(pagesList[i], str(textPath)))
+        body.append(img)
+
+        if pagesList[i] != coverpageurl:
+            pagenumber = ET.Element("p")
+            pagenumber.text = "Page " + str(i)
+            body.append(pagenumber)
+        html.append(body)
+
+        filename = str(Path(textPath / pageName))
+        doc.write(filename, encoding="utf-8", xml_declaration=True)
+        if pagesList[i] == coverpageurl:
+            coverpagehtml = os.path.relpath(filename, str(oebps))
+        htmlFiles.append(filename)
+
+    # opf file
+    opfFile = ET.ElementTree()
+    opfRoot = ET.Element("package")
+    opfRoot.set("version", "3.0")
+    opfRoot.set("unique-identifier", "BookId")
+    opfRoot.set("xmlns", "http://www.idpf.org/2007/opf")
+    opfFile._setroot(opfRoot)
+
+    # metadata
+    opfMeta = ET.Element("metadata")
+    opfMeta.set("xmlns:dc", "http://purl.org/dc/elements/1.1/")
+
+    if "language" in configDictionary.keys():
+        bookLang = ET.Element("dc:language")
+        bookLang.text = configDictionary["language"]
+        opfMeta.append(bookLang)
+    bookTitle = ET.Element("dc:title")
+    if "title" in configDictionary.keys():
+        bookTitle.text = str(configDictionary["title"])
+    else:
+        bookTitle.text = "Comic with no Name"
+    opfMeta.append(bookTitle)
+    if "authorList" in configDictionary.keys():
+        for authorE in range(len(configDictionary["authorList"])):
+            authorDict = configDictionary["authorList"][authorE]
+            authorType = "dc:creator"
+            if "role" in authorDict.keys():
+                if str(authorDict["role"]).lower() in ["editor", "assistant editor", \
"proofreader", "beta"]: +                    authorType = "dc:contributor"
+            author = ET.Element(authorType)
+            authorName = []
+            if "last-name" in authorDict.keys():
+                authorName.append(authorDict["last-name"])
+            if "first-name" in authorDict.keys():
+                authorName.append(authorDict["first-name"])
+            if "initials" in authorDict.keys():
+                authorName.append(authorDict["initials"])
+            if "nickname" in authorDict.keys():
+                authorName.append("(" + authorDict["nickname"] + ")")
+            author.text = ", ".join(authorName)
+            opfMeta.append(author)
+            if "role" in authorDict.keys():
+                author.set("id", "cre" + str(authorE))
+                role = ET.Element("meta")
+                role.set("refines", "cre" + str(authorE))
+                role.set("scheme", "marc:relators")
+                role.set("property", "role")
+                role.text = str(authorDict["role"])
+                opfMeta.append(role)
+
+    if "publishingDate" in configDictionary.keys():
+        date = ET.Element("dc:date")
+        date.text = configDictionary["publishingDate"]
+        opfMeta.append(date)
+    description = ET.Element("dc:description")
+    if "summary" in configDictionary.keys():
+        description.text = configDictionary["summary"]
+    else:
+        description.text = "There was no summary upon generation of this file."
+    opfMeta.append(description)
+
+    type = ET.Element("dc:type")
+    type.text = "Comic"
+    opfMeta.append(type)
+    if "publisherName" in configDictionary.keys():
+        publisher = ET.Element("dc:publisher")
+        publisher.text = configDictionary["publisherName"]
+        opfMeta.append(publisher)
+    if "isbn-number" in configDictionary.keys():
+        publishISBN = ET.Element("dc:identifier")
+        publishISBN.text = str("urn:isbn:") + configDictionary["isbn-number"]
+        opfMeta.append(publishISBN)
+    if "license" in configDictionary.keys():
+        rights = ET.Element("dc:rights")
+        rights.text = configDictionary["license"]
+        opfMeta.append(rights)
+
+    if "genre" in configDictionary.keys():
+        for g in configDictionary["genre"]:
+            subject = ET.Element("dc:subject")
+            subject.text = g
+            opfMeta.append(subject)
+    if "characters" in configDictionary.keys():
+        for name in configDictionary["characters"]:
+            char = ET.Element("dc:subject")
+            char.text = name
+            opfMeta.append(char)
+    if "format" in configDictionary.keys():
+        for format in configDictionary["format"]:
+            f = ET.Element("dc:subject")
+            f.text = format
+            opfMeta.append(f)
+    if "otherKeywords" in configDictionary.keys():
+        for key in configDictionary["otherKeywords"]:
+            word = ET.Element("dc:subject")
+            word.text = key
+            opfMeta.append(word)
+
+    opfRoot.append(opfMeta)
+
+    opfManifest = ET.Element("manifest")
+    toc = ET.Element("item")
+    toc.set("id", "ncx")
+    toc.set("href", "toc.ncx")
+    toc.set("media-type", "application/x-dtbncx+xml")
+    opfManifest.append(toc)
+    for p in htmlFiles:
+        item = ET.Element("item")
+        item.set("id", os.path.basename(p))
+        item.set("href", os.path.relpath(p, str(oebps)))
+        item.set("media-type", "application/xhtml+xml")
+        opfManifest.append(item)
+    for p in pagesList:
+        item = ET.Element("item")
+        item.set("id", os.path.basename(p))
+        item.set("href", os.path.relpath(p, str(oebps)))
+        item.set("media-type", "image/png")
+        if os.path.basename(p) == os.path.basename(coverpageurl):
+            item.set("properties", "cover-image")
+        opfManifest.append(item)
+
+    opfRoot.append(opfManifest)
+
+    opfSpine = ET.Element("spine")
+    opfSpine.set("toc", "ncx")
+    for p in htmlFiles:
+        item = ET.Element("itemref")
+        item.set("idref", os.path.basename(p))
+        opfSpine.append(item)
+    opfRoot.append(opfSpine)
+
+    opfGuide = ET.Element("guide")
+    if coverpagehtml is not None and coverpagehtml.isspace() is False and \
len(coverpagehtml) > 0: +        item = ET.Element("reference")
+        item.set("type", "cover")
+        item.set("title", "Cover")
+        item.set("href", coverpagehtml)
+    opfRoot.append(opfGuide)
+
+    opfFile.write(str(Path(oebps / "content.opf")), encoding="utf-8", \
xml_declaration=True) +    # toc
+    tocDoc = ET.ElementTree()
+    ncx = ET.Element("ncx")
+    ncx.set("version", "2005-1")
+    ncx.set("xmlns", "http://www.daisy.org/z3986/2005/ncx/")
+    tocDoc._setroot(ncx)
+
+    tocHead = ET.Element("head")
+    metaID = ET.Element("meta")
+    metaID.set("content", "ID_UNKNOWN")
+    metaID.set("name", "dtb:uid")
+    tocHead.append(metaID)
+    metaDepth = ET.Element("meta")
+    metaDepth.set("content", str(0))
+    metaDepth.set("name", "dtb:depth")
+    tocHead.append(metaDepth)
+    metaTotal = ET.Element("meta")
+    metaTotal.set("content", str(0))
+    metaTotal.set("name", "dtb:totalPageCount")
+    tocHead.append(metaTotal)
+    metaMax = ET.Element("meta")
+    metaMax.set("content", str(0))
+    metaMax.set("name", "dtb:maxPageNumber")
+    tocHead.append(metaDepth)
+    ncx.append(tocHead)
+
+    docTitle = ET.Element("docTitle")
+    text = ET.Element("text")
+    if "title" in configDictionary.keys():
+        text.text = str(configDictionary["title"])
+    else:
+        text.text = "Comic with no Name"
+    docTitle.append(text)
+    ncx.append(docTitle)
+
+    navmap = ET.Element("navMap")
+    navPoint = ET.Element("navPoint")
+    navPoint.set("id", "navPoint-1")
+    navPoint.set("playOrder", "1")
+    navLabel = ET.Element("navLabel")
+    navLabelText = ET.Element("text")
+    navLabelText.text = "Start"
+    navLabel.append(navLabelText)
+    navContent = ET.Element("content")
+    navContent.set("src", os.path.relpath(htmlFiles[0], str(oebps)))
+    navPoint.append(navLabel)
+    navPoint.append(navContent)
+    navmap.append(navPoint)
+    ncx.append(navmap)
+
+    tocDoc.write(str(Path(oebps / "toc.ncx")), encoding="utf-8", \
xml_declaration=True) +
+    package_epub(configDictionary, projectURL)
+    return True
+"""
+package epub packages the whole epub folder and renames the zip file to .epub.
+"""
+
+def package_epub(configDictionary = {}, projectURL = str()):
+
+    # Use the project name if there's no title to avoid sillyness with unnamed \
zipfiles. +    title = configDictionary["projectName"]
+    if "title" in configDictionary.keys():
+        title = configDictionary["title"]
+
+    # Get the appropriate paths.
+    url = os.path.join(projectURL, configDictionary["exportLocation"], title)
+    epub = os.path.join(projectURL, configDictionary["exportLocation"], \
"EPUB-files") +
+    # Make the archive.
+    shutil.make_archive(base_name=url, format="zip", root_dir=epub)
+
+    # Rename the archive to epub.
+    shutil.move(src=str(url + ".zip"), dst=str(url + ".epub"))
diff --git a/plugins/python/comics_project_management_tools/exporters/__init__.py \
b/plugins/python/comics_project_management_tools/exporters/__init__.py new file mode \
100644 index 00000000000..2e5b455d63a
--- /dev/null
+++ b/plugins/python/comics_project_management_tools/exporters/__init__.py
@@ -0,0 +1,6 @@
+# let's make a module
+from . import CPMT_Comic_Book_Info_Exporter as comic_book_info
+from . import CPMT_Comic_Rack_XML_Exporter as comic_rack_xml
+from . import CPMT_CoMet_XML_Exporter as CoMet
+from . import CPMT_ACBF_XML_Exporter as ACBF
+from . import CPMT_EPUB_exporter as EPUB


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic