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)