KF8 Output: Handle links ot binary resources

This commit is contained in:
Kovid Goyal 2012-04-17 15:15:20 +05:30
parent ed118bbaa0
commit d9b9961c77
3 changed files with 59 additions and 5 deletions

View File

@ -170,13 +170,13 @@ class MOBIOutput(OutputFormatPlugin):
resources = Resources(oeb, opts, self.is_periodical,
add_fonts=create_kf8)
kf8 = self.create_kf8() if create_kf8 else None
kf8 = self.create_kf8(resources) if create_kf8 else None
self.write_mobi(input_plugin, output_path, kf8, resources)
def create_kf8(self):
def create_kf8(self, resources):
from calibre.ebooks.mobi.writer8.main import KF8Writer
return KF8Writer(self.oeb, self.opts)
return KF8Writer(self.oeb, self.opts, resources)
def write_mobi(self, input_plugin, output_path, kf8, resources):
from calibre.ebooks.mobi.mobiml import MobiMLizer

View File

@ -7,6 +7,8 @@ __license__ = 'GPL v3'
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import imghdr
from calibre.ebooks.mobi import MAX_THUMB_DIMEN, MAX_THUMB_SIZE
from calibre.ebooks.mobi.utils import (rescale_image, mobify_image,
write_font_record)
@ -23,6 +25,7 @@ class Resources(object):
self.item_map = {}
self.records = []
self.mime_map = {}
self.masthead_offset = 0
self.used_image_indices = set()
self.image_indices = set()
@ -76,6 +79,7 @@ class Resources(object):
self.image_indices.add(len(self.records))
self.records.append(data)
self.item_map[item.href] = index
self.mime_map[item.href] = 'image/%s'%imghdr.what(None, data)
index += 1
if cover_href and item.href == cover_href:

View File

@ -8,20 +8,25 @@ __copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import copy
from functools import partial
import cssutils
from calibre.ebooks.oeb.base import (OEB_DOCS, OEB_STYLES, SVG_MIME)
from calibre import isbytestring
from calibre.ebooks.oeb.base import (OEB_DOCS, OEB_STYLES, SVG_MIME, XPath)
XML_DOCS = OEB_DOCS | {SVG_MIME}
class KF8Writer(object):
def __init__(self, oeb, opts):
def __init__(self, oeb, opts, resources):
self.oeb, self.opts, self.log = oeb, opts, oeb.log
self.used_images = set()
self.resources = resources
self.dup_data()
self.replace_resource_links()
self.create_pieces()
def dup_data(self):
@ -41,6 +46,51 @@ class KF8Writer(object):
def data(self, item):
return self._data_cache.get(item.href, item.data)
def replace_resource_links(self):
''' Replace links to resources (raster images/fonts) with pointers to
the MOBI record containing the resource. The pointers are of the form:
kindle:embed:XXXX?mime=image/* The ?mime= is apparently optional and
not used for fonts. '''
def pointer(item, oref):
ref = item.abshref(oref)
idx = self.resources.item_map.get(ref, None)
if idx is not None:
is_image = self.resources.records[idx-1][:4] not in {b'FONT'}
if is_image:
self.used_images.add(ref)
return 'kindle:embed:%04d?mime=%s'%(idx,
self.resources.mime_map[ref])
else:
return 'kindle:embed:%04d'%idx
return oref
for item in self.oeb.manifest:
if item.media_type in XML_DOCS:
root = self.data(item)
for tag in XPath('//h:img|//svg:image')(root):
for attr, ref in tag.attrib.iteritems():
if attr.split('}')[-1].lower() in {'src', 'href'}:
tag.attrib[attr] = pointer(item, ref)
for tag in XPath('//h:style')(root):
if tag.text:
sheet = cssutils.parseString(tag.text)
replacer = partial(pointer, item)
cssutils.replaceUrls(sheet, replacer,
ignoreImportRules=True)
repl = sheet.cssText
if isbytestring(repl):
repl = repl.decode('utf-8')
tag.text = '\n'+ repl + '\n'
elif item.media_type in OEB_STYLES:
sheet = self.data(item)
replacer = partial(pointer, item)
cssutils.replaceUrls(sheet, replacer, ignoreImportRules=True)
def create_pieces(self):
self.flows = [None] # First flow item is reserved for the text