View Single Post
Old 05-04-2012, 06:59 AM   #234
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 45,450
Karma: 27757438
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
@kiwidude: calibre should support a simple authenticating http proxy. So unless you use a SOCKS proxy, it should not have any errors. I dont want to add an option to suppress internet connections as there's no simple way to do that. I can probably have the update check code print out a single line error instead of a full traceback, if that will help.

Here's the complete patch:
Code:
=== modified file 'src/calibre/ebooks/conversion/plugins/epub_output.py'
--- src/calibre/ebooks/conversion/plugins/epub_output.py	2012-03-17 13:35:07 +0000
+++ src/calibre/ebooks/conversion/plugins/epub_output.py	2012-05-04 10:07:10 +0000
@@ -312,13 +312,9 @@
         Perform various markup transforms to get the output to render correctly
         in the quirky ADE.
         '''
-        from calibre.ebooks.oeb.base import XPath, XHTML, OEB_STYLES, barename, urlunquote
+        from calibre.ebooks.oeb.base import XPath, XHTML, barename, urlunquote
 
-        stylesheet = None
-        for item in self.oeb.manifest:
-            if item.media_type.lower() in OEB_STYLES:
-                stylesheet = item
-                break
+        stylesheet = self.oeb.manifest.main_stylesheet
 
         # ADE cries big wet tears when it encounters an invalid fragment
         # identifier in the NCX toc.

=== modified file 'src/calibre/ebooks/conversion/plugins/pdf_output.py'
--- src/calibre/ebooks/conversion/plugins/pdf_output.py	2012-02-05 18:14:19 +0000
+++ src/calibre/ebooks/conversion/plugins/pdf_output.py	2012-05-04 10:07:10 +0000
@@ -99,12 +99,8 @@
 
         # Remove page-break-before on <body> element as it causes
         # blank pages in PDF Output
-        from calibre.ebooks.oeb.base import OEB_STYLES, XPath
-        stylesheet = None
-        for item in self.oeb.manifest:
-            if item.media_type.lower() in OEB_STYLES:
-                stylesheet = item
-                break
+        from calibre.ebooks.oeb.base import XPath
+        stylesheet = self.oeb.manifest.main_stylesheet
         if stylesheet is not None:
             from cssutils.css import CSSRule
             classes = set(['.calibre'])

=== modified file 'src/calibre/ebooks/oeb/base.py'
--- src/calibre/ebooks/oeb/base.py	2012-04-26 10:28:18 +0000
+++ src/calibre/ebooks/oeb/base.py	2012-05-04 10:07:10 +0000
@@ -1142,6 +1142,19 @@
             element(elem, OPF('item'), attrib=attrib)
         return elem
 
+    @dynamic_property
+    def main_stylesheet(self):
+        def fget(self):
+            ans = getattr(self, '_main_stylesheet', None)
+            if ans is None:
+                for item in self:
+                    if item.media_type.lower() in OEB_STYLES:
+                        ans = item
+                        break
+            return ans
+        def fset(self, item):
+            self._main_stylesheet = item
+        return property(fget=fget, fset=fset)
 
 class Spine(object):
     """Collection of manifest items composing an OEB data model book's main

=== modified file 'src/calibre/ebooks/oeb/transforms/flatcss.py'
--- src/calibre/ebooks/oeb/transforms/flatcss.py	2012-05-03 13:58:28 +0000
+++ src/calibre/ebooks/oeb/transforms/flatcss.py	2012-05-04 10:07:10 +0000
@@ -378,7 +378,7 @@
         for child in node:
             self.flatten_node(child, stylizer, names, styles, psize, item_id, left)
 
-    def flatten_head(self, item, stylizer, href):
+    def flatten_head(self, item, href, global_href):
         html = item.data
         head = html.find(XHTML('head'))
         for node in head:
@@ -390,34 +390,56 @@
                  and node.get('type', CSS_MIME) in OEB_STYLES:
                 head.remove(node)
         href = item.relhref(href)
-        etree.SubElement(head, XHTML('link'),
-            rel='stylesheet', type=CSS_MIME, href=href)
-        stylizer.page_rule['margin-top'] = '%gpt'%\
-                float(self.context.margin_top)
-        stylizer.page_rule['margin-bottom'] = '%gpt'%\
-                float(self.context.margin_bottom)
-
-        items = stylizer.page_rule.items()
-        items.sort()
-        css = '; '.join("%s: %s" % (key, val) for key, val in items)
-        style = etree.SubElement(head, XHTML('style'), type=CSS_MIME)
-        style.text = "\n\t\t@page { %s; }" % css
-        rules = [r.cssText for r in stylizer.font_face_rules]
-        raw = '\n\n'.join(rules)
-        # Make URLs referring to fonts relative to this item
-        sheet = cssutils.parseString(raw, validate=False)
-        cssutils.replaceUrls(sheet, item.relhref, ignoreImportRules=True)
-        style.text += '\n' + sheet.cssText
+        l = etree.SubElement(head, XHTML('link'),
+            rel='stylesheet', type=CSS_MIME, href=href)
+        l.tail='\n'
+        href = item.relhref(global_href)
+        l = etree.SubElement(head, XHTML('link'),
+            rel='stylesheet', type=CSS_MIME, href=href)
+        l.tail = '\n'
 
     def replace_css(self, css):
         manifest = self.oeb.manifest
-        id, href = manifest.generate('css', 'stylesheet.css')
         for item in manifest.values():
             if item.media_type in OEB_STYLES:
                 manifest.remove(item)
-        item = manifest.add(id, href, CSS_MIME, data=css)
+        id, href = manifest.generate('css', 'stylesheet.css')
+        item = manifest.add(id, href, CSS_MIME, data=cssutils.parseString(css,
+            validate=False))
+        self.oeb.manifest.main_stylesheet = item
         return href
 
+    def collect_global_css(self):
+        global_css = defaultdict(list)
+        for item in self.oeb.spine:
+            stylizer = self.stylizers[item]
+            stylizer.page_rule['margin-top'] = '%gpt'%\
+                    float(self.context.margin_top)
+            stylizer.page_rule['margin-bottom'] = '%gpt'%\
+                    float(self.context.margin_bottom)
+            items = stylizer.page_rule.items()
+            items.sort()
+            css = ';\n'.join("%s: %s" % (key, val) for key, val in items)
+            css = '@page {\n%s\n}\n'%css
+            rules = [r.cssText for r in stylizer.font_face_rules]
+            raw = '\n\n'.join(rules)
+            css += '\n\n' + raw
+            global_css[css].append(item)
+
+        gc_map = {}
+        manifest = self.oeb.manifest
+        for css in global_css:
+            id_, href = manifest.generate('page_css', 'page_styles.css')
+            manifest.add(id_, href, CSS_MIME, data=cssutils.parseString(css,
+                validate=False))
+            gc_map[css] = href
+
+        ans = {}
+        for css, items in global_css.iteritems():
+            for item in items:
+                ans[item] = gc_map[css]
+        return ans
+
     def flatten_spine(self):
         names = defaultdict(int)
         styles = {}
@@ -433,7 +455,8 @@
         items.sort()
         css = ''.join(".%s {\n%s;\n}\n\n" % (key, val) for key, val in items)
         href = self.replace_css(css)
+        global_css = self.collect_global_css()
         for item in self.oeb.spine:
             stylizer = self.stylizers[item]
-            self.flatten_head(item, stylizer, href)
+            self.flatten_head(item, href, global_css[item])
 

=== modified file 'src/calibre/ebooks/oeb/transforms/page_margin.py'
--- src/calibre/ebooks/oeb/transforms/page_margin.py	2011-04-14 14:59:27 +0000
+++ src/calibre/ebooks/oeb/transforms/page_margin.py	2012-05-04 10:07:10 +0000
@@ -9,7 +9,7 @@
 
 from collections import Counter
 
-from calibre.ebooks.oeb.base import OEB_STYLES, barename, XPath
+from calibre.ebooks.oeb.base import barename, XPath
 
 class RemoveAdobeMargins(object):
     '''
@@ -51,10 +51,7 @@
         self.stats = {}
         self.selector_map = {}
 
-        for item in self.oeb.manifest:
-            if item.media_type.lower() in OEB_STYLES:
-                stylesheet = item
-                break
+        stylesheet = self.oeb.manifest.main_stylesheet
         if stylesheet is None:
             return
kovidgoyal is offline   Reply With Quote