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 CHANGED
@@ -3,3 +3,4 @@ pkg
3
3
  readme.html
4
4
  .yardoc/
5
5
  doc/
6
+ .bundle/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
@@ -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
- # Either start on the same line as the tag
68
+ # Either start on the same line as the tag
69
69
 
70
- body
71
- h1 id="headline" Welcome to my site.
70
+ body
71
+ h1 id="headline" Welcome to my site.
72
72
 
73
- # Or nest it. __Note:__ Must use a pipe or a backtick (followed by a space) to escape processing
73
+ # Or nest it. __Note:__ Must use a pipe or a backtick (followed by a space) to escape processing
74
74
 
75
- body
76
- h1 id="headline"
77
- | Welcome to my site.
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
- # Can make the call on the same line
81
+ # Can make the call on the same line
82
82
 
83
- body
84
- h1 id="headline" = page_headline
83
+ body
84
+ h1 id="headline" = page_headline
85
85
 
86
- # Or nest it.
86
+ # Or nest it.
87
87
 
88
- body
89
- h1 id="headline"
90
- = page_headline
88
+ body
89
+ h1 id="headline"
90
+ = page_headline
91
91
 
92
92
  #### Shortcut form for `id` and `class` attributes
93
93
 
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
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
- body
99
- h1#headline
100
- = page_headline
101
- h2#tagline.small.tagline
102
- = page_tagline
103
- .content
104
- = show_content
98
+ body
99
+ h1#headline
100
+ = page_headline
101
+ h2#tagline.small.tagline
102
+ = page_tagline
103
+ .content
104
+ = show_content
105
105
 
106
- # this is the same as
106
+ # this is the same as
107
107
 
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
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
- # Just use standard Ruby interpolation.
118
+ # Just use standard Ruby interpolation.
119
119
 
120
- body
121
- table
122
- - for user in users do
123
- tr id="user_#{user.id}"
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
- # Use a backtick to start the escape. Each following line that is
129
- # indented greater than the backtick is copied over.
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
- body
132
- p
133
- |
134
- This is a test of the text block.
138
+ body
139
+ p
140
+ |
141
+ This is a test of the text block.
135
142
 
136
- # The parsed result of the above:
143
+ # The parsed result of the above:
137
144
 
138
- <body><p>This is a test of the text block.</p></body>
145
+ <body><p>This is a test of the text block.</p></body>
139
146
 
140
- # The left margin is set at the indent of the backtick + one space.
141
- # Any additional spaces will be copied over.
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
- body
144
- p
145
- |
146
- This line is on the left margin.
147
- This line will have one space in front of it.
148
- This line will have two spaces in front of it.
149
- And so on...
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
@@ -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.5.1'
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
@@ -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*)(!?`?\|?-?=?\w*)((?:\s*(?:\w|-)*="[^=]+")+|(\s*[#.]\S+))?(.*)/
13
+ REGEX_LINE_PARSER = /^(\s*)(!?`?\|?-?=?\/?\w*)((?:\s*(?:\w|-)*="[^=]+")+|(\s*[#.]\S+))?(.*)/
14
14
  REGEX_LINE_CONTAINS_OUTPUT_CODE = /^=(.*)/
15
- REGEX_METHOD_HAS_NO_PARENTHESES = /^\w+( )/
16
- REGEX_CODE_BLOCK_DETECTED = / do ?(.*)$/
17
- REGEX_CODE_CONTROL_WORD_DETECTED = /(?:( )|(\())(#{CONTROL_WORDS * '|'})\b ?(.*)$/
18
- REGEX_CODE_ELSE_CONTROL_WORD_DETECTED = /^(#{ELSE_CONTROL_WORDS * '|'})\b/
19
- REGEX_FIND_ATTR_ID = /#([^.\s]+)/
20
- REGEX_FIND_ATTR_CLASS = /\.([^#\s]+)/
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 = ["_buf = [];"]
24
- @in_text = false
25
-
26
- text_indent = last_indent = -1; enders = []
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!; line.rstrip!
31
+ line.chomp!
32
+ line.rstrip!
30
33
 
31
34
  if line.length == 0
32
- @_buffer << "_buf << \"<br/>\";" if @in_text
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 @in_text && indent > text_indent
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
- attrs = normalize_attributes(attrs) if shortcut_attrs
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
- if ender_indent >= indent
86
- unless ender == 'end;' && line_type == :control_code && ender_indent == indent && string =~ REGEX_CODE_ELSE_CONTROL_WORD_DETECTED
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
- if string
98
+ unless string.empty?
108
99
  string.lstrip!
109
100
  if string =~ REGEX_LINE_CONTAINS_OUTPUT_CODE
110
- @_buffer << "_buf << #{parenthesesify_method($1.strip)};"
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
- @in_text = true
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 << #{parenthesesify_method(string)};"
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].to_s
124
+ @_buffer << t[0]
134
125
  end
135
126
 
136
127
  @_buffer << "_buf.join;"
137
128
 
138
- @compiled = @_buffer.join
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
- if string =~ REGEX_METHOD_HAS_NO_PARENTHESES
150
- string.sub!(' ', '(') && string.sub!(REGEX_CODE_CONTROL_WORD_DETECTED, '\2) \3 \4') || string << ')'
151
- end
152
- string
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!(REGEX_FIND_ATTR_ID, ' id="\1"')
158
- string.sub!(REGEX_FIND_ATTR_CLASS, ' class="\1"')
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
@@ -49,23 +49,22 @@ module Slim
49
49
  # _buf << "</body></html>";
50
50
  # _buf.join;
51
51
  module Optimizer
52
- def optimize
53
- @optimized = ""
54
- string = nil
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
- @optimized << "_buf << \"#{string}\";"
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
- return nil
66
+
67
+ optimized
69
68
  end
70
69
  end # Optimizer
71
70
  end # Slim
@@ -12,6 +12,4 @@ module ActionView
12
12
  end
13
13
 
14
14
  Template.register_default_template_handler :slim, TemplateHandlers::SlimHandler
15
- end
16
-
17
- puts ">> Slim (v#{Slim.version})"
15
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{slim}
8
- s.version = "0.5.1"
8
+ s.version = "0.6.0.beta.1"
9
9
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
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-08}
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
 
@@ -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
@@ -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(';')
@@ -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>&lt;script&gt;do_something_evil();&lt;&#47;script&gt;</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: false
4
+ prerelease: true
5
5
  segments:
6
6
  - 0
7
- - 5
7
+ - 6
8
+ - 0
9
+ - beta
8
10
  - 1
9
- version: 0.5.1
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-08 00:00:00 +11:00
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
- - 0
69
- version: "0"
111
+ - 1
112
+ - 3
113
+ - 1
114
+ version: 1.3.1
70
115
  requirements: []
71
116
 
72
117
  rubyforge_project: slim