From 678d8509279e9b42b40d0be45ce04de7a296f8db Mon Sep 17 00:00:00 2001 From: Andrei Fokau Date: Wed, 14 Nov 2012 10:04:51 +0100 Subject: [PATCH 1/2] added compact notation for dynamic attributes --- hamlpy/elements.py | 28 +++++++++++++++++++++++++++- setup.py | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/hamlpy/elements.py b/hamlpy/elements.py index d1cb1d6..1625c76 100644 --- a/hamlpy/elements.py +++ b/hamlpy/elements.py @@ -109,6 +109,28 @@ def _escape_attribute_quotes(self, v): return ''.join(escaped) + def _prepare_dynamic_attributes(self, attribute_dict_string): + try: + import ast + from codegen import to_source + node = ast.parse(attribute_dict_string, mode='eval') + s = [] + for k,v in zip(node.body.keys, node.body.values): + if isinstance(k, ast.Name): + #k = '"{{ %s }}"' % k.id # TODO: allow dynamic keys in settings + k = '"%s"' % k.id + else: + k = to_source(k) + if isinstance(v, ast.Str): # TODO: add allowed types + v = to_source(v) + else: + v = '"{{ %s }}"' % to_source(v) + s.append('%s: %s' % (k,v)) + attribute_dict_string = '{%s}' % ', '.join(s) + except Exception as e: + pass + return attribute_dict_string + def _parse_attribute_dictionary(self, attribute_dict_string): attributes_dict = {} if (attribute_dict_string): @@ -120,6 +142,8 @@ def _parse_attribute_dictionary(self, attribute_dict_string): attribute_dict_string = re.sub(self.RUBY_HAML_REGEX, '"\g":', attribute_dict_string) # Put double quotes around key attribute_dict_string = re.sub(self.ATTRIBUTE_REGEX, '\g
"\g":\g', attribute_dict_string)
+                # replace short notation for inline expressions
+                attribute_dict_string = self._prepare_dynamic_attributes(attribute_dict_string)
                 # Parse string as dictionary
                 attributes_dict = eval(attribute_dict_string)
                 for k, v in attributes_dict.items():
@@ -138,7 +162,9 @@ def _parse_attribute_dictionary(self, attribute_dict_string):
                                 
                             attributes_dict[k] = v
                             v = v.decode('utf-8')
-                            self.attributes += "%s=%s " % (k, self.attr_wrap(self._escape_attribute_quotes(v)))
+                            if not v.startswith('{{'):
+                                v = self._escape_attribute_quotes(v)
+                            self.attributes += "%s=%s " % (k, self.attr_wrap(v))
                 self.attributes = self.attributes.strip()
             except Exception, e:
                 raise Exception('failed to decode: %s' % attribute_dict_string)
diff --git a/setup.py b/setup.py
index a9fe101..a162fa9 100644
--- a/setup.py
+++ b/setup.py
@@ -12,6 +12,7 @@
       url = 'http://github.com/jessemiller/HamlPy',
       license = 'MIT',
       install_requires = [
+          'codegen',
           'django',
           'pygments',
           'markdown'

From 2b1696b5e010e3c293ac55e453254b7e51104765 Mon Sep 17 00:00:00 2001
From: Andrei Fokau 
Date: Thu, 28 Nov 2013 09:48:05 +0100
Subject: [PATCH 2/2] Better error handling and reporting, pep8

---
 hamlpy/elements.py | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/hamlpy/elements.py b/hamlpy/elements.py
index 1625c76..1115eae 100644
--- a/hamlpy/elements.py
+++ b/hamlpy/elements.py
@@ -115,20 +115,23 @@ def _prepare_dynamic_attributes(self, attribute_dict_string):
             from codegen import to_source
             node = ast.parse(attribute_dict_string, mode='eval')
             s = []
-            for k,v in zip(node.body.keys, node.body.values):
+            for k, v in zip(node.body.keys, node.body.values):
                 if isinstance(k, ast.Name):
                     #k = '"{{ %s }}"' % k.id # TODO: allow dynamic keys in settings
                     k = '"%s"' % k.id
                 else:
                     k = to_source(k)
-                if isinstance(v, ast.Str): # TODO: add allowed types
+                if isinstance(v, ast.Str):  # TODO: add allowed types
                     v = to_source(v)
                 else:
                     v = '"{{ %s }}"' % to_source(v)
-                s.append('%s: %s' % (k,v))
+                s.append('%s: %s' % (k, v))
             attribute_dict_string = '{%s}' % ', '.join(s)
         except Exception as e:
-            pass
+            import traceback
+            traceback.print_exc()
+            print repr(e)
+            attribute_dict_string = 'error: "%s"' % repr(e).replace('"', "'")
         return attribute_dict_string
 
     def _parse_attribute_dictionary(self, attribute_dict_string):
@@ -167,8 +170,7 @@ def _parse_attribute_dictionary(self, attribute_dict_string):
                             self.attributes += "%s=%s " % (k, self.attr_wrap(v))
                 self.attributes = self.attributes.strip()
             except Exception, e:
-                raise Exception('failed to decode: %s' % attribute_dict_string)
-                #raise Exception('failed to decode: %s. Details: %s'%(attribute_dict_string, e))
+                raise Exception('failed to decode: %s. Error: %r' % (attribute_dict_string, e))
 
         return attributes_dict