diff --git a/lib/haml/precompiler.rb b/lib/haml/precompiler.rb index ff9a70b7..3851d168 100644 --- a/lib/haml/precompiler.rb +++ b/lib/haml/precompiler.rb @@ -83,7 +83,7 @@ module Haml DOCTYPE_REGEX = /(\d\.\d)?[\s]*([a-z]*)/i # The Regex that matches a literal string or symbol value - LITERAL_VALUE_REGEX = /^\s*(:(\w*)|(('|")([^\\\#'"]*?)\4))\s*$/ + LITERAL_VALUE_REGEX = /:(\w*)|(["'])([^\\#'"]|\\.)*\2/ private @@ -451,29 +451,18 @@ END attributes end - def parse_literal_value(text) - return nil unless text - text.match(LITERAL_VALUE_REGEX) - - # $2 holds the value matched by a symbol, but is nil for a string match - # $5 holds the value matched by a string - $2 || $5 - end - def parse_static_hash(text) return {} unless text attributes = {} - text.split(',').each do |attrib| - key, value, more = attrib.split('=>') - - # Make sure the key and value and only the key and value exist - # Otherwise, it's too complicated or dynamic and we'll defer it to the actual Ruby parser - key = parse_literal_value key - value = parse_literal_value value - return nil if more || key.nil? || value.nil? - - attributes[key] = value + scanner = StringScanner.new(text) + scanner.scan(/\s+/) + until scanner.eos? + return unless key = scanner.scan(LITERAL_VALUE_REGEX) + return unless scanner.scan(/\s*=>\s*/) + return unless value = scanner.scan(LITERAL_VALUE_REGEX) + attributes[eval(key).to_s] = eval(value).to_s + scanner.scan(/[,\s]*/) end attributes end diff --git a/test/haml/engine_test.rb b/test/haml/engine_test.rb index efb4779c..d75df3b9 100644 --- a/test/haml/engine_test.rb +++ b/test/haml/engine_test.rb @@ -618,6 +618,13 @@ END assert_raise(Haml::Error, "Invalid output format :html1") { engine("%br", :format => :html1) } end + def test_static_hashes + assert_equal("\n", render("%a{:b => 'a => b'}", :suppress_eval => true)) + assert_equal("\n", render("%a{:b => 'a, b'}", :suppress_eval => true)) + assert_equal("\n", render('%a{:b => "a\tb"}', :suppress_eval => true)) + assert_equal("\n", render('%a{:b => "a\\#{foo}b"}', :suppress_eval => true)) + end + # HTML 4.0 def test_html_has_no_self_closing_tags