slim 4.1.0 → 5.0.0

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/lib/slim/embedded.rb CHANGED
@@ -30,7 +30,7 @@ module Slim
30
30
  # @api private
31
31
  class OutputProtector < Filter
32
32
  def call(exp)
33
- @protect, @collected, @tag = [], '', "%#{object_id.abs.to_s(36)}%"
33
+ @protect, @collected, @tag = [], '', object_id.abs.to_s(36)
34
34
  super(exp)
35
35
  @collected
36
36
  end
@@ -41,16 +41,16 @@ module Slim
41
41
  end
42
42
 
43
43
  def on_slim_output(escape, text, content)
44
- @collected << @tag
44
+ @collected << "%#{@tag}%#{@protect.length}%"
45
45
  @protect << [:slim, :output, escape, text, content]
46
46
  nil
47
47
  end
48
48
 
49
49
  def unprotect(text)
50
50
  block = [:multi]
51
- while text =~ /#{@tag}/
51
+ while text =~ /%#{@tag}%(\d+)%/
52
52
  block << [:static, $`]
53
- block << @protect.shift
53
+ block << @protect[$1.to_i]
54
54
  text = $'
55
55
  end
56
56
  block << [:static, text]
@@ -155,7 +155,7 @@ module Slim
155
155
  text = tilt_engine.new(tilt_options.merge(
156
156
  style: options[:pretty] ? :expanded : :compressed,
157
157
  cache: false)) { text }.render
158
- text.chomp!
158
+ text = text.chomp
159
159
  [:static, text]
160
160
  end
161
161
  end
@@ -185,6 +185,7 @@ module Slim
185
185
  # Generates a html tag and wraps another engine (specified via :engine option)
186
186
  class TagEngine < Engine
187
187
  disable_option_validator!
188
+ set_options attributes: {}
188
189
 
189
190
  def on_slim_embedded(engine, body, attrs)
190
191
 
@@ -213,7 +214,7 @@ module Slim
213
214
  class JavaScriptEngine < TagEngine
214
215
  disable_option_validator!
215
216
 
216
- set_options tag: :script, attributes: {}
217
+ set_options tag: :script
217
218
 
218
219
  def on_slim_embedded(engine, body, attrs)
219
220
  super(engine, [:html, :js, body], attrs)
@@ -233,14 +234,14 @@ module Slim
233
234
  register :rdoc, InterpolateTiltEngine
234
235
 
235
236
  # These engines are executed at compile time
236
- register :coffee, JavaScriptEngine, engine: TiltEngine
237
- register :less, TagEngine, tag: :style, attributes: { type: 'text/css' }, engine: TiltEngine
238
- register :sass, TagEngine, :pretty, tag: :style, attributes: { type: 'text/css' }, engine: SassEngine
239
- register :scss, TagEngine, :pretty, tag: :style, attributes: { type: 'text/css' }, engine: SassEngine
237
+ register :coffee, JavaScriptEngine, engine: TiltEngine
238
+ register :less, TagEngine, tag: :style, engine: TiltEngine
239
+ register :sass, TagEngine, :pretty, tag: :style, engine: SassEngine
240
+ register :scss, TagEngine, :pretty, tag: :style, engine: SassEngine
240
241
 
241
242
  # Embedded javascript/css
242
243
  register :javascript, JavaScriptEngine
243
- register :css, TagEngine, tag: :style, attributes: { type: 'text/css' }
244
+ register :css, TagEngine, tag: :style
244
245
 
245
246
  # Embedded ruby code
246
247
  register :ruby, RubyEngine
@@ -10,8 +10,8 @@ module Slim
10
10
  #
11
11
  # @api private
12
12
  class EndInserter < Filter
13
- IF_RE = /\A(if|begin|unless|else|elsif|when|rescue|ensure)\b|\bdo\s*(\|[^\|]*\|)?\s*$/
14
- ELSE_RE = /\A(else|elsif|when|rescue|ensure)\b/
13
+ IF_RE = /\A(if|begin|unless|else|elsif|when|in|rescue|ensure)\b|\bdo\s*(\|[^\|]*\|)?\s*$/
14
+ ELSE_RE = /\A(else|elsif|when|in|rescue|ensure)\b/
15
15
  END_RE = /\Aend\b/
16
16
 
17
17
  # Handle multi expression `[:multi, *exps]`
data/lib/slim/engine.rb CHANGED
@@ -30,7 +30,9 @@ module Slim
30
30
  use Slim::CodeAttributes
31
31
  use(:AttributeRemover) { Temple::HTML::AttributeRemover.new(remove_empty_attrs: options[:merge_attrs].keys) }
32
32
  html :Pretty
33
+ filter :Ambles
33
34
  filter :Escapable
35
+ filter :StaticAnalyzer
34
36
  filter :ControlFlow
35
37
  filter :MultiFlattener
36
38
  filter :StaticMerger
data/lib/slim/parser.rb CHANGED
@@ -231,10 +231,6 @@ module Slim
231
231
  # We expect the line to be broken or the next line to be indented.
232
232
  @line = $'
233
233
  trailing_ws = $2.include?('>'.freeze)
234
- if $2.include?('\''.freeze)
235
- deprecated_syntax '=\' for trailing whitespace is deprecated in favor of =>'
236
- trailing_ws = true
237
- end
238
234
  block = [:multi]
239
235
  @stacks.last << [:static, ' '] if $2.include?('<'.freeze)
240
236
  @stacks.last << [:slim, :output, $1.empty?, parse_broken_line, block]
@@ -348,11 +344,6 @@ module Slim
348
344
  @line =~ /\A[<>']*/
349
345
  @line = $'
350
346
  trailing_ws = $&.include?('>'.freeze)
351
- if $&.include?('\''.freeze)
352
- deprecated_syntax 'tag\' for trailing whitespace is deprecated in favor of tag>'
353
- trailing_ws = true
354
- end
355
-
356
347
  leading_ws = $&.include?('<'.freeze)
357
348
 
358
349
  parse_attributes(attributes)
@@ -387,10 +378,6 @@ module Slim
387
378
  # Handle output code
388
379
  @line = $'
389
380
  trailing_ws2 = $2.include?('>'.freeze)
390
- if $2.include?('\''.freeze)
391
- deprecated_syntax '=\' for trailing whitespace is deprecated in favor of =>'
392
- trailing_ws2 = true
393
- end
394
381
  block = [:multi]
395
382
  @stacks.last.insert(-2, [:static, ' ']) if !leading_ws && $2.include?('<'.freeze)
396
383
  tag << [:slim, :output, $1 != '=', parse_broken_line, block]
@@ -530,16 +517,6 @@ module Slim
530
517
  raise
531
518
  end
532
519
 
533
- def deprecated_syntax(message)
534
- line = @orig_line.lstrip
535
- column = (@orig_line && @line ? @orig_line.size - @line.size : 0) + line.size - @orig_line.size
536
- warn %{Deprecated syntax: #{message}
537
- #{options[:file]}, Line #{@lineno}, Column #{column + 1}
538
- #{line}
539
- #{' ' * column}^
540
- }
541
- end
542
-
543
520
  def expect_next_line
544
521
  next_line || syntax_error!('Unexpected end of file')
545
522
  @line.strip!
@@ -0,0 +1,17 @@
1
+ module Slim
2
+ class Railtie < Rails::Railtie
3
+ initializer "initialize slim template handler" do
4
+ ActiveSupport.on_load(:action_view) do
5
+ Slim::RailsTemplate = Temple::Templates::Rails(Slim::Engine,
6
+ register_as: :slim,
7
+ # Use rails-specific generator. This is necessary
8
+ # to support block capturing and streaming.
9
+ generator: Temple::Generators::RailsOutputBuffer,
10
+ # Disable the internal slim capturing.
11
+ # Rails takes care of the capturing by itself.
12
+ disable_capture: true,
13
+ streaming: true)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -90,8 +90,14 @@ module Slim
90
90
 
91
91
  def hyphen_attr(name, escape, value)
92
92
  if Hash === value
93
- value.each do |n, v|
94
- hyphen_attr("#{name}-#{n}", escape, v)
93
+ if @options[:hyphen_underscore_attrs]
94
+ value.each do |n, v|
95
+ hyphen_attr("#{name}-#{n.to_s.gsub('_', '-')}", escape, v)
96
+ end
97
+ else
98
+ value.each do |n, v|
99
+ hyphen_attr("#{name}-#{n}", escape, v)
100
+ end
95
101
  end
96
102
  else
97
103
  attr(name, escape_html(value != true && escape, value))
@@ -3,7 +3,8 @@ module Slim
3
3
  # @api private
4
4
  class Filter < ::Slim::Filter
5
5
  define_options :merge_attrs, :attr_quote, :sort_attrs, :default_tag, :format, :disable_capture,
6
- hyphen_attrs: %w(data aria), use_html_safe: ''.respond_to?(:html_safe?)
6
+ hyphen_attrs: %w(data aria), use_html_safe: ''.respond_to?(:html_safe?),
7
+ hyphen_underscore_attrs: false
7
8
 
8
9
  def call(exp)
9
10
  @splat_options = nil
data/lib/slim/template.rb CHANGED
@@ -2,18 +2,4 @@ module Slim
2
2
  # Tilt template implementation for Slim
3
3
  # @api public
4
4
  Template = Temple::Templates::Tilt(Slim::Engine, register_as: :slim)
5
-
6
- if defined?(::ActionView)
7
- # Rails template implementation for Slim
8
- # @api public
9
- RailsTemplate = Temple::Templates::Rails(Slim::Engine,
10
- register_as: :slim,
11
- # Use rails-specific generator. This is necessary
12
- # to support block capturing and streaming.
13
- generator: Temple::Generators::RailsOutputBuffer,
14
- # Disable the internal slim capturing.
15
- # Rails takes care of the capturing by itself.
16
- disable_capture: true,
17
- streaming: true)
18
- end
19
5
  end
data/lib/slim/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Slim
2
2
  # Slim version string
3
3
  # @api public
4
- VERSION = '4.1.0'
4
+ VERSION = '5.0.0'
5
5
  end
data/lib/slim.rb CHANGED
@@ -12,3 +12,4 @@ require 'slim/code_attributes'
12
12
  require 'slim/engine'
13
13
  require 'slim/template'
14
14
  require 'slim/version'
15
+ require 'slim/railtie' if defined?(Rails::Railtie)
data/slim.gemspec CHANGED
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  require File.dirname(__FILE__) + '/lib/slim/version'
3
2
  require 'date'
4
3
 
@@ -10,15 +9,15 @@ Gem::Specification.new do |s|
10
9
  s.email = ['mail@daniel-mendler.de', 'andy@stonean.com', 'ifredwu@gmail.com']
11
10
  s.summary = 'Slim is a template language.'
12
11
  s.description = 'Slim is a template language whose goal is reduce the syntax to the essential parts without becoming cryptic.'
13
- s.homepage = 'http://slim-lang.com/'
12
+ s.homepage = 'http://github.com/slim-template/slim/'
14
13
  s.license = 'MIT'
15
14
 
16
15
  s.files = `git ls-files`.split("\n")
17
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
17
  s.require_paths = %w(lib)
19
18
 
20
- s.required_ruby_version = '>=2.0.0'
19
+ s.required_ruby_version = '>= 2.5.0'
21
20
 
22
- s.add_runtime_dependency('temple', ['>= 0.7.6', '< 0.9'])
21
+ s.add_runtime_dependency('temple', ['~> 0.10.0'])
23
22
  s.add_runtime_dependency('tilt', ['>= 2.0.6', '< 2.1'])
24
23
  end
@@ -163,6 +163,7 @@ p id=(1 + 1)*5 Test it
163
163
  end
164
164
 
165
165
  def test_code_attribute_does_not_modify_argument
166
+ require 'ostruct'
166
167
  template = 'span class=attribute'
167
168
  model = OpenStruct.new(attribute: [:a, :b, [:c, :d]])
168
169
  output = Slim::Template.new { template }.render(model)
@@ -120,6 +120,23 @@ p
120
120
  assert_html '<p>42 is the answer</p><p>41 is the answer</p><p>42 is the answer</p><p>41 is the answer</p>', source
121
121
  end
122
122
 
123
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7")
124
+ def test_render_with_case_in
125
+ source = %q{
126
+ p
127
+ - case [:greet, "world"]
128
+ - in :greet, value if false
129
+ = "Goodbye #{value}"
130
+ - in :greet, value unless true
131
+ = "Top of the morning to you, #{value}"
132
+ - in :greet, value
133
+ = "Hello #{value}"
134
+ }
135
+
136
+ assert_html '<p>Hello world</p>', source
137
+ end
138
+ end
139
+
123
140
  def test_render_with_slim_comments
124
141
  source = %q{
125
142
  p Hello
@@ -15,9 +15,6 @@ class TestSlimCommands < Minitest::Test
15
15
  # exception raising example
16
16
  EXCEPTION_TEMPLATE = '- raise NotImplementedError'
17
17
 
18
- # Temple has this feature...
19
- STRING_FREEZER = RUBY_VERSION >= '2.1' ? '.freeze' : ''
20
-
21
18
  def test_option_help
22
19
  out, err = exec_slimrb '--help'
23
20
 
@@ -43,7 +40,7 @@ class TestSlimCommands < Minitest::Test
43
40
  def test_compile
44
41
  prepare_common_test STATIC_TEMPLATE, '--compile' do |out, err|
45
42
  assert err.empty?
46
- assert_match %r{\"<p>Hello World!<\/p>\"#{STRING_FREEZER}}, out
43
+ assert_match %r{\"<p>Hello World!<\/p>\".freeze}, out
47
44
  end
48
45
  end
49
46
 
@@ -58,10 +55,14 @@ class TestSlimCommands < Minitest::Test
58
55
  prepare_common_test DYNAMIC_TEMPLATE, '--rails' do |out, err|
59
56
  assert err.empty?
60
57
 
61
- assert out.include? %Q{@output_buffer = ActiveSupport::SafeBuffer.new;}
62
- assert out.include? %Q{@output_buffer.safe_concat(("<p>Hello "#{STRING_FREEZER}));}
58
+ if Gem::Version.new(Temple::VERSION) >= Gem::Version.new('0.9')
59
+ assert out.include? %Q{@output_buffer = output_buffer || ActionView::OutputBuffer.new;}
60
+ else
61
+ assert out.include? %Q{@output_buffer = ActiveSupport::SafeBuffer.new;}
62
+ end
63
+ assert out.include? %Q{@output_buffer.safe_concat(("<p>Hello ".freeze));}
63
64
  assert out.include? %Q{@output_buffer.safe_concat(((::Temple::Utils.escape_html((name))).to_s));}
64
- assert out.include? %Q{@output_buffer.safe_concat(("!</p>"#{STRING_FREEZER}));}
65
+ assert out.include? %Q{@output_buffer.safe_concat(("!</p>".freeze));}
65
66
  end
66
67
  end
67
68
 
@@ -11,24 +11,26 @@ markdown:
11
11
 
12
12
  #{1+2}
13
13
 
14
+ [#{1}](#{"#2"})
15
+
14
16
  * one
15
17
  * two
16
18
  }
17
19
  if ::Tilt['md'].name =~ /Redcarpet/
18
20
  # redcarpet
19
- assert_html "<h1>Header</h1>\n\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<ul>\n<li>one</li>\n<li>two</li>\n</ul>\n", source
21
+ assert_html "<h1>Header</h1>\n\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<p><a href=\"#2\">1</a></p>\n\n<ul>\n<li>one</li>\n<li>two</li>\n</ul>\n", source
20
22
  elsif ::Tilt['md'].name =~ /RDiscount/
21
23
  # rdiscount
22
- assert_html "<h1>Header</h1>\n\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<ul>\n<li>one</li>\n<li>two</li>\n</ul>\n\n", source
24
+ assert_html "<h1>Header</h1>\n\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<p><a href=\"#2\">1</a></p>\n\n<ul>\n<li>one</li>\n<li>two</li>\n</ul>\n\n", source
23
25
  else
24
26
  # kramdown, :auto_ids by default
25
- assert_html "<h1 id=\"header\">Header</h1>\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<ul>\n <li>one</li>\n <li>two</li>\n</ul>\n", source
27
+ assert_html "<h1 id=\"header\">Header</h1>\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<p><a href=\"#2\">1</a></p>\n\n<ul>\n <li>one</li>\n <li>two</li>\n</ul>\n", source
26
28
 
27
29
  Slim::Embedded.with_options(markdown: {auto_ids: false}) do
28
- assert_html "<h1>Header</h1>\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<ul>\n <li>one</li>\n <li>two</li>\n</ul>\n", source
30
+ assert_html "<h1>Header</h1>\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<p><a href=\"#2\">1</a></p>\n\n<ul>\n <li>one</li>\n <li>two</li>\n</ul>\n", source
29
31
  end
30
32
 
31
- assert_html "<h1 id=\"header\">Header</h1>\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<ul>\n <li>one</li>\n <li>two</li>\n</ul>\n", source
33
+ assert_html "<h1 id=\"header\">Header</h1>\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<p><a href=\"#2\">1</a></p>\n\n<ul>\n <li>one</li>\n <li>two</li>\n</ul>\n", source
32
34
  end
33
35
  end
34
36
 
@@ -37,7 +39,7 @@ markdown:
37
39
  css:
38
40
  h1 { color: blue }
39
41
  }
40
- assert_html "<style type=\"text/css\">h1 { color: blue }</style>", source
42
+ assert_html "<style>h1 { color: blue }</style>", source
41
43
  end
42
44
 
43
45
  def test_render_with_css_empty_attributes
@@ -45,7 +47,7 @@ css:
45
47
  css []:
46
48
  h1 { color: blue }
47
49
  }
48
- assert_html "<style type=\"text/css\">h1 { color: blue }</style>", source
50
+ assert_html "<style>h1 { color: blue }</style>", source
49
51
  end
50
52
 
51
53
  def test_render_with_css_attribute
@@ -53,7 +55,7 @@ css []:
53
55
  css scoped = "true":
54
56
  h1 { color: blue }
55
57
  }
56
- assert_html "<style scoped=\"true\" type=\"text/css\">h1 { color: blue }</style>", source
58
+ assert_html "<style scoped=\"true\">h1 { color: blue }</style>", source
57
59
  end
58
60
 
59
61
  def test_render_with_css_multiple_attributes
@@ -61,7 +63,7 @@ css scoped = "true":
61
63
  css class="myClass" scoped = "true" :
62
64
  h1 { color: blue }
63
65
  }
64
- assert_html "<style class=\"myClass\" scoped=\"true\" type=\"text/css\">h1 { color: blue }</style>", source
66
+ assert_html "<style class=\"myClass\" scoped=\"true\">h1 { color: blue }</style>", source
65
67
  end
66
68
 
67
69
  def test_render_with_javascript
@@ -163,13 +165,15 @@ ruby:
163
165
  assert_html "foobar\n", source
164
166
  end
165
167
 
168
+ # TODO: Reactivate sass tests
169
+ if false
166
170
  def test_render_with_scss
167
171
  source = %q{
168
172
  scss:
169
173
  $color: #f00;
170
174
  body { color: $color; }
171
175
  }
172
- assert_html "<style type=\"text/css\">body{color:red}</style>", source
176
+ assert_html "<style>body{color:red}</style>", source
173
177
  end
174
178
 
175
179
  def test_render_with_scss_attribute
@@ -178,7 +182,7 @@ scss [class="myClass"]:
178
182
  $color: #f00;
179
183
  body { color: $color; }
180
184
  }
181
- assert_html "<style class=\"myClass\" type=\"text/css\">body{color:red}</style>", source
185
+ assert_html "<style class=\"myClass\">body{color:red}</style>", source
182
186
  end
183
187
 
184
188
  def test_render_with_sass
@@ -188,7 +192,7 @@ sass:
188
192
  body
189
193
  color: $color
190
194
  }
191
- assert_html "<style type=\"text/css\">body{color:red}</style>", source
195
+ assert_html "<style>body{color:red}</style>", source
192
196
  end
193
197
 
194
198
  def test_render_with_sass_attribute
@@ -198,9 +202,9 @@ sass [class="myClass"]:
198
202
  body
199
203
  color: $color
200
204
  }
201
- assert_html "<style class=\"myClass\" type=\"text/css\">body{color:red}</style>", source
205
+ assert_html "<style class=\"myClass\">body{color:red}</style>", source
202
206
  end
203
-
207
+ end
204
208
 
205
209
  def test_disabled_embedded_engine
206
210
  source = %{
@@ -21,9 +21,8 @@ html
21
21
  /[if lt IE 9]
22
22
  script src="old-ie1.js"
23
23
  script src="old-ie2.js"
24
- sass:
25
- body
26
- background-color: red
24
+ css:
25
+ body { background-color: red; }
27
26
  body
28
27
  #container
29
28
  p Hello
@@ -51,9 +50,8 @@ multiline comment-->
51
50
  </script><!--[if lt IE 9]>
52
51
  <script src="old-ie1.js">
53
52
  </script><script src="old-ie2.js">
54
- </script><![endif]--><style type="text/css">body{background-color:red}
55
-
56
- </style>
53
+ </script><![endif]--><style>
54
+ body { background-color: red; }</style>
57
55
  </head><body>
58
56
  <div id="container">
59
57
  <p>Hello
@@ -116,6 +116,14 @@ option(selected class="clazz") Text
116
116
  assert_html '<div class="alpha" data-a="alpha" data-b="beta" data-c-e="epsilon" data-c_d="gamma"></div>', source
117
117
  end
118
118
 
119
+ def test_hyphenated_underscore_attribute
120
+ source = %{
121
+ .alpha data={a: 'alpha', b: 'beta', c_d: 'gamma', c: {e: 'epsilon'}}
122
+ }
123
+
124
+ assert_html '<div class="alpha" data-a="alpha" data-b="beta" data-c-d="gamma" data-c-e="epsilon"></div>', source, hyphen_underscore_attrs: true
125
+ end
126
+
119
127
  def test_splat_without_content
120
128
  source = %q{
121
129
  *hash
@@ -29,9 +29,8 @@ html
29
29
  /[if lt IE 9]
30
30
  script src="old-ie1.js"
31
31
  script src="old-ie2.js"
32
- sass:
33
- body
34
- background-color: red
32
+ css:
33
+ body { background-color: red; }
35
34
  body
36
35
  #container
37
36
  p Hello
@@ -56,10 +55,8 @@ html
56
55
  <script src="old-ie1.js"></script>
57
56
  <script src="old-ie2.js"></script>
58
57
  <![endif]-->
59
- <style type="text/css">
60
- body {
61
- background-color: red;
62
- }
58
+ <style>
59
+ body { background-color: red; }
63
60
  </style>
64
61
  </head>
65
62
  <body>