slim 0.5.1 → 0.6.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +29 -0
- data/README.md +78 -54
- data/Rakefile +3 -0
- data/lib/slim.rb +7 -1
- data/lib/slim/compiler.rb +52 -54
- data/lib/slim/optimizer.rb +7 -8
- data/lib/slim/rails.rb +1 -3
- data/slim.gemspec +14 -3
- data/test/helper.rb +8 -0
- data/test/slim/test_compiler.rb +52 -6
- data/test/slim/test_engine.rb +20 -0
- metadata +54 -9
data/.gitignore
CHANGED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
slim (0.5.1)
|
5
|
+
escape_utils
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
escape_utils (0.1.8)
|
11
|
+
gemcutter (0.6.1)
|
12
|
+
git (1.2.5)
|
13
|
+
jeweler (1.4.0)
|
14
|
+
gemcutter (>= 0.1.0)
|
15
|
+
git (>= 1.2.5)
|
16
|
+
rubyforge (>= 2.0.0)
|
17
|
+
json_pure (1.4.6)
|
18
|
+
rake (0.8.7)
|
19
|
+
rubyforge (2.0.4)
|
20
|
+
json_pure (>= 1.1.7)
|
21
|
+
|
22
|
+
PLATFORMS
|
23
|
+
ruby
|
24
|
+
|
25
|
+
DEPENDENCIES
|
26
|
+
escape_utils
|
27
|
+
jeweler
|
28
|
+
rake
|
29
|
+
slim!
|
data/README.md
CHANGED
@@ -65,88 +65,108 @@ So here's what I came up with:
|
|
65
65
|
|
66
66
|
#### Add content to a tag
|
67
67
|
|
68
|
-
|
68
|
+
# Either start on the same line as the tag
|
69
69
|
|
70
|
-
|
71
|
-
|
70
|
+
body
|
71
|
+
h1 id="headline" Welcome to my site.
|
72
72
|
|
73
|
-
|
73
|
+
# Or nest it. __Note:__ Must use a pipe or a backtick (followed by a space) to escape processing
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
body
|
76
|
+
h1 id="headline"
|
77
|
+
| Welcome to my site.
|
78
78
|
|
79
79
|
#### Add content to a tag with code
|
80
80
|
|
81
|
-
|
81
|
+
# Can make the call on the same line
|
82
82
|
|
83
|
-
|
84
|
-
|
83
|
+
body
|
84
|
+
h1 id="headline" = page_headline
|
85
85
|
|
86
|
-
|
86
|
+
# Or nest it.
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
88
|
+
body
|
89
|
+
h1 id="headline"
|
90
|
+
= page_headline
|
91
91
|
|
92
92
|
#### Shortcut form for `id` and `class` attributes
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
# Similarly to Haml, you can specify the `id` and `class`
|
95
|
+
# attributes in the following shortcut form
|
96
|
+
# Note: the shortcut form does not evaluate ruby code
|
97
97
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
98
|
+
body
|
99
|
+
h1#headline
|
100
|
+
= page_headline
|
101
|
+
h2#tagline.small.tagline
|
102
|
+
= page_tagline
|
103
|
+
.content
|
104
|
+
= show_content
|
105
105
|
|
106
|
-
|
106
|
+
# this is the same as
|
107
107
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
108
|
+
body
|
109
|
+
h1 id="headline"
|
110
|
+
= page_headline
|
111
|
+
h2 id="tagline" class="small tagline"
|
112
|
+
= page_tagline
|
113
|
+
div class="content"
|
114
|
+
= show_content
|
115
115
|
|
116
116
|
#### Set an attribute's value with a method?
|
117
117
|
|
118
|
-
|
118
|
+
# Just use standard Ruby interpolation.
|
119
119
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
120
|
+
body
|
121
|
+
table
|
122
|
+
- for user in users do
|
123
|
+
tr id="user_#{user.id}"
|
124
124
|
|
125
|
+
#### Escape the escaping?
|
126
|
+
|
127
|
+
# Just use a double equal sign
|
128
|
+
|
129
|
+
body
|
130
|
+
h1 id="headline"
|
131
|
+
== page_headline
|
125
132
|
|
126
133
|
#### Treat multiple lines of code as text that should bypass parsing.
|
127
134
|
|
128
|
-
|
129
|
-
|
135
|
+
# Use a backtick to start the escape. Each following line that is
|
136
|
+
# indented greater than the backtick is copied over.
|
130
137
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
138
|
+
body
|
139
|
+
p
|
140
|
+
|
|
141
|
+
This is a test of the text block.
|
135
142
|
|
136
|
-
|
143
|
+
# The parsed result of the above:
|
137
144
|
|
138
|
-
|
145
|
+
<body><p>This is a test of the text block.</p></body>
|
139
146
|
|
140
|
-
|
141
|
-
|
147
|
+
# The left margin is set at the indent of the backtick + one space.
|
148
|
+
# Any additional spaces will be copied over.
|
142
149
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
+
body
|
151
|
+
p
|
152
|
+
|
|
153
|
+
This line is on the left margin.
|
154
|
+
This line will have one space in front of it.
|
155
|
+
This line will have two spaces in front of it.
|
156
|
+
And so on...
|
157
|
+
|
158
|
+
#### Add ruby code comments?
|
159
|
+
|
160
|
+
# Use a forward slash for ruby code comments
|
161
|
+
|
162
|
+
body
|
163
|
+
p
|
164
|
+
/ This line won't get displayed.
|
165
|
+
/ Neither does this line.
|
166
|
+
|
167
|
+
# The parsed result of the above:
|
168
|
+
|
169
|
+
<body><p></p></body>
|
150
170
|
|
151
171
|
### Things to know:
|
152
172
|
|
@@ -169,9 +189,13 @@ So here's what I came up with:
|
|
169
189
|
* The dash denotes control code (similar to Haml). Examples of control code are loops and conditionals.
|
170
190
|
* =
|
171
191
|
* The equal sign tells Slim it's a Ruby call that produces output to add to the buffer (similar to Erb and Haml).
|
192
|
+
* ==
|
193
|
+
* Same as the single equal sign, but does not go through the escape_html method.
|
172
194
|
* !
|
173
195
|
* This is a directive. Most common example:
|
174
196
|
` ! doctype html renders <!doctype html> `
|
197
|
+
* /
|
198
|
+
* Use the forward slash for ruby code comments - anything after it won't get displayed in the final render.
|
175
199
|
|
176
200
|
|
177
201
|
### Please add feature requests and bugs to the Github issue tracker.
|
data/Rakefile
CHANGED
@@ -14,6 +14,9 @@ begin
|
|
14
14
|
gem.email = "andy@stonean.com"
|
15
15
|
gem.homepage = "http://github.com/stonean/slim"
|
16
16
|
gem.authors = ["Andrew Stone"]
|
17
|
+
gem.add_dependency 'escape_utils'
|
18
|
+
gem.add_development_dependency 'rake'
|
19
|
+
gem.add_development_dependency 'jeweler'
|
17
20
|
end
|
18
21
|
Jeweler::GemcutterTasks.new
|
19
22
|
rescue LoadError
|
data/lib/slim.rb
CHANGED
@@ -2,13 +2,19 @@
|
|
2
2
|
|
3
3
|
$:.unshift File.dirname(__FILE__)
|
4
4
|
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'escape_utils'
|
5
7
|
require 'slim/compiler'
|
6
8
|
require 'slim/engine'
|
7
9
|
|
8
10
|
module Slim
|
9
11
|
class << self
|
10
12
|
def version
|
11
|
-
'0.
|
13
|
+
'0.6.0.beta.1'
|
14
|
+
end
|
15
|
+
|
16
|
+
def escape_html(html)
|
17
|
+
EscapeUtils.escape_html(html)
|
12
18
|
end
|
13
19
|
end
|
14
20
|
end
|
data/lib/slim/compiler.rb
CHANGED
@@ -5,31 +5,34 @@ require 'slim/optimizer'
|
|
5
5
|
module Slim
|
6
6
|
module Compiler
|
7
7
|
include Optimizer
|
8
|
-
AUTOCLOSED = %w(meta img link br hr input area param col base)
|
9
8
|
|
9
|
+
AUTOCLOSED = %w{meta img link br hr input area param col base}
|
10
10
|
CONTROL_WORDS = %w{if unless do}
|
11
11
|
ELSE_CONTROL_WORDS = %w{else elsif}
|
12
12
|
|
13
|
-
REGEX_LINE_PARSER = /^(\s*)(
|
13
|
+
REGEX_LINE_PARSER = /^(\s*)(!?`?\|?-?=?\/?\w*)((?:\s*(?:\w|-)*="[^=]+")+|(\s*[#.]\S+))?(.*)/
|
14
14
|
REGEX_LINE_CONTAINS_OUTPUT_CODE = /^=(.*)/
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
REGEX_LINE_CONTAINS_ONLY_HTML_TAG = /^\s*\w+\S?$/
|
16
|
+
REGEX_LINE_CONTAINS_METHOD_DETECTED = /^(\w+\(.*\))(.*)/
|
17
|
+
REGEX_METHOD_HAS_NO_PARENTHESES = /^\w+\s/
|
18
|
+
REGEX_CODE_BLOCK_DETECTED = / do ?.*$/
|
19
|
+
REGEX_CODE_CONTROL_WORD_DETECTED = /(?:\s|(\())(#{CONTROL_WORDS * '|'})\b\s?(.*)$/
|
20
|
+
REGEX_CODE_ELSE_CONTROL_WORD_DETECTED = /^#{ELSE_CONTROL_WORDS * '\b|'}\b/
|
21
|
+
REGEX_FIND_HTML_ATTR_ID = /#([^.\s]+)/
|
22
|
+
REGEX_FIND_HTML_ATTR_CLASSES = /\.([^#\s]+)/
|
21
23
|
|
22
24
|
def compile
|
23
|
-
@_buffer
|
24
|
-
|
25
|
-
|
26
|
-
text_indent = last_indent = -1
|
25
|
+
@_buffer = ['_buf = [];']
|
26
|
+
in_text = false
|
27
|
+
enders = []
|
28
|
+
text_indent = last_indent = -1
|
27
29
|
|
28
30
|
@template.each_line do |line|
|
29
|
-
line.chomp
|
31
|
+
line.chomp!
|
32
|
+
line.rstrip!
|
30
33
|
|
31
34
|
if line.length == 0
|
32
|
-
@_buffer <<
|
35
|
+
@_buffer << '_buf << "<br/>";' if in_text
|
33
36
|
next
|
34
37
|
end
|
35
38
|
|
@@ -37,7 +40,7 @@ module Slim
|
|
37
40
|
|
38
41
|
indent = $1.to_s.length
|
39
42
|
|
40
|
-
if
|
43
|
+
if in_text && indent > text_indent
|
41
44
|
spaces = indent - text_indent
|
42
45
|
@_buffer << "_buf << \"#{(' '*(spaces - 1)) + line.lstrip}\";"
|
43
46
|
next
|
@@ -46,46 +49,34 @@ module Slim
|
|
46
49
|
marker = $2
|
47
50
|
attrs = $3
|
48
51
|
shortcut_attrs = $4
|
49
|
-
string = $5
|
52
|
+
string = $5.strip
|
50
53
|
|
51
54
|
# prepends "div" to the shortcut form of attrs if no marker is given
|
52
|
-
if shortcut_attrs && marker.empty?
|
53
|
-
marker = "div"
|
54
|
-
end
|
55
|
+
marker = 'div' if shortcut_attrs && marker.empty?
|
55
56
|
|
56
57
|
line_type = case marker
|
57
58
|
when '`', '|' then :text
|
58
59
|
when '-' then :control_code
|
59
60
|
when '=' then :output_code
|
60
61
|
when '!' then :declaration
|
62
|
+
when '/' then next # simply ignore any ruby code comments
|
61
63
|
else :markup
|
62
64
|
end
|
63
65
|
|
64
|
-
if line_type != :text
|
65
|
-
@in_text = false
|
66
|
-
text_indent = -1
|
67
|
-
end
|
68
|
-
|
69
66
|
if attrs
|
70
|
-
|
67
|
+
normalize_attributes!(attrs) if shortcut_attrs
|
71
68
|
attrs.gsub!('"', '\"')
|
72
69
|
end
|
73
70
|
|
74
|
-
if string
|
75
|
-
string.strip!
|
76
|
-
string = nil if string.empty?
|
77
|
-
end
|
78
|
-
|
79
71
|
unless indent > last_indent
|
80
72
|
begin
|
81
73
|
break if enders.empty?
|
82
74
|
continue_closing = true
|
83
75
|
ender, ender_indent = enders.pop
|
84
76
|
|
85
|
-
|
86
|
-
|
77
|
+
unless ender_indent < indent || ender == 'end;' && line_type == :control_code &&
|
78
|
+
ender_indent == indent && string =~ REGEX_CODE_ELSE_CONTROL_WORD_DETECTED
|
87
79
|
@_buffer << ender
|
88
|
-
end
|
89
80
|
else
|
90
81
|
enders << [ender, ender_indent]
|
91
82
|
continue_closing = false
|
@@ -104,16 +95,16 @@ module Slim
|
|
104
95
|
@_buffer << "_buf << \"<#{marker}#{attrs || ''}>\";"
|
105
96
|
end
|
106
97
|
|
107
|
-
|
98
|
+
unless string.empty?
|
108
99
|
string.lstrip!
|
109
100
|
if string =~ REGEX_LINE_CONTAINS_OUTPUT_CODE
|
110
|
-
@_buffer << "_buf << #{
|
101
|
+
@_buffer << "_buf << #{parse_string($1.strip)};"
|
111
102
|
else
|
112
103
|
@_buffer << "_buf << \"#{string}\";"
|
113
104
|
end
|
114
105
|
end
|
115
106
|
when :text
|
116
|
-
|
107
|
+
in_text = true
|
117
108
|
text_indent = indent
|
118
109
|
@_buffer << "_buf << \"#{string}\";" if string.to_s.length > 0
|
119
110
|
when :control_code
|
@@ -121,7 +112,7 @@ module Slim
|
|
121
112
|
@_buffer << "#{string};"
|
122
113
|
when :output_code
|
123
114
|
enders << ['end;', indent] if string =~ REGEX_CODE_BLOCK_DETECTED
|
124
|
-
@_buffer << "_buf << #{
|
115
|
+
@_buffer << "_buf << #{parse_string(string)};"
|
125
116
|
when :declaration
|
126
117
|
@_buffer << "_buf << \"<!#{string}>\";"
|
127
118
|
else
|
@@ -130,34 +121,41 @@ module Slim
|
|
130
121
|
end # template iterator
|
131
122
|
|
132
123
|
enders.reverse_each do |t|
|
133
|
-
@_buffer << t[0]
|
124
|
+
@_buffer << t[0]
|
134
125
|
end
|
135
126
|
|
136
127
|
@_buffer << "_buf.join;"
|
137
128
|
|
138
|
-
@compiled
|
139
|
-
|
140
|
-
optimize
|
141
|
-
|
142
|
-
return nil
|
129
|
+
@compiled = @_buffer.join
|
130
|
+
@optimized = optimize!
|
143
131
|
end
|
144
132
|
|
145
133
|
private
|
146
134
|
|
135
|
+
def parse_string(string)
|
136
|
+
string = string_skip_escape = $1.strip if string =~ REGEX_LINE_CONTAINS_OUTPUT_CODE
|
137
|
+
string << ' ' if string =~ REGEX_LINE_CONTAINS_ONLY_HTML_TAG
|
138
|
+
parenthesesify_method!(string) if string =~ REGEX_METHOD_HAS_NO_PARENTHESES
|
139
|
+
wraps_with_slim_escape!(string) unless string =~ REGEX_CODE_BLOCK_DETECTED || string_skip_escape
|
140
|
+
|
141
|
+
string.strip
|
142
|
+
end
|
143
|
+
|
147
144
|
# adds a pair of parentheses to the method
|
148
|
-
def parenthesesify_method(string)
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
145
|
+
def parenthesesify_method!(string)
|
146
|
+
string.sub!(' ', '(') && string.sub!(REGEX_CODE_CONTROL_WORD_DETECTED, '\1) \2 \3') || string << ')'
|
147
|
+
end
|
148
|
+
|
149
|
+
# escapes the string
|
150
|
+
def wraps_with_slim_escape!(string)
|
151
|
+
string.sub!(REGEX_LINE_CONTAINS_METHOD_DETECTED, 'Slim.escape_html(\1) \2')
|
153
152
|
end
|
154
153
|
|
155
|
-
# converts 'p#hello.world' to 'p id="hello" class="world"'
|
156
|
-
def normalize_attributes(string)
|
157
|
-
string.sub!(
|
158
|
-
string.sub!(
|
154
|
+
# converts 'p#hello.world.mate' to 'p id="hello" class="world mate"'
|
155
|
+
def normalize_attributes!(string)
|
156
|
+
string.sub!(REGEX_FIND_HTML_ATTR_ID, ' id="\1"')
|
157
|
+
string.sub!(REGEX_FIND_HTML_ATTR_CLASSES, ' class="\1"')
|
159
158
|
string.gsub!('.', ' ')
|
160
|
-
string
|
161
159
|
end
|
162
160
|
end
|
163
|
-
end
|
161
|
+
end
|
data/lib/slim/optimizer.rb
CHANGED
@@ -49,23 +49,22 @@ module Slim
|
|
49
49
|
# _buf << "</body></html>";
|
50
50
|
# _buf.join;
|
51
51
|
module Optimizer
|
52
|
-
def optimize
|
53
|
-
|
54
|
-
string
|
52
|
+
def optimize!
|
53
|
+
optimized = ""
|
54
|
+
string = nil
|
55
55
|
|
56
56
|
@_buffer.each do |line|
|
57
57
|
if line =~ /^_buf << "(.+)"/
|
58
58
|
string ||= ""
|
59
59
|
string << $1
|
60
60
|
else
|
61
|
-
if string
|
62
|
-
|
63
|
-
end
|
64
|
-
@optimized << line
|
61
|
+
optimized << "_buf << \"#{string}\";" if string
|
62
|
+
optimized << line
|
65
63
|
string = nil
|
66
64
|
end
|
67
65
|
end
|
68
|
-
|
66
|
+
|
67
|
+
optimized
|
69
68
|
end
|
70
69
|
end # Optimizer
|
71
70
|
end # Slim
|
data/lib/slim/rails.rb
CHANGED
data/slim.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{slim}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0.beta.1"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Andrew Stone"]
|
12
|
-
s.date = %q{2010-10-
|
12
|
+
s.date = %q{2010-10-14}
|
13
13
|
s.description = %q{Slim is a template language whose goal is reduce the syntax to the essential parts without becoming cryptic.}
|
14
14
|
s.email = %q{andy@stonean.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -17,6 +17,8 @@ Gem::Specification.new do |s|
|
|
17
17
|
]
|
18
18
|
s.files = [
|
19
19
|
".gitignore",
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
20
22
|
"README.md",
|
21
23
|
"Rakefile",
|
22
24
|
"lib/slim.rb",
|
@@ -50,9 +52,18 @@ Gem::Specification.new do |s|
|
|
50
52
|
s.specification_version = 3
|
51
53
|
|
52
54
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
|
+
s.add_runtime_dependency(%q<escape_utils>, [">= 0"])
|
56
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
57
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
53
58
|
else
|
59
|
+
s.add_dependency(%q<escape_utils>, [">= 0"])
|
60
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
61
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
54
62
|
end
|
55
63
|
else
|
64
|
+
s.add_dependency(%q<escape_utils>, [">= 0"])
|
65
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
66
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
56
67
|
end
|
57
68
|
end
|
58
69
|
|
data/test/helper.rb
CHANGED
@@ -13,6 +13,10 @@ class Env
|
|
13
13
|
"notice"
|
14
14
|
end
|
15
15
|
|
16
|
+
def hash
|
17
|
+
{:a => 'The letter a', :b => 'The letter b'}
|
18
|
+
end
|
19
|
+
|
16
20
|
def show_first?(show = false)
|
17
21
|
show
|
18
22
|
end
|
@@ -26,4 +30,8 @@ class Env
|
|
26
30
|
def in_keyword
|
27
31
|
"starts with keyword"
|
28
32
|
end
|
33
|
+
|
34
|
+
def evil_method
|
35
|
+
"<script>do_something_evil();</script>"
|
36
|
+
end
|
29
37
|
end
|
data/test/slim/test_compiler.rb
CHANGED
@@ -188,7 +188,7 @@ p
|
|
188
188
|
= hello_world
|
189
189
|
HTML
|
190
190
|
|
191
|
-
expected = %q|_buf = [];_buf << "<p>";_buf << hello_world;_buf << "</p>";_buf.join;|
|
191
|
+
expected = %q|_buf = [];_buf << "<p>";_buf << Slim.escape_html(hello_world());_buf << "</p>";_buf.join;|
|
192
192
|
|
193
193
|
assert_equal expected, TestEngine.new(string).compiled
|
194
194
|
end
|
@@ -199,7 +199,7 @@ p
|
|
199
199
|
= hello_world(params[:key])
|
200
200
|
HTML
|
201
201
|
|
202
|
-
expected = %q|_buf = [];_buf << "<p>";_buf << hello_world(params[:key]);_buf << "</p>";_buf.join;|
|
202
|
+
expected = %q|_buf = [];_buf << "<p>";_buf << Slim.escape_html(hello_world(params[:key]));_buf << "</p>";_buf.join;|
|
203
203
|
|
204
204
|
assert_equal expected, TestEngine.new(string).compiled
|
205
205
|
end
|
@@ -221,7 +221,7 @@ body
|
|
221
221
|
p id="first" = hello_world
|
222
222
|
TEMPLATE
|
223
223
|
|
224
|
-
expected = %q|_buf = [];_buf << "<body>";_buf << "<p id=\"first\">";_buf << hello_world;_buf << "</p>";_buf << "</body>";_buf.join;|
|
224
|
+
expected = %q|_buf = [];_buf << "<body>";_buf << "<p id=\"first\">";_buf << Slim.escape_html(hello_world());_buf << "</p>";_buf << "</body>";_buf.join;|
|
225
225
|
|
226
226
|
assert_equal expected, TestEngine.new(string).compiled
|
227
227
|
end
|
@@ -232,7 +232,7 @@ body
|
|
232
232
|
p id="first" = hello_world("Hello Ruby!")
|
233
233
|
TEMPLATE
|
234
234
|
|
235
|
-
expected = %q|_buf = [];_buf << "<body>";_buf << "<p id=\"first\">";_buf << hello_world("Hello Ruby!");_buf << "</p>";_buf << "</body>";_buf.join;|
|
235
|
+
expected = %q|_buf = [];_buf << "<body>";_buf << "<p id=\"first\">";_buf << Slim.escape_html(hello_world("Hello Ruby!"));_buf << "</p>";_buf << "</body>";_buf.join;|
|
236
236
|
|
237
237
|
assert_equal expected, TestEngine.new(string).compiled
|
238
238
|
end
|
@@ -243,7 +243,7 @@ body
|
|
243
243
|
p id="first" = hello_world "Hello Ruby!"
|
244
244
|
TEMPLATE
|
245
245
|
|
246
|
-
expected = %q|_buf = [];_buf << "<body>";_buf << "<p id=\"first\">";_buf << hello_world("Hello Ruby!");_buf << "</p>";_buf << "</body>";_buf.join;|
|
246
|
+
expected = %q|_buf = [];_buf << "<body>";_buf << "<p id=\"first\">";_buf << Slim.escape_html(hello_world("Hello Ruby!"));_buf << "</p>";_buf << "</body>";_buf.join;|
|
247
247
|
|
248
248
|
assert_equal expected, TestEngine.new(string).compiled
|
249
249
|
end
|
@@ -254,7 +254,7 @@ body
|
|
254
254
|
p id="first" = hello_world "Hello Ruby!", :dummy => "value"
|
255
255
|
TEMPLATE
|
256
256
|
|
257
|
-
expected = %q|_buf = [];_buf << "<body>";_buf << "<p id=\"first\">";_buf << hello_world("Hello Ruby!", :dummy => "value");_buf << "</p>";_buf << "</body>";_buf.join;|
|
257
|
+
expected = %q|_buf = [];_buf << "<body>";_buf << "<p id=\"first\">";_buf << Slim.escape_html(hello_world("Hello Ruby!", :dummy => "value"));_buf << "</p>";_buf << "</body>";_buf.join;|
|
258
258
|
|
259
259
|
assert_equal expected, TestEngine.new(string).compiled
|
260
260
|
end
|
@@ -307,6 +307,52 @@ TEMPLATE
|
|
307
307
|
assert_equal expected, TestEngine.new(string).compiled
|
308
308
|
end
|
309
309
|
|
310
|
+
def test_call_to_hash
|
311
|
+
string = <<TEMPLATE
|
312
|
+
p = session[:id]
|
313
|
+
TEMPLATE
|
314
|
+
|
315
|
+
expected = %q|_buf = [];_buf << "<p>";_buf << session[:id];_buf << "</p>";_buf.join;|
|
316
|
+
|
317
|
+
assert_equal expected, TestEngine.new(string).compiled
|
318
|
+
end
|
319
|
+
|
320
|
+
def test_escape_escaping
|
321
|
+
string = <<TEMPLATE
|
322
|
+
p == safe_method_call
|
323
|
+
TEMPLATE
|
324
|
+
|
325
|
+
expected = %q|_buf = [];_buf << "<p>";_buf << safe_method_call();_buf << "</p>";_buf.join;|
|
326
|
+
|
327
|
+
assert_equal expected, TestEngine.new(string).compiled
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_ruby_comments
|
331
|
+
string = <<TEMPLATE
|
332
|
+
p
|
333
|
+
/ This is a ruby comment, it won't be displayed in the final render.
|
334
|
+
/ Neither does this line.
|
335
|
+
| But this line should be there.
|
336
|
+
TEMPLATE
|
337
|
+
|
338
|
+
expected = %q|_buf = [];_buf << "<p>";_buf << "But this line should be there.";_buf << "</p>";_buf.join;|
|
339
|
+
|
340
|
+
assert_equal expected, TestEngine.new(string).compiled
|
341
|
+
end
|
342
|
+
|
343
|
+
def test_irregular_spaces
|
344
|
+
string = <<TEMPLATE
|
345
|
+
body
|
346
|
+
p
|
347
|
+
| hey
|
348
|
+
== hello
|
349
|
+
TEMPLATE
|
350
|
+
|
351
|
+
expected = %q|_buf = [];_buf << "<body>";_buf << "<p>";_buf << "hey";_buf << hello();_buf << "</p>";_buf << "</body>";_buf.join;|
|
352
|
+
|
353
|
+
assert_equal expected, TestEngine.new(string).compiled
|
354
|
+
end
|
355
|
+
|
310
356
|
# Use this to do a line by line check. Much easier to see where the problem is.
|
311
357
|
def iterate_it(expected, output)
|
312
358
|
es = expected.split(';')
|
data/test/slim/test_engine.rb
CHANGED
@@ -283,4 +283,24 @@ HTML
|
|
283
283
|
|
284
284
|
assert_equal expected, Slim::Engine.new(string).render(@env)
|
285
285
|
end
|
286
|
+
|
287
|
+
def test_hash_call
|
288
|
+
string = <<HTML
|
289
|
+
p = hash[:a]
|
290
|
+
HTML
|
291
|
+
|
292
|
+
expected = "<p>The letter a</p>"
|
293
|
+
|
294
|
+
assert_equal expected, Slim::Engine.new(string).render(@env)
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_escaping_evil_method
|
298
|
+
string = <<HTML
|
299
|
+
p = evil_method
|
300
|
+
HTML
|
301
|
+
|
302
|
+
expected = "<p><script>do_something_evil();</script></p>"
|
303
|
+
|
304
|
+
assert_equal expected, Slim::Engine.new(string).render(@env)
|
305
|
+
end
|
286
306
|
end
|
metadata
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
4
|
+
prerelease: true
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 6
|
8
|
+
- 0
|
9
|
+
- beta
|
8
10
|
- 1
|
9
|
-
version: 0.
|
11
|
+
version: 0.6.0.beta.1
|
10
12
|
platform: ruby
|
11
13
|
authors:
|
12
14
|
- Andrew Stone
|
@@ -14,10 +16,48 @@ autorequire:
|
|
14
16
|
bindir: bin
|
15
17
|
cert_chain: []
|
16
18
|
|
17
|
-
date: 2010-10-
|
19
|
+
date: 2010-10-14 00:00:00 +11:00
|
18
20
|
default_executable:
|
19
|
-
dependencies:
|
20
|
-
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: escape_utils
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
prerelease: false
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rake
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
segments:
|
43
|
+
- 0
|
44
|
+
version: "0"
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: jeweler
|
50
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
prerelease: false
|
60
|
+
version_requirements: *id003
|
21
61
|
description: Slim is a template language whose goal is reduce the syntax to the essential parts without becoming cryptic.
|
22
62
|
email: andy@stonean.com
|
23
63
|
executables: []
|
@@ -28,6 +68,8 @@ extra_rdoc_files:
|
|
28
68
|
- README.md
|
29
69
|
files:
|
30
70
|
- .gitignore
|
71
|
+
- Gemfile
|
72
|
+
- Gemfile.lock
|
31
73
|
- README.md
|
32
74
|
- Rakefile
|
33
75
|
- lib/slim.rb
|
@@ -56,17 +98,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
56
98
|
requirements:
|
57
99
|
- - ">="
|
58
100
|
- !ruby/object:Gem::Version
|
101
|
+
hash: -4287789825889488572
|
59
102
|
segments:
|
60
103
|
- 0
|
61
104
|
version: "0"
|
62
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
106
|
none: false
|
64
107
|
requirements:
|
65
|
-
- - "
|
108
|
+
- - ">"
|
66
109
|
- !ruby/object:Gem::Version
|
67
110
|
segments:
|
68
|
-
-
|
69
|
-
|
111
|
+
- 1
|
112
|
+
- 3
|
113
|
+
- 1
|
114
|
+
version: 1.3.1
|
70
115
|
requirements: []
|
71
116
|
|
72
117
|
rubyforge_project: slim
|