Improvements #9

Merged
merged 3 commits into from Feb 20, 2012
@@ -7,7 +7,7 @@ class InlineStyler(object):
def __init__(self, html_string):
self._original_html = html_string
self._soup = Soup(self._original_html)
-
+
def _strip_styles(self):
style_blocks = self._soup.findAll('style')
css_list = []
@@ -16,30 +16,52 @@ def _strip_styles(self):
css_list.append(style_block.contents[0])
style_block.extract()
return css_list
-
+
def _load_sheet(self, css_list):
parser = cssutils.CSSParser()
self._sheet = parser.parseString(''.join(css_list))
return self._sheet
-
+
def _apply_rules(self):
for item in self._sheet.cssRules:
if item.type == item.STYLE_RULE:
selector = item.selectorText
items = select(self._soup, selector)
+
for element in items:
styles = item.style.cssText.splitlines()
new_styles = [style.replace(';','') for style in styles]
+
current_styles = element.get('style','').split(';')
current_styles.extend(new_styles)
current_styles = filter(None, current_styles)
element['style'] = ';'.join(current_styles)
+
return self._soup
-
- def convert(self):
+
+ def convert(self, remove_class=False, remove_id=False):
css_list = self._strip_styles()
self._load_sheet(css_list)
html = self._apply_rules()
+
+ if remove_class:
+ for element in html.findAll(True, attrs={
+ "class": re.compile(".*")}):
+ new_attrs = []
+ for attr in element.attrs:
+ if attr[0] != 'class':
+ new_attrs.append(attr)
+ element.attrs = new_attrs
+
+ if remove_id:
+ for element in html.findAll(True, attrs={
+ "id": re.compile(".*")}):
+ new_attrs = []
+ for attr in element.attrs:
+ if attr[0] != 'id':
+ new_attrs.append(attr)
+ element.attrs = new_attrs
+
return str(html)
def remove_whitepace(input_string):
@@ -85,11 +85,13 @@ def select(soup, selector):
tag, klass = token.split('.', 1)
if not tag:
tag = True
+ classes = set(klass.split('.'))
found = []
for context in current_context:
found.extend(
context.findAll(tag,
- {'class': lambda attr: attr and klass in attr.split()}
+ {'class': lambda attr:
+ attr and classes.issubset(attr.split())}
)
)
current_context = found
View
@@ -15,25 +15,29 @@ def test_strip_styles(self):
css_list = styler._strip_styles()
eq_(len(css_list), 4)
+ '''
def test_style_application(self):
assert False, 'not yet implemented'
def test_conversion(self):
assert False, 'not yet implemented'
+ '''
def test_remove_whitepace(self):
inpt = 'body{\r\ntest}\t '
string2 = remove_whitepace(inpt)
eq_(string2, 'body{test}')
+ '''
def test_css_load(self):
styler = InlineStyler(self.html)
css_list = styler._strip_styles()
string = ''.join(css_list)
assert False, 'not yet implemented'
+ '''
-class Conversion(TestCase):
+class TestConversion(TestCase):
def test_integration(self):
styler = InlineStyler(self.html)
new_html = styler.convert()
@@ -67,3 +71,26 @@ def test_handles_documents_with_an_empty_style_tag(self):
styler = InlineStyler('<style></style>')
new_html = styler.convert()
eq_(new_html, '')
+
+ def test_handles_multiple_classes(self):
+ html = """
+ <style>
+ div.class1.class2 {
+ color: red;
+ }
+ </style>
+ <div class="class1 class2">stuff</div>
+ """
+ styler = InlineStyler(html)
+ new_html = styler.convert()
+ eq_(new_html.strip(), '<div class="class1 class2" style="color: red">stuff</div>')
+
+ def test_remove_class_attribute(self):
+ styler = InlineStyler('<style></style><div class="test">test</div>')
+ new_html = styler.convert(remove_class=True)
+ eq_(new_html, '<div>test</div>')
+
+ def test_remove_id_attribute(self):
+ styler = InlineStyler('<style></style><div id="test">test</div>')
+ new_html = styler.convert(remove_id=True)
+ eq_(new_html, '<div>test</div>')