diff --git a/src/calibre/ebooks/conversion/cli.py b/src/calibre/ebooks/conversion/cli.py
index ed332acac2..7a6997249f 100644
--- a/src/calibre/ebooks/conversion/cli.py
+++ b/src/calibre/ebooks/conversion/cli.py
@@ -134,7 +134,7 @@ def add_pipeline_options(parser, plumber):
'font_size_mapping',
'line_height', 'minimum_line_height',
'linearize_tables',
- 'extra_css',
+ 'extra_css', 'filter_css',
'smarten_punctuation', 'unsmarten_punctuation',
'margin_top', 'margin_left', 'margin_right',
'margin_bottom', 'change_justification',
diff --git a/src/calibre/ebooks/conversion/plumber.py b/src/calibre/ebooks/conversion/plumber.py
index defb2b837d..1d43d3cb7e 100644
--- a/src/calibre/ebooks/conversion/plumber.py
+++ b/src/calibre/ebooks/conversion/plumber.py
@@ -308,6 +308,16 @@ OptionRecommendation(name='extra_css',
'rules.')
),
+OptionRecommendation(name='filter_css',
+ recommended_value=None, level=OptionRecommendation.LOW,
+ help=_('A comma separated list of CSS properties that '
+ 'will be removed from all CSS style rules. This is useful '
+ 'if the presence of some style information prevents it '
+ 'from being overridden on your device. '
+ 'For example: '
+ 'font-family,color,margin-left,margin-right')
+ ),
+
OptionRecommendation(name='page_breaks_before',
recommended_value="//*[name()='h1' or name()='h2']",
level=OptionRecommendation.LOW,
diff --git a/src/calibre/ebooks/oeb/transforms/flatcss.py b/src/calibre/ebooks/oeb/transforms/flatcss.py
index 6f338cb6d1..664b07baa5 100644
--- a/src/calibre/ebooks/oeb/transforms/flatcss.py
+++ b/src/calibre/ebooks/oeb/transforms/flatcss.py
@@ -118,8 +118,20 @@ class CSSFlattener(object):
def __call__(self, oeb, context):
oeb.logger.info('Flattening CSS and remapping font sizes...')
+ self.context = self.opts =context
self.oeb = oeb
- self.context = context
+
+ self.filter_css = frozenset()
+ if self.opts.filter_css:
+ try:
+ self.filter_css = frozenset([x.strip().lower() for x in
+ self.opts.filter_css.split(',')])
+ except:
+ self.oeb.log.warning('Failed to parse filter_css, ignoring')
+ else:
+ self.oeb.log.debug('Filtering CSS properties: %s'%
+ ', '.join(self.filter_css))
+
self.stylize_spine()
self.sbase = self.baseline_spine() if self.fbase else None
self.fmap = FontMapper(self.sbase, self.fbase, self.fkey)
@@ -279,6 +291,10 @@ class CSSFlattener(object):
except:
self.oeb.logger.exception('Failed to set minimum line-height')
+ if cssdict:
+ for x in self.filter_css:
+ cssdict.pop(x, None)
+
if cssdict:
if self.lineh and self.fbase and tag != 'body':
self.clean_edges(cssdict, style, psize)
@@ -311,7 +327,6 @@ class CSSFlattener(object):
lineh = self.lineh / psize
cssdict['line-height'] = "%0.5fem" % lineh
-
if (self.context.remove_paragraph_spacing or
self.context.insert_blank_line) and tag in ('p', 'div'):
if item_id != 'calibre_jacket' or self.context.output_profile.name == 'Kindle':
diff --git a/src/calibre/gui2/convert/look_and_feel.py b/src/calibre/gui2/convert/look_and_feel.py
index 4785e222fc..ad604ec4e3 100644
--- a/src/calibre/gui2/convert/look_and_feel.py
+++ b/src/calibre/gui2/convert/look_and_feel.py
@@ -18,6 +18,16 @@ class LookAndFeelWidget(Widget, Ui_Form):
HELP = _('Control the look and feel of the output')
COMMIT_NAME = 'look_and_feel'
+ FILTER_CSS = {
+ 'fonts': {'font-family'},
+ 'margins': {'margin', 'margin-left', 'margin-right', 'margin-top',
+ 'margin-bottom'},
+ 'padding': {'padding', 'padding-left', 'padding-right', 'padding-top',
+ 'padding-bottom'},
+ 'floats': {'float'},
+ 'colors': {'color', 'background', 'background-color'},
+ }
+
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
Widget.__init__(self, parent,
['change_justification', 'extra_css', 'base_font_size',
@@ -27,7 +37,7 @@ class LookAndFeelWidget(Widget, Ui_Form):
'remove_paragraph_spacing',
'remove_paragraph_spacing_indent_size',
'insert_blank_line_size',
- 'input_encoding',
+ 'input_encoding', 'filter_css',
'asciiize', 'keep_ligatures',
'linearize_tables']
)
@@ -56,6 +66,15 @@ class LookAndFeelWidget(Widget, Ui_Form):
if g is self.opt_change_justification:
ans = unicode(g.itemData(g.currentIndex()).toString())
return ans
+ if g is self.opt_filter_css:
+ ans = set()
+ for key, item in self.FILTER_CSS.iteritems():
+ w = getattr(self, 'filter_css_%s'%key)
+ if w.isChecked():
+ ans = ans.union(item)
+ ans = ans.union(set([x.strip().lower() for x in
+ unicode(self.filter_css_others.text()).split(',')]))
+ return ','.join(ans) if ans else None
return Widget.get_value_handler(self, g)
def set_value_handler(self, g, val):
@@ -66,6 +85,27 @@ class LookAndFeelWidget(Widget, Ui_Form):
g.setCurrentIndex(i)
break
return True
+ if g is self.opt_filter_css:
+ if not val: val = ''
+ items = frozenset([x.strip().lower() for x in val.split(',')])
+ for key, vals in self.FILTER_CSS.iteritems():
+ w = getattr(self, 'filter_css_%s'%key)
+ if not vals - items:
+ items = items - vals
+ w.setChecked(True)
+ else:
+ w.setChecked(False)
+ self.filter_css_others.setText(', '.join(items))
+ return True
+
+ def connect_gui_obj_handler(self, gui_obj, slot):
+ if gui_obj is self.opt_filter_css:
+ for key in self.FILTER_CSS:
+ w = getattr(self, 'filter_css_%s'%key)
+ w.stateChanged.connect(slot)
+ self.filter_css_others.textChanged.connect(slot)
+ return
+ raise NotImplementedError()
def font_key_wizard(self):
from calibre.gui2.convert.font_key import FontKeyChooser
diff --git a/src/calibre/gui2/convert/look_and_feel.ui b/src/calibre/gui2/convert/look_and_feel.ui
index 2c63ce4846..fae1cf2331 100644
--- a/src/calibre/gui2/convert/look_and_feel.ui
+++ b/src/calibre/gui2/convert/look_and_feel.ui
@@ -6,7 +6,7 @@
0
0
- 642
+ 655
522
@@ -164,6 +164,41 @@
+ -
+
+
+ &Indent size:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ opt_remove_paragraph_spacing_indent_size
+
+
+
+ -
+
+
+ <p>When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent.
+
+
+ No change
+
+
+ em
+
+
+ 1
+
+
+ -0.100000000000000
+
+
+ 0.100000000000000
+
+
+
-
@@ -171,6 +206,19 @@
+ -
+
+
+ &Line size:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ opt_insert_blank_line_size
+
+
+
-
@@ -194,80 +242,6 @@
-
- -
-
-
- &Transliterate unicode characters to ASCII
-
-
-
- -
-
-
- Keep &ligatures
-
-
-
- -
-
-
- Extra &CSS
-
-
-
-
-
-
-
-
-
- -
-
-
- <p>When calibre removes inter paragraph spacing, it automatically sets a paragraph indent, to ensure that paragraphs can be easily distinguished. This option controls the width of that indent.
-
-
- No change
-
-
- em
-
-
- 1
-
-
- -0.100000000000000
-
-
- 0.100000000000000
-
-
-
- -
-
-
- &Indent size:
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- opt_remove_paragraph_spacing_indent_size
-
-
-
- -
-
-
- &Line size:
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- opt_insert_blank_line_size
-
-
-
-
@@ -275,6 +249,13 @@
+ -
+
+
+ &Transliterate unicode characters to ASCII
+
+
+
-
@@ -282,6 +263,13 @@
+ -
+
+
+ Keep &ligatures
+
+
+
-
@@ -289,6 +277,111 @@
+ -
+
+
+ 0
+
+
+
+ &Extra CSS
+
+
+
-
+
+
+
+
+
+
+ &Filter Style Information
+
+
+ -
+
+
+ Select what style information you want completely removed:
+
+
+ true
+
+
+
+ -
+
+
+ Removes the font-family CSS property
+
+
+ &Fonts
+
+
+
+ -
+
+
+ Removes the margin CSS properties. Note that page margins are not affected by this setting.
+
+
+ &Margins
+
+
+
+ -
+
+
+ Removes the padding CSS properties
+
+
+ &Padding
+
+
+
+ -
+
+
+ Convert floating images/text into static images/text
+
+
+ F&loats
+
+
+
+ -
+
+
+ Removes foreground and background colors
+
+
+ &Colors
+
+
+
+ -
+
+
-
+
+
+ &Other CSS Properties:
+
+
+ filter_css_others
+
+
+
+ -
+
+
+ Comma separated list of CSS properties to remove. For example: display, color, font-family
+
+
+
+
+
+
+
+
+