diff --git a/calibre-plugin/plugin-defaults.ini b/calibre-plugin/plugin-defaults.ini index 3cd5256..836fa4d 100644 --- a/calibre-plugin/plugin-defaults.ini +++ b/calibre-plugin/plugin-defaults.ini @@ -599,6 +599,11 @@ include_logpage: false ## end up with Completed stories that have just one logpage entry. #include_logpage: smart +## By default, logpage is placed before the story chapters. This +## setting, if true, will place the logpage after the chapters +## instead. +logpage_at_end: false + ## items to include in the log page Empty metadata entries, or those ## that haven't changed since the last update, will *not* appear, even ## if in the list. You can include extra text or HTML that will be diff --git a/fanficfare/configurable.py b/fanficfare/configurable.py index f35a7da..754cded 100644 --- a/fanficfare/configurable.py +++ b/fanficfare/configurable.py @@ -176,6 +176,7 @@ def get_valid_set_options(): None,boollist), 'include_logpage':(None,['epub'],boollist+['smart']), + 'logpage_at_end':(None,['epub'],boollist), 'windows_eol':(None,['txt'],boollist), @@ -283,6 +284,7 @@ def get_valid_keywords(): 'image_max_size', 'include_images', 'include_logpage', + 'logpage_at_end', 'include_subject_tags', 'include_titlepage', 'include_tocpage', diff --git a/fanficfare/defaults.ini b/fanficfare/defaults.ini index 4889f32..8972a9a 100644 --- a/fanficfare/defaults.ini +++ b/fanficfare/defaults.ini @@ -604,6 +604,11 @@ include_logpage: false ## end up with Completed stories that have just one logpage entry. #include_logpage: smart +## By default, logpage is placed before the story chapters. This +## setting, if true, will place the logpage after the chapters +## instead. +logpage_at_end: false + ## items to include in the log page Empty metadata entries, or those ## that haven't changed since the last update, will *not* appear, even ## if in the list. You can include extra text or HTML that will be diff --git a/fanficfare/writers/writer_epub.py b/fanficfare/writers/writer_epub.py index 3a54ff7..3a802c5 100644 --- a/fanficfare/writers/writer_epub.py +++ b/fanficfare/writers/writer_epub.py @@ -46,7 +46,7 @@ class EpubWriter(BaseStoryWriter): BaseStoryWriter.__init__(self, config, story) self.EPUB_CSS = string.Template('''${output_css}''') - + self.EPUB_TITLE_PAGE_START = string.Template(''' @@ -117,7 +117,7 @@ ${value}
self.EPUB_TOC_ENTRY = string.Template(''' ${chapter}
''') - + self.EPUB_TOC_PAGE_END = string.Template(''' @@ -156,15 +156,15 @@ ${value}
self.EPUB_LOG_UPDATE_START = string.Template('''

''') - + self.EPUB_LOG_ENTRY = string.Template(''' ${label}: ${value} ''') - + self.EPUB_LOG_UPDATE_END = string.Template('''


''') - + self.EPUB_LOG_PAGE_END = string.Template(''' @@ -184,7 +184,7 @@ div { margin: 0pt; padding: 0pt; } cover ''') - + def writeLogPage(self, out): """ Write the log page, but only include entries that there's @@ -201,7 +201,7 @@ div { margin: 0pt; padding: 0pt; } END = string.Template(self.getConfig("logpage_end")) else: END = self.EPUB_LOG_PAGE_END - + # if there's a self.story.logfile, there's an existing log # to add to. if self.story.logfile: @@ -234,7 +234,7 @@ div { margin: 0pt; padding: 0pt; } pass return values - + def _makeLogEntry(self, oldvalues={}): if self.hasConfig("logpage_update_start"): START = string.Template(self.getConfig("logpage_update_start")) @@ -275,16 +275,16 @@ div { margin: 0pt; padding: 0pt; } # mostly it makes it easy to tell when you get the # keyword wrong. retval = retval + entry - + retval = retval + END.substitute(self.story.getAllMetadata()) - + if self.getConfig('replace_hr'): # replacing a self-closing tag with a container tag in the # soup is more difficult than it first appears. So cheat. retval = re.sub("]*>","
* * *
",retval) - + return retval - + def writeStoryImpl(self, out): ## Python 2.5 ZipFile is rather more primative than later @@ -305,7 +305,7 @@ div { margin: 0pt; padding: 0pt; } ## Re-open file for content. outputepub = ZipFile(zipio, 'a', compression=ZIP_DEFLATED) outputepub.debug=3 - + ## Create META-INF/container.xml file. The only thing it does is ## point to content.opf containerdom = getDOMImplementation().createDocument(None, "container", None) @@ -332,7 +332,7 @@ div { margin: 0pt; padding: 0pt; } self.getMetadata('site'), self.story.getList('authorId')[0], self.getMetadata('storyId')) - + contentdom = getDOMImplementation().createDocument(None, "package", None) package = contentdom.documentElement package.setAttribute("version","2.0") @@ -374,12 +374,12 @@ div { margin: 0pt; padding: 0pt; } metadata.appendChild(newTag(contentdom,"dc:date", attrs={"opf:event":"publication"}, text=self.story.getMetadataRaw('datePublished').strftime("%Y-%m-%d"))) - + if self.story.getMetadataRaw('dateCreated'): metadata.appendChild(newTag(contentdom,"dc:date", attrs={"opf:event":"creation"}, text=self.story.getMetadataRaw('dateCreated').strftime("%Y-%m-%d"))) - + if self.story.getMetadataRaw('dateUpdated'): metadata.appendChild(newTag(contentdom,"dc:date", attrs={"opf:event":"modification"}, @@ -387,7 +387,7 @@ div { margin: 0pt; padding: 0pt; } metadata.appendChild(newTag(contentdom,"meta", attrs={"name":"calibre:timestamp", "content":self.story.getMetadataRaw('dateUpdated').strftime("%Y-%m-%dT%H:%M:%S")})) - + if self.getMetadata('description'): metadata.appendChild(newTag(contentdom,"dc:description",text= self.getMetadata('description'))) @@ -395,11 +395,11 @@ div { margin: 0pt; padding: 0pt; } for subject in self.story.getSubjectTags(): metadata.appendChild(newTag(contentdom,"dc:subject",text=subject)) - + if self.getMetadata('site'): metadata.appendChild(newTag(contentdom,"dc:publisher", text=self.getMetadata('site'))) - + if self.getMetadata('storyUrl'): metadata.appendChild(newTag(contentdom,"dc:identifier", attrs={"opf:scheme":"URL"}, @@ -415,7 +415,7 @@ div { margin: 0pt; padding: 0pt; } guide = None coverIO = None - + coverimgid = "image0000" if not self.story.cover and self.story.oldcover: logger.debug("writer_epub: no new cover, has old cover, write image.") @@ -427,7 +427,7 @@ div { margin: 0pt; padding: 0pt; } oldcoverimgdata) = self.story.oldcover outputepub.writestr(oldcoverhtmlhref,oldcoverhtmldata) outputepub.writestr(oldcoverimghref,oldcoverimgdata) - + coverimgid = "image0" items.append((coverimgid, oldcoverimghref, @@ -441,8 +441,8 @@ div { margin: 0pt; padding: 0pt; } guide.appendChild(newTag(contentdom,"reference",attrs={"type":"cover", "title":"Cover", "href":oldcoverhtmlhref})) - - + + if self.getConfig('include_images'): imgcount=0 @@ -459,7 +459,7 @@ div { margin: 0pt; padding: 0pt; } # just the first image. coverimgid = items[-1][0] - + items.append(("style","OEBPS/stylesheet.css","text/css",None)) if self.story.cover: @@ -467,7 +467,7 @@ div { margin: 0pt; padding: 0pt; } # for it to work on Nook. items.append(("cover","OEBPS/cover.xhtml","application/xhtml+xml",None)) itemrefs.append("cover") - # + # # metadata.appendChild(newTag(contentdom,"meta",{"content":coverimgid, "name":"cover"})) @@ -480,14 +480,14 @@ div { margin: 0pt; padding: 0pt; } guide.appendChild(newTag(contentdom,"reference",attrs={"type":"cover", "title":"Cover", "href":"OEBPS/cover.xhtml"})) - + if self.hasConfig("cover_content"): COVER = string.Template(self.getConfig("cover_content")) else: COVER = self.EPUB_COVER coverIO = StringIO.StringIO() coverIO.write(COVER.substitute(dict(self.story.getAllMetadata().items()+{'coverimg':self.story.cover}.items()))) - + if self.getConfig("include_titlepage"): items.append(("title_page","OEBPS/title_page.xhtml","application/xhtml+xml","Title Page")) itemrefs.append("title_page") @@ -495,14 +495,13 @@ div { margin: 0pt; padding: 0pt; } items.append(("toc_page","OEBPS/toc_page.xhtml","application/xhtml+xml","Table of Contents")) itemrefs.append("toc_page") + ## save where to insert logpage. + logpage_indices = (len(items),len(itemrefs)) + dologpage = ( self.getConfig("include_logpage") == "smart" and \ (self.story.logfile or self.story.getMetadataRaw("status") == "In-Progress") ) \ or self.getConfig("include_logpage") == "true" - if dologpage: - items.append(("log_page","OEBPS/log_page.xhtml","application/xhtml+xml","Update Log")) - itemrefs.append("log_page") - for index, chap in enumerate(self.story.getChapters(fortoc=True)): if chap.html: i=index+1 @@ -512,6 +511,13 @@ div { margin: 0pt; padding: 0pt; } chap.title)) itemrefs.append("file%04d"%i) + if dologpage: + if self.getConfig("logpage_at_end") == "true": + ## insert logpage after chapters. + logpage_indices = (len(items),len(itemrefs)) + items.insert(logpage_indices[0],("log_page","OEBPS/log_page.xhtml","application/xhtml+xml","Update Log")) + itemrefs.insert(logpage_indices[1],"log_page") + manifest = contentdom.createElement("manifest") package.appendChild(manifest) for item in items: @@ -520,7 +526,7 @@ div { margin: 0pt; padding: 0pt; } attrs={'id':id, 'href':href, 'media-type':type})) - + spine = newTag(contentdom,"spine",attrs={"toc":"ncx"}) package.appendChild(spine) for itemref in itemrefs: @@ -530,10 +536,10 @@ div { margin: 0pt; padding: 0pt; } # guide only exists if there's a cover. if guide: package.appendChild(guide) - + # write content.opf to zip. contentxml = contentdom.toxml(encoding='utf-8') - + # tweak for brain damaged Nook STR. Nook insists on name before content. contentxml = contentxml.replace(''%coverimgid, ''%coverimgid) @@ -557,11 +563,11 @@ div { margin: 0pt; padding: 0pt; } attrs={"name":"dtb:totalPageCount", "content":"0"})) head.appendChild(newTag(tocncxdom,"meta", attrs={"name":"dtb:maxPageNumber", "content":"0"})) - + docTitle = tocncxdom.createElement("docTitle") docTitle.appendChild(newTag(tocncxdom,"text",text=self.getMetadata('title'))) ncx.appendChild(docTitle) - + tocnavMap = tocncxdom.createElement("navMap") ncx.appendChild(tocnavMap) @@ -586,14 +592,14 @@ div { margin: 0pt; padding: 0pt; } navLabel.appendChild(newTag(tocncxdom,"text",text=stripHTML(title))) navPoint.appendChild(newTag(tocncxdom,"content",attrs={"src":href})) index=index+1 - + # write toc.ncx to zip file outputepub.writestr("toc.ncx",tocncxdom.toxml(encoding='utf-8')) tocncxdom.unlink() del tocncxdom # write stylesheet.css file. - outputepub.writestr("OEBPS/stylesheet.css",self.EPUB_CSS.substitute(self.story.getAllMetadata())) + outputepub.writestr("OEBPS/stylesheet.css",self.EPUB_CSS.substitute(self.story.getAllMetadata())) # write title page. if self.getConfig("titlepage_use_table"): @@ -612,7 +618,7 @@ div { margin: 0pt; padding: 0pt; } if coverIO: outputepub.writestr("OEBPS/cover.xhtml",coverIO.getvalue()) coverIO.close() - + titlepageIO = StringIO.StringIO() self.writeTitlePage(out=titlepageIO, START=TITLE_PAGE_START, @@ -624,7 +630,7 @@ div { margin: 0pt; padding: 0pt; } outputepub.writestr("OEBPS/title_page.xhtml",titlepageIO.getvalue()) titlepageIO.close() - # write toc page. + # write toc page. tocpageIO = StringIO.StringIO() self.writeTOCPage(tocpageIO, self.EPUB_TOC_PAGE_START, @@ -645,12 +651,12 @@ div { margin: 0pt; padding: 0pt; } CHAPTER_START = string.Template(self.getConfig("chapter_start")) else: CHAPTER_START = self.EPUB_CHAPTER_START - + if self.hasConfig('chapter_end'): CHAPTER_END = string.Template(self.getConfig("chapter_end")) else: CHAPTER_END = self.EPUB_CHAPTER_END - + for index, chap in enumerate(self.story.getChapters()): # (url,title,html) if chap.html: #logger.debug('Writing chapter text for: %s' % chap.title)