diff --git a/src/calibre/ebooks/css_transform_rules.py b/src/calibre/ebooks/css_transform_rules.py index 3bd8428c2d..acf8e4b44d 100644 --- a/src/calibre/ebooks/css_transform_rules.py +++ b/src/calibre/ebooks/css_transform_rules.py @@ -75,10 +75,13 @@ class StyleDeclaration(object): dec._setSeq(seq) self.changed = True - def change_property(self, prop, parent_prop, val): + def change_property(self, prop, parent_prop, val, match_pat=None): if parent_prop is not None: self.expand_property(parent_prop) - prop.value = val + if match_pat is None: + prop.value = val + else: + prop.value = match_pat.sub(val, prop.value) self.changed = True def append_properties(self, props): @@ -167,6 +170,7 @@ class Rule(object): def __init__(self, property='color', match_type='*', query='', action='remove', action_data=''): self.property_name = property.lower() self.action, self.action_data = action, action_data + self.match_pat = None if self.action == 'append': decl = safe_parser().parseStyle(self.action_data) self.appended_properties = list(all_properties(decl)) @@ -179,11 +183,11 @@ class Rule(object): elif match_type == '*': self.property_matches = lambda x: True elif 'matches' in match_type: - q = compile_pat(query) + self.match_pat = compile_pat(query) if match_type.startswith('not_'): - self.property_matches = lambda x: q.match(x) is None + self.property_matches = lambda x: self.match_pat.match(x) is None else: - self.property_matches = lambda x: q.match(x) is not None + self.property_matches = lambda x: self.match_pat.match(x) is not None else: value, unit = parse_css_length_or_number(query) op = getattr(operator, operator_map[match_type]) @@ -197,7 +201,7 @@ class Rule(object): if self.action == 'remove': declaration.remove_property(prop, parent_prop) elif self.action == 'change': - declaration.change_property(prop, parent_prop, self.action_data) + declaration.change_property(prop, parent_prop, self.action_data, self.match_pat) elif self.action == 'append': declaration.append_properties(self.appended_properties) else: @@ -385,8 +389,15 @@ def test(return_tests=False): # {{{ def test_matching(self): - def m(match_type='*', query=''): - self.ae(apply_rule(css, property=prop, match_type=match_type, query=query), ecss) + def m(match_type='*', query='', action_data=''): + action = 'change' if action_data else 'remove' + self.ae(apply_rule( + css, property=prop, match_type=match_type, query=query, action=action, action_data=action_data + ), ecss) + + prop = 'font-size' + css, ecss = 'font-size: 1.2rem', 'font-size: 1.2em' + m('matches', query='(.+)rem', action_data=r'\1em') prop = 'color' css, ecss = 'color: red; margin: 0', 'margin: 0' @@ -446,6 +457,7 @@ def test(return_tests=False): # {{{ m('line-height: 2', 'line-height: 1', '/', '2') prop = 'border-top-width' m('border-width: 1', 'border-bottom-width: 1;\nborder-left-width: 1;\nborder-right-width: 1;\nborder-top-width: 3', '*', '3') + prop = 'font-size' def test_export_import(self): rule = {'property':'a', 'match_type':'*', 'query':'some text', 'action':'remove', 'action_data':'color: red; a: b'}