Skip to content

Commit

Permalink
Merge branch 'interpolation-styles'
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwildig committed Mar 6, 2014
2 parents 67cb8aa + fb9a2b1 commit 7c0b082
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/haml/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def process_line(line)
case line.text[0]
when DIV_CLASS; push div(line)
when DIV_ID
return push plain(line) if line.text[1] == ?{
return push plain(line) if %w[{ @ $].include?(line.text[1])
push div(line)
when ELEMENT; push tag(line)
when COMMENT; push comment(line.text[1..-1].lstrip)
Expand Down
16 changes: 11 additions & 5 deletions lib/haml/util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def inspect_obj(obj)
# @return [String] The text remaining in the scanner after all `#{`s have been processed
def handle_interpolation(str)
scan = StringScanner.new(str)
yield scan while scan.scan(/(.*?)(\\*)\#\{/)
yield scan while scan.scan(/(.*?)(\\*)\#([\{@$])/)
scan.rest
end

Expand Down Expand Up @@ -224,20 +224,26 @@ def human_indentation(indentation)
end

def contains_interpolation?(str)
str.include?('#{')
/#[\{$@]/ === str
end

def unescape_interpolation(str, escape_html = nil)
res = ''
rest = Haml::Util.handle_interpolation str.dump do |scan|
escapes = (scan[2].size - 1) / 2
char = scan[3] # '{', '@' or '$'
res << scan.matched[0...-3 - escapes]
if escapes % 2 == 1
res << '#{'
res << "\##{char}"
else
content = eval('"' + balance(scan, ?{, ?}, 1)[0][0...-1] + '"')
interpolated = if char == '{'
balance(scan, ?{, ?}, 1)[0][0...-1]
else
scan.scan(/\w+/)
end
content = eval('"' + interpolated + '"')
content = "Haml::Helpers.html_escape((#{content}))" if escape_html
res << '#{' + content + "}"# Use eval to get rid of string escapes
res << "\##{char}#{content}#{"}" if char == '{'}"
end
end
res + rest
Expand Down
45 changes: 45 additions & 0 deletions test/engine_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,61 @@ def test_interpolation
assert_equal("<p>\n Hello World\n</p>\n", render("%p\n Hello \#{who}", :locals => {:who => 'World'}))
end

def test_interpolation_with_instance_var
scope = Object.new
scope.instance_variable_set(:@who, 'World')

assert_equal("<p>Hello World</p>\n", render('%p Hello #@who', :scope => scope))
assert_equal("<p>\n Hello World\n</p>\n", render("%p\n Hello \#@who", :scope => scope))
end

def test_interpolation_with_global
$global_var_for_testing = 'World'

assert_equal("<p>Hello World</p>\n", render('%p Hello #$global_var_for_testing'))
assert_equal("<p>\n Hello World\n</p>\n", render("%p\n Hello \#$global_var_for_testing"))
end

def test_interpolation_in_the_middle_of_a_string
assert_equal("\"title 'Title'. \"\n",
render("\"title '\#{\"Title\"}'. \""))
end

def test_interpolation_with_instance_var_in_the_middle_of_a_string
scope = Object.new
scope.instance_variable_set(:@title, 'Title')

assert_equal("\"title 'Title'. \"\n",
render("\"title '\#@title'. \"", :scope => scope))
end

def test_interpolation_with_global_in_the_middle_of_a_string
$global_var_for_testing = 'Title'

assert_equal("\"title 'Title'. \"\n",
render("\"title '\#$global_var_for_testing'. \""))
end

def test_interpolation_at_the_beginning_of_a_line
assert_equal("<p>2</p>\n", render('%p #{1 + 1}'))
assert_equal("<p>\n 2\n</p>\n", render("%p\n \#{1 + 1}"))
end

def test_interpolation_with_instance_var_at_the_beginning_of_a_line
scope = Object.new
scope.instance_variable_set(:@foo, 2)

assert_equal("<p>2</p>\n", render('%p #@foo', :scope => scope))
assert_equal("<p>\n 2\n</p>\n", render("%p\n \#@foo", :scope => scope))
end

def test_interpolation_with_global_at_the_beginning_of_a_line
$global_var_for_testing = 2

assert_equal("<p>2</p>\n", render('%p #$global_var_for_testing'))
assert_equal("<p>\n 2\n</p>\n", render("%p\n \#$global_var_for_testing"))
end

def test_escaped_interpolation
assert_equal("<p>Foo &amp; Bar & Baz</p>\n", render('%p& Foo #{"&"} Bar & Baz'))
end
Expand Down

0 comments on commit 7c0b082

Please sign in to comment.