slim 4.1.0 → 5.1.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +51 -0
  3. data/.yardopts +1 -1
  4. data/CHANGES +27 -7
  5. data/Gemfile +15 -41
  6. data/LICENSE +1 -1
  7. data/README.jp.md +17 -20
  8. data/README.md +32 -24
  9. data/Rakefile +1 -8
  10. data/doc/jp/translator.md +1 -1
  11. data/doc/logic_less.md +1 -1
  12. data/doc/translator.md +1 -1
  13. data/lib/slim/do_inserter.rb +1 -1
  14. data/lib/slim/embedded.rb +12 -11
  15. data/lib/slim/end_inserter.rb +2 -2
  16. data/lib/slim/engine.rb +2 -0
  17. data/lib/slim/parser.rb +9 -29
  18. data/lib/slim/railtie.rb +17 -0
  19. data/lib/slim/splat/builder.rb +8 -2
  20. data/lib/slim/splat/filter.rb +2 -1
  21. data/lib/slim/template.rb +0 -14
  22. data/lib/slim/version.rb +1 -1
  23. data/lib/slim.rb +1 -0
  24. data/slim.gemspec +4 -5
  25. data/test/core/test_code_evaluation.rb +1 -0
  26. data/test/core/test_code_structure.rb +17 -0
  27. data/test/core/test_commands.rb +8 -7
  28. data/test/core/test_embedded_engines.rb +18 -14
  29. data/test/core/test_erb_converter.rb +4 -6
  30. data/test/core/test_html_attributes.rb +8 -0
  31. data/test/core/test_html_structure.rb +6 -0
  32. data/test/core/test_pretty.rb +4 -7
  33. data/test/literate/TESTS.md +72 -22
  34. data/test/literate/run.rb +2 -2
  35. data/test/rails/config/application.rb +0 -17
  36. data/test/rails/test/test_slim.rb +6 -12
  37. data/test/sinatra/helper.rb +0 -2
  38. metadata +13 -27
  39. data/.travis.yml +0 -38
  40. data/benchmarks/context.rb +0 -11
  41. data/benchmarks/profile-parser.rb +0 -10
  42. data/benchmarks/profile-render.rb +0 -12
  43. data/benchmarks/run-benchmarks.rb +0 -120
  44. data/benchmarks/run-diffbench.rb +0 -21
  45. data/benchmarks/view.erb +0 -25
  46. data/benchmarks/view.haml +0 -20
  47. data/benchmarks/view.slim +0 -19
  48. data/test/rails/config/initializers/secret_token.rb +0 -7
@@ -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
@@ -79,7 +79,7 @@ module Slim
79
79
  @attr_list_delims_re = /\A\s*([#{keys}])/
80
80
  @embedded_re = /\A(#{Regexp.union(Embedded.engines.keys.map(&:to_s))})(?:\s*(?:(.*)))?:(\s*)/
81
81
  keys = Regexp.escape ('"\'></='.split(//) + @attr_list_delims.flatten + @code_attr_delims.flatten).uniq.join
82
- @attr_name = "\\A\\s*([^\0\s#{keys}]+)"
82
+ @attr_name = "\\A\\s*([^\\0\\s#{keys}]+)"
83
83
  @quoted_attr_re = /#{@attr_name}\s*=(=?)\s*("|')/
84
84
  @code_attr_re = /#{@attr_name}\s*=(=?)\s*/
85
85
 
@@ -209,10 +209,12 @@ module Slim
209
209
  when /\A\//
210
210
  # Slim comment
211
211
  parse_comment_block
212
- when /\A([\|'])( ?)/
212
+ when /\A([\|'])([<>]{1,2}(?: |\z)| ?)/
213
213
  # Found verbatim text block.
214
- trailing_ws = $1 == "'"
215
- @stacks.last << [:slim, :text, :verbatim, parse_text_block($', @indents.last + $2.size + 1)]
214
+ leading_ws = $2.include?('<'.freeze)
215
+ trailing_ws = ($1 == "'") || $2.include?('>'.freeze)
216
+ @stacks.last << [:static, ' '] if leading_ws
217
+ @stacks.last << [:slim, :text, :verbatim, parse_text_block($', @indents.last + $2.count(' ') + 1)]
216
218
  @stacks.last << [:static, ' '] if trailing_ws
217
219
  when /\A</
218
220
  # Inline html
@@ -226,17 +228,14 @@ module Slim
226
228
  block = [:multi]
227
229
  @stacks.last << [:slim, :control, parse_broken_line, block]
228
230
  @stacks << block
229
- when /\A=(=?)(['<>]*)/
231
+ when /\A=(=?)([<>]*)/
230
232
  # Found an output block.
231
233
  # We expect the line to be broken or the next line to be indented.
232
234
  @line = $'
235
+ leading_ws = $2.include?('<'.freeze)
233
236
  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
237
  block = [:multi]
239
- @stacks.last << [:static, ' '] if $2.include?('<'.freeze)
238
+ @stacks.last << [:static, ' '] if leading_ws
240
239
  @stacks.last << [:slim, :output, $1.empty?, parse_broken_line, block]
241
240
  @stacks.last << [:static, ' '] if trailing_ws
242
241
  @stacks << block
@@ -348,11 +347,6 @@ module Slim
348
347
  @line =~ /\A[<>']*/
349
348
  @line = $'
350
349
  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
350
  leading_ws = $&.include?('<'.freeze)
357
351
 
358
352
  parse_attributes(attributes)
@@ -387,10 +381,6 @@ module Slim
387
381
  # Handle output code
388
382
  @line = $'
389
383
  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
384
  block = [:multi]
395
385
  @stacks.last.insert(-2, [:static, ' ']) if !leading_ws && $2.include?('<'.freeze)
396
386
  tag << [:slim, :output, $1 != '=', parse_broken_line, block]
@@ -530,16 +520,6 @@ module Slim
530
520
  raise
531
521
  end
532
522
 
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
523
  def expect_next_line
544
524
  next_line || syntax_error!('Unexpected end of file')
545
525
  @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.1.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'])
23
- s.add_runtime_dependency('tilt', ['>= 2.0.6', '< 2.1'])
21
+ s.add_runtime_dependency('temple', ['~> 0.10.0'])
22
+ s.add_runtime_dependency('tilt', ['>= 2.0.6', '< 2.2'])
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
@@ -311,6 +311,12 @@ p[id="marvin" class="martian" data-info="Illudium Q-36"] = output_number
311
311
  assert_html '<p class="martian" data-info="Illudium Q-36" id="marvin">1337</p>', source
312
312
  end
313
313
 
314
+ # Regression test for bug #796
315
+ def test_square_brackets_around_attributes_multiline_with_tabs
316
+ source = "div\n\tp[\n\t\tclass=\"martian\"\n\t]\n\tp Next line"
317
+ assert_html '<div><p class="martian"></p><p>Next line</p></div>', source
318
+ end
319
+
314
320
  def test_parens_around_attributes_with_equal_sign_snug_to_right_paren
315
321
  source = %q{
316
322
  p(id="marvin" class="martian" data-info="Illudium Q-36")= output_number
@@ -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>