mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Mobipocket support:
- Fix another relative path bug - Complete command-line support - Tweak automatic image rescaling - Further fix HTML <font/> -> CSS conversion
This commit is contained in:
parent
9cce46ad08
commit
538615eed4
@ -798,8 +798,9 @@ class Processor(Parser):
|
|||||||
if face is not None:
|
if face is not None:
|
||||||
faces = []
|
faces = []
|
||||||
for face in face.split(','):
|
for face in face.split(','):
|
||||||
if ' ' in face:
|
face = face.strip()
|
||||||
face = "%s" % face
|
if ' ' in face and not (face[0] == face[-1] == '"'):
|
||||||
|
face = '"%s"' % face.replace('"', r'\"')
|
||||||
faces.append(face)
|
faces.append(face)
|
||||||
for generic in ('serif', 'sans-serif', 'monospace'):
|
for generic in ('serif', 'sans-serif', 'monospace'):
|
||||||
if generic in faces:
|
if generic in faces:
|
||||||
|
@ -115,7 +115,7 @@ class MobiMLizer(object):
|
|||||||
if isinstance(ptsize, basestring):
|
if isinstance(ptsize, basestring):
|
||||||
return ptsize
|
return ptsize
|
||||||
embase = self.profile.fbase
|
embase = self.profile.fbase
|
||||||
if ptsize < embase:
|
if round(ptsize) < embase:
|
||||||
return "%dpt" % int(round(ptsize))
|
return "%dpt" % int(round(ptsize))
|
||||||
return "%dem" % int(round(ptsize / embase))
|
return "%dem" % int(round(ptsize / embase))
|
||||||
|
|
||||||
|
@ -346,7 +346,9 @@ class MobiWriter(object):
|
|||||||
format = image.format
|
format = image.format
|
||||||
changed = False
|
changed = False
|
||||||
if image.format not in ('JPEG', 'GIF'):
|
if image.format not in ('JPEG', 'GIF'):
|
||||||
format = 'GIF'
|
width, height = image.size
|
||||||
|
area = width * height
|
||||||
|
format = 'GIF' if area <= 40000 else 'JPEG'
|
||||||
changed = True
|
changed = True
|
||||||
if dimen is not None:
|
if dimen is not None:
|
||||||
image.thumbnail(dimen, Image.ANTIALIAS)
|
image.thumbnail(dimen, Image.ANTIALIAS)
|
||||||
@ -481,7 +483,11 @@ class MobiWriter(object):
|
|||||||
|
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
|
profiles = Context.PROFILES.keys()
|
||||||
|
profiles.sort()
|
||||||
|
profiles = ', '.join(profiles)
|
||||||
from calibre.utils.config import OptionParser
|
from calibre.utils.config import OptionParser
|
||||||
|
from optparse import OptionGroup
|
||||||
parser = OptionParser(usage=_('%prog [options] OPFFILE'))
|
parser = OptionParser(usage=_('%prog [options] OPFFILE'))
|
||||||
parser.add_option(
|
parser.add_option(
|
||||||
'-o', '--output', default=None,
|
'-o', '--output', default=None,
|
||||||
@ -495,6 +501,16 @@ def option_parser():
|
|||||||
parser.add_option(
|
parser.add_option(
|
||||||
'-v', '--verbose', default=False, action='store_true',
|
'-v', '--verbose', default=False, action='store_true',
|
||||||
help=_('Useful for debugging.'))
|
help=_('Useful for debugging.'))
|
||||||
|
group = OptionGroup(parser, _('Profiles'), _('Device renderer profiles. '
|
||||||
|
'Affects conversion of default font sizes and rasterization '
|
||||||
|
'resolution. Valid profiles are: %s.') % profiles)
|
||||||
|
group.add_option(
|
||||||
|
'--source-profile', default='Browser', metavar='PROFILE',
|
||||||
|
help=_("Source renderer profile. Default is 'Browser'."))
|
||||||
|
group.add_option(
|
||||||
|
'--dest-profile', default='CybookG3', metavar='PROFILE',
|
||||||
|
help=_("Destination renderer profile. Default is 'CybookG3'."))
|
||||||
|
parser.add_option_group(group)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def oeb2mobi(opts, inpath):
|
def oeb2mobi(opts, inpath):
|
||||||
@ -504,9 +520,17 @@ def oeb2mobi(opts, inpath):
|
|||||||
if outpath is None:
|
if outpath is None:
|
||||||
outpath = os.path.basename(inpath)
|
outpath = os.path.basename(inpath)
|
||||||
outpath = os.path.splitext(outpath)[0] + '.mobi'
|
outpath = os.path.splitext(outpath)[0] + '.mobi'
|
||||||
|
source = opts.source_profile
|
||||||
|
if source not in Context.PROFILES:
|
||||||
|
logger.error(_('Unknown source profile %r') % source)
|
||||||
|
return 1
|
||||||
|
dest = opts.dest_profile
|
||||||
|
if dest not in Context.PROFILES:
|
||||||
|
logger.error(_('Unknown destination profile %r') % dest)
|
||||||
|
return 1
|
||||||
compression = PALMDOC if opts.compress else UNCOMPRESSED
|
compression = PALMDOC if opts.compress else UNCOMPRESSED
|
||||||
imagemax = MAX_IMAGE_SIZE if opts.rescale_images else None
|
imagemax = MAX_IMAGE_SIZE if opts.rescale_images else None
|
||||||
context = Context('Firefox', 'EZReader')
|
context = Context(source, dest)
|
||||||
oeb = OEBBook(inpath, logger=logger)
|
oeb = OEBBook(inpath, logger=logger)
|
||||||
tocadder = HTMLTOCAdder()
|
tocadder = HTMLTOCAdder()
|
||||||
tocadder.transform(oeb, context)
|
tocadder.transform(oeb, context)
|
||||||
@ -535,8 +559,8 @@ def main(argv=sys.argv):
|
|||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 1
|
return 1
|
||||||
inpath = args[0]
|
inpath = args[0]
|
||||||
oeb2mobi(opts, inpath)
|
retval = oeb2mobi(opts, inpath)
|
||||||
return 0
|
return retval
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
@ -45,7 +45,7 @@ PROFILES = {
|
|||||||
fsizes=[14, 14, 16, 18, 20, 22, 24, 26]),
|
fsizes=[14, 14, 16, 18, 20, 22, 24, 26]),
|
||||||
|
|
||||||
# No clue on usable screen size; DPI should be good
|
# No clue on usable screen size; DPI should be good
|
||||||
'EZReader':
|
'HanlinV3':
|
||||||
Profile(width=584, height=754, dpi=168.451, fbase=16,
|
Profile(width=584, height=754, dpi=168.451, fbase=16,
|
||||||
fsizes=[12, 12, 14, 16, 18, 21, 24, 28]),
|
fsizes=[12, 12, 14, 16, 18, 21, 24, 28]),
|
||||||
|
|
||||||
@ -57,13 +57,15 @@ PROFILES = {
|
|||||||
Profile(width=525, height=640, dpi=168.451, fbase=16,
|
Profile(width=525, height=640, dpi=168.451, fbase=16,
|
||||||
fsizes=[12, 12, 14, 16, 18, 21, 24, 28]),
|
fsizes=[12, 12, 14, 16, 18, 21, 24, 28]),
|
||||||
|
|
||||||
'Firefox':
|
'Browser':
|
||||||
Profile(width=800, height=600, dpi=100.0, fbase=12,
|
Profile(width=800, height=600, dpi=100.0, fbase=12,
|
||||||
fsizes=[5, 7, 9, 12, 13.5, 17, 20, 22, 24])
|
fsizes=[5, 7, 9, 12, 13.5, 17, 20, 22, 24])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Context(object):
|
class Context(object):
|
||||||
|
PROFILES = PROFILES
|
||||||
|
|
||||||
def __init__(self, source, dest):
|
def __init__(self, source, dest):
|
||||||
if source in PROFILES:
|
if source in PROFILES:
|
||||||
source = PROFILES[source]
|
source = PROFILES[source]
|
||||||
|
@ -40,8 +40,9 @@ class CaseMangler(object):
|
|||||||
self.oeb.manifest.add(id, href, CSS_MIME, data=CASE_MANGLER_CSS)
|
self.oeb.manifest.add(id, href, CSS_MIME, data=CASE_MANGLER_CSS)
|
||||||
for item in self.oeb.spine:
|
for item in self.oeb.spine:
|
||||||
html = item.data
|
html = item.data
|
||||||
|
relhref = item.relhref(href)
|
||||||
etree.SubElement(html.find(XHTML('head')), XHTML('link'),
|
etree.SubElement(html.find(XHTML('head')), XHTML('link'),
|
||||||
rel='stylesheet', href=href, type=CSS_MIME)
|
rel='stylesheet', href=relhref, type=CSS_MIME)
|
||||||
stylizer = Stylizer(html, item.href, self.oeb, self.profile)
|
stylizer = Stylizer(html, item.href, self.oeb, self.profile)
|
||||||
self.mangle_elem(html.find(XHTML('body')), stylizer)
|
self.mangle_elem(html.find(XHTML('body')), stylizer)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user