slim 0.5.1 → 0.6.0.beta.1
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/.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
|