mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 18:24:30 -04:00
KF8 Output: Handle links ot binary resources
This commit is contained in:
parent
ed118bbaa0
commit
d9b9961c77
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user