haml 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/MIT-LICENSE +20 -0
- data/REFERENCE +662 -0
- data/Rakefile +167 -0
- data/VERSION +1 -0
- data/bin/haml +18 -0
- data/lib/haml/buffer.rb +224 -0
- data/lib/haml/engine.rb +551 -0
- data/lib/haml/helpers.rb +220 -0
- data/lib/haml/helpers/action_view_mods.rb +53 -0
- data/lib/haml/template.rb +138 -0
- data/test/benchmark.rb +62 -0
- data/test/engine_test.rb +93 -0
- data/test/helper_test.rb +105 -0
- data/test/mocks/article.rb +6 -0
- data/test/profile.rb +45 -0
- data/test/results/content_for_layout.xhtml +16 -0
- data/test/results/eval_suppressed.xhtml +2 -0
- data/test/results/helpers.xhtml +50 -0
- data/test/results/helpful.xhtml +5 -0
- data/test/results/just_stuff.xhtml +36 -0
- data/test/results/list.xhtml +12 -0
- data/test/results/original_engine.xhtml +24 -0
- data/test/results/partials.xhtml +20 -0
- data/test/results/silent_script.xhtml +74 -0
- data/test/results/standard.xhtml +42 -0
- data/test/results/tag_parsing.xhtml +28 -0
- data/test/results/very_basic.xhtml +7 -0
- data/test/results/whitespace_handling.xhtml +51 -0
- data/test/rhtml/standard.rhtml +51 -0
- data/test/runner.rb +15 -0
- data/test/template_test.rb +137 -0
- data/test/templates/_partial.haml +7 -0
- data/test/templates/_text_area.haml +3 -0
- data/test/templates/content_for_layout.haml +10 -0
- data/test/templates/eval_suppressed.haml +5 -0
- data/test/templates/helpers.haml +39 -0
- data/test/templates/helpful.haml +6 -0
- data/test/templates/just_stuff.haml +29 -0
- data/test/templates/list.haml +12 -0
- data/test/templates/original_engine.haml +17 -0
- data/test/templates/partialize.haml +1 -0
- data/test/templates/partials.haml +12 -0
- data/test/templates/silent_script.haml +40 -0
- data/test/templates/standard.haml +40 -0
- data/test/templates/tag_parsing.haml +24 -0
- data/test/templates/very_basic.haml +4 -0
- data/test/templates/whitespace_handling.haml +66 -0
- metadata +108 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xml-lang='en-US'>
|
3
|
+
<head>
|
4
|
+
<title>Hampton Catlin Is Totally Awesome</title>
|
5
|
+
<meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<!-- You're In my house now! -->
|
9
|
+
<div class='header'>
|
10
|
+
Yes, ladies and gentileman. He is just that egotistical.
|
11
|
+
Fantastic! This should be multi-line output
|
12
|
+
The question is if this would translate! Ahah!
|
13
|
+
20
|
14
|
+
</div>
|
15
|
+
<div id='body'> Quotes should be loved! Just like people!</div>
|
16
|
+
Wow.|
|
17
|
+
<p>
|
18
|
+
Holy cow multiline tags! A pipe (|) even!
|
19
|
+
PipesIgnored|PipesIgnored|PipesIgnored|
|
20
|
+
1|2|3
|
21
|
+
</p>
|
22
|
+
<div class='silent'>
|
23
|
+
this shouldn't evaluate but now it should!
|
24
|
+
</div>
|
25
|
+
<ul class='really cool'>
|
26
|
+
<li>a</li>
|
27
|
+
<li>b</li>
|
28
|
+
<li>c</li>
|
29
|
+
<li>d</li>
|
30
|
+
<li>e</li>
|
31
|
+
<li>f</li>
|
32
|
+
</ul>
|
33
|
+
<div class='of_divs_with_underscore' id='combo'>with this text</div>
|
34
|
+
hello
|
35
|
+
<div class='footer'>
|
36
|
+
<strong class='shout'>
|
37
|
+
This is a really long ruby quote. It should be loved and wrapped because its more than 50 characters. This value may change in the future and this test may look stupid.
|
38
|
+
So, I'm just making it *really* long. God, I hope this works
|
39
|
+
</strong>
|
40
|
+
</div>
|
41
|
+
</body>
|
42
|
+
</html>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<div class='tags'>
|
2
|
+
<foo>1</foo>
|
3
|
+
<FOO>2</FOO>
|
4
|
+
<fooBAR>3</fooBAR>
|
5
|
+
<fooBar>4</fooBar>
|
6
|
+
<foo_bar>5</foo_bar>
|
7
|
+
<foo-bar>6</foo-bar>
|
8
|
+
<foo:bar>7</foo:bar>
|
9
|
+
<foo class='bar'>8</foo>
|
10
|
+
<fooBAr_baz:boom_bar>9</fooBAr_baz:boom_bar>
|
11
|
+
<foo13>10</foo13>
|
12
|
+
<foo2u>11</foo2u>
|
13
|
+
</div>
|
14
|
+
<div class='classes'>
|
15
|
+
<p class='foo bar' id='boom'>
|
16
|
+
</p>
|
17
|
+
<div class='fooBar'>a</div>
|
18
|
+
<div class='foo-bar'>b</div>
|
19
|
+
<div class='foo_bar'>c</div>
|
20
|
+
<div class='FOOBAR'>d</div>
|
21
|
+
<div class='foo16'>e</div>
|
22
|
+
<div class='123'>f</div>
|
23
|
+
<div class='foo2u'>g</div>
|
24
|
+
</div>
|
25
|
+
<div class='broken'>
|
26
|
+
<foo><{ :a => :b }</foo>
|
27
|
+
<div class='foo'>>{ :c => :d }</div>
|
28
|
+
</div>
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<div id='whitespace_test'>
|
2
|
+
<div class='text_area_test_area'>
|
3
|
+
<textarea>Oneline</textarea>
|
4
|
+
</div>
|
5
|
+
<textarea>BLAH
|
6
|
+
</textarea>
|
7
|
+
<div class='text_area_test_area'>
|
8
|
+
<textarea>Two
lines</textarea>
|
9
|
+
</div>
|
10
|
+
<textarea>BLAH
|
11
|
+
</textarea>
|
12
|
+
<div class='text_area_test_area'>
|
13
|
+
<textarea>Oneline</textarea>
|
14
|
+
</div>
|
15
|
+
<textarea>BLAH
</textarea>
|
16
|
+
<div class='text_area_test_area'>
|
17
|
+
<textarea>Two
lines</textarea>
|
18
|
+
</div>
|
19
|
+
<textarea>BLAH
</textarea>
|
20
|
+
<div id='flattened'>
|
21
|
+
<div class='text_area_test_area'>
|
22
|
+
<textarea>Two
lines</textarea>
|
23
|
+
</div>
|
24
|
+
<textarea>BLAH
</textarea>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
<div class='hithere'>
|
28
|
+
Foo bar
|
29
|
+
<pre>foo bar</pre>
|
30
|
+
<pre>foo
bar</pre>
|
31
|
+
<p><pre>foo
bar</pre></p>
|
32
|
+
<p>
|
33
|
+
foo
|
34
|
+
bar
|
35
|
+
</p>
|
36
|
+
<pre>
 ___
 ,o88888
 ,o8888888'
 ,:o:o:oooo. ,8O88Pd8888"
 ,.::.::o:ooooOoOoO. ,oO8O8Pd888'"
 ,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O"
 , ..:.::o:ooOoOOOO8OOOOo.FdO8O8"
 , ..:.::o:ooOoOO8O888O8O,COCOO"
 , . ..:.::o:ooOoOOOO8OOOOCOCO"
 . ..:.::o:ooOoOoOO8O8OCCCC"o
 . ..:.::o:ooooOoCoCCC"o:o
 . ..:.::o:o:,cooooCo"oo:o:
 ` . . ..:.:cocoooo"'o:o:::'
 .` . ..::ccccoc"'o:o:o:::'
 :.:. ,c:cccc"':.:.:.:.:.'
 ..:.:"'`::::c:"'..:.:.:.:.:.' http://www.chris.com/ASCII/
 ...:.'.:.::::"' . . . . .'
 .. . ....:."' ` . . . ''
 . . . ...."'
 .. . ."' -hrr-
 .


 It's a planet!
%strong This shouldn't be bold!
</pre>
|
37
|
+
<strong>This should!</strong>
|
38
|
+
<textarea>
|
39
|
+
___ ___ ___ ___
 /\__\ /\ \ /\__\ /\__\
 /:/ / /::\ \ /::| | /:/ /
 /:/__/ /:/\:\ \ /:|:| | /:/ /
 /::\ \ ___ /::\~\:\ \ /:/|:|__|__ /:/ /
 /:/\:\ /\__\ /:/\:\ \:\__\ /:/ |::::\__\ /:/__/
 \/__\:\/:/ / \/__\:\/:/ / \/__/~~/:/ / \:\ \
 \::/ / \::/ / /:/ / \:\ \
 /:/ / /:/ / /:/ / \:\ \
 /:/ / /:/ / /:/ / \:\__\
 \/__/ \/__/ \/__/ \/__/
 
 Many
 thanks
 to
 http://www.network-science.de/ascii/

|
40
|
+
<strong>indeed!</strong>
|
41
|
+
</textarea>
|
42
|
+
</div>
|
43
|
+
<div class='foo'>
|
44
|
+
13
|
45
|
+
<textarea>
a
</textarea><textarea>
b
</textarea><textarea>
c
</textarea>
|
46
|
+
</div>
|
47
|
+
<pre>
|
48
|
+
foo

|
49
|
+
bar
|
50
|
+
</pre>
|
51
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xml-lang='en-US'>
|
3
|
+
<head>
|
4
|
+
<title>Hampton Catlin Is Totally Awesome</title>
|
5
|
+
<meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<!-- You're In my house now! -->
|
9
|
+
<div class='header'>
|
10
|
+
Yes, ladies and gentileman. He is just that egotistical.
|
11
|
+
Fantastic! This should be multi-line output
|
12
|
+
The question is if this would translate! Ahah!
|
13
|
+
<%= 1 + 9 + 8 + 2 %>
|
14
|
+
<%# numbers should work and this should be ignored %>
|
15
|
+
</div>
|
16
|
+
<div id='body'><%= " Quotes should be loved! Just like people!" %></div>
|
17
|
+
Wow.
|
18
|
+
<p>
|
19
|
+
<%= "Holy cow " +
|
20
|
+
"multiline " +
|
21
|
+
"tags! " +
|
22
|
+
"A pipe (|) even!" %>
|
23
|
+
<%= [1, 2, 3].collect { |n| "PipesIgnored|" } %>
|
24
|
+
<%= [1, 2, 3].collect { |n|
|
25
|
+
n.to_s
|
26
|
+
}.join("|") %>
|
27
|
+
</p>
|
28
|
+
<div class='silent'>
|
29
|
+
<% foo = String.new
|
30
|
+
foo << "this"
|
31
|
+
foo << " shouldn't"
|
32
|
+
foo << " evaluate" %>
|
33
|
+
<%= foo + "but now it should!" %>
|
34
|
+
<%# Woah crap a comment! %>
|
35
|
+
</div>
|
36
|
+
<ul class='really cool'>
|
37
|
+
<% ('a'..'f').each do |a|%>
|
38
|
+
<li><%= a %>
|
39
|
+
<% end %>
|
40
|
+
<div class='of_divs_with_underscore' id='combo'><%= @should_eval = "with this text" %></div>
|
41
|
+
<%= [ 104, 101, 108, 108, 111 ].map do |byte|
|
42
|
+
byte.chr
|
43
|
+
end %>
|
44
|
+
<div class='footer'>
|
45
|
+
<strong class='shout'>
|
46
|
+
<%= "This is a really long ruby quote. It should be loved and wrapped because its more than 50 characters. This value may change in the future and this test may look stupid.\n" +
|
47
|
+
" So, I'm just making it *really* long. God, I hope this works" %>
|
48
|
+
</strong>
|
49
|
+
</div>
|
50
|
+
</body>
|
51
|
+
</html>
|
data/test/runner.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_support'
|
3
|
+
require 'action_view'
|
4
|
+
require '../lib/haml/template'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
haml_template_engine = Haml::Template.new(ActionView::Base.new)
|
8
|
+
haml_template_engine.render(File.dirname(__FILE__) + '/templates/standard.haml')
|
9
|
+
|
10
|
+
begin
|
11
|
+
eval(File.read("template_test.rb"))
|
12
|
+
rescue StandardError => e
|
13
|
+
puts e.backtrace
|
14
|
+
puts e.inspect
|
15
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'active_support'
|
6
|
+
require 'action_view'
|
7
|
+
|
8
|
+
require File.dirname(__FILE__) + '/../lib/haml/template'
|
9
|
+
require File.dirname(__FILE__) + '/mocks/article'
|
10
|
+
|
11
|
+
class TemplateTest < Test::Unit::TestCase
|
12
|
+
@@templates = %w{ very_basic standard helpers
|
13
|
+
whitespace_handling original_engine list helpful
|
14
|
+
silent_script tag_parsing just_stuff partials }
|
15
|
+
|
16
|
+
def setup
|
17
|
+
ActionView::Base.register_template_handler("haml", Haml::Template)
|
18
|
+
@base = ActionView::Base.new(File.dirname(__FILE__) + "/../test/templates/")
|
19
|
+
@base.instance_variable_set("@article", Article.new)
|
20
|
+
@base.instance_variable_set("@foo", 'value one')
|
21
|
+
end
|
22
|
+
|
23
|
+
def render(text)
|
24
|
+
Haml::Engine.new(text).to_html(@base)
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_result(name)
|
28
|
+
@result = ''
|
29
|
+
File.new(File.dirname(__FILE__) + "/results/#{name}.xhtml").each_line { |l| @result += l }
|
30
|
+
@result
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert_renders_correctly(name)
|
34
|
+
test = Proc.new do |rendered|
|
35
|
+
load_result(name).split("\n").zip(rendered.split("\n")).each_with_index do |pair, line|
|
36
|
+
message = "template: #{name}\nline: #{line}"
|
37
|
+
assert_equal(pair.first, pair.last, message)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
test.call(@base.render(name))
|
41
|
+
test.call(@base.render(:file => "partialize", :locals => { :name => name }))
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_empty_render_should_remain_empty
|
45
|
+
assert_equal('', render(''))
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_templates_should_render_correctly
|
49
|
+
@@templates.each do |template|
|
50
|
+
assert_renders_correctly template
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_action_view_templates_render_correctly
|
55
|
+
@base.instance_variable_set("@content_for_layout", 'Lorem ipsum dolor sit amet')
|
56
|
+
assert_renders_correctly 'content_for_layout'
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_instance_variables_should_work_inside_templates
|
60
|
+
@base.instance_variable_set("@content_for_layout", 'something')
|
61
|
+
assert_equal("<p>something</p>", render("%p= @content_for_layout").chomp)
|
62
|
+
|
63
|
+
@base.instance_eval("@author = 'Hampton Catlin'")
|
64
|
+
assert_equal("<div class='author'>Hampton Catlin</div>", render(".author= @author").chomp)
|
65
|
+
|
66
|
+
@base.instance_eval("@author = 'Hampton'")
|
67
|
+
assert_equal("Hampton", render("= @author").chomp)
|
68
|
+
|
69
|
+
@base.instance_eval("@author = 'Catlin'")
|
70
|
+
assert_equal("Catlin", render("= @author").chomp)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_instance_variables_should_work_inside_attributes
|
74
|
+
@base.instance_eval("@author = 'hcatlin'")
|
75
|
+
assert_equal("<p class='hcatlin'>foo</p>", render("%p{:class => @author} foo").chomp)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_template_renders_should_eval
|
79
|
+
assert_equal("2\n", render("= 1+1"))
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_rhtml_still_renders
|
83
|
+
res = @base.render("../rhtml/standard")
|
84
|
+
assert !(res.nil? || res.empty?)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_haml_options
|
88
|
+
Haml::Template.options = { :suppress_eval => true }
|
89
|
+
assert_equal({ :suppress_eval => true }, Haml::Template.options)
|
90
|
+
assert_renders_correctly("eval_suppressed")
|
91
|
+
Haml::Template.options = {}
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_exceptions_should_work_correctly
|
95
|
+
template = <<END
|
96
|
+
%p
|
97
|
+
%h1 Hello!
|
98
|
+
= "lots of lines"
|
99
|
+
- raise "Oh no!"
|
100
|
+
%p
|
101
|
+
this is after the exception
|
102
|
+
%strong yes it is!
|
103
|
+
ho ho ho.
|
104
|
+
END
|
105
|
+
@base.haml_filename = "(test)"
|
106
|
+
begin
|
107
|
+
render(template.chomp)
|
108
|
+
rescue Exception => e
|
109
|
+
assert_equal("(test).haml:4", e.backtrace[0])
|
110
|
+
end
|
111
|
+
|
112
|
+
@base.haml_filename = nil
|
113
|
+
begin
|
114
|
+
render(template.chomp)
|
115
|
+
rescue Exception => e
|
116
|
+
assert_equal("(haml):4", e.backtrace[0])
|
117
|
+
end
|
118
|
+
|
119
|
+
template = <<END
|
120
|
+
%p
|
121
|
+
%h1 Hello!
|
122
|
+
= "lots of lines"
|
123
|
+
= "even more!"
|
124
|
+
- compile_error(
|
125
|
+
%p
|
126
|
+
this is after the exception
|
127
|
+
%strong yes it is!
|
128
|
+
ho ho ho.
|
129
|
+
END
|
130
|
+
|
131
|
+
begin
|
132
|
+
render(template.chomp)
|
133
|
+
rescue Exception => e
|
134
|
+
assert_equal("(haml):5", e.backtrace[0])
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
= h("&&&&&&&&&&&") # This is an ActionView Helper... should load
|
2
|
+
- foo = capture do # This ActionView Helper is designed for ERB, but should work with HAML
|
3
|
+
%div
|
4
|
+
%p.title Title
|
5
|
+
%p.text
|
6
|
+
Woah this is really crazy
|
7
|
+
I mean wow,
|
8
|
+
man.
|
9
|
+
- 3.times do
|
10
|
+
= foo
|
11
|
+
%p foo
|
12
|
+
- tab_up
|
13
|
+
%p reeeeeeeeeeeeeeeeeeeeeeeeeeeeeeally loooooooooooooooooong
|
14
|
+
- tab_down
|
15
|
+
.woah
|
16
|
+
#funky
|
17
|
+
= capture_haml do
|
18
|
+
%div
|
19
|
+
%h1 Big!
|
20
|
+
%p Small
|
21
|
+
/ Invisible
|
22
|
+
= capture do
|
23
|
+
.dilly
|
24
|
+
%p foo
|
25
|
+
%h1 bar
|
26
|
+
= surround '(', ')' do
|
27
|
+
%strong parentheses!
|
28
|
+
= precede '*' do
|
29
|
+
%span.small Not really
|
30
|
+
click
|
31
|
+
= succeed '.' do
|
32
|
+
%a{:href=>"thing"} here
|
33
|
+
%p baz
|
34
|
+
- buffer.tabulation = 10
|
35
|
+
%p boom
|
36
|
+
- concat "foo\n"
|
37
|
+
- buffer.tabulation = 0
|
38
|
+
= list_of({:google => 'http://www.google.com'}) do |name, link|
|
39
|
+
%a{ :href => link }= name
|
@@ -0,0 +1,29 @@
|
|
1
|
+
!!! XML
|
2
|
+
!!! XML ISO-8859-1
|
3
|
+
!!! XML UtF-8 Foo bar
|
4
|
+
!!!
|
5
|
+
!!! 1.1
|
6
|
+
!!! 1.1 Strict
|
7
|
+
!!! Strict foo bar
|
8
|
+
!!! FRAMESET
|
9
|
+
%strong{:apos => "Foo's bar!"} Boo!
|
10
|
+
.render= render :inline => "%em= 'wow!'", :type => :haml
|
11
|
+
%p
|
12
|
+
\Escape
|
13
|
+
\- character
|
14
|
+
\%p foo
|
15
|
+
\yee\ha
|
16
|
+
/ Short comment
|
17
|
+
/ This is a really long comment look how long it is it should be on a line of its own don't you think?
|
18
|
+
/
|
19
|
+
This is a block comment
|
20
|
+
cool, huh?
|
21
|
+
%strong there can even be sub-tags!
|
22
|
+
= "Or script!"
|
23
|
+
/[if lte IE6] conditional comment!
|
24
|
+
/[if gte IE7]
|
25
|
+
%p Block conditional comment
|
26
|
+
%div
|
27
|
+
%h1 Cool, eh?
|
28
|
+
/[if gte IE5.2]
|
29
|
+
Woah a period.
|