haml-edge 2.3.55 → 2.3.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/EDGE_GEM_VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.55
1
+ 2.3.56
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.55
1
+ 2.3.56
data/lib/haml/exec.rb CHANGED
@@ -387,12 +387,20 @@ Description: Transforms an HTML file into corresponding Haml code.
387
387
  Options:
388
388
  END
389
389
 
390
- opts.on('-r', '--rhtml', 'Parse RHTML tags.') do
391
- @module_opts[:rhtml] = true
390
+ opts.on('-e', '--erb', 'Parse ERb tags.') do
391
+ @module_opts[:erb] = true
392
392
  end
393
393
 
394
- opts.on('--no-rhtml', "Don't parse RHTML tags.") do
395
- @options[:no_rhtml] = true
394
+ opts.on('--no-erb', "Don't parse ERb tags.") do
395
+ @options[:no_erb] = true
396
+ end
397
+
398
+ opts.on('-r', '--rhtml', 'Deprecated; same as --erb.') do
399
+ @module_opts[:erb] = true
400
+ end
401
+
402
+ opts.on('--no-rhtml', "Deprecated; same as --no-erb.") do
403
+ @options[:no_erb] = true
396
404
  end
397
405
 
398
406
  opts.on('-x', '--xhtml', 'Parse the input using the more strict XHTML parser.') do
@@ -410,8 +418,8 @@ END
410
418
  input = @options[:input]
411
419
  output = @options[:output]
412
420
 
413
- @module_opts[:rhtml] ||= input.respond_to?(:path) && input.path =~ /\.(rhtml|erb)$/
414
- @module_opts[:rhtml] &&= @options[:no_rhtml] != false
421
+ @module_opts[:erb] ||= input.respond_to?(:path) && input.path =~ /\.(rhtml|erb)$/
422
+ @module_opts[:erb] &&= @options[:no_erb] != false
415
423
 
416
424
  output.write(::Haml::HTML.new(input, @module_opts).render)
417
425
  rescue ::Haml::Error => e
data/lib/haml/filters.rb CHANGED
@@ -271,7 +271,7 @@ END
271
271
  end
272
272
  end
273
273
 
274
- # Parses the filtered text with ERB, like an RHTML template.
274
+ # Parses the filtered text with ERB.
275
275
  # Not available if the {file:HAML_REFERENCE.md#suppress_eval-option `:suppress_eval`} option is set to true.
276
276
  # Embedded Ruby code is evaluated in the same context as the Haml template.
277
277
  module ERB
@@ -0,0 +1,71 @@
1
+ require 'cgi'
2
+ require 'erubis'
3
+ require 'ruby_parser'
4
+
5
+ module Haml
6
+ class HTML
7
+ class ERB < Erubis::Basic::Engine
8
+ def self.compile(template)
9
+ new(template).src
10
+ end
11
+
12
+ def escaped_expr(code)
13
+ raise "html2haml doesn't support escaped expressions."
14
+ end
15
+
16
+ def add_preamble(src); end
17
+ def add_postamble(src); end
18
+
19
+ def add_text(src, text)
20
+ src << text
21
+ end
22
+
23
+ def add_stmt(src, code)
24
+ src << '</haml:block>' if block_closer?(code) || mid_block?(code)
25
+ src << '<haml:silent>' << h(code) << '</haml:silent>' unless code.strip == "end"
26
+ src << '<haml:block>' if block_opener?(code) || mid_block?(code)
27
+ end
28
+
29
+ def add_expr_literal(src, code)
30
+ src << '<haml:loud>' << h(code) << '</haml:loud>'
31
+ src << '<haml:block>' if block_opener?(code)
32
+ end
33
+
34
+ def add_expr_debug(src, code)
35
+ raise "html2haml doesn't support debugging expressions."
36
+ end
37
+
38
+ private
39
+
40
+ def h(code)
41
+ CGI.escapeHTML(code)
42
+ end
43
+
44
+ # Returns whether the code is valid Ruby code on its own
45
+ def valid_ruby?(code)
46
+ RubyParser.new.parse(code)
47
+ rescue Racc::ParseError => e
48
+ false
49
+ end
50
+
51
+ # Checks if the Ruby code opens a block
52
+ def block_opener?(code)
53
+ valid_ruby?(code + "\nend") ||
54
+ valid_ruby?(code + "\nwhen foo\nend")
55
+ end
56
+
57
+ # Checks if the Ruby code closes a block
58
+ def block_closer?(code)
59
+ valid_ruby?("begin\n" + code)
60
+ end
61
+
62
+ # Checks if the Ruby code comes in the middle of a block
63
+ def mid_block?(code)
64
+ return if valid_ruby?(code)
65
+ valid_ruby?("if foo\n#{code}\nend") || # else, elsif
66
+ valid_ruby?("begin\n#{code}\nend") || # rescue, ensure
67
+ valid_ruby?("case foo\n#{code}\nend") # when
68
+ end
69
+ end
70
+ end
71
+ end
data/lib/haml/html.rb CHANGED
@@ -9,33 +9,71 @@ module Haml
9
9
  # A module containing utility methods that every Hpricot node
10
10
  # should have.
11
11
  module Node
12
+ # Whether this node has already been converted to Haml.
13
+ # Only used for text nodes and elements.
14
+ #
15
+ # @return [Boolean]
16
+ attr_accessor :converted_to_haml
17
+
12
18
  # Returns the Haml representation of the given node.
13
19
  #
14
20
  # @param tabs [Fixnum] The indentation level of the resulting Haml.
15
21
  # @option options (see Haml::HTML#initialize)
16
22
  def to_haml(tabs, options)
17
- parse_text(self.to_s, tabs)
23
+ return "" if converted_to_haml || to_s.strip.empty?
24
+ text = uninterp(self.to_s)
25
+ node = next_node
26
+ while node.is_a?(::Hpricot::Elem) && node.name == "haml:loud"
27
+ node.converted_to_haml = true
28
+ text << '#{' <<
29
+ CGI.unescapeHTML(node.inner_text).gsub(/\n\s*/, ' ').strip << '}'
30
+
31
+ if node.next_node.is_a?(::Hpricot::Text)
32
+ node = node.next_node
33
+ text << uninterp(node.to_s)
34
+ node.converted_to_haml = true
35
+ end
36
+
37
+ node = node.next_node
38
+ end
39
+ return parse_text_with_interpolation(text, tabs)
18
40
  end
19
41
 
20
42
  private
21
43
 
44
+ def erb_to_interpolation(text, options)
45
+ return text unless options[:erb]
46
+ text = CGI.escapeHTML(uninterp(text))
47
+ %w[<haml:loud> </haml:loud>].each {|str| text.gsub!(CGI.escapeHTML(str), str)}
48
+ ::Hpricot::XML(text).children.inject("") do |str, elem|
49
+ if elem.is_a?(::Hpricot::Text)
50
+ str + CGI.unescapeHTML(elem.to_s)
51
+ else # <haml:loud> element
52
+ str + '#{' + CGI.unescapeHTML(elem.innerText.strip) + '}'
53
+ end
54
+ end
55
+ end
56
+
22
57
  def tabulate(tabs)
23
58
  ' ' * tabs
24
59
  end
25
60
 
61
+ def uninterp(text)
62
+ text.gsub('#{', '\#{') #'
63
+ end
64
+
26
65
  def parse_text(text, tabs)
66
+ parse_text_with_interpolation(uninterp(text), tabs)
67
+ end
68
+
69
+ def parse_text_with_interpolation(text, tabs)
27
70
  text.strip!
28
- text.gsub!('#{', '\#{') #'
29
- if text.empty?
30
- String.new
31
- else
32
- lines = text.split("\n")
71
+ return "" if text.empty?
33
72
 
34
- lines.map do |line|
35
- line.strip!
36
- "#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
37
- end.join
38
- end
73
+ text.split("\n").map do |line|
74
+ line.strip!
75
+ "#{tabulate(tabs)}#{'\\' if Haml::Engine::SPECIAL_CHARACTERS.include?(line[0])}#{line}\n"
76
+ end.join
39
77
  end
40
78
  end
41
79
  end
@@ -67,7 +105,7 @@ module Haml
67
105
  # #=> "%a{:href => 'http://google.com'} Blat"
68
106
  class HTML
69
107
  # @param template [String, Hpricot::Node] The HTML template to convert
70
- # @option options :rhtml [Boolean] (false) Whether or not to parse
108
+ # @option options :erb [Boolean] (false) Whether or not to parse
71
109
  # ERB's `<%= %>` and `<% %>` into Haml's `=` and `-`
72
110
  # @option options :xhtml [Boolean] (false) Whether or not to parse
73
111
  # the HTML strictly as XHTML
@@ -83,9 +121,9 @@ module Haml
83
121
 
84
122
  Haml::Util.check_encoding(template) {|msg, line| raise Haml::Error.new(msg, line)}
85
123
 
86
- if @options[:rhtml]
87
- match_to_html(template, /<%=(.*?)-?%>/m, 'loud')
88
- match_to_html(template, /<%-?(.*?)-?%>/m, 'silent')
124
+ if @options[:erb]
125
+ require 'haml/html/erb'
126
+ template = ERB.compile(template)
89
127
  end
90
128
 
91
129
  method = @options[:xhtml] ? Hpricot.method(:XML) : method(:Hpricot)
@@ -122,7 +160,9 @@ module Haml
122
160
  class ::Hpricot::CData
123
161
  # @see Haml::HTML::Node#to_haml
124
162
  def to_haml(tabs, options)
125
- "#{tabulate(tabs)}:cdata\n#{parse_text(self.content, tabs + 1)}"
163
+ content = parse_text_with_interpolation(
164
+ erb_to_interpolation(self.content, options), tabs + 1)
165
+ "#{tabulate(tabs)}:cdata\n#{content}"
126
166
  end
127
167
  end
128
168
 
@@ -161,7 +201,17 @@ module Haml
161
201
  class ::Hpricot::Comment
162
202
  # @see Haml::HTML::Node#to_haml
163
203
  def to_haml(tabs, options)
164
- "#{tabulate(tabs)}/\n#{parse_text(self.content, tabs + 1)}"
204
+ content = self.content
205
+ if content =~ /\A(\[[^\]]+\])>(.*)<!\[endif\]\z/m
206
+ condition = $1
207
+ content = $2
208
+ end
209
+
210
+ if content.include?("\n")
211
+ "#{tabulate(tabs)}/#{condition}\n#{parse_text(content, tabs + 1)}"
212
+ else
213
+ "#{tabulate(tabs)}/#{condition} #{content.strip}"
214
+ end
165
215
  end
166
216
  end
167
217
 
@@ -169,32 +219,78 @@ module Haml
169
219
  class ::Hpricot::Elem
170
220
  # @see Haml::HTML::Node#to_haml
171
221
  def to_haml(tabs, options)
172
- output = "#{tabulate(tabs)}"
173
- if options[:rhtml] && name[0...5] == 'haml:'
174
- return output + send("haml_tag_#{name[5..-1]}", CGI.unescapeHTML(self.inner_text))
222
+ return "" if converted_to_haml
223
+ if name == "script" &&
224
+ (attributes['type'].nil? || attributes['type'] == "text/javascript") &&
225
+ (attributes.keys - ['type']).empty?
226
+ return script_to_haml(tabs, options)
227
+ end
228
+
229
+ output = tabulate(tabs)
230
+ if options[:erb] && name[0...5] == 'haml:'
231
+ case name[5..-1]
232
+ when "loud"
233
+ return output + "= #{CGI.unescapeHTML(inner_text).gsub(/\n\s*/, ' ').strip}\n"
234
+ when "silent"
235
+ return CGI.unescapeHTML(inner_text).split("\n").map do |line|
236
+ next "" if line.strip.empty?
237
+ "#{output}- #{line.strip}\n"
238
+ end.join
239
+ when "block"
240
+ return render_children("", tabs, options)
241
+ end
175
242
  end
176
243
 
177
- output += "%#{name}" unless name == 'div' &&
178
- (static_id?(options) || static_classname?(options))
244
+ output << "%#{name}" unless name == 'div' &&
245
+ (static_id?(options) ||
246
+ static_classname?(options) &&
247
+ attributes['class'].split(' ').any?(&method(:haml_css_attr?)))
179
248
 
180
249
  if attributes
181
250
  if static_id?(options)
182
- output += "##{attributes['id']}"
251
+ output << "##{attributes['id']}"
183
252
  remove_attribute('id')
184
253
  end
185
254
  if static_classname?(options)
186
- attributes['class'].split(' ').each { |c| output += ".#{c}" }
255
+ leftover = attributes['class'].split(' ').reject do |c|
256
+ next unless haml_css_attr?(c)
257
+ output << ".#{c}"
258
+ end
187
259
  remove_attribute('class')
260
+ set_attribute('class', leftover.join(' ')) unless leftover.empty?
188
261
  end
189
- output += haml_attributes(options) if attributes.length > 0
262
+ output << haml_attributes(options) if attributes.length > 0
190
263
  end
191
264
 
192
- (self.children || []).inject(output + "\n") do |output, child|
193
- output + child.to_haml(tabs + 1, options)
265
+ output << "/" if empty? && !etag
266
+
267
+ if children && children.size == 1
268
+ child = children.first
269
+ if child.is_a?(::Hpricot::Text)
270
+ if !child.to_s.include?("\n")
271
+ text = child.to_haml(tabs + 1, options)
272
+ return output + " " + text.lstrip unless text.chomp.include?("\n")
273
+ return output + "\n" + text
274
+ elsif ["pre", "textarea"].include?(name) ||
275
+ (name == "code" && parent.is_a?(::Hpricot::Elem) && parent.name == "pre")
276
+ return output + "\n#{tabulate(tabs + 1)}:preserve\n" +
277
+ innerText.gsub(/^/, tabulate(tabs + 2))
278
+ end
279
+ elsif child.is_a?(::Hpricot::Elem) && child.name == "haml:loud"
280
+ return output + child.to_haml(tabs + 1, options).lstrip
281
+ end
194
282
  end
283
+
284
+ render_children(output + "\n", tabs, options)
195
285
  end
196
286
 
197
287
  private
288
+
289
+ def render_children(so_far, tabs, options)
290
+ (self.children || []).inject(so_far) do |output, child|
291
+ output + child.to_haml(tabs + 1, options)
292
+ end
293
+ end
198
294
 
199
295
  def dynamic_attributes
200
296
  @dynamic_attributes ||= begin
@@ -211,47 +307,53 @@ module Haml
211
307
  end
212
308
  end
213
309
 
214
- def haml_tag_loud(text)
215
- "= #{text.gsub(/\n\s*/, ' ').strip}\n"
216
- end
310
+ def script_to_haml(tabs, options)
311
+ content =
312
+ if children.first.is_a?(::Hpricot::CData)
313
+ children.first.content
314
+ else
315
+ CGI.unescapeHTML(self.innerText)
316
+ end
317
+
318
+ content = erb_to_interpolation(content, options)
319
+ content.gsub!(/\A\s*\n(\s*)/, '\1')
320
+ original_indent = content[/\A(\s*)/, 1]
321
+ if content.split("\n").all? {|l| l.strip.empty? || l =~ /^#{original_indent}/}
322
+ content.gsub!(/^#{original_indent}/, tabulate(tabs + 1))
323
+ end
217
324
 
218
- def haml_tag_silent(text)
219
- text.split("\n").map { |line| "- #{line.strip}\n" }.join
325
+ "#{tabulate(tabs)}:javascript\n#{content}"
220
326
  end
221
327
 
222
328
  def static_attribute?(name, options)
223
- attributes[name] and !dynamic_attribute?(name, options)
329
+ attributes[name] && !dynamic_attribute?(name, options)
224
330
  end
225
331
 
226
332
  def dynamic_attribute?(name, options)
227
- options[:rhtml] and dynamic_attributes.key?(name)
333
+ options[:erb] and dynamic_attributes.key?(name)
228
334
  end
229
335
 
230
336
  def static_id?(options)
231
- static_attribute?('id', options)
337
+ static_attribute?('id', options) && haml_css_attr?(attributes['id'])
232
338
  end
233
339
 
234
340
  def static_classname?(options)
235
341
  static_attribute?('class', options)
236
342
  end
237
343
 
344
+ def haml_css_attr?(attr)
345
+ attr =~ /^[-:\w]+$/
346
+ end
347
+
238
348
  # Returns a string representation of an attributes hash
239
349
  # that's prettier than that produced by Hash#inspect
240
350
  def haml_attributes(options)
241
- attrs = attributes.map do |name, value|
351
+ attrs = attributes.sort.map do |name, value|
242
352
  value = dynamic_attribute?(name, options) ? dynamic_attributes[name] : value.inspect
243
353
  name = name.index(/\W/) ? name.inspect : ":#{name}"
244
354
  "#{name} => #{value}"
245
355
  end
246
- "{ #{attrs.join(', ')} }"
247
- end
248
- end
249
-
250
- private
251
-
252
- def match_to_html(string, regex, tag)
253
- string.gsub!(regex) do
254
- "<haml:#{tag}>#{CGI.escapeHTML($1)}</haml:#{tag}>"
356
+ "{#{attrs.join(', ')}}"
255
357
  end
256
358
  end
257
359
  end
data/test/benchmark.rb CHANGED
@@ -40,7 +40,7 @@ RBench.run(times) do
40
40
  template_name = 'standard'
41
41
  directory = File.dirname(__FILE__) + '/haml'
42
42
  haml_template = File.read("#{directory}/templates/#{template_name}.haml")
43
- erb_template = File.read("#{directory}/rhtml/#{template_name}.rhtml")
43
+ erb_template = File.read("#{directory}/erb/#{template_name}.erb")
44
44
  markaby_template = File.read("#{directory}/markaby/#{template_name}.mab")
45
45
 
46
46
  report "Cached" do
@@ -64,10 +64,10 @@ RBench.run(times) do
64
64
  Haml::Template.options[:ugly] = false
65
65
  # To cache the template
66
66
  render @base, 'haml/templates/standard'
67
- render @base, 'haml/rhtml/standard'
67
+ render @base, 'haml/erb/standard'
68
68
 
69
69
  haml { render @base, 'haml/templates/standard' }
70
- erb { render @base, 'haml/rhtml/standard' }
70
+ erb { render @base, 'haml/erb/standard' }
71
71
 
72
72
  Haml::Template.options[:ugly] = true
73
73
  render @base, 'haml/templates/standard_ugly'
@@ -81,10 +81,10 @@ RBench.run(times) do
81
81
  Haml::Template.options[:ugly] = false
82
82
  # To cache the template
83
83
  render @base, 'haml/templates/action_view'
84
- render @base, 'haml/rhtml/action_view'
84
+ render @base, 'haml/erb/action_view'
85
85
 
86
86
  haml { render @base, 'haml/templates/action_view' }
87
- erb { render @base, 'haml/rhtml/action_view' }
87
+ erb { render @base, 'haml/erb/action_view' }
88
88
 
89
89
  Haml::Template.options[:ugly] = true
90
90
  render @base, 'haml/templates/action_view_ugly'
@@ -6,7 +6,7 @@
6
6
  <li>
7
7
  <strong>Partial:</strong>
8
8
  <% @nesting = 5 %>
9
- <%= render :partial => 'haml/rhtml/av_partial_2' %>
9
+ <%= render :partial => 'haml/erb/av_partial_2' %>
10
10
  <% end %>
11
11
  </ul>
12
12
  </div>
@@ -3,6 +3,6 @@
3
3
  <h3>This is a crazy deep-nested partial.</h3>
4
4
  <p>Nesting level <%= @nesting %></p>
5
5
  <% if @nesting > 0 %>
6
- <%= render :partial => 'haml/rhtml/av_partial_2' %>
6
+ <%= render :partial => 'haml/erb/av_partial_2' %>
7
7
  <% end %>
8
8
  </div>
File without changes
@@ -3,7 +3,6 @@ require File.dirname(__FILE__) + '/../test_helper'
3
3
  require 'haml/html'
4
4
 
5
5
  class Html2HamlTest < Test::Unit::TestCase
6
-
7
6
  def test_empty_render_should_remain_empty
8
7
  assert_equal '', render('')
9
8
  end
@@ -22,14 +21,21 @@ class Html2HamlTest < Test::Unit::TestCase
22
21
  end
23
22
 
24
23
  def test_should_have_pretty_attributes
25
- assert_equal_attributes('%input{ :type => "text", :name => "login" }',
24
+ assert_equal('%input{:name => "login", :type => "text"}/',
26
25
  render('<input type="text" name="login" />'))
27
- assert_equal_attributes('%meta{ "http-equiv" => "Content-Type", :content => "text/html" }',
26
+ assert_equal('%meta{:content => "text/html", "http-equiv" => "Content-Type"}/',
28
27
  render('<meta http-equiv="Content-Type" content="text/html" />'))
29
28
  end
30
29
 
31
- def test_sqml_comment
32
- assert_equal "/\n IE sucks", render('<!-- IE sucks -->')
30
+ def test_class_with_dot_and_hash
31
+ assert_equal('%div{:class => "foo.bar"}', render("<div class='foo.bar'></div>"))
32
+ assert_equal('%div{:class => "foo#bar"}', render("<div class='foo#bar'></div>"))
33
+ assert_equal('.foo.bar{:class => "foo#bar foo.bar"}', render("<div class='foo foo#bar bar foo.bar'></div>"))
34
+ end
35
+
36
+ def test_id_with_dot_and_hash
37
+ assert_equal('%div{:id => "foo.bar"}', render("<div id='foo.bar'></div>"))
38
+ assert_equal('%div{:id => "foo#bar"}', render("<div id='foo#bar'></div>"))
33
39
  end
34
40
 
35
41
  def test_interpolation
@@ -37,54 +43,7 @@ class Html2HamlTest < Test::Unit::TestCase
37
43
  end
38
44
 
39
45
  def test_interpolation_in_attrs
40
- assert_equal('%p{ :foo => "\#{bar} baz" }', render('<p foo="#{bar} baz"></p>'))
41
- end
42
-
43
- def test_rhtml
44
- assert_equal '- foo = bar', render_rhtml('<% foo = bar %>')
45
- assert_equal '- foo = bar', render_rhtml('<% foo = bar -%>')
46
- assert_equal '= h @item.title', render_rhtml('<%=h @item.title %>')
47
- assert_equal '= h @item.title', render_rhtml('<%=h @item.title -%>')
48
- end
49
-
50
- def test_rhtml_with_html_special_chars
51
- assert_equal '= 3 < 5 ? "OK" : "Your computer is b0rken"',
52
- render_rhtml(%Q{<%= 3 < 5 ? "OK" : "Your computer is b0rken" %>})
53
- end
54
-
55
- def test_rhtml_in_class_attribute
56
- assert_equal "%div{ :class => dyna_class }\n I have a dynamic attribute",
57
- render_rhtml(%Q{<div class="<%= dyna_class %>">I have a dynamic attribute</div>})
58
- end
59
-
60
- def test_rhtml_in_id_attribute
61
- assert_equal "%div{ :id => dyna_id }\n I have a dynamic attribute",
62
- render_rhtml(%Q{<div id="<%= dyna_id %>">I have a dynamic attribute</div>})
63
- end
64
-
65
- def test_rhtml_in_attribute_results_in_string_interpolation
66
- assert_equal %(%div{ :id => "item_\#{i}" }\n Ruby string interpolation FTW),
67
- render_rhtml(%Q{<div id="item_<%= i %>">Ruby string interpolation FTW</div>})
68
- end
69
-
70
- def test_rhtml_in_attribute_with_trailing_content
71
- assert_equal %(%div{ :class => "\#{12}!" }\n Bang!),
72
- render_rhtml(%Q{<div class="<%= 12 %>!">Bang!</div>})
73
- end
74
-
75
- def test_rhtml_in_html_escaped_attribute
76
- assert_equal %(%div{ :class => "foo" }\n Bang!),
77
- render_rhtml(%Q{<div class="<%= "foo" %>">Bang!</div>})
78
- end
79
-
80
- def test_rhtml_in_attribute_to_multiple_interpolations
81
- assert_equal %(%div{ :class => "\#{12} + \#{13}" }\n Math is super),
82
- render_rhtml(%Q{<div class="<%= 12 %> + <%= 13 %>">Math is super</div>})
83
- end
84
-
85
- def test_whitespace_eating_erb_tags
86
- assert_equal %(- form_for),
87
- render_rhtml(%Q{<%- form_for -%>})
46
+ assert_equal('%p{:foo => "\#{bar} baz"}', render('<p foo="#{bar} baz"></p>'))
88
47
  end
89
48
 
90
49
  def test_cdata
@@ -103,13 +62,443 @@ HAML
103
62
  HTML
104
63
  end
105
64
 
106
- def test_interpolation_in_rhtml
107
- assert_equal('= "Foo #{bar} baz"', render_rhtml('<%= "Foo #{bar} baz" %>'))
65
+ def test_self_closing_tag
66
+ assert_equal("%foo/", render("<foo />"))
67
+ end
68
+
69
+ def test_inline_text
70
+ assert_equal("%p foo", render("<p>foo</p>"))
71
+ end
72
+
73
+ def test_inline_comment
74
+ assert_equal("/ foo", render("<!-- foo -->"))
75
+ end
76
+
77
+ def test_non_inline_comment
78
+ assert_equal(<<HAML.rstrip, render(<<HTML))
79
+ /
80
+ Foo
81
+ Bar
82
+ HAML
83
+ <!-- Foo
84
+ Bar -->
85
+ HTML
86
+ end
87
+
88
+ def test_non_inline_text
89
+ assert_equal(<<HAML.rstrip, render(<<HTML))
90
+ %p
91
+ foo
92
+ HAML
93
+ <p>
94
+ foo
95
+ </p>
96
+ HTML
97
+ assert_equal(<<HAML.rstrip, render(<<HTML))
98
+ %p
99
+ foo
100
+ HAML
101
+ <p>
102
+ foo</p>
103
+ HTML
104
+ assert_equal(<<HAML.rstrip, render(<<HTML))
105
+ %p
106
+ foo
107
+ HAML
108
+ <p>foo
109
+ </p>
110
+ HTML
111
+ end
112
+
113
+ def test_script_tag
114
+ assert_equal(<<HAML.rstrip, render(<<HTML))
115
+ :javascript
116
+ function foo() {
117
+ return "12" & "13";
118
+ }
119
+ HAML
120
+ <script type="text/javascript">
121
+ function foo() {
122
+ return "12" &amp; "13";
123
+ }
124
+ </script>
125
+ HTML
126
+ end
127
+
128
+ def test_script_tag_with_cdata
129
+ assert_equal(<<HAML.rstrip, render(<<HTML))
130
+ :javascript
131
+ function foo() {
132
+ return "&amp;";
133
+ }
134
+ HAML
135
+ <script type="text/javascript">
136
+ <![CDATA[
137
+ function foo() {
138
+ return "&amp;";
139
+ }
140
+ ]]>
141
+ </script>
142
+ HTML
143
+ end
144
+
145
+ def test_pre
146
+ assert_equal(<<HAML.rstrip, render(<<HTML))
147
+ %pre
148
+ :preserve
149
+ foo
150
+ bar
151
+ baz
152
+ HAML
153
+ <pre>foo
154
+ bar
155
+ baz</pre>
156
+ HTML
157
+ end
158
+
159
+ def test_pre_code
160
+ assert_equal(<<HAML.rstrip, render(<<HTML))
161
+ %pre
162
+ %code
163
+ :preserve
164
+ foo
165
+ bar
166
+ baz
167
+ HAML
168
+ <pre><code>foo
169
+ bar
170
+ baz</code></pre>
171
+ HTML
172
+ end
173
+
174
+ def test_code_without_pre
175
+ assert_equal(<<HAML.rstrip, render(<<HTML))
176
+ %code
177
+ foo
178
+ bar
179
+ baz
180
+ HAML
181
+ <code>foo
182
+ bar
183
+ baz</code>
184
+ HTML
185
+ end
186
+
187
+ def test_conditional_comment
188
+ assert_equal(<<HAML.rstrip, render(<<HTML))
189
+ /[if foo]
190
+ bar
191
+ baz
192
+ HAML
193
+ <!--[if foo]>
194
+ bar
195
+ baz
196
+ <![endif]-->
197
+ HTML
198
+ end
199
+
200
+ def test_inline_conditional_comment
201
+ assert_equal(<<HAML.rstrip, render(<<HTML))
202
+ /[if foo] bar baz
203
+ HAML
204
+ <!--[if foo]> bar baz <![endif]-->
205
+ HTML
206
+ end
207
+
208
+ ## ERB
209
+
210
+ def test_erb
211
+ assert_equal '- foo = bar', render_erb('<% foo = bar %>')
212
+ assert_equal '- foo = bar', render_erb('<% foo = bar -%>')
213
+ assert_equal '= h @item.title', render_erb('<%=h @item.title %>')
214
+ assert_equal '= h @item.title', render_erb('<%=h @item.title -%>')
215
+ end
216
+
217
+ def test_inline_erb
218
+ assert_equal("%p= foo", render_erb("<p><%= foo %></p>"))
219
+ end
220
+
221
+ def test_non_inline_erb
222
+ assert_equal(<<HAML.rstrip, render_erb(<<HTML))
223
+ %p
224
+ = foo
225
+ HAML
226
+ <p>
227
+ <%= foo %>
228
+ </p>
229
+ HTML
230
+ assert_equal(<<HAML.rstrip, render_erb(<<HTML))
231
+ %p
232
+ = foo
233
+ HAML
234
+ <p>
235
+ <%= foo %></p>
236
+ HTML
237
+ assert_equal(<<HAML.rstrip, render_erb(<<HTML))
238
+ %p
239
+ = foo
240
+ HAML
241
+ <p><%= foo %>
242
+ </p>
243
+ HTML
244
+ end
245
+
246
+ def test_erb_in_cdata
247
+ assert_equal(<<HAML.rstrip, render_erb(<<HTML))
248
+ :cdata
249
+ Foo \#{bar} baz
250
+ HAML
251
+ <![CDATA[Foo <%= bar %> baz]]>
252
+ HTML
253
+ end
254
+
255
+ def test_erb_in_script
256
+ assert_equal(<<HAML.rstrip, render_erb(<<HTML))
257
+ :javascript
258
+ function foo() {
259
+ return \#{foo.to_json};
260
+ }
261
+ HAML
262
+ <script type="text/javascript">
263
+ function foo() {
264
+ return <%= foo.to_json %>;
265
+ }
266
+ </script>
267
+ HTML
268
+ end
269
+
270
+ def test_erb_in_line
271
+ assert_equal 'foo bar #{baz}', render_erb('foo bar <%= baz %>')
272
+ assert_equal 'foo bar #{baz}! Bang.', render_erb('foo bar <%= baz %>! Bang.')
108
273
  end
109
274
 
110
- def test_interpolation_in_rhtml_attrs
111
- assert_equal('%p{ :foo => "#{bar} baz" }',
112
- render_rhtml('<p foo="<%= "#{bar} baz" %>"></p>'))
275
+ def test_erb_multi_in_line
276
+ assert_equal('foo bar #{baz}! Bang #{bop}.',
277
+ render_erb('foo bar <%= baz %>! Bang <%= bop %>.'))
278
+ assert_equal('foo bar #{baz}#{bop}!',
279
+ render_erb('foo bar <%= baz %><%= bop %>!'))
280
+ end
281
+
282
+ def test_erb_with_html_special_chars
283
+ assert_equal '= 3 < 5 ? "OK" : "Your computer is b0rken"',
284
+ render_erb('<%= 3 < 5 ? "OK" : "Your computer is b0rken" %>')
285
+ end
286
+
287
+ def test_erb_in_class_attribute
288
+ assert_equal "%div{:class => dyna_class} I have a dynamic attribute",
289
+ render_erb('<div class="<%= dyna_class %>">I have a dynamic attribute</div>')
290
+ end
291
+
292
+ def test_erb_in_id_attribute
293
+ assert_equal "%div{:id => dyna_id} I have a dynamic attribute",
294
+ render_erb('<div id="<%= dyna_id %>">I have a dynamic attribute</div>')
295
+ end
296
+
297
+ def test_erb_in_attribute_results_in_string_interpolation
298
+ assert_equal('%div{:id => "item_#{i}"} Ruby string interpolation FTW',
299
+ render_erb('<div id="item_<%= i %>">Ruby string interpolation FTW</div>'))
300
+ end
301
+
302
+ def test_erb_in_attribute_with_trailing_content
303
+ assert_equal('%div{:class => "#{12}!"} Bang!',
304
+ render_erb('<div class="<%= 12 %>!">Bang!</div>'))
305
+ end
306
+
307
+ def test_erb_in_html_escaped_attribute
308
+ assert_equal '%div{:class => "foo"} Bang!',
309
+ render_erb('<div class="<%= "foo" %>">Bang!</div>')
310
+ end
311
+
312
+ def test_erb_in_attribute_to_multiple_interpolations
313
+ assert_equal('%div{:class => "#{12} + #{13}"} Math is super',
314
+ render_erb('<div class="<%= 12 %> + <%= 13 %>">Math is super</div>'))
315
+ end
316
+
317
+ def test_whitespace_eating_erb_tags
318
+ assert_equal '- form_for', render_erb('<%- form_for -%>')
319
+ end
320
+
321
+ def test_interpolation_in_erb
322
+ assert_equal('= "Foo #{bar} baz"', render_erb('<%= "Foo #{bar} baz" %>'))
323
+ end
324
+
325
+ def test_interpolation_in_erb_attrs
326
+ assert_equal('%p{:foo => "#{bar} baz"}',
327
+ render_erb('<p foo="<%= "#{bar} baz" %>"></p>'))
328
+ end
329
+
330
+ def test_multiline_erb_silent_script
331
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
332
+ .blah
333
+ - foo
334
+ - bar
335
+ - baz
336
+ %p foo
337
+ HAML
338
+ <div class="blah">
339
+ <%
340
+ foo
341
+ bar
342
+ baz
343
+ %>
344
+ <p>foo</p>
345
+ </div>
346
+ ERB
347
+ end
348
+
349
+ ### Block Parsing
350
+
351
+ def test_block_parsing
352
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
353
+ - foo do
354
+ %p bar
355
+ HAML
356
+ <% foo do %>
357
+ <p>bar</p>
358
+ <% end %>
359
+ ERB
360
+ end
361
+
362
+ def test_block_parsing_with_args
363
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
364
+ - foo do |a, b, c|
365
+ %p bar
366
+ HAML
367
+ <% foo do |a, b, c| %>
368
+ <p>bar</p>
369
+ <% end %>
370
+ ERB
371
+ end
372
+
373
+ def test_block_parsing_with_equals
374
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
375
+ = foo do
376
+ %p bar
377
+ HAML
378
+ <%= foo do %>
379
+ <p>bar</p>
380
+ <% end %>
381
+ ERB
382
+ end
383
+
384
+ def test_block_parsing_with_modified_end
385
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
386
+ - foo do
387
+ blah
388
+ - end.bip
389
+ HAML
390
+ <% foo do %>
391
+ blah
392
+ <% end.bip %>
393
+ ERB
394
+ end
395
+
396
+ def test_block_parsing_with_modified_end_with_block
397
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
398
+ - foo do
399
+ blah
400
+ - end.bip do
401
+ brang
402
+ HAML
403
+ <% foo do %>
404
+ blah
405
+ <% end.bip do %>
406
+ brang
407
+ <% end %>
408
+ ERB
409
+ end
410
+
411
+ def test_multiline_block_opener
412
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
413
+ - foo bar
414
+ - baz bang
415
+ - biddle do
416
+ foo
417
+ HAML
418
+ <% foo bar
419
+ baz bang
420
+ biddle do %>
421
+ foo
422
+ <% end %>
423
+ ERB
424
+ end
425
+
426
+ def test_if_elsif_else_parsing
427
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
428
+ - if foo
429
+ %p bar
430
+ - elsif bar.foo("zip")
431
+ #bang baz
432
+ - else
433
+ %strong bibble
434
+ HAML
435
+ <% if foo %>
436
+ <p>bar</p>
437
+ <% elsif bar.foo("zip") %>
438
+ <div id="bang">baz</div>
439
+ <% else %>
440
+ <strong>bibble</strong>
441
+ <% end %>
442
+ ERB
443
+ end
444
+
445
+ def test_case_when_parsing
446
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
447
+ - case foo.bar
448
+ - when "bip"
449
+ %p bip
450
+ - when "bop"
451
+ %p BOP
452
+ - when bizzle.bang.boop.blip
453
+ %em BIZZLE BANG BOOP BLIP
454
+ HAML
455
+ <% case foo.bar %>
456
+ <% when "bip" %>
457
+ <p>bip</p>
458
+ <% when "bop" %>
459
+ <p>BOP</p>
460
+ <% when bizzle.bang.boop.blip %>
461
+ <em>BIZZLE BANG BOOP BLIP</em>
462
+ <% end %>
463
+ ERB
464
+
465
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
466
+ - case foo.bar
467
+ - when "bip"
468
+ %p bip
469
+ - when "bop"
470
+ %p BOP
471
+ - when bizzle.bang.boop.blip
472
+ %em BIZZLE BANG BOOP BLIP
473
+ HAML
474
+ <% case foo.bar
475
+ when "bip" %>
476
+ <p>bip</p>
477
+ <% when "bop" %>
478
+ <p>BOP</p>
479
+ <% when bizzle.bang.boop.blip %>
480
+ <em>BIZZLE BANG BOOP BLIP</em>
481
+ <% end %>
482
+ ERB
483
+ end
484
+
485
+ def test_begin_rescue_ensure
486
+ assert_equal(<<HAML.rstrip, render_erb(<<ERB))
487
+ - begin
488
+ %p a
489
+ - rescue FooException => e
490
+ %p b
491
+ - ensure
492
+ %p c
493
+ HAML
494
+ <% begin %>
495
+ <p>a</p>
496
+ <% rescue FooException => e %>
497
+ <p>b</p>
498
+ <% ensure %>
499
+ <p>c</p>
500
+ <% end %>
501
+ ERB
113
502
  end
114
503
 
115
504
  # Encodings
@@ -140,13 +529,7 @@ HTML
140
529
  Haml::HTML.new(text, options).render.rstrip
141
530
  end
142
531
 
143
- def render_rhtml(text)
144
- render(text, :rhtml => true)
145
- end
146
-
147
- def assert_equal_attributes(expected, result)
148
- expected_attr, result_attr = [expected, result].map { |s| s.gsub!(/\{ (.+) \}/, ''); $1.split(', ').sort }
149
- assert_equal expected_attr, result_attr
150
- assert_equal expected, result
532
+ def render_erb(text)
533
+ render(text, :erb => true)
151
534
  end
152
535
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml-edge
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.55
4
+ version: 2.3.56
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -73,6 +73,8 @@ files:
73
73
  - lib/haml/template/plugin.rb
74
74
  - lib/haml/util.rb
75
75
  - lib/haml/version.rb
76
+ - lib/haml/html
77
+ - lib/haml/html/erb.rb
76
78
  - lib/sass.rb
77
79
  - lib/sass
78
80
  - lib/sass/css.rb
@@ -148,10 +150,6 @@ files:
148
150
  - test/haml/results/very_basic.xhtml
149
151
  - test/haml/results/whitespace_handling.xhtml
150
152
  - test/haml/rhtml
151
- - test/haml/rhtml/_av_partial_1.rhtml
152
- - test/haml/rhtml/_av_partial_2.rhtml
153
- - test/haml/rhtml/action_view.rhtml
154
- - test/haml/rhtml/standard.rhtml
155
153
  - test/haml/spec
156
154
  - test/haml/spec_test.rb
157
155
  - test/haml/template_test.rb
@@ -188,6 +186,11 @@ files:
188
186
  - test/haml/templates/very_basic.haml
189
187
  - test/haml/templates/whitespace_handling.haml
190
188
  - test/haml/util_test.rb
189
+ - test/haml/erb
190
+ - test/haml/erb/_av_partial_1.erb
191
+ - test/haml/erb/_av_partial_2.erb
192
+ - test/haml/erb/action_view.erb
193
+ - test/haml/erb/standard.rhtml
191
194
  - test/linked_rails.rb
192
195
  - test/sass
193
196
  - test/sass/css2sass_test.rb