Report abuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Index: test/haml/engine_test.rb
===================================================================
--- test/haml/engine_test.rb  (revision 738)
+++ test/haml/engine_test.rb  (working copy)
@@ -133,6 +133,13 @@
     assert_equal("<p escaped='quo4te'>\n</p>\n", render("%p{ :escaped => \"quo\#{2 + 2}te\"}"))
   end
   
+  def test_correct_parsing_with_brackets
+    assert_equal("<p class='foo'>{tada} foo</p>\n", render("%p{:class => 'foo'} {tada} foo"))
+    assert_equal("<p class='foo'>deep {nested { things }}</p>\n", render("%p{:class => 'foo'} deep {nested { things }}"))
+    assert_equal("<p class='bar foo'>{a { d</p>\n", render("%p{{:class => 'foo'}, :class => 'bar'} {a { d"))
+    assert_equal("<p>a }</p>\n", render("%p a }"))
+  end
+  
   def test_empty_attrs
     assert_equal("<p attr=''>empty</p>\n", render("%p{ :attr => '' } empty"))
     assert_equal("<p attr=''>empty</p>\n", render("%p{ :attr => x } empty", :locals => {:x => ''}))
Index: lib/haml/precompiler.rb
===================================================================
--- lib/haml/precompiler.rb (revision 738)
+++ lib/haml/precompiler.rb (working copy)
@@ -479,9 +479,18 @@
     def render_tag(line)
       raise SyntaxError.new("Invalid tag: \"#{line}\"") unless match = line.scan(TAG_REGEX)[0]
       tag_name, attributes, attributes_hash, object_ref, action, value = match
-      value = value.to_s.strip
-      attributes_hash = attributes_hash[1...-1] if attributes_hash
-
+      # Check to see if attributes containes } { (which means things got messed up)
+      if attributes_hash && garble = attributes_hash.scan(/\{(.*(\}.*\{).*)\}/)[0]
+        scanner = StringScanner.new(attributes_hash[1, attributes_hash.length])
+        attributes_hash = balance_brackets(scanner)
+        # Strip off the attributes
+        rest = garble[0][attributes_hash.length + 2...garble[0].length]
+        object_ref, action, start_value = rest.scan(/(\[.*\])?([=\/\~]?)?(.*)?/)[0] unless rest.nil?
+        value = start_value + "}" + value
+      else
+        value = value.to_s.strip
+        attributes_hash = attributes_hash[1...-1] if attributes_hash
+      end
       raise SyntaxError.new("Illegal element: classes and ids must have values.") if attributes =~ /[\.#](\.|#|\z)/
 
       case action