diff --git a/src/calibre/ebooks/html.py b/src/calibre/ebooks/html.py
index f14e153057..634963e775 100644
--- a/src/calibre/ebooks/html.py
+++ b/src/calibre/ebooks/html.py
@@ -798,8 +798,9 @@ class Processor(Parser):
if face is not None:
faces = []
for face in face.split(','):
- if ' ' in face:
- face = "%s" % face
+ face = face.strip()
+ if ' ' in face and not (face[0] == face[-1] == '"'):
+ face = '"%s"' % face.replace('"', r'\"')
faces.append(face)
for generic in ('serif', 'sans-serif', 'monospace'):
if generic in faces:
diff --git a/src/calibre/ebooks/mobi/mobiml.py b/src/calibre/ebooks/mobi/mobiml.py
index 6193fbba13..da0da7c543 100644
--- a/src/calibre/ebooks/mobi/mobiml.py
+++ b/src/calibre/ebooks/mobi/mobiml.py
@@ -115,7 +115,7 @@ class MobiMLizer(object):
if isinstance(ptsize, basestring):
return ptsize
embase = self.profile.fbase
- if ptsize < embase:
+ if round(ptsize) < embase:
return "%dpt" % int(round(ptsize))
return "%dem" % int(round(ptsize / embase))
diff --git a/src/calibre/ebooks/mobi/writer.py b/src/calibre/ebooks/mobi/writer.py
index 2a7a3addfa..c1b6e87d72 100644
--- a/src/calibre/ebooks/mobi/writer.py
+++ b/src/calibre/ebooks/mobi/writer.py
@@ -346,7 +346,9 @@ class MobiWriter(object):
format = image.format
changed = False
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
if dimen is not None:
image.thumbnail(dimen, Image.ANTIALIAS)
@@ -481,7 +483,11 @@ class MobiWriter(object):
def option_parser():
+ profiles = Context.PROFILES.keys()
+ profiles.sort()
+ profiles = ', '.join(profiles)
from calibre.utils.config import OptionParser
+ from optparse import OptionGroup
parser = OptionParser(usage=_('%prog [options] OPFFILE'))
parser.add_option(
'-o', '--output', default=None,
@@ -495,6 +501,16 @@ def option_parser():
parser.add_option(
'-v', '--verbose', default=False, action='store_true',
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
def oeb2mobi(opts, inpath):
@@ -504,9 +520,17 @@ def oeb2mobi(opts, inpath):
if outpath is None:
outpath = os.path.basename(inpath)
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
imagemax = MAX_IMAGE_SIZE if opts.rescale_images else None
- context = Context('Firefox', 'EZReader')
+ context = Context(source, dest)
oeb = OEBBook(inpath, logger=logger)
tocadder = HTMLTOCAdder()
tocadder.transform(oeb, context)
@@ -535,8 +559,8 @@ def main(argv=sys.argv):
parser.print_help()
return 1
inpath = args[0]
- oeb2mobi(opts, inpath)
- return 0
+ retval = oeb2mobi(opts, inpath)
+ return retval
if __name__ == '__main__':
sys.exit(main())
diff --git a/src/calibre/ebooks/oeb/profile.py b/src/calibre/ebooks/oeb/profile.py
index f57257907f..032fe5e5ff 100644
--- a/src/calibre/ebooks/oeb/profile.py
+++ b/src/calibre/ebooks/oeb/profile.py
@@ -45,7 +45,7 @@ PROFILES = {
fsizes=[14, 14, 16, 18, 20, 22, 24, 26]),
# No clue on usable screen size; DPI should be good
- 'EZReader':
+ 'HanlinV3':
Profile(width=584, height=754, dpi=168.451, fbase=16,
fsizes=[12, 12, 14, 16, 18, 21, 24, 28]),
@@ -57,13 +57,15 @@ PROFILES = {
Profile(width=525, height=640, dpi=168.451, fbase=16,
fsizes=[12, 12, 14, 16, 18, 21, 24, 28]),
- 'Firefox':
+ 'Browser':
Profile(width=800, height=600, dpi=100.0, fbase=12,
fsizes=[5, 7, 9, 12, 13.5, 17, 20, 22, 24])
}
class Context(object):
+ PROFILES = PROFILES
+
def __init__(self, source, dest):
if source in PROFILES:
source = PROFILES[source]
diff --git a/src/calibre/ebooks/oeb/transforms/manglecase.py b/src/calibre/ebooks/oeb/transforms/manglecase.py
index 07fec10fb2..3a3d91364f 100644
--- a/src/calibre/ebooks/oeb/transforms/manglecase.py
+++ b/src/calibre/ebooks/oeb/transforms/manglecase.py
@@ -40,8 +40,9 @@ class CaseMangler(object):
self.oeb.manifest.add(id, href, CSS_MIME, data=CASE_MANGLER_CSS)
for item in self.oeb.spine:
html = item.data
+ relhref = item.relhref(href)
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)
self.mangle_elem(html.find(XHTML('body')), stylizer)