slim 1.3.9 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -8
- data/.travis.yml +8 -7
- data/CHANGES +35 -0
- data/Gemfile +9 -9
- data/README.md +94 -176
- data/Rakefile +7 -14
- data/benchmarks/run-benchmarks.rb +9 -37
- data/doc/logic_less.md +140 -0
- data/doc/translator.md +31 -0
- data/lib/slim.rb +3 -1
- data/lib/slim/code_attributes.rb +20 -20
- data/lib/slim/command.rb +16 -6
- data/lib/slim/do_inserter.rb +33 -0
- data/lib/slim/embedded.rb +0 -6
- data/lib/slim/end_inserter.rb +2 -2
- data/lib/slim/engine.rb +9 -23
- data/lib/slim/erb_converter.rb +14 -0
- data/lib/slim/filter.rb +2 -2
- data/lib/slim/logic_less/context.rb +8 -0
- data/lib/slim/logic_less/filter.rb +12 -11
- data/lib/slim/parser.rb +57 -113
- data/lib/slim/splat/builder.rb +79 -0
- data/lib/slim/splat/filter.rb +93 -0
- data/lib/slim/version.rb +1 -1
- data/slim.gemspec +1 -1
- data/test/core/helper.rb +1 -3
- data/test/core/test_code_blocks.rb +51 -0
- data/test/core/test_code_evaluation.rb +4 -12
- data/test/core/test_embedded_engines.rb +18 -44
- data/test/core/test_encoding.rb +8 -1
- data/test/core/test_erb_converter.rb +67 -0
- data/test/core/test_html_attributes.rb +19 -25
- data/test/core/test_html_escaping.rb +10 -2
- data/test/core/test_html_structure.rb +6 -6
- data/test/core/test_parser_errors.rb +1 -1
- data/test/core/test_ruby_errors.rb +2 -6
- data/test/core/test_thread_options.rb +4 -4
- data/test/core/test_unicode.rb +18 -0
- data/test/literate/TESTS.md +193 -34
- data/test/logic_less/test_logic_less.rb +17 -0
- data/test/rails/app/controllers/application_controller.rb +0 -1
- data/test/rails/app/controllers/entries_controller.rb +5 -0
- data/test/rails/app/controllers/slim_controller.rb +3 -0
- data/test/rails/app/models/entry.rb +16 -0
- data/test/rails/app/views/entries/edit.html.slim +3 -0
- data/test/rails/app/views/slim/form_for.html.slim +2 -0
- data/test/rails/app/views/slim/xml.slim +1 -0
- data/test/rails/config/application.rb +2 -2
- data/test/rails/config/environments/test.rb +1 -1
- data/test/rails/config/routes.rb +1 -1
- data/test/rails/test/helper.rb +0 -3
- data/test/rails/test/test_slim.rb +13 -8
- data/test/translator/test_translator.rb +13 -2
- metadata +17 -14
- data/lib/slim/splat_attributes.rb +0 -113
- data/test/rails/app/controllers/parents_controller.rb +0 -85
- data/test/rails/app/models/child.rb +0 -3
- data/test/rails/app/models/parent.rb +0 -4
- data/test/rails/app/views/parents/_form.html.slim +0 -8
- data/test/rails/app/views/parents/edit.html.slim +0 -2
- data/test/rails/app/views/parents/new.html.slim +0 -2
- data/test/rails/app/views/parents/show.html.slim +0 -5
- data/test/rails/config/database.yml +0 -4
- data/test/rails/db/migrate/20101220223037_parents_and_children.rb +0 -17
data/Rakefile
CHANGED
@@ -51,8 +51,14 @@ namespace 'test' do
|
|
51
51
|
require 'sinatra'
|
52
52
|
spec = Gem::Specification.find_by_name('sinatra')
|
53
53
|
Rake::TestTask.new('sinatra') do |t|
|
54
|
+
# FIXME: Rename deprecated attribute
|
55
|
+
file = "#{spec.gem_dir}/test/slim_test.rb"
|
56
|
+
code = File.read(file)
|
57
|
+
code.gsub!('attr_wrapper', 'attr_quote')
|
58
|
+
File.open(file, 'w') {|out| out.write(code) }
|
59
|
+
|
54
60
|
# Run Slim integration test in Sinatra
|
55
|
-
t.test_files = FileList[
|
61
|
+
t.test_files = FileList[file]
|
56
62
|
t.verbose = true
|
57
63
|
end
|
58
64
|
rescue LoadError
|
@@ -62,19 +68,6 @@ namespace 'test' do
|
|
62
68
|
end
|
63
69
|
end
|
64
70
|
|
65
|
-
begin
|
66
|
-
require 'rcov/rcovtask'
|
67
|
-
Rcov::RcovTask.new do |t|
|
68
|
-
t.libs << 'lib' << 'test/slim'
|
69
|
-
t.test_files = FileList['test/slim/test_*.rb']
|
70
|
-
t.verbose = true
|
71
|
-
end
|
72
|
-
rescue LoadError
|
73
|
-
task :rcov do
|
74
|
-
abort 'RCov is not available. In order to run rcov, you must: gem install rcov'
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
71
|
begin
|
79
72
|
require 'yard'
|
80
73
|
YARD::Rake::YardocTask.new do |t|
|
@@ -22,7 +22,6 @@ class SlimBenchmarks
|
|
22
22
|
|
23
23
|
init_compiled_benches
|
24
24
|
init_tilt_benches
|
25
|
-
init_cached_benches
|
26
25
|
init_parsing_benches if slow
|
27
26
|
end
|
28
27
|
|
@@ -76,41 +75,18 @@ class SlimBenchmarks
|
|
76
75
|
bench('(2) haml ugly') { tilt_haml_ugly.render(context) }
|
77
76
|
end
|
78
77
|
|
79
|
-
def init_cached_benches
|
80
|
-
context = Context.new
|
81
|
-
context_binding = context.instance_eval { binding }
|
82
|
-
|
83
|
-
erb = ERB.new(@erb_code)
|
84
|
-
erubis = Erubis::Eruby.new(@erb_code)
|
85
|
-
fast_erubis = Erubis::FastEruby.new(@erb_code)
|
86
|
-
temple_erb = Temple::ERB::Template.new { @erb_code }
|
87
|
-
haml_pretty = Haml::Engine.new(@haml_code, :format => :html5)
|
88
|
-
haml_ugly = Haml::Engine.new(@haml_code, :format => :html5, :ugly => true)
|
89
|
-
slim_pretty = Slim::Template.new(:pretty => true) { @slim_code }
|
90
|
-
slim_ugly = Slim::Template.new { @slim_code }
|
91
|
-
|
92
|
-
bench('(3) erb') { erb.result(context_binding) }
|
93
|
-
bench('(3) erubis') { erubis.result(context_binding) }
|
94
|
-
bench('(3) fast erubis') { fast_erubis.result(context_binding) }
|
95
|
-
bench('(3) temple erb') { temple_erb.render(context) }
|
96
|
-
bench('(3) slim pretty') { slim_pretty.render(context) }
|
97
|
-
bench('(3) slim ugly') { slim_ugly.render(context) }
|
98
|
-
bench('(3) haml pretty') { haml_pretty.render(context) }
|
99
|
-
bench('(3) haml ugly') { haml_ugly.render(context) }
|
100
|
-
end
|
101
|
-
|
102
78
|
def init_parsing_benches
|
103
79
|
context = Context.new
|
104
80
|
context_binding = context.instance_eval { binding }
|
105
81
|
|
106
|
-
bench('(
|
107
|
-
bench('(
|
108
|
-
bench('(
|
109
|
-
bench('(
|
110
|
-
bench('(
|
111
|
-
bench('(
|
112
|
-
bench('(
|
113
|
-
bench('(
|
82
|
+
bench('(3) erb') { ERB.new(@erb_code).result(context_binding) }
|
83
|
+
bench('(3) erubis') { Erubis::Eruby.new(@erb_code).result(context_binding) }
|
84
|
+
bench('(3) fast erubis') { Erubis::FastEruby.new(@erb_code).result(context_binding) }
|
85
|
+
bench('(3) temple erb') { Temple::ERB::Template.new { @erb_code }.render(context) }
|
86
|
+
bench('(3) slim pretty') { Slim::Template.new(:pretty => true) { @slim_code }.render(context) }
|
87
|
+
bench('(3) slim ugly') { Slim::Template.new { @slim_code }.render(context) }
|
88
|
+
bench('(3) haml pretty') { Haml::Engine.new(@haml_code, :format => :html5).render(context) }
|
89
|
+
bench('(3) haml ugly') { Haml::Engine.new(@haml_code, :format => :html5, :ugly => true).render(context) }
|
114
90
|
end
|
115
91
|
|
116
92
|
def run
|
@@ -133,11 +109,7 @@ class SlimBenchmarks
|
|
133
109
|
Sinatra, Ramaze and Camping. (Rails still uses its own template
|
134
110
|
compilation.)
|
135
111
|
|
136
|
-
(3)
|
137
|
-
The ruby code generated by the template engine might be evaluated every time.
|
138
|
-
This benchmark uses the standard API of the template engine.
|
139
|
-
|
140
|
-
(4) Parsing benchmark. Template is parsed every time.
|
112
|
+
(3) Parsing benchmark. Template is parsed every time.
|
141
113
|
This is not the recommended way to use the template engine
|
142
114
|
and Slim is not optimized for it. Activate this benchmark with 'rake bench slow=1'.
|
143
115
|
|
data/doc/logic_less.md
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
# Logic less mode
|
2
|
+
|
3
|
+
Logic less mode is inspired by [Mustache](https://github.com/defunkt/mustache). Logic less mode uses a dictionary object
|
4
|
+
e.g. a recursive hash tree which contains the dynamic content.
|
5
|
+
|
6
|
+
## Conditional
|
7
|
+
|
8
|
+
If the object is not false or empty?, the content will show
|
9
|
+
|
10
|
+
- article
|
11
|
+
h1 = title
|
12
|
+
|
13
|
+
## Inverted conditional
|
14
|
+
|
15
|
+
If the object is false or empty?, the content will show
|
16
|
+
|
17
|
+
-! article
|
18
|
+
p Sorry, article not found
|
19
|
+
|
20
|
+
## Iteration
|
21
|
+
|
22
|
+
If the object is an array, the section will iterate
|
23
|
+
|
24
|
+
- articles
|
25
|
+
tr: td = title
|
26
|
+
|
27
|
+
## Lambdas
|
28
|
+
|
29
|
+
Like mustache, Slim supports lambdas.
|
30
|
+
|
31
|
+
= person
|
32
|
+
= name
|
33
|
+
|
34
|
+
The lambda method could be defined like this
|
35
|
+
|
36
|
+
def lambda_method
|
37
|
+
"<div class='person'>#{yield(:name => 'Andrew')}</div>"
|
38
|
+
end
|
39
|
+
|
40
|
+
You can optionally pass one or more hashes to `yield`. If you pass multiple hashes, the block will be iterated as described above.
|
41
|
+
|
42
|
+
## Dictionary access
|
43
|
+
|
44
|
+
Example code:
|
45
|
+
|
46
|
+
- article
|
47
|
+
h1 = title
|
48
|
+
|
49
|
+
The dictionary object is accessed in the order given by the `:dictionary_access`. Default order:
|
50
|
+
|
51
|
+
1. `:symbol` - If `article.respond_to?(:has_key?)` and `article.has_key?(:title)`, Slim will execute `article[:title]`
|
52
|
+
2. `:string` - If `article.respond_to?(:has_key?)` and `article.has_key?('title')`, Slim will execute `article['title']`
|
53
|
+
3. `:method` - If `article.respond_to?(:title)`, Slim will execute `article.send(:title)`
|
54
|
+
4. `:instance_variable` - If `article.instance_variable_defined?(@title)`, Slim will execute `article.instance_variable_get @title`
|
55
|
+
|
56
|
+
If all the above fails, Slim will try to resolve the title reference in the same order against the parent object. In this example, the parent would be the dictionary object you are rendering the template against.
|
57
|
+
|
58
|
+
As you might have guessed, the article reference goes through the same steps against the dictionary. Instance variables are not allowed in the view code, but Slim will find and use them. Essentially, you're just using dropping the @ prefix in your template. Parameterized method calls are not allowed.
|
59
|
+
|
60
|
+
|
61
|
+
## Strings
|
62
|
+
|
63
|
+
The `self` keyword will return the `.to_s` value for the element under consideration.
|
64
|
+
|
65
|
+
Given
|
66
|
+
|
67
|
+
{
|
68
|
+
:article => [
|
69
|
+
'Article 1',
|
70
|
+
'Article 2'
|
71
|
+
]
|
72
|
+
}
|
73
|
+
|
74
|
+
And
|
75
|
+
|
76
|
+
- article
|
77
|
+
tr: td = self
|
78
|
+
|
79
|
+
This will yield
|
80
|
+
|
81
|
+
<tr>
|
82
|
+
<td>Article 1</td>
|
83
|
+
</>
|
84
|
+
<tr>
|
85
|
+
<td>Article 2</td>
|
86
|
+
</tr>
|
87
|
+
|
88
|
+
|
89
|
+
## Logic less in Rails
|
90
|
+
|
91
|
+
Install:
|
92
|
+
|
93
|
+
$ gem install slim
|
94
|
+
|
95
|
+
Require:
|
96
|
+
|
97
|
+
gem 'slim', :require => 'slim/logic_less'
|
98
|
+
|
99
|
+
You might want to activate logic less mode only for a few actions, you should disable logic-less mode globally at first in the configuration
|
100
|
+
|
101
|
+
Slim::Engine.set_default_options :logic_less => false
|
102
|
+
|
103
|
+
and activate logic less mode per render call in your action
|
104
|
+
|
105
|
+
class Controller
|
106
|
+
def action
|
107
|
+
Slim::Engine.with_options(:logic_less => true) do
|
108
|
+
render
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
## Logic less in Sinatra
|
114
|
+
|
115
|
+
Sinata has built-in support for Slim. All you have to do is require the logic less Slim plugin. This can be done in your config.ru:
|
116
|
+
|
117
|
+
require 'slim/logic_less'
|
118
|
+
|
119
|
+
You are then ready to rock!
|
120
|
+
|
121
|
+
You might want to activate logic less mode only for a few actions, you should disable logic-less mode globally at first in the configuration
|
122
|
+
|
123
|
+
Slim::Engine.set_default_options :logic_less => false
|
124
|
+
|
125
|
+
and activate logic less mode per render call in your application
|
126
|
+
|
127
|
+
get '/page'
|
128
|
+
slim :page, :logic_less => true
|
129
|
+
end
|
130
|
+
|
131
|
+
## Options
|
132
|
+
|
133
|
+
<table>
|
134
|
+
<thead style="font-weight:bold"><tr><td>Type</td><td>Name</td><td>Default</td><td>Purpose</td></tr></thead>
|
135
|
+
<tbody>
|
136
|
+
<tr><td>Boolean</td><td>:logic_less</td><td>true</td><td>Enable logic less mode (Enabled if 'slim/logic_less' is required)</td></tr>
|
137
|
+
<tr><td>String</td><td>:dictionary</td><td>"self"</td><td>Dictionary where variables are looked up</td></tr>
|
138
|
+
<tr><td>Symbol/Array<Symbol></td><td>:dictionary_access</td><td>[:symbol, :string, :method, :instance_variable]</td><td>Dictionary access order (:symbol, :string, :method, :instance_variable)</td></tr>
|
139
|
+
</tbody>
|
140
|
+
</table>
|
data/doc/translator.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Translator/I18n
|
2
|
+
|
3
|
+
The translator plugin provides automatic translation of the templates using Gettext, Fast-Gettext or Rails I18n. Static text
|
4
|
+
in the template is replaced by the translated version.
|
5
|
+
|
6
|
+
Example:
|
7
|
+
|
8
|
+
h1 Welcome to #{url}!
|
9
|
+
|
10
|
+
Gettext translates the string from english to german where interpolations are replaced by %1, %2, ...
|
11
|
+
|
12
|
+
"Welcome to %1!" -> "Willkommen auf %1!"
|
13
|
+
|
14
|
+
and renders as
|
15
|
+
|
16
|
+
<h1>Willkommen auf slim-lang.com!</h1>
|
17
|
+
|
18
|
+
Enable the translator plugin with
|
19
|
+
|
20
|
+
require 'slim/translator'
|
21
|
+
|
22
|
+
# Options
|
23
|
+
|
24
|
+
<table>
|
25
|
+
<thead style="font-weight:bold"><tr><td>Type</td><td>Name</td><td>Default</td><td>Purpose</td></tr></thead>
|
26
|
+
<tbody>
|
27
|
+
<tr><td>Boolean</td><td>:tr</td><td>true</td><td>Enable translator (Enabled if 'slim/translator' is required)</td></tr>
|
28
|
+
<tr><td>Symbol</td><td>:tr_mode</td><td>:dynamic</td><td>When to translate: :static = at compile time, :dynamic = at runtime</td></tr>
|
29
|
+
<tr><td>String</td><td>:tr_fn</td><td>Depending on installed translation library</td><td>Translation function, could be '_' for gettext</td></tr>
|
30
|
+
</tbody>
|
31
|
+
</table>
|
data/lib/slim.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require 'temple'
|
2
2
|
require 'slim/parser'
|
3
3
|
require 'slim/filter'
|
4
|
+
require 'slim/do_inserter'
|
4
5
|
require 'slim/end_inserter'
|
5
6
|
require 'slim/embedded'
|
6
7
|
require 'slim/interpolation'
|
7
8
|
require 'slim/controls'
|
8
|
-
require 'slim/
|
9
|
+
require 'slim/splat/filter'
|
10
|
+
require 'slim/splat/builder'
|
9
11
|
require 'slim/code_attributes'
|
10
12
|
require 'slim/engine'
|
11
13
|
require 'slim/template'
|
data/lib/slim/code_attributes.rb
CHANGED
@@ -11,34 +11,34 @@ module Slim
|
|
11
11
|
[:multi, *attrs.map {|a| compile(a) }]
|
12
12
|
end
|
13
13
|
|
14
|
-
# Handle attribute expression `[:
|
14
|
+
# Handle attribute expression `[:html, :attr, escape, code]`
|
15
15
|
#
|
16
16
|
# @param [String] name Attribute name
|
17
17
|
# @param [Array] value Value expression
|
18
18
|
# @return [Array] Compiled temple expression
|
19
19
|
def on_html_attr(name, value)
|
20
|
-
|
21
|
-
# We
|
20
|
+
if value[0] == :slim && value[1] == :attrvalue && !options[:merge_attrs][name]
|
21
|
+
# We handle the attribute as a boolean attribute
|
22
|
+
escape, code = value[2], value[3]
|
23
|
+
case code
|
24
|
+
when 'true'
|
25
|
+
[:html, :attr, name, [:static, name]]
|
26
|
+
when 'false', 'nil'
|
27
|
+
[:multi]
|
28
|
+
else
|
29
|
+
tmp = unique_name
|
30
|
+
[:multi,
|
31
|
+
[:code, "#{tmp} = #{code}"],
|
32
|
+
[:case, tmp,
|
33
|
+
['true', [:html, :attr, name, [:static, name]]],
|
34
|
+
['false, nil', [:multi]],
|
35
|
+
[:else, [:html, :attr, name, [:escape, escape, [:dynamic, tmp]]]]]]
|
36
|
+
end
|
37
|
+
else
|
38
|
+
# Attribute with merging
|
22
39
|
@attr = name
|
23
40
|
return super
|
24
41
|
end
|
25
|
-
|
26
|
-
# We handle the attribute as a boolean attribute
|
27
|
-
escape, code = value[2], value[3]
|
28
|
-
case code
|
29
|
-
when 'true'
|
30
|
-
[:html, :attr, name, [:static, name]]
|
31
|
-
when 'false', 'nil'
|
32
|
-
[:multi]
|
33
|
-
else
|
34
|
-
tmp = unique_name
|
35
|
-
[:multi,
|
36
|
-
[:code, "#{tmp} = #{code}"],
|
37
|
-
[:case, tmp,
|
38
|
-
['true', [:html, :attr, name, [:static, name]]],
|
39
|
-
['false, nil', [:multi]],
|
40
|
-
[:else, [:html, :attr, name, [:escape, escape, [:dynamic, tmp]]]]]]
|
41
|
-
end
|
42
42
|
end
|
43
43
|
|
44
44
|
# Handle attribute expression `[:slim, :attrvalue, escape, code]`
|
data/lib/slim/command.rb
CHANGED
@@ -42,6 +42,10 @@ module Slim
|
|
42
42
|
@options[:compile] = true
|
43
43
|
end
|
44
44
|
|
45
|
+
opts.on('-e', '--erb', 'Convert to ERB') do
|
46
|
+
@options[:erb] = true
|
47
|
+
end
|
48
|
+
|
45
49
|
opts.on('-r', '--rails', 'Generate rails compatible code (Implies --compile)') do
|
46
50
|
Engine.set_default_options :disable_capture => true, :generator => Temple::Generators::RailsOutputBuffer
|
47
51
|
@options[:compile] = true
|
@@ -70,7 +74,7 @@ module Slim
|
|
70
74
|
end
|
71
75
|
|
72
76
|
opts.on_tail('-v', '--version', 'Print version') do
|
73
|
-
puts "Slim #{
|
77
|
+
puts "Slim #{VERSION}"
|
74
78
|
exit
|
75
79
|
end
|
76
80
|
end
|
@@ -94,11 +98,17 @@ module Slim
|
|
94
98
|
@options[:output] = file ? File.open(file, 'w') : $stdout
|
95
99
|
end
|
96
100
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
101
|
+
result =
|
102
|
+
if @options[:erb]
|
103
|
+
require 'slim/erb_converter'
|
104
|
+
ERBConverter.new(:file => @options[:file]).call(@options[:input].read)
|
105
|
+
elsif @options[:compile]
|
106
|
+
Engine.new(:file => @options[:file]).call(@options[:input].read)
|
107
|
+
else
|
108
|
+
Template.new(@options[:file]) { @options[:input].read }.render
|
109
|
+
end
|
110
|
+
|
111
|
+
@options[:output].puts(result)
|
102
112
|
end
|
103
113
|
end
|
104
114
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Slim
|
2
|
+
# In Slim you don't need the do keyword sometimes. This
|
3
|
+
# filter adds the missing keyword.
|
4
|
+
#
|
5
|
+
# - 10.times
|
6
|
+
# | Hello
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class DoInserter < Filter
|
10
|
+
BLOCK_REGEX = /(\A(if|unless|else|elsif|when|begin|rescue|ensure)\b)|do\s*(\|[^\|]*\|\s*)?\Z/
|
11
|
+
|
12
|
+
# Handle control expression `[:slim, :control, code, content]`
|
13
|
+
#
|
14
|
+
# @param [String] code Ruby code
|
15
|
+
# @param [Array] content Temple expression
|
16
|
+
# @return [Array] Compiled temple expression
|
17
|
+
def on_slim_control(code, content)
|
18
|
+
code = code + ' do' unless code =~ BLOCK_REGEX || empty_exp?(content)
|
19
|
+
[:slim, :control, code, compile(content)]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Handle output expression `[:slim, :output, escape, code, content]`
|
23
|
+
#
|
24
|
+
# @param [Boolean] escape Escape html
|
25
|
+
# @param [String] code Ruby code
|
26
|
+
# @param [Array] content Temple expression
|
27
|
+
# @return [Array] Compiled temple expression
|
28
|
+
def on_slim_output(escape, code, content)
|
29
|
+
code = code + ' do' unless code =~ BLOCK_REGEX || empty_exp?(content)
|
30
|
+
[:slim, :output, escape, code, compile(content)]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/slim/embedded.rb
CHANGED
@@ -268,10 +268,4 @@ module Slim
|
|
268
268
|
# Embedded ruby code
|
269
269
|
register :ruby, RubyEngine
|
270
270
|
end
|
271
|
-
|
272
|
-
def self.const_missing(name)
|
273
|
-
super unless name == :EmbeddedEngine
|
274
|
-
warn 'Slim::EmbeddedEngine is deprecated, it is called Slim::Embedded in Slim 2.0'
|
275
|
-
Embedded
|
276
|
-
end
|
277
271
|
end
|
data/lib/slim/end_inserter.rb
CHANGED
@@ -10,7 +10,7 @@ module Slim
|
|
10
10
|
#
|
11
11
|
# @api private
|
12
12
|
class EndInserter < Filter
|
13
|
-
|
13
|
+
BLOCK_REGEX = /\A(else|elsif|when|rescue|ensure)\b/
|
14
14
|
END_REGEX = /\Aend\b/
|
15
15
|
|
16
16
|
# Handle multi expression `[:multi, *exps]`
|
@@ -28,7 +28,7 @@ module Slim
|
|
28
28
|
|
29
29
|
# Two control code in a row. If this one is *not*
|
30
30
|
# an else block, we should close the previous one.
|
31
|
-
append_end(result) if prev_indent && exp[2] !~
|
31
|
+
append_end(result) if prev_indent && exp[2] !~ BLOCK_REGEX
|
32
32
|
|
33
33
|
# Indent if the control code contains something.
|
34
34
|
prev_indent = !empty_exp?(exp[3])
|