27def export(configDictionary = {}, projectURL = str(), pagesLocationList = [], pageData = []):
28 path = Path(os.path.join(projectURL, configDictionary[
"exportLocation"]))
29 exportPath = path /
"EPUB-files"
30 metaInf = exportPath /
"META-INF"
31 oebps = exportPath /
"OEBPS"
32 imagePath = oebps /
"Images"
35 textPath = oebps /
"Text"
37 if exportPath.exists()
is False:
50 title = configDictionary[
"projectName"]
51 if "title" in configDictionary.keys():
52 title = str(configDictionary[
"title"]).replace(
" ",
"_")
55 url = str(path / str(title +
".epub"))
58 epubArchive = zipfile.ZipFile(url, mode=
"w", compression=zipfile.ZIP_STORED)
60 mimetype = open(str(Path(exportPath /
"mimetype")), mode=
"w")
61 mimetype.write(
"application/epub+zip")
65 epubArchive.write(Path(exportPath /
"mimetype"), Path(
"mimetype"))
67 container = QDomDocument()
68 cRoot = container.createElement(
"container")
69 cRoot.setAttribute(
"version",
"1.0")
70 cRoot.setAttribute(
"xmlns",
"urn:oasis:names:tc:opendocument:xmlns:container")
71 container.appendChild(cRoot)
72 rootFiles = container.createElement(
"rootfiles")
73 rootfile = container.createElement(
"rootfile")
74 rootfile.setAttribute(
"full-path",
"OEBPS/content.opf")
75 rootfile.setAttribute(
"media-type",
"application/oebps-package+xml")
76 rootFiles.appendChild(rootfile)
77 cRoot.appendChild(rootFiles)
79 containerFileName = str(Path(metaInf /
"container.xml"))
81 containerFile = open(containerFileName,
'w', newline=
"", encoding=
"utf-8")
82 containerFile.write(container.toString(indent=2))
86 epubArchive.write(containerFileName, os.path.relpath(containerFileName, str(exportPath)))
90 if len(pagesLocationList)>0:
91 if "cover" in configDictionary.keys():
92 coverNumber = configDictionary[
"pages"].index(configDictionary[
"cover"])
95 for p
in pagesLocationList:
97 shutil.copy2(p, str(imagePath))
98 filename = str(Path(imagePath / os.path.basename(p)))
99 pagesList.append(filename)
100 epubArchive.write(filename, os.path.relpath(filename, str(exportPath)))
101 if len(pagesLocationList) >= coverNumber:
102 coverpageurl = pagesList[coverNumber]
104 print(
"CPMT: Couldn't find the location for the epub images.")
113 for i
in range(len(pagesList)):
114 pageName =
"Page" + str(i) +
".xhtml"
116 html = doc.createElement(
"html")
117 doc.appendChild(html)
118 html.setAttribute(
"xmlns",
"http://www.w3.org/1999/xhtml")
119 html.setAttribute(
"xmlns:epub",
"http://www.idpf.org/2007/ops")
125 head = doc.createElement(
"head")
126 viewport = doc.createElement(
"meta")
127 viewport.setAttribute(
"name",
"viewport")
130 img.load(pagesLocationList[i])
134 widthHeight =
"width="+str(w)+
", height="+str(h)
136 viewport.setAttribute(
"content", widthHeight)
137 head.appendChild(viewport)
138 html.appendChild(head)
144 transform = data[
"transform"]
145 for v
in data[
"vector"]:
147 dominantColor = QColor(Qt.white)
149 for point
in v[
"boundingBox"]:
150 offset = QPointF(transform[
"offsetX"], transform[
"offsetY"])
151 pixelPoint = QPointF(point.x() * transform[
"resDiff"], point.y() * transform[
"resDiff"])
152 newPoint = pixelPoint - offset
153 x = max(0, min(w, int(newPoint.x() * transform[
"scaleWidth"])))
154 y = max(0, min(h, int(newPoint.y() * transform[
"scaleHeight"])))
155 listOfColors.append(img.pixelColor(QPointF(x, y).toPoint()))
156 pointsList.append(QPointF((x/w)*100, (y/h)*100))
158 if "text" in v.keys():
160 if len(listOfColors)>0:
161 dominantColor = listOfColors[-1]
162 listOfColors = listOfColors[:-1]
163 for color
in listOfColors:
164 dominantColor.setRedF(0.5*(dominantColor.redF()+color.redF()))
165 dominantColor.setGreenF(0.5*(dominantColor.greenF()+color.greenF()))
166 dominantColor.setBlueF(0.5*(dominantColor.blueF()+color.blueF()))
168 bounds = QPolygonF(pointsList).boundingRect()
169 region[
"points"] = bounds
170 region[
"type"] = regionType
171 region[
"page"] = str(Path(textPath / pageName))
172 region[
"primaryColor"] = dominantColor.name()
173 regions.append(region)
177 if "acbf_title" in data[
"keys"]:
178 listOfNavItems[str(Path(textPath / pageName))] = data[
"title"]
182 if "epub_spread" in data[
"keys"]:
183 listofSpreads.append(str(Path(textPath / pageName)))
185 body = doc.createElement(
"body")
187 img = doc.createElement(
"img")
188 img.setAttribute(
"src", os.path.relpath(pagesList[i], str(textPath)))
189 body.appendChild(img)
191 html.appendChild(body)
193 filename = str(Path(textPath / pageName))
194 docFile = open(filename,
'w', newline=
"", encoding=
"utf-8")
195 docFile.write(doc.toString(indent=2))
198 if pagesList[i] == coverpageurl:
199 coverpagehtml = os.path.relpath(filename, str(oebps))
200 htmlFiles.append(filename)
203 epubArchive.write(filename, os.path.relpath(filename, str(exportPath)))
207 filename =
write_opf_file(oebps, configDictionary, htmlFiles, pagesList, coverpageurl, coverpagehtml, listofSpreads)
208 epubArchive.write(filename, os.path.relpath(filename, str(exportPath)))
211 epubArchive.write(filename, os.path.relpath(filename, str(exportPath)))
214 filename =
write_nav_file(oebps, configDictionary, htmlFiles, listOfNavItems)
215 epubArchive.write(filename, os.path.relpath(filename, str(exportPath)))
217 filename =
write_ncx_file(oebps, configDictionary, htmlFiles, listOfNavItems)
218 epubArchive.write(filename, os.path.relpath(filename, str(exportPath)))
225Write OPF metadata file
229def write_opf_file(path, configDictionary, htmlFiles, pagesList, coverpageurl, coverpagehtml, listofSpreads):
233 marcRelators = {
"abr":i18n(
"Abridger"),
"acp":i18n(
"Art copyist"),
"act":i18n(
"Actor"),
"adi":i18n(
"Art director"),
"adp":i18n(
"Adapter"),
"ann":i18n(
"Annotator"),
"ant":i18n(
"Bibliographic antecedent"),
"arc":i18n(
"Architect"),
"ard":i18n(
"Artistic director"),
"art":i18n(
"Artist"),
"asn":i18n(
"Associated name"),
"ato":i18n(
"Autographer"),
"att":i18n(
"Attributed name"),
"aud":i18n(
"Author of dialog"),
"aut":i18n(
"Author"),
"bdd":i18n(
"Binding designer"),
"bjd":i18n(
"Bookjacket designer"),
"bkd":i18n(
"Book designer"),
"bkp":i18n(
"Book producer"),
"blw":i18n(
"Blurb writer"),
"bnd":i18n(
"Binder"),
"bpd":i18n(
"Bookplate designer"),
"bsl":i18n(
"Bookseller"),
"cll":i18n(
"Calligrapher"),
"clr":i18n(
"Colorist"),
"cns":i18n(
"Censor"),
"cov":i18n(
"Cover designer"),
"cph":i18n(
"Copyright holder"),
"cre":i18n(
"Creator"),
"ctb":i18n(
"Contributor"),
"cur":i18n(
"Curator"),
"cwt":i18n(
"Commentator for written text"),
"drm":i18n(
"Draftsman"),
"dsr":i18n(
"Designer"),
"dub":i18n(
"Dubious author"),
"edt":i18n(
"Editor"),
"etr":i18n(
"Etcher"),
"exp":i18n(
"Expert"),
"fnd":i18n(
"Funder"),
"ill":i18n(
"Illustrator"),
"ilu":i18n(
"Illuminator"),
"ins":i18n(
"Inscriber"),
"lse":i18n(
"Licensee"),
"lso":i18n(
"Licensor"),
"ltg":i18n(
"Lithographer"),
"mdc":i18n(
"Metadata contact"),
"oth":i18n(
"Other"),
"own":i18n(
"Owner"),
"pat":i18n(
"Patron"),
"pbd":i18n(
"Publishing director"),
"pbl":i18n(
"Publisher"),
"prt":i18n(
"Printer"),
"sce":i18n(
"Scenarist"),
"scr":i18n(
"Scribe"),
"spn":i18n(
"Sponsor"),
"stl":i18n(
"Storyteller"),
"trc":i18n(
"Transcriber"),
"trl":i18n(
"Translator"),
"tyd":i18n(
"Type designer"),
"tyg":i18n(
"Typographer"),
"wac":i18n(
"Writer of added commentary"),
"wal":i18n(
"Writer of added lyrics"),
"wam":i18n(
"Writer of accompanying material"),
"wat":i18n(
"Writer of added text"),
"win":i18n(
"Writer of introduction"),
"wpr":i18n(
"Writer of preface"),
"wst":i18n(
"Writer of supplementary textual content")}
236 opfFile = QDomDocument()
237 opfRoot = opfFile.createElement(
"package")
238 opfRoot.setAttribute(
"version",
"3.0")
239 opfRoot.setAttribute(
"unique-identifier",
"BookId")
240 opfRoot.setAttribute(
"xmlns",
"http://www.idpf.org/2007/opf")
241 opfRoot.setAttribute(
"prefix",
"rendition: http://www.idpf.org/vocab/rendition/#")
242 opfFile.appendChild(opfRoot)
244 opfMeta = opfFile.createElement(
"metadata")
245 opfMeta.setAttribute(
"xmlns:dc",
"http://purl.org/dc/elements/1.1/")
246 opfMeta.setAttribute(
"xmlns:dcterms",
"http://purl.org/dc/terms/")
251 if "language" in configDictionary.keys():
252 langString = str(configDictionary[
"language"]).replace(
"_",
"-")
254 bookLang = opfFile.createElement(
"dc:language")
255 bookLang.appendChild(opfFile.createTextNode(langString))
256 opfMeta.appendChild(bookLang)
258 bookTitle = opfFile.createElement(
"dc:title")
259 if "title" in configDictionary.keys():
260 bookTitle.appendChild(opfFile.createTextNode(str(configDictionary[
"title"])))
262 bookTitle.appendChild(opfFile.createTextNode(
"Comic with no Name"))
263 opfMeta.appendChild(bookTitle)
266 if "seriesName" in configDictionary.keys():
267 bookTitle.setAttribute(
"id",
"main")
269 refine = opfFile.createElement(
"meta")
270 refine.setAttribute(
"refines",
"#main")
271 refine.setAttribute(
"property",
"title-type")
272 refine.appendChild(opfFile.createTextNode(
"main"))
273 opfMeta.appendChild(refine)
275 refine2 = opfFile.createElement(
"meta")
276 refine2.setAttribute(
"refines",
"#main")
277 refine2.setAttribute(
"property",
"display-seq")
278 refine2.appendChild(opfFile.createTextNode(
"1"))
279 opfMeta.appendChild(refine2)
281 seriesTitle = opfFile.createElement(
"dc:title")
282 seriesTitle.appendChild(opfFile.createTextNode(str(configDictionary[
"seriesName"])))
283 seriesTitle.setAttribute(
"id",
"series")
284 opfMeta.appendChild(seriesTitle)
286 refineS = opfFile.createElement(
"meta")
287 refineS.setAttribute(
"refines",
"#series")
288 refineS.setAttribute(
"property",
"title-type")
289 refineS.appendChild(opfFile.createTextNode(
"collection"))
290 opfMeta.appendChild(refineS)
292 refineS2 = opfFile.createElement(
"meta")
293 refineS2.setAttribute(
"refines",
"#series")
294 refineS2.setAttribute(
"property",
"display-seq")
295 refineS2.appendChild(opfFile.createTextNode(
"2"))
296 opfMeta.appendChild(refineS2)
298 if "seriesNumber" in configDictionary.keys():
299 refineS3 = opfFile.createElement(
"meta")
300 refineS3.setAttribute(
"refines",
"#series")
301 refineS3.setAttribute(
"property",
"group-position")
302 refineS3.appendChild(opfFile.createTextNode(str(configDictionary[
"seriesNumber"])))
303 opfMeta.appendChild(refineS3)
305 uuid = str(configDictionary[
"uuid"])
306 uuid = uuid.strip(
"{")
307 uuid = uuid.strip(
"}")
310 uniqueID = opfFile.createElement(
"dc:identifier")
311 uniqueID.appendChild(opfFile.createTextNode(
"urn:uuid:"+uuid))
312 uniqueID.setAttribute(
"id",
"BookId")
313 opfMeta.appendChild(uniqueID)
315 if "authorList" in configDictionary.keys():
317 for authorE
in range(len(configDictionary[
"authorList"])):
318 authorDict = configDictionary[
"authorList"][authorE]
319 authorType =
"dc:creator"
320 if "role" in authorDict.keys():
322 if str(authorDict[
"role"]).lower()
in [
"editor",
"assistant editor",
"proofreader",
"beta",
"patron",
"funder"]:
323 authorType =
"dc:contributor"
324 author = opfFile.createElement(authorType)
326 if "last-name" in authorDict.keys():
327 authorName.append(authorDict[
"last-name"])
328 if "first-name" in authorDict.keys():
329 authorName.append(authorDict[
"first-name"])
330 if "initials" in authorDict.keys():
331 authorName.append(authorDict[
"initials"])
332 if "nickname" in authorDict.keys():
333 authorName.append(
"(" + authorDict[
"nickname"] +
")")
334 author.appendChild(opfFile.createTextNode(
", ".join(authorName)))
335 author.setAttribute(
"id",
"cre" + str(authorE))
336 opfMeta.appendChild(author)
337 if "role" in authorDict.keys():
338 role = opfFile.createElement(
"meta")
339 role.setAttribute(
"refines",
"#cre" + str(authorE))
340 role.setAttribute(
"scheme",
"marc:relators")
341 role.setAttribute(
"property",
"role")
342 roleString = str(authorDict[
"role"])
343 if roleString
in marcRelators.values()
or roleString
in marcRelators.keys():
344 i = list(marcRelators.values()).index(roleString)
345 roleString = list(marcRelators.keys())[i]
348 role.appendChild(opfFile.createTextNode(roleString))
349 opfMeta.appendChild(role)
350 refine = opfFile.createElement(
"meta")
351 refine.setAttribute(
"refines",
"#cre"+str(authorE))
352 refine.setAttribute(
"property",
"display-seq")
353 refine.appendChild(opfFile.createTextNode(str(authorE+1)))
354 opfMeta.appendChild(refine)
356 if "publishingDate" in configDictionary.keys():
357 date = opfFile.createElement(
"dc:date")
358 date.appendChild(opfFile.createTextNode(configDictionary[
"publishingDate"]))
359 opfMeta.appendChild(date)
362 modified = opfFile.createElement(
"meta")
363 modified.setAttribute(
"property",
"dcterms:modified")
364 modified.appendChild(opfFile.createTextNode(QDateTime.currentDateTimeUtc().toString(Qt.DateFormat.ISODate)))
365 opfMeta.appendChild(modified)
367 if "source" in configDictionary.keys():
368 if len(configDictionary[
"source"])>0:
369 source = opfFile.createElement(
"dc:source")
370 source.appendChild(opfFile.createTextNode(configDictionary[
"source"]))
371 opfMeta.appendChild(source)
373 description = opfFile.createElement(
"dc:description")
374 if "summary" in configDictionary.keys():
375 description.appendChild(opfFile.createTextNode(configDictionary[
"summary"]))
377 description.appendChild(opfFile.createTextNode(
"There was no summary upon generation of this file."))
378 opfMeta.appendChild(description)
384 if "publisherName" in configDictionary.keys():
385 publisher = opfFile.createElement(
"dc:publisher")
386 publisher.appendChild(opfFile.createTextNode(configDictionary[
"publisherName"]))
387 opfMeta.appendChild(publisher)
390 if "isbn-number" in configDictionary.keys():
391 isbnnumber = configDictionary[
"isbn-number"]
393 if len(isbnnumber)>0:
394 publishISBN = opfFile.createElement(
"dc:identifier")
395 publishISBN.appendChild(opfFile.createTextNode(str(
"urn:isbn:") + isbnnumber))
396 opfMeta.appendChild(publishISBN)
398 if "license" in configDictionary.keys():
400 if len(configDictionary[
"license"])>0:
401 rights = opfFile.createElement(
"dc:rights")
402 rights.appendChild(opfFile.createTextNode(configDictionary[
"license"]))
403 opfMeta.appendChild(rights)
407 Relation - This is for whether the work has a relationship with another work.
408 It could be fanart, but also adaptation, an academic work, etc.
409 Coverage - This is for the time/place that the work covers. Typically to determine
410 whether an academic work deals with a certain time period or place.
411 For comics you could use this to mark historical comics, but other than
412 that we'd need a much better ui to define this.
419 if "genre" in configDictionary.keys():
420 genreListConf = configDictionary[
"genre"]
421 if isinstance(configDictionary[
"genre"], dict):
422 genreListConf = configDictionary[
"genre"].keys()
423 for g
in genreListConf:
424 subject = opfFile.createElement(
"dc:subject")
425 subject.appendChild(opfFile.createTextNode(g))
426 opfMeta.appendChild(subject)
427 if "characters" in configDictionary.keys():
428 for name
in configDictionary[
"characters"]:
429 char = opfFile.createElement(
"dc:subject")
430 char.appendChild(opfFile.createTextNode(name))
431 opfMeta.appendChild(char)
432 if "format" in configDictionary.keys():
433 for formatF
in configDictionary[
"format"]:
434 f = opfFile.createElement(
"dc:subject")
435 f.appendChild(opfFile.createTextNode(formatF))
436 opfMeta.appendChild(f)
437 if "otherKeywords" in configDictionary.keys():
438 for key
in configDictionary[
"otherKeywords"]:
439 word = opfFile.createElement(
"dc:subject")
440 word.appendChild(opfFile.createTextNode(key))
441 opfMeta.appendChild(word)
446 elLayout = opfFile.createElement(
"meta")
447 elLayout.setAttribute(
"property",
"rendition:layout")
448 elLayout.appendChild(opfFile.createTextNode(
"pre-paginated"))
449 opfMeta.appendChild(elLayout)
452 elOrientation = opfFile.createElement(
"meta")
453 elOrientation.setAttribute(
"property",
"rendition:orientation")
454 elOrientation.appendChild(opfFile.createTextNode(
"portrait"))
455 opfMeta.appendChild(elOrientation)
457 elSpread = opfFile.createElement(
"meta")
458 elSpread.setAttribute(
"property",
"rendition:spread")
459 elSpread.appendChild(opfFile.createTextNode(
"landscape"))
460 opfMeta.appendChild(elSpread)
462 opfRoot.appendChild(opfMeta)
466 opfManifest = opfFile.createElement(
"manifest")
467 toc = opfFile.createElement(
"item")
468 toc.setAttribute(
"id",
"ncx")
469 toc.setAttribute(
"href",
"toc.ncx")
470 toc.setAttribute(
"media-type",
"application/x-dtbncx+xml")
471 opfManifest.appendChild(toc)
473 region = opfFile.createElement(
"item")
474 region.setAttribute(
"id",
"regions")
475 region.setAttribute(
"href",
"region-nav.xhtml")
476 region.setAttribute(
"media-type",
"application/xhtml+xml")
477 region.setAttribute(
"properties",
"data-nav")
478 opfManifest.appendChild(region)
480 nav = opfFile.createElement(
"item")
481 nav.setAttribute(
"id",
"nav")
482 nav.setAttribute(
"href",
"nav.xhtml")
483 nav.setAttribute(
"media-type",
"application/xhtml+xml")
484 nav.setAttribute(
"properties",
"nav")
485 opfManifest.appendChild(nav)
489 item = opfFile.createElement(
"item")
490 item.setAttribute(
"id",
"img"+str(ids))
492 item.setAttribute(
"href", os.path.relpath(p, str(path)))
493 item.setAttribute(
"media-type",
"image/png")
494 if os.path.basename(p) == os.path.basename(coverpageurl):
495 item.setAttribute(
"properties",
"cover-image")
496 opfManifest.appendChild(item)
501 item = opfFile.createElement(
"item")
502 item.setAttribute(
"id",
"p"+str(ids))
504 item.setAttribute(
"href", os.path.relpath(p, str(path)))
505 item.setAttribute(
"media-type",
"application/xhtml+xml")
506 opfManifest.appendChild(item)
509 opfRoot.appendChild(opfManifest)
513 opfSpine = opfFile.createElement(
"spine")
515 opfSpine.setAttribute(
"toc",
"ncx")
520 if "readingDirection" in configDictionary.keys():
521 if configDictionary[
"readingDirection"] ==
"rightToLeft":
522 opfSpine.setAttribute(
"page-progression-direction",
"rtl")
526 opfSpine.setAttribute(
"page-progression-direction",
"ltr")
532 item = opfFile.createElement(
"itemref")
533 item.setAttribute(
"idref",
"p"+str(ids))
536 if p
in listofSpreads:
538 props.append(
"rendition:page-spread-center")
549 props.append(
"page-spread-right")
552 props.append(
"page-spread-left")
554 item.setAttribute(
"properties",
" ".join(props))
555 opfSpine.appendChild(item)
556 opfRoot.appendChild(opfSpine)
560 opfGuide = opfFile.createElement(
"guide")
561 if coverpagehtml
is not None and coverpagehtml.isspace()
is False and len(coverpagehtml) > 0:
562 item = opfFile.createElement(
"reference")
563 item.setAttribute(
"type",
"cover")
564 item.setAttribute(
"title",
"Cover")
565 item.setAttribute(
"href", coverpagehtml)
566 opfGuide.appendChild(item)
567 opfRoot.appendChild(opfGuide)
569 docFile = open(str(Path(path /
"content.opf")),
'w', newline=
"", encoding=
"utf-8")
570 docFile.write(opfFile.toString(indent=2))
572 return str(Path(path /
"content.opf"))
575Write a region navmap file.
579 navDoc = QDomDocument()
580 navRoot = navDoc.createElement(
"html")
581 navRoot.setAttribute(
"xmlns",
"http://www.w3.org/1999/xhtml")
582 navRoot.setAttribute(
"xmlns:epub",
"http://www.idpf.org/2007/ops")
583 navDoc.appendChild(navRoot)
585 head = navDoc.createElement(
"head")
586 title = navDoc.createElement(
"title")
587 title.appendChild(navDoc.createTextNode(
"Region Navigation"))
588 head.appendChild(title)
589 navRoot.appendChild(head)
591 body = navDoc.createElement(
"body")
592 navRoot.appendChild(body)
594 nav = navDoc.createElement(
"nav")
595 nav.setAttribute(
"epub:type",
"region-based")
596 nav.setAttribute(
"prefix",
"ahl: http://idpf.org/epub/vocab/ahl")
597 body.appendChild(nav)
601 olPanels = navDoc.createElement(
"ol")
602 for region
in regions:
603 if region[
"type"] ==
"panel":
604 pageName = os.path.relpath(region[
"page"], str(path))
605 print(
"accessing panel")
606 li = navDoc.createElement(
"li")
607 li.setAttribute(
"epub:type",
"panel")
609 anchor = navDoc.createElement(
"a")
610 bounds = region[
"points"]
611 anchor.setAttribute(
"href", pageName+
"#xywh=percent:"+str(bounds.x())+
","+str(bounds.y())+
","+str(bounds.width())+
","+str(bounds.height()))
613 if len(region[
"primaryColor"])>0:
614 primaryC = navDoc.createElement(
"meta")
615 primaryC.setAttribute(
"property",
"ahl:primary-color")
616 primaryC.setAttribute(
"content", region[
"primaryColor"])
617 anchor.appendChild(primaryC)
619 li.appendChild(anchor)
620 olBalloons = navDoc.createElement(
"ol")
623 The region nav spec specifies that we should have text-areas/balloons as a refinement on
625 For each panel, we'll check if there's balloons/text-areas inside, and we'll do that by
626 checking whether the center point is inside the panel because some comics have balloons
627 that overlap the gutters.
629 for balloon
in regions:
630 if balloon[
"type"] ==
"text" and balloon[
"page"] == region[
"page"]
and bounds.contains(balloon[
"points"].center()):
631 liBalloon = navDoc.createElement(
"li")
632 liBalloon.setAttribute(
"epub:type",
"text-area")
634 anchorBalloon = navDoc.createElement(
"a")
635 BBounds = balloon[
"points"]
636 anchorBalloon.setAttribute(
"href", pageName+
"#xywh=percent:"+str(BBounds.x())+
","+str(BBounds.y())+
","+str(BBounds.width())+
","+str(BBounds.height()))
638 liBalloon.appendChild(anchorBalloon)
639 olBalloons.appendChild(liBalloon)
641 if olBalloons.hasChildNodes():
642 li.appendChild(olBalloons)
643 olPanels.appendChild(li)
644 nav.appendChild(olPanels)
646 navFile = open(str(Path(path /
"region-nav.xhtml")),
'w', newline=
"", encoding=
"utf-8")
647 navFile.write(navDoc.toString(indent=2))
649 return str(Path(path /
"region-nav.xhtml"))
654This is virtually the same as the NCX file, except that
655the navigation document can be styled, and is what 3.1 and
6563.2 expect as a primary navigation document.
658This function will both create a table of contents, using the
659"acbf_title" feature, as well as a regular pageslist.
663 navDoc = QDomDocument()
664 navRoot = navDoc.createElement(
"html")
665 navRoot.setAttribute(
"xmlns",
"http://www.w3.org/1999/xhtml")
666 navRoot.setAttribute(
"xmlns:epub",
"http://www.idpf.org/2007/ops")
667 navDoc.appendChild(navRoot)
669 head = navDoc.createElement(
"head")
670 title = navDoc.createElement(
"title")
671 title.appendChild(navDoc.createTextNode(
"Table of Contents"))
672 head.appendChild(title)
673 navRoot.appendChild(head)
675 body = navDoc.createElement(
"body")
676 navRoot.appendChild(body)
680 toc = navDoc.createElement(
"nav")
681 toc.setAttribute(
"epub:type",
"toc")
682 oltoc = navDoc.createElement(
"ol")
683 li = navDoc.createElement(
"li")
684 anchor = navDoc.createElement(
"a")
685 anchor.setAttribute(
"href", os.path.relpath(htmlFiles[0], str(path)))
686 anchor.appendChild(navDoc.createTextNode(
"Start"))
687 li.appendChild(anchor)
688 oltoc.appendChild(li)
689 for fileName
in listOfNavItems.keys():
690 li = navDoc.createElement(
"li")
691 anchor = navDoc.createElement(
"a")
692 anchor.setAttribute(
"href", os.path.relpath(fileName, str(path)))
693 anchor.appendChild(navDoc.createTextNode(listOfNavItems[fileName]))
694 li.appendChild(anchor)
695 oltoc.appendChild(li)
697 toc.appendChild(oltoc)
698 body.appendChild(toc)
702 pageslist = navDoc.createElement(
"nav")
703 pageslist.setAttribute(
"epub:type",
"page-list")
704 olpages = navDoc.createElement(
"ol")
707 for i
in range(len(htmlFiles)):
708 li = navDoc.createElement(
"li")
709 anchor = navDoc.createElement(
"a")
710 anchor.setAttribute(
"href", os.path.relpath(htmlFiles[1], str(path)))
711 anchor.appendChild(navDoc.createTextNode(str(i)))
712 li.appendChild(anchor)
713 olpages.appendChild(li)
714 pageslist.appendChild(olpages)
716 body.appendChild(pageslist)
720 navFile = open(str(Path(path /
"nav.xhtml")),
'w', newline=
"", encoding=
"utf-8")
721 navFile.write(navDoc.toString(indent=2))
723 return str(Path(path /
"nav.xhtml"))
728This is the same as the navigation document above, but then
729for 2.0 backward compatibility.
733 tocDoc = QDomDocument()
734 ncx = tocDoc.createElement(
"ncx")
735 ncx.setAttribute(
"version",
"2005-1")
736 ncx.setAttribute(
"xmlns",
"http://www.daisy.org/z3986/2005/ncx/")
737 tocDoc.appendChild(ncx)
739 tocHead = tocDoc.createElement(
"head")
744 uuid = str(configDictionary[
"uuid"])
745 uuid = uuid.strip(
"{")
746 uuid = uuid.strip(
"}")
747 metaID = tocDoc.createElement(
"meta")
748 metaID.setAttribute(
"content", uuid)
749 metaID.setAttribute(
"name",
"dtb:uid")
750 tocHead.appendChild(metaID)
751 metaDepth = tocDoc.createElement(
"meta")
752 metaDepth.setAttribute(
"content", str(1))
753 metaDepth.setAttribute(
"name",
"dtb:depth")
754 tocHead.appendChild(metaDepth)
755 metaTotal = tocDoc.createElement(
"meta")
756 metaTotal.setAttribute(
"content", str(len(htmlFiles)))
757 metaTotal.setAttribute(
"name",
"dtb:totalPageCount")
758 tocHead.appendChild(metaTotal)
759 metaMax = tocDoc.createElement(
"meta")
760 metaMax.setAttribute(
"content", str(len(htmlFiles)))
761 metaMax.setAttribute(
"name",
"dtb:maxPageNumber")
762 tocHead.appendChild(metaDepth)
763 ncx.appendChild(tocHead)
765 docTitle = tocDoc.createElement(
"docTitle")
766 text = tocDoc.createElement(
"text")
767 if "title" in configDictionary.keys():
768 text.appendChild(tocDoc.createTextNode(str(configDictionary[
"title"])))
770 text.appendChild(tocDoc.createTextNode(
"Comic with no Name"))
771 docTitle.appendChild(text)
772 ncx.appendChild(docTitle)
776 navmap = tocDoc.createElement(
"navMap")
777 navPoint = tocDoc.createElement(
"navPoint")
778 navPoint.setAttribute(
"id",
"navPoint-1")
779 navPoint.setAttribute(
"playOrder",
"1")
780 navLabel = tocDoc.createElement(
"navLabel")
781 navLabelText = tocDoc.createElement(
"text")
782 navLabelText.appendChild(tocDoc.createTextNode(
"Start"))
783 navLabel.appendChild(navLabelText)
784 navContent = tocDoc.createElement(
"content")
785 navContent.setAttribute(
"src", os.path.relpath(htmlFiles[0], str(path)))
786 navPoint.appendChild(navLabel)
787 navPoint.appendChild(navContent)
788 navmap.appendChild(navPoint)
790 for fileName
in listOfNavItems.keys():
792 navPointT = tocDoc.createElement(
"navPoint")
793 navPointT.setAttribute(
"id",
"navPoint-"+str(entry))
794 navPointT.setAttribute(
"playOrder", str(entry))
795 navLabelT = tocDoc.createElement(
"navLabel")
796 navLabelTText = tocDoc.createElement(
"text")
797 navLabelTText.appendChild(tocDoc.createTextNode(listOfNavItems[fileName]))
798 navLabelT.appendChild(navLabelTText)
799 navContentT = tocDoc.createElement(
"content")
800 navContentT.setAttribute(
"src", os.path.relpath(fileName, str(path)))
801 navPointT.appendChild(navLabelT)
802 navPointT.appendChild(navContentT)
803 navmap.appendChild(navPointT)
804 ncx.appendChild(navmap)
808 pagesList = tocDoc.createElement(
"pageList")
809 navLabelPages = tocDoc.createElement(
"navLabel")
810 navLabelPagesText = tocDoc.createElement(
"text")
811 navLabelPagesText.appendChild(tocDoc.createTextNode(
"Pages"))
812 navLabelPages.appendChild(navLabelPagesText)
813 pagesList.appendChild(navLabelPages)
814 for i
in range(len(htmlFiles)):
815 pageTarget = tocDoc.createElement(
"pageTarget")
816 pageTarget.setAttribute(
"type",
"normal")
817 pageTarget.setAttribute(
"id",
"page-"+str(i))
818 pageTarget.setAttribute(
"value", str(i))
819 navLabelPagesTarget = tocDoc.createElement(
"navLabel")
820 navLabelPagesTargetText = tocDoc.createElement(
"text")
821 navLabelPagesTargetText.appendChild(tocDoc.createTextNode(str(i+1)))
822 navLabelPagesTarget.appendChild(navLabelPagesTargetText)
823 pageTarget.appendChild(navLabelPagesTarget)
824 pageTargetContent = tocDoc.createElement(
"content")
825 pageTargetContent.setAttribute(
"src", os.path.relpath(htmlFiles[i], str(path)))
826 pageTarget.appendChild(pageTargetContent)
827 pagesList.appendChild(pageTarget)
828 ncx.appendChild(pagesList)
832 docFile = open(str(Path(path /
"toc.ncx")),
'w', newline=
"", encoding=
"utf-8")
833 docFile.write(tocDoc.toString(indent=2))
835 return str(Path(path /
"toc.ncx"))