mirror of
https://github.com/gryf/ebook-converter.git
synced 2026-04-23 06:31:30 +02:00
Compare commits
4 Commits
76e604c951
...
c240495c3d
| Author | SHA1 | Date | |
|---|---|---|---|
| c240495c3d | |||
| 53dea56929 | |||
| ef02332465 | |||
| 74abaf0de0 |
@@ -32,7 +32,7 @@ def debug():
|
|||||||
# plugins {{{
|
# plugins {{{
|
||||||
|
|
||||||
|
|
||||||
class Plugins(collections.Mapping):
|
class Plugins(collections.abc.Mapping):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._plugins = {}
|
self._plugins = {}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ def is_iterable(obj):
|
|||||||
return hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes))
|
return hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes))
|
||||||
|
|
||||||
|
|
||||||
class OrderedSet(collections.MutableSet):
|
class OrderedSet(collections.abc.MutableSet):
|
||||||
"""
|
"""
|
||||||
An OrderedSet is a custom MutableSet that remembers its order, so that
|
An OrderedSet is a custom MutableSet that remembers its order, so that
|
||||||
every entry has an index that can be looked up.
|
every entry has an index that can be looked up.
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ class HTMLInput(InputFormatPlugin):
|
|||||||
if not os.access(link, os.R_OK):
|
if not os.access(link, os.R_OK):
|
||||||
return link_
|
return link_
|
||||||
if os.path.isdir(link):
|
if os.path.isdir(link):
|
||||||
self.log.warning(link_, 'is a link to a directory. Ignoring.')
|
self.log.warning('%s is a link to a directory. Ignoring.', link_)
|
||||||
return link_
|
return link_
|
||||||
if link not in self.added_resources:
|
if link not in self.added_resources:
|
||||||
bhref = os.path.basename(link)
|
bhref = os.path.basename(link)
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ class MobiMLizer(object):
|
|||||||
try:
|
try:
|
||||||
item = self.oeb.manifest.hrefs[base.urlnormalize(href)]
|
item = self.oeb.manifest.hrefs[base.urlnormalize(href)]
|
||||||
except:
|
except:
|
||||||
self.oeb.logger.warning('Failed to find image:', href)
|
self.oeb.logger.warning('Failed to find image: %s', href)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
width, height = identify(item.data)[1:]
|
width, height = identify(item.data)[1:]
|
||||||
|
|||||||
@@ -444,8 +444,8 @@ class Indexer(object): # {{{
|
|||||||
if self.is_periodical and self.masthead_offset is None:
|
if self.is_periodical and self.masthead_offset is None:
|
||||||
raise ValueError('Periodicals must have a masthead')
|
raise ValueError('Periodicals must have a masthead')
|
||||||
|
|
||||||
self.log('Generating MOBI index for a %s', 'periodical' if
|
self.log.info('Generating MOBI index for a %s', 'periodical' if
|
||||||
self.is_periodical else 'book')
|
self.is_periodical else 'book')
|
||||||
self.is_flat_periodical = False
|
self.is_flat_periodical = False
|
||||||
if self.is_periodical:
|
if self.is_periodical:
|
||||||
periodical_node = next(iter(oeb.toc))
|
periodical_node = next(iter(oeb.toc))
|
||||||
|
|||||||
@@ -14,13 +14,15 @@ from odf.draw import Frame as odFrame, Image as odImage
|
|||||||
from odf.namespaces import TEXTNS as odTEXTNS
|
from odf.namespaces import TEXTNS as odTEXTNS
|
||||||
|
|
||||||
from ebook_converter.utils import directory
|
from ebook_converter.utils import directory
|
||||||
|
from ebook_converter.ebooks.oeb import parse_utils
|
||||||
from ebook_converter.ebooks.oeb.base import _css_logger
|
from ebook_converter.ebooks.oeb.base import _css_logger
|
||||||
from ebook_converter import polyglot
|
from ebook_converter import polyglot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Extract(ODF2XHTML):
|
class Extract(ODF2XHTML):
|
||||||
|
|
||||||
def extract_pictures(self, zf):
|
def _extract_pictures(self, zf):
|
||||||
if not os.path.exists('Pictures'):
|
if not os.path.exists('Pictures'):
|
||||||
os.makedirs('Pictures')
|
os.makedirs('Pictures')
|
||||||
for name in zf.namelist():
|
for name in zf.namelist():
|
||||||
@@ -30,8 +32,8 @@ class Extract(ODF2XHTML):
|
|||||||
with open(name, 'wb') as f:
|
with open(name, 'wb') as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
def apply_list_starts(self, root, log):
|
def _apply_list_starts(self, root, log):
|
||||||
if not self.list_starts:
|
if not hasattr(self, "list_starts") or not self.list_starts:
|
||||||
return
|
return
|
||||||
list_starts = frozenset(self.list_starts)
|
list_starts = frozenset(self.list_starts)
|
||||||
for ol in root.xpath('//*[local-name() = "ol" and @class]'):
|
for ol in root.xpath('//*[local-name() = "ol" and @class]'):
|
||||||
@@ -46,7 +48,7 @@ class Extract(ODF2XHTML):
|
|||||||
self.filter_css(root, log)
|
self.filter_css(root, log)
|
||||||
self.extract_css(root, log)
|
self.extract_css(root, log)
|
||||||
self.epubify_markup(root, log)
|
self.epubify_markup(root, log)
|
||||||
self.apply_list_starts(root, log)
|
self._apply_list_starts(root, log)
|
||||||
html = etree.tostring(root, encoding='utf-8', xml_declaration=True)
|
html = etree.tostring(root, encoding='utf-8', xml_declaration=True)
|
||||||
return html
|
return html
|
||||||
|
|
||||||
@@ -84,22 +86,21 @@ class Extract(ODF2XHTML):
|
|||||||
return rule
|
return rule
|
||||||
|
|
||||||
def epubify_markup(self, root, log):
|
def epubify_markup(self, root, log):
|
||||||
from ebook_converter.ebooks.oeb.base import XPath, XHTML
|
|
||||||
# Fix empty title tags
|
# Fix empty title tags
|
||||||
for t in XPath('//h:title')(root):
|
for t in parse_utils.XPath('//h:title')(root):
|
||||||
if not t.text:
|
if not t.text:
|
||||||
t.text = u' '
|
t.text = u' '
|
||||||
# Fix <p><div> constructs as the asinine epubchecker complains
|
# Fix <p><div> constructs as the asinine epubchecker complains
|
||||||
# about them
|
# about them
|
||||||
pdiv = XPath('//h:p/h:div')
|
pdiv = parse_utils.XPath('//h:p/h:div')
|
||||||
for div in pdiv(root):
|
for div in pdiv(root):
|
||||||
div.getparent().tag = XHTML('div')
|
div.getparent().tag = parse_utils.XHTML('div')
|
||||||
|
|
||||||
# Remove the position:relative as it causes problems with some epub
|
# Remove the position:relative as it causes problems with some epub
|
||||||
# renderers. Remove display: block on an image inside a div as it is
|
# renderers. Remove display: block on an image inside a div as it is
|
||||||
# redundant and prevents text-align:center from working in ADE
|
# redundant and prevents text-align:center from working in ADE
|
||||||
# Also ensure that the img is contained in its containing div
|
# Also ensure that the img is contained in its containing div
|
||||||
imgpath = XPath('//h:div/h:img[@style]')
|
imgpath = parse_utils.XPath('//h:div/h:img[@style]')
|
||||||
for img in imgpath(root):
|
for img in imgpath(root):
|
||||||
div = img.getparent()
|
div = img.getparent()
|
||||||
if len(div) == 1:
|
if len(div) == 1:
|
||||||
@@ -119,7 +120,7 @@ class Extract(ODF2XHTML):
|
|||||||
# works in both WebKit and ADE.
|
# works in both WebKit and ADE.
|
||||||
# https://bugs.launchpad.net/bugs/1063207
|
# https://bugs.launchpad.net/bugs/1063207
|
||||||
# https://bugs.launchpad.net/calibre/+bug/859343
|
# https://bugs.launchpad.net/calibre/+bug/859343
|
||||||
imgpath = XPath('descendant::h:div/h:div/h:img')
|
imgpath = parse_utils.XPath('descendant::h:div/h:div/h:img')
|
||||||
for img in imgpath(root):
|
for img in imgpath(root):
|
||||||
div2 = img.getparent()
|
div2 = img.getparent()
|
||||||
div1 = div2.getparent()
|
div1 = div2.getparent()
|
||||||
@@ -297,7 +298,7 @@ class Extract(ODF2XHTML):
|
|||||||
with open('index.xhtml', 'wb') as f:
|
with open('index.xhtml', 'wb') as f:
|
||||||
f.write(polyglot.as_bytes(html))
|
f.write(polyglot.as_bytes(html))
|
||||||
zf = ZipFile(stream, 'r')
|
zf = ZipFile(stream, 'r')
|
||||||
self.extract_pictures(zf)
|
self._extract_pictures(zf)
|
||||||
opf = OPFCreator(os.path.abspath(os.getcwd()), mi)
|
opf = OPFCreator(os.path.abspath(os.getcwd()), mi)
|
||||||
opf.create_manifest([(os.path.abspath(os.path.join(r, f2)), None)
|
opf.create_manifest([(os.path.abspath(os.path.join(r, f2)), None)
|
||||||
for r, _, fnames in os.walk(os.getcwd())
|
for r, _, fnames in os.walk(os.getcwd())
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from ebook_converter import logging
|
from ebook_converter import logging
|
||||||
from ebook_converter.customize.conversion import OptionRecommendation
|
|
||||||
from ebook_converter.ebooks.conversion.plumber import Plumber
|
from ebook_converter.ebooks.conversion.plumber import Plumber
|
||||||
|
|
||||||
|
|
||||||
@@ -68,6 +67,7 @@ def run(args):
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('from_file', help="Input file to be converted")
|
parser.add_argument('from_file', help="Input file to be converted")
|
||||||
@@ -83,5 +83,4 @@ def main():
|
|||||||
|
|
||||||
LOG.set_verbose(args.verbose, args.quiet)
|
LOG.set_verbose(args.verbose, args.quiet)
|
||||||
|
|
||||||
print(args)
|
|
||||||
sys.exit(run(args))
|
sys.exit(run(args))
|
||||||
|
|||||||
Reference in New Issue
Block a user