Expand shorthand properties in filter CSS

Conversion: Fix specifying shorthand properties in filter css not
working. Now all shorthand properties automatically filter out all the
properties they are shorthand for.
This commit is contained in:
Kovid Goyal 2013-11-27 15:56:25 +05:30
parent 0199955e0e
commit bdd03a58d2
2 changed files with 39 additions and 3 deletions

View File

@ -13,7 +13,7 @@ try:
from cssutils.css import PropertyValue
except ImportError:
raise RuntimeError('You need cssutils >= 0.9.9 for calibre')
from cssutils import profile as cssprofiles
from cssutils import profile as cssprofiles, CSSParser
DEFAULTS = {'azimuth': 'center', 'background-attachment': 'scroll', # {{{
'background-color': 'transparent', 'background-image': 'none',
@ -165,6 +165,25 @@ for x in EDGES:
name = 'border-' + x
normalizers[name] = simple_normalizer(name, BORDER_PROPS, check_inherit=False)
SHORTHAND_DEFAULTS = {
'margin': '0', 'padding': '0', 'border-style': 'none', 'border-width': '0', 'border-color': 'currentColor',
'border':'none', 'border-left': 'none', 'border-right':'none', 'border-top': 'none', 'border-bottom': 'none',
'list-style': 'inherit', 'font': 'inherit',
}
def normalize_filter_css(props):
import logging
ans = set()
p = CSSParser(loglevel=logging.CRITICAL, validate=False)
for prop in props:
n = normalizers.get(prop, None)
ans.add(prop)
if n is not None and prop in SHORTHAND_DEFAULTS:
dec = p.parseStyle('%s: %s' % (prop, SHORTHAND_DEFAULTS[prop]))
cssvalue = dec.getPropertyCSSValue(dec.item(0))
ans |= set(n(prop, cssvalue))
return ans
def condense_edge(vals):
edges = {x.name.rpartition('-')[-1]:x.value for x in vals}
if len(edges) != 4:
@ -337,6 +356,21 @@ def test_normalization(): # {{{
cval = tuple(parseStyle('list-style: %s' % raw, validate=False))[0].cssValue
self.assertDictEqual(ls_dict(expected), normalizers['list-style']('list-style', cval))
def test_filter_css_normalization(self):
ae = self.assertEqual
ae({'font'} | set(font_composition), normalize_filter_css({'font'}))
for p in ('margin', 'padding'):
ae({p} | {p + '-' + x for x in EDGES}, normalize_filter_css({p}))
bvals = {'border-%s-%s' % (edge, x) for edge in EDGES for x in BORDER_PROPS}
ae(bvals | {'border'}, normalize_filter_css({'border'}))
for x in BORDER_PROPS:
sbvals = {'border-%s-%s' % (e, x) for e in EDGES}
ae(sbvals | {'border-%s' % x}, normalize_filter_css({'border-%s' % x}))
for e in EDGES:
sbvals = {'border-%s-%s' % (e, x) for x in BORDER_PROPS}
ae(sbvals | {'border-%s' % e}, normalize_filter_css({'border-%s' % e}))
ae({'list-style', 'list-style-image', 'list-style-type', 'list-style-position'}, normalize_filter_css({'list-style'}))
def test_edge_condensation(self):
for s, v in {
(1, 1, 3) : None,

View File

@ -150,11 +150,13 @@ class CSSFlattener(object):
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(',')])
self.filter_css = {x.strip().lower() for x in
self.opts.filter_css.split(',')}
except:
self.oeb.log.warning('Failed to parse filter_css, ignoring')
else:
from calibre.ebooks.oeb.normalize_css import normalize_filter_css
self.filter_css = frozenset(normalize_filter_css(self.filter_css))
self.oeb.log.debug('Filtering CSS properties: %s'%
', '.join(self.filter_css))