[Haml] [html2haml] Transform inline ERB into Ruby interpolation.

This commit is contained in:
Nathan Weizenbaum 2009-10-05 16:24:38 -07:00
parent ff0bdd254c
commit 0138b212c5
3 changed files with 59 additions and 2 deletions

View File

@ -40,6 +40,20 @@ including the line number and the offending character.
The same is true for inline ERB when running in ERB mode.
`<p><%= foo %></p>` will now become `%p= foo`.
* ERB included within text is now transformed into Ruby interpolation.
For example:
<p>
Foo <%= bar %> baz!
Flip <%= bang %>.
</p>
is now transformed into:
%p
Foo #{bar} baz!
Flip #{bang}.
* Attributes are now output in a more-standard format,
without spaces within the curly braces
(e.g. `%p{:foo => "bar"}` as opposed to `%p{ :foo => "bar" }`).

View File

@ -9,12 +9,34 @@ module Haml
# A module containing utility methods that every Hpricot node
# should have.
module Node
# Whether this node has already been converted to Haml.
# Only used for text nodes and elements.
#
# @return [Boolean]
attr_accessor :converted_to_haml
# Returns the Haml representation of the given node.
#
# @param tabs [Fixnum] The indentation level of the resulting Haml.
# @option options (see Haml::HTML#initialize)
def to_haml(tabs, options)
parse_text(self.to_s, tabs)
return "" if converted_to_haml || to_s.strip.empty?
text = uninterp(self.to_s)
node = next_node
while node.is_a?(::Hpricot::Elem) && node.name == "haml:loud"
node.converted_to_haml = true
text << '#{' <<
CGI.unescapeHTML(node.inner_text).gsub(/\n\s*/, ' ').strip << '}'
if node.next_node.is_a?(::Hpricot::Text)
node = node.next_node
text << uninterp(node.to_s)
node.converted_to_haml = true
end
node = node.next_node
end
return parse_text_with_interpolation(text, tabs)
end
private
@ -23,9 +45,16 @@ module Haml
' ' * tabs
end
def uninterp(text)
text.gsub('#{', '\#{') #'
end
def parse_text(text, tabs)
parse_text_with_interpolation(uninterp(text), tabs)
end
def parse_text_with_interpolation(text, tabs)
text.strip!
text.gsub!('#{', '\#{') #'
return "" if text.empty?
text.split("\n").map do |line|
@ -165,6 +194,8 @@ module Haml
class ::Hpricot::Elem
# @see Haml::HTML::Node#to_haml
def to_haml(tabs, options)
return "" if converted_to_haml
output = "#{tabulate(tabs)}"
if options[:erb] && name[0...5] == 'haml:'
return output + send("haml_tag_#{name[5..-1]}", CGI.unescapeHTML(self.inner_text))

View File

@ -122,6 +122,18 @@ HAML
HTML
end
def test_erb_in_line
assert_equal 'foo bar #{baz}', render_erb('foo bar <%= baz %>')
assert_equal 'foo bar #{baz}! Bang.', render_erb('foo bar <%= baz %>! Bang.')
end
def test_erb_multi_in_line
assert_equal('foo bar #{baz}! Bang #{bop}.',
render_erb('foo bar <%= baz %>! Bang <%= bop %>.'))
assert_equal('foo bar #{baz}#{bop}!',
render_erb('foo bar <%= baz %><%= bop %>!'))
end
def test_erb_with_html_special_chars
assert_equal '= 3 < 5 ? "OK" : "Your computer is b0rken"',
render_erb('<%= 3 < 5 ? "OK" : "Your computer is b0rken" %>')