mirror of
https://github.com/gryf/ebook-converter.git
synced 2026-04-24 07:01:30 +02:00
Added first portion of logging adaptation.
Things may be broken at this point - there are still several modules to be adapted.
This commit is contained in:
@@ -36,16 +36,16 @@ class DataURL(object):
|
||||
data = polyglot.as_bytes(data)
|
||||
fmt = what(None, data)
|
||||
if not fmt:
|
||||
self.log.warn('Image encoded as data URL has unknown '
|
||||
'format, ignoring')
|
||||
self.log.warning('Image encoded as data URL has unknown '
|
||||
'format, ignoring')
|
||||
continue
|
||||
img.set('src',
|
||||
item.relhref(self.convert_image_data_uri(data, fmt,
|
||||
oeb)))
|
||||
|
||||
def convert_image_data_uri(self, data, fmt, oeb):
|
||||
self.log('Found image encoded as data URI converting it to normal '
|
||||
'image')
|
||||
self.log.info('Found image encoded as data URI converting it to '
|
||||
'normal image')
|
||||
item_id, item_href = oeb.manifest.generate('data-url-image',
|
||||
'data-url-image.' + fmt)
|
||||
oeb.manifest.add(item_id, item_href,
|
||||
|
||||
@@ -117,8 +117,9 @@ class UniqueFilenames(object): # {{{
|
||||
self.seen_filenames.add(fname)
|
||||
|
||||
if self.rename_map:
|
||||
self.log('Found non-unique filenames, renaming to support broken'
|
||||
' EPUB readers like FBReader, Aldiko and Stanza...')
|
||||
self.log.info('Found non-unique filenames, renaming to support '
|
||||
'broken EPUB readers like FBReader, Aldiko and '
|
||||
'Stanza...')
|
||||
from pprint import pformat
|
||||
self.log.debug(pformat(self.rename_map))
|
||||
|
||||
@@ -173,8 +174,8 @@ class FlatFilenames(object): # {{{
|
||||
oeb.spine.insert(isp, nitem, item.linear)
|
||||
|
||||
if self.rename_map:
|
||||
self.log('Found non-flat filenames, renaming to support broken'
|
||||
' EPUB readers like FBReader...')
|
||||
self.log.info('Found non-flat filenames, renaming to support '
|
||||
'broken EPUB readers like FBReader...')
|
||||
from pprint import pformat
|
||||
self.log.debug(pformat(self.rename_map))
|
||||
self.log.debug(pformat(self.renamed_items_map))
|
||||
|
||||
@@ -182,8 +182,8 @@ class CSSFlattener(object):
|
||||
else:
|
||||
from ebook_converter.ebooks.oeb.normalize_css import normalize_filter_css
|
||||
self.filter_css = frozenset(normalize_filter_css(self.filter_css))
|
||||
self.oeb.log.debug('Filtering CSS properties: %s'%
|
||||
', '.join(self.filter_css))
|
||||
self.oeb.log.debug('Filtering CSS properties: %s',
|
||||
', '.join(self.filter_css))
|
||||
|
||||
for item in oeb.manifest.values():
|
||||
# Make all links to resources absolute, as these sheets will be
|
||||
@@ -231,13 +231,13 @@ class CSSFlattener(object):
|
||||
msg = ('No embeddable fonts found for family: %r'%family)
|
||||
if failure_critical:
|
||||
raise ValueError(msg)
|
||||
self.oeb.log.warn(msg)
|
||||
self.oeb.log.warning(msg)
|
||||
return body_font_family, efi
|
||||
if not faces:
|
||||
msg = ('No embeddable fonts found for family: %r'%family)
|
||||
if failure_critical:
|
||||
raise ValueError(msg)
|
||||
self.oeb.log.warn(msg)
|
||||
self.oeb.log.warning(msg)
|
||||
return body_font_family, efi
|
||||
|
||||
for i, font in enumerate(faces):
|
||||
@@ -258,7 +258,7 @@ class CSSFlattener(object):
|
||||
if i == 0:
|
||||
generic_family = panose_to_css_generic_family(font['panose'])
|
||||
body_font_family = "'%s',%s"%(font['font-family'], generic_family)
|
||||
self.oeb.log('Embedding font: %s'%font['font-family'])
|
||||
self.oeb.log.info('Embedding font: %s', font['font-family'])
|
||||
for k in ('font-weight', 'font-style', 'font-stretch'):
|
||||
if font[k] != 'normal':
|
||||
cfont[k] = font[k]
|
||||
@@ -323,8 +323,7 @@ class CSSFlattener(object):
|
||||
sbase = max(list(sizes.items()), key=operator.itemgetter(1))[0]
|
||||
except:
|
||||
sbase = 12.0
|
||||
self.oeb.logger.info(
|
||||
"Source base font size is %0.05fpt" % sbase)
|
||||
self.oeb.logger.info("Source base font size is %0.05fpt", sbase)
|
||||
return sbase
|
||||
|
||||
def clean_edges(self, cssdict, style, fsize):
|
||||
@@ -346,8 +345,7 @@ class CSSFlattener(object):
|
||||
try:
|
||||
value = round(value / slineh) * dlineh
|
||||
except:
|
||||
self.oeb.logger.warning(
|
||||
'Invalid length:', value)
|
||||
self.oeb.logger.warning('Invalid length: %s', value)
|
||||
value = 0.0
|
||||
cssdict[property] = "%0.5fem" % (value / fsize)
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
|
||||
class Clean(object):
|
||||
'''Clean up guide, leaving only known values '''
|
||||
|
||||
@@ -28,7 +23,8 @@ class Clean(object):
|
||||
if covers:
|
||||
ref = covers[0][0]
|
||||
if len(covers) > 1:
|
||||
self.log('Choosing %s:%s as the cover'%(ref.type, ref.href))
|
||||
self.log.info('Choosing %s:%s as the cover', ref.type,
|
||||
ref.href)
|
||||
ref.type = 'cover'
|
||||
self.oeb.guide.refs['cover'] = ref
|
||||
|
||||
|
||||
@@ -34,19 +34,19 @@ class RemoveFirstImage:
|
||||
continue
|
||||
removed = self.remove_images(item)
|
||||
if removed > 0:
|
||||
self.log('Removed first image')
|
||||
self.log.info('Removed first image')
|
||||
body = XPath('//h:body')(item.data)
|
||||
if body:
|
||||
raw = xml2text(body[0]).strip()
|
||||
imgs = XPath('//h:img|//svg:svg')(item.data)
|
||||
if not raw and not imgs:
|
||||
self.log('Removing %s as it has no content' %
|
||||
item.href)
|
||||
self.log.info('Removing %s as it has no content',
|
||||
item.href)
|
||||
self.oeb.manifest.remove(item)
|
||||
deleted_item = item
|
||||
break
|
||||
else:
|
||||
self.log.warn('Could not find first image to remove')
|
||||
self.log.warning('Could not find first image to remove')
|
||||
if deleted_item is not None:
|
||||
for item in list(self.oeb.toc):
|
||||
href = urllib.parse.urldefrag(item.href)[0]
|
||||
|
||||
@@ -101,7 +101,7 @@ class MergeMetadata(object):
|
||||
_oim = override_input_metadata
|
||||
self.oeb, self.log = oeb, oeb.log
|
||||
m = self.oeb.metadata
|
||||
self.log('Merging user specified metadata...')
|
||||
self.log.info('Merging user specified metadata...')
|
||||
meta_info_to_oeb_metadata(mi, m, oeb.log,
|
||||
override_input_metadata=_oim)
|
||||
cover_id = self.set_cover(mi, opts.prefer_metadata_cover)
|
||||
@@ -210,8 +210,8 @@ class MergeMetadata(object):
|
||||
text = ''
|
||||
text = re.sub(r'\s+', '', text)
|
||||
if not text and not XPath('//h:img|//svg:svg')(item.data):
|
||||
self.log('Removing %s as it is a wrapper around the cover '
|
||||
'image' % item.href)
|
||||
self.log.info('Removing %s as it is a wrapper around the '
|
||||
'cover image', item.href)
|
||||
self.oeb.spine.remove(item)
|
||||
self.oeb.manifest.remove(item)
|
||||
self.oeb.guide.remove_by_href(item.href)
|
||||
|
||||
@@ -5,11 +5,6 @@ from ebook_converter.ebooks.oeb import parse_utils
|
||||
from ebook_converter.ebooks.oeb.base import XPath
|
||||
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
|
||||
class RemoveAdobeMargins(object):
|
||||
'''
|
||||
Remove margins specified in Adobe's page templates.
|
||||
@@ -19,12 +14,13 @@ class RemoveAdobeMargins(object):
|
||||
self.oeb, self.opts, self.log = oeb, opts, log
|
||||
|
||||
for item in self.oeb.manifest:
|
||||
if item.media_type in {
|
||||
'application/vnd.adobe-page-template+xml', 'application/vnd.adobe.page-template+xml',
|
||||
'application/adobe-page-template+xml', 'application/adobe.page-template+xml',
|
||||
} and hasattr(item.data, 'xpath'):
|
||||
self.log('Removing page margins specified in the'
|
||||
' Adobe page template')
|
||||
if (item.media_type in {'application/vnd.adobe-page-template+xml',
|
||||
'application/vnd.adobe.page-template+xml',
|
||||
'application/adobe-page-template+xml',
|
||||
'application/adobe.page-template+xml'} and
|
||||
hasattr(item.data, 'xpath')):
|
||||
self.log.info('Removing page margins specified in the '
|
||||
'Adobe page template')
|
||||
for elem in item.data.xpath(
|
||||
'//*[@margin-bottom or @margin-top '
|
||||
'or @margin-left or @margin-right]'):
|
||||
@@ -59,7 +55,7 @@ class RemoveFakeMargins(object):
|
||||
if stylesheet is None:
|
||||
return
|
||||
|
||||
self.log('Removing fake margins...')
|
||||
self.log.info('Removing fake margins...')
|
||||
|
||||
stylesheet = stylesheet.data
|
||||
|
||||
@@ -73,8 +69,8 @@ class RemoveFakeMargins(object):
|
||||
try:
|
||||
self.process_level(level)
|
||||
except NegativeTextIndent:
|
||||
self.log.debug('Negative text indent detected at level '
|
||||
' %s, ignoring this level'%level)
|
||||
self.log.debug('Negative text indent detected at level %s, '
|
||||
'ignoring this level', level)
|
||||
|
||||
def get_margins(self, elem):
|
||||
cls = elem.get('class', None)
|
||||
@@ -102,19 +98,21 @@ class RemoveFakeMargins(object):
|
||||
self.stats[level+'_left'][lm] += 1
|
||||
self.stats[level+'_right'][rm] += 1
|
||||
|
||||
self.log.debug(level, ' left margin stats:', self.stats[level+'_left'])
|
||||
self.log.debug(level, ' right margin stats:', self.stats[level+'_right'])
|
||||
self.log.debug('%s left margin stats: %s', level,
|
||||
self.stats[level+'_left'])
|
||||
self.log.debug('%s right margin stats: %s', level,
|
||||
self.stats[level+'_right'])
|
||||
|
||||
remove_left = self.analyze_stats(self.stats[level+'_left'])
|
||||
remove_right = self.analyze_stats(self.stats[level+'_right'])
|
||||
|
||||
if remove_left:
|
||||
mcl = self.stats[level+'_left'].most_common(1)[0][0]
|
||||
self.log('Removing level %s left margin of:'%level, mcl)
|
||||
self.log.info('Removing level %s left margin of: %s', level, mcl)
|
||||
|
||||
if remove_right:
|
||||
mcr = self.stats[level+'_right'].most_common(1)[0][0]
|
||||
self.log('Removing level %s right margin of:'%level, mcr)
|
||||
self.log.info('Removing level %s right margin of: %s', level, mcr)
|
||||
|
||||
if remove_left or remove_right:
|
||||
for elem in elems:
|
||||
@@ -151,7 +149,7 @@ class RemoveFakeMargins(object):
|
||||
remove = set()
|
||||
for k, v in self.levels.items():
|
||||
num = len(v)
|
||||
self.log.debug('Found %d items of level:'%num, k)
|
||||
self.log.debug('Found %s items of level: %s', num, k)
|
||||
level = int(k.split('_')[-1])
|
||||
tag = k.split('_')[0]
|
||||
if tag == 'p' and num < 25:
|
||||
@@ -169,7 +167,7 @@ class RemoveFakeMargins(object):
|
||||
|
||||
for k in remove:
|
||||
self.levels.pop(k)
|
||||
self.log.debug('Ignoring level', k)
|
||||
self.log.debug('Ignoring level %s', k)
|
||||
|
||||
def analyze_stats(self, stats):
|
||||
if not stats:
|
||||
|
||||
@@ -45,12 +45,14 @@ class RescaleImages(object):
|
||||
|
||||
try:
|
||||
if self.check_colorspaces and img.mode == 'CMYK':
|
||||
self.log.warn(
|
||||
'The image %s is in the CMYK colorspace, converting it '
|
||||
'to RGB as Adobe Digital Editions cannot display CMYK' % item.href)
|
||||
self.log.warning('The image %s is in the CMYK '
|
||||
'colorspace, converting it to RGB as '
|
||||
'Adobe Digital Editions cannot '
|
||||
'display CMYK', item.href)
|
||||
img = img.convert('RGB')
|
||||
except Exception:
|
||||
self.log.exception('Failed to convert image %s from CMYK to RGB' % item.href)
|
||||
self.log.exception('Failed to convert image %s from CMYK '
|
||||
'to RGB', item.href)
|
||||
|
||||
scaled, new_width, new_height = uimg.fit_image(width, height,
|
||||
page_width,
|
||||
@@ -58,18 +60,20 @@ class RescaleImages(object):
|
||||
if scaled:
|
||||
new_width = max(1, new_width)
|
||||
new_height = max(1, new_height)
|
||||
self.log('Rescaling image from %dx%d to %dx%d'%(
|
||||
width, height, new_width, new_height), item.href)
|
||||
self.log('Rescaling image from %sx%s to %sx%s %s', width,
|
||||
height, new_width, new_height, item.href)
|
||||
try:
|
||||
img = img.resize((new_width, new_height))
|
||||
except Exception:
|
||||
self.log.exception('Failed to rescale image: %s' % item.href)
|
||||
self.log.exception('Failed to rescale image: %s',
|
||||
item.href)
|
||||
continue
|
||||
buf = BytesIO()
|
||||
try:
|
||||
img.save(buf, ext)
|
||||
except Exception:
|
||||
self.log.exception('Failed to rescale image: %s' % item.href)
|
||||
self.log.exception('Failed to rescale image: %s',
|
||||
item.href)
|
||||
else:
|
||||
item.data = buf.getvalue()
|
||||
item.unload_data_from_memory()
|
||||
|
||||
@@ -59,7 +59,8 @@ class Split(object):
|
||||
def __call__(self, oeb, opts):
|
||||
self.oeb = oeb
|
||||
self.log = oeb.log
|
||||
self.log('Splitting markup on page breaks and flow limits, if any...')
|
||||
self.log.info('Splitting markup on page breaks and flow limits, if '
|
||||
'any...')
|
||||
self.opts = opts
|
||||
self.map = {}
|
||||
for item in list(self.oeb.manifest.items):
|
||||
@@ -127,8 +128,7 @@ class Split(object):
|
||||
page_breaks.add(elem)
|
||||
except SelectorError as err:
|
||||
self.log.warn('Ignoring page breaks specified with invalid '
|
||||
'CSS selector: %r (%s)' %
|
||||
(selector, err))
|
||||
'CSS selector: %s (%s)', selector, err)
|
||||
|
||||
for i, elem in enumerate(item.data.iter('*')):
|
||||
try:
|
||||
@@ -221,13 +221,13 @@ class FlowSplitter(object):
|
||||
|
||||
if self.max_flow_size > 0:
|
||||
lt_found = False
|
||||
self.log('\tLooking for large trees in %s...' % item.href)
|
||||
self.log.info('\tLooking for large trees in %s...', item.href)
|
||||
trees = list(self.trees)
|
||||
self.tree_map = {}
|
||||
for i, tree in enumerate(trees):
|
||||
size = len(tostring(tree.getroot()))
|
||||
if size > self.max_flow_size:
|
||||
self.log('\tFound large tree #%d' % i)
|
||||
self.log.info('\tFound large tree #%s', i)
|
||||
lt_found = True
|
||||
self.split_trees = []
|
||||
self.split_to_size(tree)
|
||||
@@ -240,7 +240,7 @@ class FlowSplitter(object):
|
||||
|
||||
self.was_split = len(self.trees) > 1
|
||||
if self.was_split:
|
||||
self.log('\tSplit into %d parts' % len(self.trees))
|
||||
self.log('\tSplit into %s parts', len(self.trees))
|
||||
self.commit()
|
||||
|
||||
def split_on_page_breaks(self, orig_tree):
|
||||
@@ -259,7 +259,7 @@ class FlowSplitter(object):
|
||||
tree = self.trees[i]
|
||||
elem = pattern(tree)
|
||||
if elem:
|
||||
self.log.debug('\t\tSplitting on page-break at id=%s' %
|
||||
self.log.debug('\t\tSplitting on page-break at id=%s',
|
||||
elem[0].get('id'))
|
||||
before_tree, after_tree = self.do_split(tree, elem[0],
|
||||
before)
|
||||
@@ -322,10 +322,10 @@ class FlowSplitter(object):
|
||||
return True
|
||||
|
||||
def split_text(self, text, root, size):
|
||||
self.log.debug('\t\t\tSplitting text of length: %d' % len(text))
|
||||
self.log.debug('\t\t\tSplitting text of length: %d', len(text))
|
||||
rest = text.replace('\r', '')
|
||||
parts = re.split('\n\n', rest)
|
||||
self.log.debug('\t\t\t\tFound %d parts' % len(parts))
|
||||
self.log.debug('\t\t\t\tFound %d parts', len(parts))
|
||||
if max(map(len, parts)) > size:
|
||||
raise SplitError('Cannot split as file contains a <pre> tag '
|
||||
'with a very large paragraph', root)
|
||||
@@ -364,7 +364,7 @@ class FlowSplitter(object):
|
||||
split_point, before = self.find_split_point(root)
|
||||
if split_point is None:
|
||||
raise SplitError(self.item.href, root)
|
||||
self.log.debug('\t\t\tSplit point:', split_point.tag,
|
||||
self.log.debug('\t\t\tSplit point: %s %s', split_point.tag,
|
||||
tree.getpath(split_point))
|
||||
|
||||
trees = self.do_split(tree, split_point, before)
|
||||
@@ -380,10 +380,10 @@ class FlowSplitter(object):
|
||||
continue
|
||||
elif size <= self.max_flow_size:
|
||||
self.split_trees.append(t)
|
||||
self.log.debug('\t\t\tCommitted sub-tree #%d (%d KB)' %
|
||||
(len(self.split_trees), size/1024.))
|
||||
self.log.debug('\t\t\tCommitted sub-tree #%s (%s KB)',
|
||||
len(self.split_trees), size/1024.)
|
||||
else:
|
||||
self.log.debug('\t\t\tSplit tree still too large: %d KB' %
|
||||
self.log.debug('\t\t\tSplit tree still too large: %d KB',
|
||||
size/1024)
|
||||
self.split_to_size(t)
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ class DetectStructure(object):
|
||||
self.log = oeb.log
|
||||
self.oeb = oeb
|
||||
self.opts = opts
|
||||
self.log('Detecting structure...')
|
||||
self.log.info('Detecting structure...')
|
||||
|
||||
self.detect_chapters()
|
||||
if self.oeb.auto_generated_toc or opts.use_auto_toc:
|
||||
@@ -67,15 +67,15 @@ class DetectStructure(object):
|
||||
self.oeb.toc = orig_toc
|
||||
else:
|
||||
self.oeb.auto_generated_toc = True
|
||||
self.log('Auto generated TOC with %d entries.' %
|
||||
self.oeb.toc.count())
|
||||
self.log.info('Auto generated TOC with %s entries.',
|
||||
self.oeb.toc.count())
|
||||
|
||||
if opts.toc_filter is not None:
|
||||
regexp = re.compile(opts.toc_filter)
|
||||
for node in list(self.oeb.toc.iter()):
|
||||
if not node.title or regexp.search(node.title) is not None:
|
||||
self.log('Filtering', node.title if node.title else
|
||||
'empty node', 'from TOC')
|
||||
self.log.info('Filtering %s from TOC', node.title if
|
||||
node.title else 'empty node')
|
||||
self.oeb.toc.remove(node)
|
||||
|
||||
if opts.page_breaks_before is not None:
|
||||
@@ -112,8 +112,8 @@ class DetectStructure(object):
|
||||
try:
|
||||
expr = XPath(expr)
|
||||
except Exception:
|
||||
self.log.warn('Invalid start reading at XPath expression, '
|
||||
'ignoring: %s' % expr)
|
||||
self.log.warning('Invalid start reading at XPath expression, '
|
||||
'ignoring: %s', expr)
|
||||
return
|
||||
for item in self.oeb.spine:
|
||||
if not hasattr(item.data, 'xpath'):
|
||||
@@ -129,11 +129,11 @@ class DetectStructure(object):
|
||||
if 'text' in self.oeb.guide:
|
||||
self.oeb.guide.remove('text')
|
||||
self.oeb.guide.add('text', 'Start', item.href+'#'+eid)
|
||||
self.log('Setting start reading at position to %s in %s' %
|
||||
(self.opts.start_reading_at, item.href))
|
||||
self.log.info('Setting start reading at position to %s in %s',
|
||||
self.opts.start_reading_at, item.href)
|
||||
return
|
||||
self.log.warn("Failed to find start reading at position: %s" %
|
||||
self.opts.start_reading_at)
|
||||
self.log.warning("Failed to find start reading at position: %s",
|
||||
self.opts.start_reading_at)
|
||||
|
||||
def get_toc_parts_for_xpath(self, expr):
|
||||
# if an attribute is selected by the xpath expr then truncate it
|
||||
@@ -155,8 +155,8 @@ class DetectStructure(object):
|
||||
len(ans)
|
||||
return ans
|
||||
except Exception:
|
||||
self.log.warn('Invalid chapter expression, ignoring: %s' %
|
||||
expr)
|
||||
self.log.warning('Invalid chapter expression, ignoring: %s',
|
||||
expr)
|
||||
return []
|
||||
|
||||
if self.opts.chapter:
|
||||
@@ -175,7 +175,7 @@ class DetectStructure(object):
|
||||
c[item] += 1
|
||||
text = base.xml2text(elem).strip()
|
||||
text = re.sub(r'\s+', ' ', text.strip())
|
||||
self.log('\tDetected chapter:', text[:50])
|
||||
self.log.info('\tDetected chapter: %s', text[:50])
|
||||
if chapter_mark == 'none':
|
||||
continue
|
||||
if chapter_mark == 'rule':
|
||||
@@ -221,7 +221,7 @@ class DetectStructure(object):
|
||||
try:
|
||||
purl = urllib.parse.urlparse(href)
|
||||
except ValueError:
|
||||
self.log.warning('Ignoring malformed URL:', href)
|
||||
self.log.warning('Ignoring malformed URL: %s', href)
|
||||
continue
|
||||
if not purl[0] or purl[0] == 'file':
|
||||
href, frag = purl.path, purl.fragment
|
||||
@@ -240,13 +240,14 @@ class DetectStructure(object):
|
||||
play_order=self.oeb.toc.next_play_order())
|
||||
num += 1
|
||||
except ValueError:
|
||||
self.oeb.log.exception('Failed to process link: '
|
||||
'%r' % href)
|
||||
self.oeb.log.critical('Failed to process link: %s',
|
||||
href)
|
||||
# Most likely an incorrectly URL encoded link
|
||||
continue
|
||||
if self.opts.max_toc_links > 0 and \
|
||||
num >= self.opts.max_toc_links:
|
||||
self.log('Maximum TOC links reached, stopping.')
|
||||
self.log.info('Maximum TOC links reached, '
|
||||
'stopping.')
|
||||
return
|
||||
|
||||
def elem_to_link(self, item, elem, title_attribute, counter):
|
||||
@@ -277,7 +278,7 @@ class DetectStructure(object):
|
||||
len(ans)
|
||||
return ans
|
||||
except Exception:
|
||||
self.log.warn('Invalid ToC expression, ignoring: %s' % expr)
|
||||
self.log.warning('Invalid ToC expression, ignoring: %s', expr)
|
||||
return []
|
||||
|
||||
for document in self.oeb.spine:
|
||||
|
||||
@@ -5,11 +5,6 @@ from ebook_converter.utils.fonts.sfnt.subset import subset, NoGlyphs, Unsupporte
|
||||
from ebook_converter.tinycss.fonts3 import parse_font_family
|
||||
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
|
||||
def get_font_properties(rule, default=None):
|
||||
'''
|
||||
Given a CSS rule, extract normalized font properties from
|
||||
@@ -19,7 +14,7 @@ def get_font_properties(rule, default=None):
|
||||
props = {}
|
||||
s = rule.style
|
||||
for q in ('font-family', 'src', 'font-weight', 'font-stretch',
|
||||
'font-style'):
|
||||
'font-style'):
|
||||
g = 'uri' if q == 'src' else 'value'
|
||||
try:
|
||||
val = s.getProperty(q).propertyValue[0]
|
||||
@@ -149,18 +144,19 @@ class SubsetFonts(object):
|
||||
|
||||
for font in fonts.values():
|
||||
if not font['chars']:
|
||||
self.log('The font %s is unused. Removing it.'%font['src'])
|
||||
self.log('The font %s is unused. Removing it.', font['src'])
|
||||
remove(font)
|
||||
continue
|
||||
try:
|
||||
raw, old_stats, new_stats = subset(font['item'].data, font['chars'])
|
||||
except NoGlyphs:
|
||||
self.log('The font %s has no used glyphs. Removing it.'%font['src'])
|
||||
self.log('The font %s has no used glyphs. Removing it.',
|
||||
font['src'])
|
||||
remove(font)
|
||||
continue
|
||||
except UnsupportedFont as e:
|
||||
self.log.warn('The font %s is unsupported for subsetting. %s'%(
|
||||
font['src'], e))
|
||||
self.log.warning('The font %s is unsupported for subsetting. '
|
||||
'%s', font['src'], e)
|
||||
sz = len(font['item'].data)
|
||||
totals[0] += sz
|
||||
totals[1] += sz
|
||||
@@ -168,16 +164,16 @@ class SubsetFonts(object):
|
||||
font['item'].data = raw
|
||||
nlen = sum(new_stats.values())
|
||||
olen = sum(old_stats.values())
|
||||
self.log('Decreased the font %s to %.1f%% of its original size'%
|
||||
(font['src'], nlen/olen *100))
|
||||
self.log('Decreased the font %s to %.1f%% of its original '
|
||||
'size', font['src'], nlen/olen * 100)
|
||||
totals[0] += nlen
|
||||
totals[1] += olen
|
||||
|
||||
font['item'].unload_data_from_memory()
|
||||
|
||||
if totals[0]:
|
||||
self.log('Reduced total font size to %.1f%% of original'%
|
||||
(totals[0]/totals[1] * 100))
|
||||
self.log('Reduced total font size to %.1f%% of original',
|
||||
totals[0]/totals[1] * 100)
|
||||
|
||||
def find_embedded_fonts(self):
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user