@kiwidude: I was bored while waiting for today's calibre release to upload, so I implemented the stylesheet consolidation. This patch is without any testing at all, but it should be a good starting point for you:
Code:
=== 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 09:38: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,24 +390,13 @@
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
@@ -418,6 +407,37 @@
item = manifest.add(id, href, CSS_MIME, data=css)
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 +453,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])