EPUB Input: Use raster cover metadata

EPUB Input: If the EPUB file identifies an actual cover image in
addition to the titlepage html file, use the cover image instead of
rendering the titlepage. This is faster and has the advantage that an
EPUB to EPUB conversion preserves internal cover structure.
This commit is contained in:
Kovid Goyal 2013-08-04 12:35:19 +05:30
parent ba0ce696f4
commit 938fe0fa66
2 changed files with 33 additions and 12 deletions

View File

@ -75,6 +75,10 @@ class EPUBInput(InputFormatPlugin):
return False return False
def rationalize_cover(self, opf, log): def rationalize_cover(self, opf, log):
''' Ensure that the cover information in the guide is correct. That
means, at most one entry with type="cover" that points to a raster
cover and at most one entry with type="titlepage" that points to an
HTML titlepage. '''
removed = None removed = None
from lxml import etree from lxml import etree
guide_cover, guide_elem = None, None guide_cover, guide_elem = None, None
@ -109,24 +113,41 @@ class EPUBInput(InputFormatPlugin):
# display in the end # display in the end
spine[0].attrib.pop('linear', None) spine[0].attrib.pop('linear', None)
opf.spine[0].is_linear = True opf.spine[0].is_linear = True
guide_elem.set('href', 'calibre_raster_cover.jpg') # Ensure that the guide has a cover entry pointing to a raster cover
# and a titlepage entry pointing to the html titlepage. The titlepage
# entry will be used by the epub output plugin, the raster cover entry
# by other output plugins.
from calibre.ebooks.oeb.base import OPF from calibre.ebooks.oeb.base import OPF
t = etree.SubElement(elem[0].getparent(), OPF('item'),
href=guide_elem.get('href'), id='calibre_raster_cover') # Search for a raster cover identified in the OPF
t.set('media-type', 'image/jpeg') raster_cover = opf.raster_cover
# Set the cover guide entry
if raster_cover is not None:
guide_elem.set('href', raster_cover)
else:
# Render the titlepage to create a raster cover
from calibre.ebooks import render_html_svg_workaround
guide_elem.set('href', 'calibre_raster_cover.jpg')
t = etree.SubElement(
elem[0].getparent(), OPF('item'), href=guide_elem.get('href'), id='calibre_raster_cover')
t.set('media-type', 'image/jpeg')
if os.path.exists(guide_cover):
renderer = render_html_svg_workaround(guide_cover, log)
if renderer is not None:
open('calibre_raster_cover.jpg', 'wb').write(
renderer)
# Set the titlepage guide entry
for elem in list(opf.iterguide()): for elem in list(opf.iterguide()):
if elem.get('type', '').lower() == 'titlepage': if elem.get('type', '').lower() == 'titlepage':
elem.getparent().remove(elem) elem.getparent().remove(elem)
t = etree.SubElement(guide_elem.getparent(), OPF('reference')) t = etree.SubElement(guide_elem.getparent(), OPF('reference'))
t.set('type', 'titlepage') t.set('type', 'titlepage')
t.set('href', guide_cover) t.set('href', guide_cover)
t.set('title', 'Title Page') t.set('title', 'Title Page')
from calibre.ebooks import render_html_svg_workaround
if os.path.exists(guide_cover):
renderer = render_html_svg_workaround(guide_cover, log)
if renderer is not None:
open('calibre_raster_cover.jpg', 'wb').write(
renderer)
return removed return removed
def find_opf(self): def find_opf(self):

View File

@ -1083,12 +1083,12 @@ class OPF(object): # {{{
for item in self.itermanifest(): for item in self.itermanifest():
if item.get('id', None) == cover_id: if item.get('id', None) == cover_id:
mt = item.get('media-type', '') mt = item.get('media-type', '')
if 'xml' not in mt: if mt and 'xml' not in mt and 'html' not in mt:
return item.get('href', None) return item.get('href', None)
for item in self.itermanifest(): for item in self.itermanifest():
if item.get('href', None) == cover_id: if item.get('href', None) == cover_id:
mt = item.get('media-type', '') mt = item.get('media-type', '')
if mt.startswith('image/'): if mt and mt.startswith('image/'):
return item.get('href', None) return item.get('href', None)
@dynamic_property @dynamic_property