haml 1.8.0 → 2.0.3

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.
Files changed (89) hide show
  1. data/FAQ +138 -0
  2. data/MIT-LICENSE +1 -1
  3. data/{README → README.rdoc} +66 -3
  4. data/REVISION +1 -0
  5. data/Rakefile +115 -147
  6. data/VERSION +1 -1
  7. data/bin/css2sass +0 -0
  8. data/bin/haml +2 -1
  9. data/bin/html2haml +0 -0
  10. data/bin/sass +0 -0
  11. data/init.rb +6 -1
  12. data/lib/haml/buffer.rb +122 -64
  13. data/lib/haml/engine.rb +77 -46
  14. data/lib/haml/error.rb +15 -6
  15. data/lib/haml/exec.rb +61 -10
  16. data/lib/haml/filters.rb +229 -74
  17. data/lib/haml/helpers/action_view_extensions.rb +1 -1
  18. data/lib/haml/helpers/action_view_mods.rb +109 -24
  19. data/lib/haml/helpers.rb +137 -76
  20. data/lib/haml/html.rb +8 -8
  21. data/lib/haml/precompiler.rb +280 -153
  22. data/lib/haml/template/patch.rb +10 -3
  23. data/lib/haml/template/plugin.rb +61 -10
  24. data/lib/haml/template.rb +14 -9
  25. data/lib/haml.rb +483 -214
  26. data/lib/sass/constant/color.rb +13 -13
  27. data/lib/sass/constant/literal.rb +8 -7
  28. data/lib/sass/constant/nil.rb +9 -0
  29. data/lib/sass/constant/number.rb +10 -10
  30. data/lib/sass/constant/operation.rb +4 -4
  31. data/lib/sass/constant/string.rb +3 -3
  32. data/lib/sass/constant.rb +46 -77
  33. data/lib/sass/css.rb +130 -56
  34. data/lib/sass/engine.rb +131 -43
  35. data/lib/sass/plugin/merb.rb +48 -12
  36. data/lib/sass/plugin/rails.rb +10 -4
  37. data/lib/sass/plugin.rb +33 -10
  38. data/lib/sass/tree/attr_node.rb +5 -5
  39. data/lib/sass/tree/directive_node.rb +2 -7
  40. data/lib/sass/tree/node.rb +1 -12
  41. data/lib/sass/tree/rule_node.rb +39 -31
  42. data/lib/sass/tree/value_node.rb +1 -1
  43. data/lib/sass.rb +194 -19
  44. data/rails/init.rb +1 -0
  45. data/test/benchmark.rb +67 -80
  46. data/test/haml/engine_test.rb +368 -152
  47. data/test/haml/helper_test.rb +68 -16
  48. data/test/haml/html2haml_test.rb +3 -4
  49. data/test/haml/results/content_for_layout.xhtml +1 -2
  50. data/test/haml/results/eval_suppressed.xhtml +2 -4
  51. data/test/haml/results/filters.xhtml +38 -30
  52. data/test/haml/results/helpers.xhtml +4 -8
  53. data/test/haml/results/just_stuff.xhtml +8 -7
  54. data/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
  55. data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
  56. data/test/haml/results/original_engine.xhtml +3 -7
  57. data/test/haml/results/partials.xhtml +1 -0
  58. data/test/haml/results/tag_parsing.xhtml +1 -6
  59. data/test/haml/results/very_basic.xhtml +2 -4
  60. data/test/haml/results/whitespace_handling.xhtml +13 -21
  61. data/test/haml/template_test.rb +42 -57
  62. data/test/haml/templates/_partial.haml +1 -0
  63. data/test/haml/templates/filters.haml +39 -21
  64. data/test/haml/templates/helpers.haml +10 -10
  65. data/test/haml/templates/just_stuff.haml +8 -3
  66. data/test/haml/templates/nuke_inner_whitespace.haml +32 -0
  67. data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
  68. data/test/haml/templates/partials.haml +1 -1
  69. data/test/haml/templates/tag_parsing.haml +0 -3
  70. data/test/haml/templates/whitespace_handling.haml +10 -10
  71. data/test/sass/engine_test.rb +97 -39
  72. data/test/sass/plugin_test.rb +4 -7
  73. data/test/sass/results/constants.css +2 -0
  74. data/test/sass/results/import.css +2 -2
  75. data/test/sass/results/mixins.css +95 -0
  76. data/test/sass/results/multiline.css +24 -0
  77. data/test/sass/templates/constants.sass +3 -0
  78. data/test/sass/templates/import.sass +4 -1
  79. data/test/sass/templates/importee.sass +4 -0
  80. data/test/sass/templates/mixins.sass +76 -0
  81. data/test/sass/templates/multiline.sass +20 -0
  82. data/test/test_helper.rb +18 -0
  83. metadata +70 -53
  84. data/lib/haml/helpers/action_view_mods.rb.rej +0 -30
  85. data/lib/haml/util.rb +0 -18
  86. data/lib/sass/constant.rb.rej +0 -42
  87. data/test/haml/runner.rb +0 -16
  88. data/test/profile.rb +0 -65
  89. data/test/sass/engine_test.rb.rej +0 -18
@@ -1,32 +1,40 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require 'test/unit'
4
- require 'rubygems'
5
- require 'action_pack'
6
-
7
- require File.dirname(__FILE__) + '/../../lib/haml'
2
+ require File.dirname(__FILE__) + '/../test_helper'
8
3
  require 'haml/template'
9
4
  require File.dirname(__FILE__) + '/mocks/article'
10
5
 
11
- class TestFilter
12
- def initialize(text)
13
- @text = text
14
- end
6
+ module Haml::Filters::Test
7
+ include Haml::Filters::Base
15
8
 
16
- def render
9
+ def render(text)
17
10
  "TESTING HAHAHAHA!"
18
11
  end
19
12
  end
20
13
 
14
+ module Haml::Helpers
15
+ def test_partial(name, locals = {})
16
+ Haml::Engine.new(File.read(File.join(TemplateTest::TEMPLATE_PATH, "_#{name}.haml"))).render(self, locals)
17
+ end
18
+ end
19
+
21
20
  class TemplateTest < Test::Unit::TestCase
22
- @@templates = %w{ very_basic standard helpers
21
+ TEMPLATE_PATH = File.join(File.dirname(__FILE__), "templates")
22
+ TEMPLATES = %w{ very_basic standard helpers
23
23
  whitespace_handling original_engine list helpful
24
24
  silent_script tag_parsing just_stuff partials
25
- filters }
25
+ filters nuke_outer_whitespace nuke_inner_whitespace }
26
26
 
27
27
  def setup
28
- Haml::Template.options = { :filters => { 'test'=>TestFilter } }
29
- @base = ActionView::Base.new(File.dirname(__FILE__) + "/templates/", {'article' => Article.new, 'foo' => 'value one'})
28
+ vars = { 'article' => Article.new, 'foo' => 'value one' }
29
+
30
+ unless ActionView::Base.instance_methods.include? 'finder'
31
+ @base = ActionView::Base.new(TEMPLATE_PATH, vars)
32
+ else
33
+ # Rails 2.1.0
34
+ @base = ActionView::Base.new([], vars)
35
+ @base.finder.append_view_path(TEMPLATE_PATH)
36
+ end
37
+
30
38
  @base.send(:evaluate_assigns)
31
39
 
32
40
  # This is used by form_for.
@@ -46,20 +54,16 @@ class TemplateTest < Test::Unit::TestCase
46
54
 
47
55
  def assert_renders_correctly(name, &render_method)
48
56
  render_method ||= proc { |name| @base.render(name) }
49
- test = Proc.new do |rendered|
50
- load_result(name).split("\n").zip(rendered.split("\n")).each_with_index do |pair, line|
51
- message = "template: #{name}\nline: #{line}"
52
- assert_equal(pair.first, pair.last, message)
53
- end
57
+
58
+ load_result(name).split("\n").zip(render_method[name].split("\n")).each_with_index do |pair, line|
59
+ message = "template: #{name}\nline: #{line}"
60
+ assert_equal(pair.first, pair.last, message)
54
61
  end
55
- begin
56
- test.call(render_method[name])
57
- rescue ActionView::TemplateError => e
58
- if e.message =~ /Can't run [\w:]+ filter; required (one of|file) ((?:'\w+'(?: or )?)+)(, but none were found| not found)/
59
- puts "\nCouldn't require #{$2}; skipping a test."
60
- else
61
- raise e
62
- end
62
+ rescue ActionView::TemplateError => e
63
+ if e.message =~ /Can't run [\w:]+ filter; required (one of|file) ((?:'\w+'(?: or )?)+)(, but none were found| not found)/
64
+ puts "\nCouldn't require #{$2}; skipping a test."
65
+ else
66
+ raise e
63
67
  end
64
68
  end
65
69
 
@@ -67,30 +71,24 @@ class TemplateTest < Test::Unit::TestCase
67
71
  assert_equal('', render(''))
68
72
  end
69
73
 
70
- def test_templates_should_render_correctly
71
- @@templates.each do |template|
74
+ TEMPLATES.each do |template|
75
+ define_method "test_template_should_render_correctly [template: #{template}] " do
72
76
  assert_renders_correctly template
73
77
  end
74
78
  end
75
79
 
76
80
  def test_templates_should_render_correctly_with_render_proc
77
- @@templates.each do |template|
78
- assert_renders_correctly(template) do |name|
79
- engine = Haml::Engine.new(File.read(File.dirname(__FILE__) + "/templates/#{name}.haml"), :filters => { 'test'=>TestFilter })
80
- engine.render_proc(@base).call
81
- end
81
+ assert_renders_correctly("standard") do |name|
82
+ engine = Haml::Engine.new(File.read(File.dirname(__FILE__) + "/templates/#{name}.haml"))
83
+ engine.render_proc(@base).call
82
84
  end
83
85
  end
84
-
86
+
85
87
  def test_templates_should_render_correctly_with_def_method
86
- @@templates.each do |template|
87
- assert_renders_correctly(template) do |name|
88
- method = "render_haml_" + name.gsub(/[^a-zA-Z0-9]/, '_')
89
-
90
- engine = Haml::Engine.new(File.read(File.dirname(__FILE__) + "/templates/#{name}.haml"), :filters => { 'test'=>TestFilter })
91
- engine.def_method(@base, method)
92
- @base.send(method)
93
- end
88
+ assert_renders_correctly("standard") do |name|
89
+ engine = Haml::Engine.new(File.read(File.dirname(__FILE__) + "/templates/#{name}.haml"))
90
+ engine.def_method(@base, "render_standard")
91
+ @base.render_standard
94
92
  end
95
93
  end
96
94
 
@@ -122,19 +120,6 @@ class TemplateTest < Test::Unit::TestCase
122
120
  assert_equal("2\n", render("= 1+1"))
123
121
  end
124
122
 
125
- def test_rhtml_still_renders
126
- # Make sure it renders normally
127
- res = @base.render("../rhtml/standard")
128
- assert !(res.nil? || res.empty?)
129
-
130
- # Register Haml stuff in @base...
131
- @base.render("standard")
132
-
133
- # Does it still render?
134
- res = @base.render("../rhtml/standard")
135
- assert !(res.nil? || res.empty?)
136
- end
137
-
138
123
  def test_haml_options
139
124
  Haml::Template.options = { :suppress_eval => true }
140
125
  assert_equal({ :suppress_eval => true }, Haml::Template.options)
@@ -2,6 +2,7 @@
2
2
  @foo =
3
3
  = @foo
4
4
  - @foo = 'value three'
5
+ == Toplevel? #{haml_buffer.toplevel?}
5
6
  %p
6
7
  @foo =
7
8
  = @foo
@@ -1,9 +1,10 @@
1
1
  %style
2
+ - width = 5 + 17
2
3
  :sass
3
4
  p
4
5
  :border
5
6
  :style dotted
6
- :width 10px
7
+ :width #{width}px
7
8
  :color #ff00ff
8
9
  h1
9
10
  :font-weight normal
@@ -14,20 +15,11 @@
14
15
  Not
15
16
  Print
16
17
 
17
- :redcloth
18
- Foo
19
- ===
20
-
21
- This is preformatted!
22
- Look at that!
23
- Wowie-zowie!
24
-
25
- *boldilicious!*
26
-
27
- :textile
28
- h1. Yeah
29
-
30
- _pretty much the same as above_
18
+ %p
19
+ :javascript
20
+ function newline(str) {
21
+ return "\n" + str;
22
+ }
31
23
 
32
24
  :plain
33
25
  This
@@ -35,11 +27,31 @@
35
27
  Plain
36
28
  Text
37
29
  %strong right?
30
+ \#{not interpolated}
31
+ \\#{1 + 2}
32
+ \\\#{also not}
33
+ \\
38
34
 
39
- :erb
40
- <% 10.times do |c| %>
41
- <%= (c+97).chr %>
42
- <% end %>
35
+ - last = "noitalo"
36
+ %p
37
+ %pre
38
+ :preserve
39
+ This pre is pretty deeply
40
+ nested.
41
+ Does #{"interp" + last.reverse} work?
42
+ :preserve
43
+ This one is, too.
44
+ Nested, that is.
45
+
46
+ - num = 10
47
+ %ul
48
+ :erb
49
+ <% num.times do |c| %>
50
+ <li><%= (c+97).chr %></li>
51
+ <% end %>
52
+ <% res = 178 %>
53
+
54
+ .res= res
43
55
 
44
56
  :markdown
45
57
  * Foo
@@ -48,6 +60,12 @@
48
60
 
49
61
  = "Text!"
50
62
 
63
+ - var = "Hello"
51
64
  :ruby
52
- puts "Hello, World!"
53
- puts "How are you doing today?"
65
+ printf "%s, World!\n", var
66
+ print "How are you doing today?\n"
67
+
68
+ :escaped
69
+ <div class="foo">
70
+ <p>I think &mdash; or do I?</p>
71
+ </div>
@@ -31,10 +31,10 @@ click
31
31
  = succeed '.' do
32
32
  %a{:href=>"thing"} here
33
33
  %p baz
34
- - buffer.tabulation = 10
34
+ - haml_buffer.tabulation = 10
35
35
  %p boom
36
36
  - concat "foo\n"
37
- - buffer.tabulation = 0
37
+ - haml_buffer.tabulation = 0
38
38
  - def url_for(*stuff); stuff.join(' '); end
39
39
  -# The form URLs must be empty
40
40
  -# because of a weird bug that causes url_for to misbehave.
@@ -43,7 +43,7 @@ click
43
43
  - form_tag '' do
44
44
  %div= submit_tag 'save'
45
45
  - @foo = 'value one'
46
- = render :partial => './partial'
46
+ = test_partial 'partial'
47
47
  - form_for :article, @article, :url => '' do |f|
48
48
  Title:
49
49
  = f.text_field :title
@@ -58,12 +58,12 @@ click
58
58
  - puts "boom"
59
59
  baz
60
60
  - puts "boom, again"
61
- - open :table do
62
- - open :tr do
63
- - open :td, {:class => 'cell'} do
64
- - open :strong, "strong!"
61
+ - haml_tag :table do
62
+ - haml_tag :tr do
63
+ - haml_tag :td, {:class => 'cell'} do
64
+ - haml_tag :strong, "strong!"
65
65
  - puts "data"
66
- - open :td do
66
+ - haml_tag :td do
67
67
  - puts "more_data"
68
- - open :hr
69
- - open :div, ''
68
+ - haml_tag :hr
69
+ - haml_tag :div, ''
@@ -19,7 +19,6 @@
19
19
  %p== Embedded? #{embedded}!
20
20
  %p== Embedded? #{"twice! #{true}"}!
21
21
  %p== Embedded? #{"one"} af"t"er #{"another"}!
22
- .render= render :inline => "%em= 'wow!'", :type => :haml
23
22
  = "stuff followed by whitespace"
24
23
 
25
24
  - if true
@@ -31,7 +30,6 @@
31
30
  \%p foo
32
31
  \yee\ha
33
32
  / Short comment
34
- / This is a really long comment look how long it is it should be on a line of its own don't you think?
35
33
  /
36
34
  This is a block comment
37
35
  cool, huh?
@@ -75,4 +73,11 @@
75
73
  %p.qux{:class => 'quux'}[@article] Blump
76
74
  == #{"Woah inner quotes"}
77
75
  %p.dynamic_quote{:quotes => "single '", :dyn => 1 + 2}
78
- %p.dynamic_atomic{:dyn => 1 + 2}/
76
+ %p.dynamic_self_closing{:dyn => 1 + 2}/
77
+ %body
78
+ :plain
79
+ hello
80
+ %div
81
+
82
+ %img
83
+
@@ -0,0 +1,32 @@
1
+ %p
2
+ %q< Foo
3
+ %p
4
+ %q{:a => 1 + 1}< Foo
5
+ %p
6
+ %q<= "Foo\nBar"
7
+ %p
8
+ %q{:a => 1 + 1}<= "Foo\nBar"
9
+ %p
10
+ %q<
11
+ Foo
12
+ Bar
13
+ %p
14
+ %q{:a => 1 + 1}<
15
+ Foo
16
+ Bar
17
+ %p
18
+ %q<
19
+ %div
20
+ Foo
21
+ Bar
22
+ %p
23
+ %q{:a => 1 + 1}<
24
+ %div
25
+ Foo
26
+ Bar
27
+
28
+ -# Regression test
29
+ %p
30
+ %q<= "foo"
31
+ %q{:a => 1 + 1}
32
+ bar
@@ -0,0 +1,144 @@
1
+ %p
2
+ %p
3
+ %q>
4
+ Foo
5
+ %p
6
+ %p
7
+ %q{:a => 1 + 1}>
8
+ Foo
9
+ %p
10
+ %p
11
+ %q> Foo
12
+ %p
13
+ %p
14
+ %q{:a => 1 + 1}> Foo
15
+ %p
16
+ %p
17
+ %q>
18
+ = "Foo"
19
+ %p
20
+ %p
21
+ %q{:a => 1 + 1}>
22
+ = "Foo"
23
+ %p
24
+ %p
25
+ %q>= "Foo"
26
+ %p
27
+ %p
28
+ %q{:a => 1 + 1}>= "Foo"
29
+ %p
30
+ %p
31
+ %q>
32
+ = "Foo\nBar"
33
+ %p
34
+ %p
35
+ %q{:a => 1 + 1}>
36
+ = "Foo\nBar"
37
+ %p
38
+ %p
39
+ %q>= "Foo\nBar"
40
+ %p
41
+ %p
42
+ %q{:a => 1 + 1}>= "Foo\nBar"
43
+ %p
44
+ %p
45
+ - tab_up
46
+ foo
47
+ %q>
48
+ Foo
49
+ bar
50
+ - tab_down
51
+ %p
52
+ %p
53
+ - tab_up
54
+ foo
55
+ %q{:a => 1 + 1}>
56
+ Foo
57
+ bar
58
+ - tab_down
59
+ %p
60
+ %p
61
+ - tab_up
62
+ foo
63
+ %q> Foo
64
+ bar
65
+ - tab_down
66
+ %p
67
+ %p
68
+ - tab_up
69
+ foo
70
+ %q{:a => 1 + 1}> Foo
71
+ bar
72
+ - tab_down
73
+ %p
74
+ %p
75
+ - tab_up
76
+ foo
77
+ %q>
78
+ = "Foo"
79
+ bar
80
+ - tab_down
81
+ %p
82
+ %p
83
+ - tab_up
84
+ foo
85
+ %q{:a => 1 + 1}>
86
+ = "Foo"
87
+ bar
88
+ - tab_down
89
+ %p
90
+ %p
91
+ - tab_up
92
+ foo
93
+ %q>= "Foo"
94
+ bar
95
+ - tab_down
96
+ %p
97
+ %p
98
+ - tab_up
99
+ foo
100
+ %q{:a => 1 + 1}>= "Foo"
101
+ bar
102
+ - tab_down
103
+ %p
104
+ %p
105
+ - tab_up
106
+ foo
107
+ %q>
108
+ = "Foo\nBar"
109
+ bar
110
+ - tab_down
111
+ %p
112
+ %p
113
+ - tab_up
114
+ foo
115
+ %q{:a => 1 + 1}>
116
+ = "Foo\nBar"
117
+ bar
118
+ - tab_down
119
+ %p
120
+ %p
121
+ - tab_up
122
+ foo
123
+ %q>= "Foo\nBar"
124
+ bar
125
+ - tab_down
126
+ %p
127
+ %p
128
+ - tab_up
129
+ foo
130
+ %q{:a => 1 + 1}>= "Foo\nBar"
131
+ bar
132
+ - tab_down
133
+ %p
134
+ %p
135
+ %q>
136
+ %p
137
+ %p
138
+ %q>/
139
+ %p
140
+ %p
141
+ %q{:a => 1 + 1}>
142
+ %p
143
+ %p
144
+ %q{:a => 1 + 1}>/
@@ -6,7 +6,7 @@
6
6
  %p
7
7
  @foo =
8
8
  = @foo
9
- = render :file => "_partial.haml"
9
+ = test_partial "partial"
10
10
  %p
11
11
  @foo =
12
12
  = @foo
@@ -19,6 +19,3 @@
19
19
  .foo16 e
20
20
  .123 f
21
21
  .foo2u g
22
- %div.broken
23
- %foo<{ :a => :b }
24
- .foo>{ :c => :d }
@@ -1,9 +1,9 @@
1
1
  #whitespace_test
2
- = render :file => "_text_area.haml", :locals => { :value => "Oneline" }
3
- = render :file => "_text_area.haml", :locals => { :value => "Two\nlines" }
4
- ~ render :file => "_text_area.haml", :locals => { :value => "Oneline" }
5
- ~ render :file => "_text_area.haml", :locals => { :value => "Two\nlines" }
6
- #flattened~ render :file => "_text_area.haml", :locals => { :value => "Two\nlines" }
2
+ = test_partial "text_area", :value => "Oneline"
3
+ = test_partial "text_area", :value => "Two\nlines"
4
+ ~ test_partial "text_area", :value => "Oneline"
5
+ ~ test_partial "text_area", :value => "Two\nlines"
6
+ #flattened~ test_partial "text_area", :value => "Two\nlines"
7
7
  .hithere
8
8
  ~ "Foo bar"
9
9
  ~ "<pre>foo bar</pre>"
@@ -15,11 +15,11 @@
15
15
  ~ ['a', 'b', 'c'].map do |a|
16
16
  - "<textarea>\n#{a}\n</textarea>"
17
17
  #whitespace_test
18
- = render :file => "_text_area.haml", :locals => { :value => "Oneline" }
19
- = render :file => "_text_area.haml", :locals => { :value => "Two\nlines" }
20
- = find_and_preserve render(:file => "_text_area.haml", :locals => { :value => "Oneline" })
21
- = find_and_preserve render(:file => "_text_area.haml", :locals => { :value => "Two\nlines" })
22
- #flattened= find_and_preserve render(:file => "_text_area.haml", :locals => { :value => "Two\nlines" })
18
+ = test_partial "text_area", :value => "Oneline"
19
+ = test_partial "text_area", :value => "Two\nlines"
20
+ = find_and_preserve test_partial("text_area", :value => "Oneline")
21
+ = find_and_preserve test_partial("text_area", :value => "Two\nlines")
22
+ #flattened= find_and_preserve test_partial("text_area", :value => "Two\nlines")
23
23
  .hithere
24
24
  = find_and_preserve("Foo bar")
25
25
  = find_and_preserve("<pre>foo bar</pre>")