KF8 Output: Workaround Kindle Touch bug that causes the book to be rendered as black pages when a height os specified for <body>

This commit is contained in:
Kovid Goyal 2012-05-03 17:28:11 +05:30
parent 632796e533
commit 226a26d208
6 changed files with 56 additions and 2 deletions

View File

@ -295,3 +295,15 @@ class OutputFormatPlugin(Plugin):
return self.oeb.metadata.publication_type and \ return self.oeb.metadata.publication_type and \
unicode(self.oeb.metadata.publication_type[0]).startswith('periodical:') unicode(self.oeb.metadata.publication_type[0]).startswith('periodical:')
def specialize_css_for_output(self, log, opts, item, stylizer):
'''
Can be used to make changes to the css during the CSS flattening
process.
:param item: The item (HTML file) being processed
:param stylizer: A Stylizer object containing the flattened styles for
item. You can get the style for any element by stylizer.style(element).
'''
pass

View File

@ -232,6 +232,10 @@ class MOBIOutput(OutputFormatPlugin):
writer(oeb, output_path) writer(oeb, output_path)
extract_mobi(output_path, opts) extract_mobi(output_path, opts)
def specialize_css_for_output(self, log, opts, item, stylizer):
from calibre.ebooks.mobi.writer8.cleanup import CSSCleanup
CSSCleanup(log, opts)(item, stylizer)
class AZW3Output(OutputFormatPlugin): class AZW3Output(OutputFormatPlugin):
name = 'AZW3 Output' name = 'AZW3 Output'
@ -298,4 +302,8 @@ class AZW3Output(OutputFormatPlugin):
kf8.write(output_path) kf8.write(output_path)
extract_mobi(output_path, opts) extract_mobi(output_path, opts)
def specialize_css_for_output(self, log, opts, item, stylizer):
from calibre.ebooks.mobi.writer8.cleanup import CSSCleanup
CSSCleanup(log, opts)(item, stylizer)

View File

@ -4,6 +4,7 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os, re, sys, shutil, pprint import os, re, sys, shutil, pprint
from functools import partial
from calibre.customize.conversion import OptionRecommendation, DummyReporter from calibre.customize.conversion import OptionRecommendation, DummyReporter
from calibre.customize.ui import input_profiles, output_profiles, \ from calibre.customize.ui import input_profiles, output_profiles, \
@ -1061,7 +1062,9 @@ OptionRecommendation(name='search_replace',
untable=self.output_plugin.file_type in ('mobi','lit'), untable=self.output_plugin.file_type in ('mobi','lit'),
unfloat=self.output_plugin.file_type in ('mobi', 'lit'), unfloat=self.output_plugin.file_type in ('mobi', 'lit'),
page_break_on_body=self.output_plugin.file_type in ('mobi', page_break_on_body=self.output_plugin.file_type in ('mobi',
'lit')) 'lit'),
specializer=partial(self.output_plugin.specialize_css_for_output,
self.log, self.opts))
flattener(self.oeb, self.opts) flattener(self.oeb, self.opts)
self.opts.insert_blank_line = oibl self.opts.insert_blank_line = oibl

View File

@ -0,0 +1,25 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import (unicode_literals, division, absolute_import,
print_function)
__license__ = 'GPL v3'
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from calibre.ebooks.oeb.base import XPath
class CSSCleanup(object):
def __init__(self, log, opts):
self.log, self.opts = log, opts
def __call__(self, item, stylizer):
if not hasattr(item.data, 'xpath'): return
# The Kindle touch displays all black pages if the height is set on
# body
for body in XPath('//h:body')(item.data):
style = stylizer.style(body)
style.drop('height')

View File

@ -494,6 +494,9 @@ class Style(object):
def set(self, prop, val): def set(self, prop, val):
self._style[prop] = val self._style[prop] = val
def drop(self, prop):
self._style.pop(prop, None)
def _update_cssdict(self, cssdict): def _update_cssdict(self, cssdict):
self._style.update(cssdict) self._style.update(cssdict)

View File

@ -102,12 +102,13 @@ def FontMapper(sbase=None, dbase=None, dkey=None):
class CSSFlattener(object): class CSSFlattener(object):
def __init__(self, fbase=None, fkey=None, lineh=None, unfloat=False, def __init__(self, fbase=None, fkey=None, lineh=None, unfloat=False,
untable=False, page_break_on_body=False): untable=False, page_break_on_body=False, specializer=None):
self.fbase = fbase self.fbase = fbase
self.fkey = fkey self.fkey = fkey
self.lineh = lineh self.lineh = lineh
self.unfloat = unfloat self.unfloat = unfloat
self.untable = untable self.untable = untable
self.specializer = specializer
self.page_break_on_body = page_break_on_body self.page_break_on_body = page_break_on_body
@classmethod @classmethod
@ -423,6 +424,8 @@ class CSSFlattener(object):
for item in self.oeb.spine: for item in self.oeb.spine:
html = item.data html = item.data
stylizer = self.stylizers[item] stylizer = self.stylizers[item]
if self.specializer is not None:
self.specializer(item, stylizer)
body = html.find(XHTML('body')) body = html.find(XHTML('body'))
fsize = self.context.dest.fbase fsize = self.context.dest.fbase
self.flatten_node(body, stylizer, names, styles, fsize, item.id) self.flatten_node(body, stylizer, names, styles, fsize, item.id)