Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
diff -Naur haml/lib/haml/precompiler.rb hamlnew/lib/haml/precompiler.rb --- haml/lib/haml/precompiler.rb 2008-02-07 15:35:58.000000000 -0500 +++ hamlnew/lib/haml/precompiler.rb 2008-02-07 15:28:52.000000000 -0500 @@ -83,6 +83,8 @@ # The Regex that matches an HTML tag command. TAG_REGEX = /[%]([-:\w]+)([-\w\.\#]*)(\{.*\})?(\[.*\])?([=\/\~]?)?(.*)?/ + INLINE_TAG_HASH = /\{(.*(\}.*\{).*)\}/ + # TAG_REGEX = /[%]([-:\w]+)([-\w\.\#]*)(\{((?<=\{)\})[^\}]*\})?(\[.*\])?([=\/\~]?)?(.*(\{.*\}|).*?)?/ # The Regex that matches a literal string or symbol value LITERAL_VALUE_REGEX = /^\s*(:(\w*)|(('|")([^\\\#'"]*?)\4))\s*$/ @@ -479,9 +481,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(INLINE_TAG_HASH)[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 diff -Naur haml/test/haml/engine_test.rb hamlnew/test/haml/engine_test.rb --- haml/test/haml/engine_test.rb 2008-02-07 15:35:57.000000000 -0500 +++ hamlnew/test/haml/engine_test.rb 2008-02-07 15:33:54.000000000 -0500 @@ -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 => ''}))
This paste will be private.
From the Design Piracy series on my blog: