Repository: peterbe/premailer

Issue:
SyntaxErr on <h1> with !important
Feeding the following into ```transform()``` results in a ```SyntaxErr```:

```
<style type="text/css">
h1 { border:1px solid black }
p { color:red;}
</style>
<p>Hey</p>
<h1 style="display: block;font-family: Helvetica;font-size: 26px;font-style: normal;font-weight: bold;line-height: 100%;letter-spacing: normal;margin-top: 0;margin-right: 0;margin-bottom: 10px;margin-left: 0;text-align: left;color: #202020 !important;">Some Stuff</h1>
```

Results in:

```
SyntaxErr: PropertyValue: Missing token for production Choice(ColorValue, Dimension, URIValue, Value, variable, MSValue, CSSCalc, function): ('CHAR', '!', 1, 230)
```

Removing the ```!important``` from the inline style on the H1 allows it to be inlined as expected.

Discussion:
lavr: csstext_to_pairs results are stripped and sorted again.

Patch:
diff --git a/premailer/merge_style.py b/premailer/merge_style.py
index 0fe93f7..9842e63 100644
--- a/premailer/merge_style.py
+++ b/premailer/merge_style.py
@@ -1,5 +1,6 @@
 import cssutils
 import threading
+from operator import itemgetter
 
 
 def csstext_to_pairs(csstext):
@@ -10,11 +11,10 @@ def csstext_to_pairs(csstext):
     # The lock is required to avoid ``cssutils`` concurrency
     # issues documented in issue #65
     with csstext_to_pairs._lock:
-        parsed = cssutils.css.CSSVariablesDeclaration(csstext)
-        return [
-            (key.strip(), parsed.getVariableValue(key).strip())
-            for key in sorted(parsed)
-        ]
+        return sorted([(prop.name.strip(), prop.propertyValue.cssText.strip())
+                       for prop in cssutils.parseStyle(csstext)],
+                      key=itemgetter(0))
+
 
 csstext_to_pairs._lock = threading.RLock()
 


Test patch:
diff --git a/premailer/tests/test_merge_style.py b/premailer/tests/test_merge_style.py
index 7a8a215..0d4d11f 100644
--- a/premailer/tests/test_merge_style.py
+++ b/premailer/tests/test_merge_style.py
@@ -1,7 +1,5 @@
 from __future__ import absolute_import, unicode_literals
 import unittest
-import xml
-from nose.tools import raises
 from premailer.merge_style import csstext_to_pairs, merge_styles
 
 
@@ -14,9 +12,13 @@ class TestMergeStyle(unittest.TestCase):
         parsed_csstext = csstext_to_pairs(csstext)
         self.assertEqual(('font-size', '1px'), parsed_csstext[0])
 
-    @raises(xml.dom.SyntaxErr)
     def test_inline_invalid_syntax(self):
-        # inline shouldn't have those as I understand
-        # but keep the behaviour
+        # Invalid syntax does not raise
         inline = '{color:pink} :hover{color:purple} :active{color:red}'
         merge_styles(inline, [], [])
+
+    def test_important_rule(self):
+        # No exception after #133
+        csstext = 'font-size:1px !important'
+        parsed_csstext = csstext_to_pairs(csstext)
+        self.assertEqual(('font-size', '1px'), parsed_csstext[0])