slim 2.1.0 → 3.0.0.beta.2

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -24
  3. data/CHANGES +8 -0
  4. data/Gemfile +5 -7
  5. data/README.jp.md +29 -31
  6. data/README.md +34 -34
  7. data/Rakefile +9 -7
  8. data/benchmarks/context.rb +3 -3
  9. data/benchmarks/run-benchmarks.rb +9 -9
  10. data/benchmarks/view.slim +1 -1
  11. data/doc/jp/logic_less.md +7 -7
  12. data/doc/logic_less.md +7 -7
  13. data/lib/slim/command.rb +6 -16
  14. data/lib/slim/embedded.rb +10 -13
  15. data/lib/slim/engine.rb +21 -23
  16. data/lib/slim/erb_converter.rb +2 -1
  17. data/lib/slim/include.rb +2 -2
  18. data/lib/slim/logic_less.rb +1 -2
  19. data/lib/slim/logic_less/filter.rb +3 -3
  20. data/lib/slim/parser.rb +43 -19
  21. data/lib/slim/smart.rb +3 -3
  22. data/lib/slim/smart/escaper.rb +1 -1
  23. data/lib/slim/smart/filter.rb +3 -3
  24. data/lib/slim/smart/parser.rb +6 -4
  25. data/lib/slim/splat/builder.rb +9 -4
  26. data/lib/slim/splat/filter.rb +3 -4
  27. data/lib/slim/template.rb +5 -5
  28. data/lib/slim/translator.rb +12 -13
  29. data/lib/slim/version.rb +1 -1
  30. data/slim.gemspec +3 -1
  31. data/test/core/helper.rb +3 -3
  32. data/test/core/test_code_escaping.rb +14 -14
  33. data/test/core/test_code_evaluation.rb +1 -1
  34. data/test/core/test_code_output.rb +1 -1
  35. data/test/core/test_embedded_engines.rb +16 -16
  36. data/test/core/test_encoding.rb +4 -4
  37. data/test/core/test_html_attributes.rb +9 -9
  38. data/test/core/test_html_structure.rb +20 -20
  39. data/test/core/test_parser_errors.rb +1 -1
  40. data/test/core/test_pretty.rb +4 -4
  41. data/test/core/test_ruby_errors.rb +5 -5
  42. data/test/core/test_slim_template.rb +2 -2
  43. data/test/core/test_tabs.rb +5 -5
  44. data/test/core/test_thread_options.rb +4 -4
  45. data/test/core/test_unicode.rb +11 -13
  46. data/test/include/test_include.rb +2 -2
  47. data/test/literate/TESTS.md +37 -8
  48. data/test/literate/helper.rb +2 -2
  49. data/test/logic_less/test_logic_less.rb +37 -37
  50. data/test/rails/app/controllers/slim_controller.rb +3 -3
  51. data/test/rails/config/initializers/session_store.rb +1 -1
  52. data/test/rails/config/routes.rb +4 -4
  53. data/test/rails/test/test_slim.rb +9 -15
  54. data/test/smart/test_smart_text.rb +5 -9
  55. data/test/translator/test_translator.rb +14 -14
  56. metadata +7 -7
data/Rakefile CHANGED
@@ -60,15 +60,17 @@ namespace 'test' do
60
60
  end
61
61
 
62
62
  begin
63
- require 'rubygems'
64
63
  require 'sinatra'
65
64
  spec = Gem::Specification.find_by_name('sinatra')
66
65
  Rake::TestTask.new('sinatra') do |t|
67
- # FIXME: Rename deprecated attribute
68
66
  file = "#{spec.gem_dir}/test/slim_test.rb"
69
- code = File.read(file)
70
- code.gsub!('attr_wrapper', 'attr_quote')
71
- File.open(file, 'w') {|out| out.write(code) }
67
+
68
+ if Sinatra::VERSION =~ /\A1\.3/
69
+ # FIXME: Rename deprecated attribute
70
+ code = File.read(file)
71
+ code.gsub!('attr_wrapper', 'attr_quote')
72
+ File.open(file, 'w') {|out| out.write(code) }
73
+ end
72
74
 
73
75
  # Run Slim integration test in Sinatra
74
76
  t.test_files = FileList[file]
@@ -93,6 +95,6 @@ rescue LoadError
93
95
  end
94
96
 
95
97
  desc "Generate Documentation"
96
- task :doc => :yard
98
+ task doc: :yard
97
99
 
98
- task :default => 'test'
100
+ task default: 'test'
@@ -4,8 +4,8 @@ class Context
4
4
  end
5
5
 
6
6
  def item
7
- [ { :name => 'red', :current => true, :url => '#red' },
8
- { :name => 'green', :current => false, :url => '#green' },
9
- { :name => 'blue', :current => false, :url => '#blue' } ]
7
+ [ { name: 'red', current: true, url: '#red' },
8
+ { name: 'green', current: false, url: '#green' },
9
+ { name: 'blue', current: false, url: '#blue' } ]
10
10
  end
11
11
  end
@@ -29,8 +29,8 @@ class SlimBenchmarks
29
29
  erb = ERB.new(@erb_code)
30
30
  erubis = Erubis::Eruby.new(@erb_code)
31
31
  fast_erubis = Erubis::FastEruby.new(@erb_code)
32
- haml_pretty = Haml::Engine.new(@haml_code, :format => :html5)
33
- haml_ugly = Haml::Engine.new(@haml_code, :format => :html5, :ugly => true)
32
+ haml_pretty = Haml::Engine.new(@haml_code, format: :html5)
33
+ haml_ugly = Haml::Engine.new(@haml_code, format: :html5, ugly: true)
34
34
 
35
35
  context = Context.new
36
36
 
@@ -41,7 +41,7 @@ class SlimBenchmarks
41
41
  def run_erubis; #{erubis.src}; end
42
42
  def run_temple_erb; #{Temple::ERB::Engine.new.call @erb_code}; end
43
43
  def run_fast_erubis; #{fast_erubis.src}; end
44
- def run_slim_pretty; #{Slim::Engine.new(:pretty => true).call @slim_code}; end
44
+ def run_slim_pretty; #{Slim::Engine.new(pretty: true).call @slim_code}; end
45
45
  def run_slim_ugly; #{Slim::Engine.new.call @slim_code}; end
46
46
  }
47
47
 
@@ -59,9 +59,9 @@ class SlimBenchmarks
59
59
  tilt_erb = Tilt::ERBTemplate.new { @erb_code }
60
60
  tilt_erubis = Tilt::ErubisTemplate.new { @erb_code }
61
61
  tilt_temple_erb = Temple::ERB::Template.new { @erb_code }
62
- tilt_haml_pretty= Tilt::HamlTemplate.new(:format => :html5){ @haml_code }
63
- tilt_haml_ugly = Tilt::HamlTemplate.new(:format => :html5, :ugly => true){ @haml_code }
64
- tilt_slim_pretty= Slim::Template.new(:pretty => true) { @slim_code }
62
+ tilt_haml_pretty= Tilt::HamlTemplate.new(format: :html5){ @haml_code }
63
+ tilt_haml_ugly = Tilt::HamlTemplate.new(format: :html5, ugly: true){ @haml_code }
64
+ tilt_slim_pretty= Slim::Template.new(pretty: true) { @slim_code }
65
65
  tilt_slim_ugly = Slim::Template.new { @slim_code }
66
66
 
67
67
  context = Context.new
@@ -83,10 +83,10 @@ class SlimBenchmarks
83
83
  bench('(3) erubis') { Erubis::Eruby.new(@erb_code).result(context_binding) }
84
84
  bench('(3) fast erubis') { Erubis::FastEruby.new(@erb_code).result(context_binding) }
85
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) }
86
+ bench('(3) slim pretty') { Slim::Template.new(pretty: true) { @slim_code }.render(context) }
87
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) }
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) }
90
90
  end
91
91
 
92
92
  def run
data/benchmarks/view.slim CHANGED
@@ -12,6 +12,6 @@ html
12
12
  strong == i[:name]
13
13
  - else
14
14
  li
15
- a href=i[:url] == i[:name]
15
+ a href==i[:url] == i[:name]
16
16
  - else
17
17
  p The list is empty.
data/doc/jp/logic_less.md CHANGED
@@ -34,7 +34,7 @@ Mustache のように, Slim はラムダ式をサポートします。
34
34
  ラムダ式は次のように定義できます:
35
35
 
36
36
  def lambda_method
37
- "<div class='person'>#{yield(:name => 'Andrew')}</div>"
37
+ "<div class='person'>#{yield(name: 'Andrew')}</div>"
38
38
  end
39
39
 
40
40
  任意に 1 つ以上のハッシュを `yield` に渡すことができます。複数のハッシュを渡した場合, 先述したようにブロックが繰り返されます。
@@ -65,7 +65,7 @@ Mustache のように, Slim はラムダ式をサポートします。
65
65
  辞書オブジェクトを与え,
66
66
 
67
67
  {
68
- :article => [
68
+ article: [
69
69
  'Article 1',
70
70
  'Article 2'
71
71
  ]
@@ -94,17 +94,17 @@ Mustache のように, Slim はラムダ式をサポートします。
94
94
 
95
95
  require で指定:
96
96
 
97
- gem 'slim', :require => 'slim/logic_less'
97
+ gem 'slim', require: 'slim/logic_less'
98
98
 
99
99
  特定のアクションでのみロジックレスモードを有効化したい場合, まず設定でロジックレスモードを global に無効化します。
100
100
 
101
- Slim::Engine.set_default_options :logic_less => false
101
+ Slim::Engine.set_options logic_less: false
102
102
 
103
103
  さらに, アクションの中でレンダリングする度にロジックレスモードを有効化します。
104
104
 
105
105
  class Controller
106
106
  def action
107
- Slim::Engine.with_options(:logic_less => true) do
107
+ Slim::Engine.with_options(logic_less: true) do
108
108
  render
109
109
  end
110
110
  end
@@ -120,12 +120,12 @@ Sinatra には Slim のビルトインサポートがあります。しなけれ
120
120
 
121
121
  特定のアクションでのみロジックレスモードを有効化したい場合, まず設定でロジックレスモードを global に無効化します。
122
122
 
123
- Slim::Engine.set_default_options :logic_less => false
123
+ Slim::Engine.set_options logic_less: false
124
124
 
125
125
  さらに, アクションの中でレンダリングする度にロジックレスモードを有効化します。
126
126
 
127
127
  get '/page'
128
- slim :page, :logic_less => true
128
+ slim :page, logic_less: true
129
129
  end
130
130
 
131
131
  ## オプション
data/doc/logic_less.md CHANGED
@@ -34,7 +34,7 @@ Like mustache, Slim supports lambdas.
34
34
  The lambda method could be defined like this
35
35
 
36
36
  def lambda_method
37
- "<div class='person'>#{yield(:name => 'Andrew')}</div>"
37
+ "<div class='person'>#{yield(name: 'Andrew')}</div>"
38
38
  end
39
39
 
40
40
  You can optionally pass one or more hashes to `yield`. If you pass multiple hashes, the block will be iterated as described above.
@@ -65,7 +65,7 @@ The `self` keyword will return the `.to_s` value for the element under considera
65
65
  Given
66
66
 
67
67
  {
68
- :article => [
68
+ article: [
69
69
  'Article 1',
70
70
  'Article 2'
71
71
  ]
@@ -94,17 +94,17 @@ Install:
94
94
 
95
95
  Require:
96
96
 
97
- gem 'slim', :require => 'slim/logic_less'
97
+ gem 'slim', require: 'slim/logic_less'
98
98
 
99
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
100
 
101
- Slim::Engine.set_default_options :logic_less => false
101
+ Slim::Engine.set_options logic_less: false
102
102
 
103
103
  and activate logic less mode per render call in your action
104
104
 
105
105
  class Controller
106
106
  def action
107
- Slim::Engine.with_options(:logic_less => true) do
107
+ Slim::Engine.with_options(logic_less: true) do
108
108
  render
109
109
  end
110
110
  end
@@ -120,12 +120,12 @@ You are then ready to rock!
120
120
 
121
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
122
 
123
- Slim::Engine.set_default_options :logic_less => false
123
+ Slim::Engine.set_options logic_less: false
124
124
 
125
125
  and activate logic less mode per render call in your application
126
126
 
127
127
  get '/page'
128
- slim :page, :logic_less => true
128
+ slim :page, logic_less: true
129
129
  end
130
130
 
131
131
  ## Options
data/lib/slim/command.rb CHANGED
@@ -2,7 +2,7 @@ require 'slim'
2
2
  require 'optparse'
3
3
 
4
4
  module Slim
5
- Engine.set_default_options :pretty => false
5
+ Engine.set_options pretty: false
6
6
 
7
7
  # Slim commandline interface
8
8
  # @api private
@@ -40,7 +40,7 @@ module Slim
40
40
  end
41
41
 
42
42
  opts.on('--rails', 'Generate rails compatible code (Implies --compile)') do
43
- Engine.set_default_options :disable_capture => true, :generator => Temple::Generators::RailsOutputBuffer
43
+ Engine.set_options disable_capture: true, generator: Temple::Generators::RailsOutputBuffer
44
44
  @options[:compile] = true
45
45
  end
46
46
 
@@ -48,23 +48,13 @@ module Slim
48
48
  require lib
49
49
  end
50
50
 
51
- opts.on('-t', '--translator', 'Enable translator plugin') do
52
- puts "Deprecated option: Use -r slim/translator"
53
- require 'slim/translator'
54
- end
55
-
56
- opts.on('-l', '--logic-less', 'Enable logic less plugin') do
57
- puts "Deprecated option: Use -r slim/logic_less"
58
- require 'slim/logic_less'
59
- end
60
-
61
51
  opts.on('-p', '--pretty', 'Produce pretty html') do
62
- Engine.set_default_options :pretty => true
52
+ Engine.set_options pretty: true
63
53
  end
64
54
 
65
55
  opts.on('-o', '--option name=code', String, 'Set slim option') do |str|
66
56
  parts = str.split('=', 2)
67
- Engine.default_options[parts.first.gsub(/\A:/, '').to_sym] = eval(parts.last)
57
+ Engine.options[parts.first.gsub(/\A:/, '').to_sym] = eval(parts.last)
68
58
  end
69
59
 
70
60
  opts.on_tail('-h', '--help', 'Show this message') do
@@ -95,9 +85,9 @@ module Slim
95
85
  result =
96
86
  if @options[:erb]
97
87
  require 'slim/erb_converter'
98
- ERBConverter.new(:file => @options[:file]).call(@options[:input].read)
88
+ ERBConverter.new(file: @options[:file]).call(@options[:input].read)
99
89
  elsif @options[:compile]
100
- Engine.new(:file => @options[:file]).call(@options[:input].read)
90
+ Engine.new(file: @options[:file]).call(@options[:input].read)
101
91
  else
102
92
  Template.new(@options[:file]) { @options[:input].read }.render
103
93
  end
data/lib/slim/embedded.rb CHANGED
@@ -136,10 +136,7 @@ module Slim
136
136
  tilt_options = options[engine.to_sym] || {}
137
137
  [:multi, tilt_render(tilt_engine, tilt_options, collect_text(body)), collect_newlines(body)]
138
138
  end
139
- end
140
139
 
141
- # Tilt-based static template (evaluated at compile-time)
142
- class StaticTiltEngine < TiltEngine
143
140
  protected
144
141
 
145
142
  def tilt_render(tilt_engine, tilt_options, text)
@@ -155,8 +152,8 @@ module Slim
155
152
 
156
153
  def tilt_render(tilt_engine, tilt_options, text)
157
154
  text = tilt_engine.new(tilt_options.merge(
158
- :style => options[:pretty] ? :expanded : :compressed,
159
- :cache => false)) { text }.render
155
+ style: options[:pretty] ? :expanded : :compressed,
156
+ cache: false)) { text }.render
160
157
  text.chomp!
161
158
  [:static, text]
162
159
  end
@@ -229,7 +226,7 @@ module Slim
229
226
  class JavaScriptEngine < TagEngine
230
227
  disable_option_validator!
231
228
 
232
- set_default_options :tag => :script, :attributes => { :type => 'text/javascript' }
229
+ set_options tag: :script, attributes: { type: 'text/javascript' }
233
230
 
234
231
  def on_slim_embedded(engine, body)
235
232
  super(engine, [:html, :js, body])
@@ -254,12 +251,12 @@ module Slim
254
251
  register :org, InterpolateTiltEngine
255
252
 
256
253
  # These engines are executed at compile time
257
- register :coffee, JavaScriptEngine, :engine => StaticTiltEngine
258
- register :opal, JavaScriptEngine, :engine => StaticTiltEngine
259
- register :less, TagEngine, :tag => :style, :attributes => { :type => 'text/css' }, :engine => StaticTiltEngine
260
- register :styl, TagEngine, :tag => :style, :attributes => { :type => 'text/css' }, :engine => StaticTiltEngine
261
- register :sass, TagEngine, :pretty, :tag => :style, :attributes => { :type => 'text/css' }, :engine => SassEngine
262
- register :scss, TagEngine, :pretty, :tag => :style, :attributes => { :type => 'text/css' }, :engine => SassEngine
254
+ register :coffee, JavaScriptEngine, engine: TiltEngine
255
+ register :opal, JavaScriptEngine, engine: TiltEngine
256
+ register :less, TagEngine, tag: :style, attributes: { type: 'text/css' }, engine: TiltEngine
257
+ register :styl, TagEngine, tag: :style, attributes: { type: 'text/css' }, engine: TiltEngine
258
+ register :sass, TagEngine, :pretty, tag: :style, attributes: { type: 'text/css' }, engine: SassEngine
259
+ register :scss, TagEngine, :pretty, tag: :style, attributes: { type: 'text/css' }, engine: SassEngine
263
260
 
264
261
  # These engines are precompiled, code is embedded
265
262
  register :erb, ERBEngine
@@ -268,7 +265,7 @@ module Slim
268
265
 
269
266
  # Embedded javascript/css
270
267
  register :javascript, JavaScriptEngine
271
- register :css, TagEngine, :tag => :style, :attributes => { :type => 'text/css' }
268
+ register :css, TagEngine, tag: :style, attributes: { type: 'text/css' }
272
269
 
273
270
  # Embedded ruby code
274
271
  register :ruby, RubyEngine
data/lib/slim/engine.rb CHANGED
@@ -5,37 +5,35 @@ module Slim
5
5
  # This overwrites some Temple default options or sets default options for Slim specific filters.
6
6
  # It is recommended to set the default settings only once in the code and avoid duplication. Only use
7
7
  # `define_options` when you have to override some default settings.
8
- define_options :pretty => false,
9
- :sort_attrs => true,
10
- :format => :xhtml,
11
- :attr_quote => '"',
12
- :merge_attrs => {'class' => ' '},
13
- :generator => Temple::Generators::ArrayBuffer,
14
- :default_tag => 'div'
15
- define_deprecated_options :attr_delims
8
+ define_options pretty: false,
9
+ sort_attrs: true,
10
+ format: :xhtml,
11
+ attr_quote: '"',
12
+ merge_attrs: {'class' => ' '},
13
+ generator: Temple::Generators::ArrayBuffer,
14
+ default_tag: 'div'
16
15
 
17
- filter :Encoding, :encoding
16
+ filter :Encoding
18
17
  filter :RemoveBOM
19
- use Slim::Parser, :file, :tabsize, :shortcut, :default_tag, :attr_delims, :attr_list_delims, :code_attr_delims
20
- use Slim::Embedded, :enable_engines, :disable_engines, :pretty
18
+ use Slim::Parser
19
+ use Slim::Embedded
21
20
  use Slim::Interpolation
22
- use Slim::Splat::Filter, :merge_attrs, :attr_quote, :sort_attrs, :default_tag, :hyphen_attrs, :format, :use_html_safe
21
+ use Slim::Splat::Filter
23
22
  use Slim::DoInserter
24
23
  use Slim::EndInserter
25
- use Slim::Controls, :disable_capture
26
- html :AttributeSorter, :sort_attrs
27
- html :AttributeMerger, :merge_attrs
28
- use Slim::CodeAttributes, :merge_attrs
29
- use(:AttributeRemover) { Temple::HTML::AttributeRemover.new(:remove_empty_attrs => options[:merge_attrs].keys) }
30
- html :Pretty, :format, :attr_quote, :pretty, :indent, :js_wrapper
31
- filter :Escapable, :use_html_safe, :disable_escape
24
+ use Slim::Controls
25
+ html :AttributeSorter
26
+ html :AttributeMerger
27
+ use Slim::CodeAttributes
28
+ use(:AttributeRemover) { Temple::HTML::AttributeRemover.new(remove_empty_attrs: options[:merge_attrs].keys) }
29
+ html :Pretty
30
+ filter :Escapable
32
31
  filter :ControlFlow
33
32
  filter :MultiFlattener
34
- use :Optimizer do
35
- (options[:streaming] ? Temple::Filters::StaticMerger : Temple::Filters::DynamicInliner).new
36
- end
33
+ filter :StaticMerger
34
+ filter :StaticFreezer
37
35
  use :Generator do
38
- options[:generator].new(options.to_hash.reject {|k,v| !options[:generator].default_options.valid_keys.include?(k) })
36
+ options[:generator].new(options.to_hash.reject {|k,v| !options[:generator].options.valid_key?(k) })
39
37
  end
40
38
  end
41
39
  end
@@ -8,7 +8,8 @@ module Slim
8
8
  #
9
9
  # @api public
10
10
  class ERBConverter < Engine
11
- replace :Optimizer, Temple::Filters::CodeMerger
11
+ remove :StaticMerger
12
+ replace :StaticFreezer, Temple::Filters::CodeMerger
12
13
  replace :Generator, Temple::Generators::ERB
13
14
  end
14
15
  end
data/lib/slim/include.rb CHANGED
@@ -7,7 +7,7 @@ module Slim
7
7
  #
8
8
  # @api private
9
9
  class Include < Slim::Filter
10
- define_options :file, :include_dirs => [Dir.pwd, '.']
10
+ define_options :file, include_dirs: [Dir.pwd, '.']
11
11
 
12
12
  def on_html_tag(tag, attributes, content)
13
13
  return super if tag != 'include'
@@ -35,7 +35,7 @@ module Slim
35
35
  end
36
36
 
37
37
  class Engine
38
- after Slim::Parser, Slim::Include, :file, :include_dirs
38
+ after Slim::Parser, Slim::Include
39
39
  after Slim::Include, :stop do |exp|
40
40
  throw :stop, exp if Thread.current[:slim_include_level] > 1
41
41
  exp
@@ -2,5 +2,4 @@ require 'slim'
2
2
  require 'slim/logic_less/filter'
3
3
  require 'slim/logic_less/context'
4
4
 
5
- # Insert plugin filter into Slim engine chain
6
- Slim::Engine.after(Slim::Interpolation, Slim::LogicLess, :logic_less, :dictionary, :dictionary_access)
5
+ Slim::Engine.after Slim::Interpolation, Slim::LogicLess
@@ -6,9 +6,9 @@ module Slim
6
6
  # Default dictionary access order, change it with the option :dictionary_access
7
7
  DEFAULT_ACCESS_ORDER = [:symbol, :string, :method, :instance_variable].freeze
8
8
 
9
- define_options :logic_less => true,
10
- :dictionary => 'self',
11
- :dictionary_access => DEFAULT_ACCESS_ORDER
9
+ define_options logic_less: true,
10
+ dictionary: 'self',
11
+ dictionary_access: DEFAULT_ACCESS_ORDER
12
12
 
13
13
  def initialize(opts = {})
14
14
  super
data/lib/slim/parser.rb CHANGED
@@ -5,18 +5,21 @@ module Slim
5
5
  class Parser < Temple::Parser
6
6
  define_options :file,
7
7
  :default_tag,
8
- :code_attr_delims,
9
- :attr_list_delims,
10
- :tabsize => 4,
11
- :shortcut => {
12
- '#' => { :attr => 'id' },
13
- '.' => { :attr => 'class' }
8
+ tabsize: 4,
9
+ code_attr_delims: {
10
+ '(' => ')',
11
+ '[' => ']',
12
+ '{' => '}',
14
13
  },
15
- :attr_delims => {
14
+ attr_list_delims: {
16
15
  '(' => ')',
17
16
  '[' => ']',
18
17
  '{' => '}',
19
- }
18
+ },
19
+ shortcut: {
20
+ '#' => { attr: 'id' },
21
+ '.' => { attr: 'class' }
22
+ }
20
23
 
21
24
  class SyntaxError < StandardError
22
25
  attr_reader :error, :file, :line, :lineno, :column
@@ -42,8 +45,8 @@ module Slim
42
45
 
43
46
  def initialize(opts = {})
44
47
  super
45
- @attr_list_delims = options[:attr_list_delims] || options[:attr_delims]
46
- @code_attr_delims = options[:code_attr_delims] || options[:attr_delims]
48
+ @attr_list_delims = options[:attr_list_delims]
49
+ @code_attr_delims = options[:code_attr_delims]
47
50
  tabsize = options[:tabsize]
48
51
  if tabsize > 1
49
52
  @tab_re = /\G((?: {#{tabsize}})*) {0,#{tabsize-1}}\t/
@@ -58,13 +61,13 @@ module Slim
58
61
  @tag_shortcut[k] = v[:tag] || options[:default_tag]
59
62
  if v.include?(:attr)
60
63
  @attr_shortcut[k] = [v[:attr]].flatten
61
- raise ArgumentError, 'You can only use special characters for attribute shortcuts' if k =~ /(#{WORD_RE}|-)/
64
+ raise ArgumentError, 'You can only use special characters for attribute shortcuts' if k =~ /(\p{Word}|-)/
62
65
  end
63
66
  end
64
67
  keys = Regexp.union @attr_shortcut.keys.sort_by {|k| -k.size }
65
- @attr_shortcut_re = /\A(#{keys}+)((?:#{WORD_RE}|-)*)/
68
+ @attr_shortcut_re = /\A(#{keys}+)((?:\p{Word}|-)*)/
66
69
  keys = Regexp.union @tag_shortcut.keys.sort_by {|k| -k.size }
67
- @tag_re = /\A(?:#{keys}|\*(?=[^\s]+)|(#{WORD_RE}(?:#{WORD_RE}|:|-)*#{WORD_RE}|#{WORD_RE}+))/
70
+ @tag_re = /\A(?:#{keys}|\*(?=[^\s]+)|(\p{Word}(?:\p{Word}|:|-)*\p{Word}|\p{Word}+))/
68
71
  keys = Regexp.escape @code_attr_delims.keys.join
69
72
  @code_attr_delims_re = /\A[#{keys}]/
70
73
  keys = Regexp.escape @attr_list_delims.keys.join
@@ -89,9 +92,7 @@ module Slim
89
92
 
90
93
  protected
91
94
 
92
- WORD_RE = ''.respond_to?(:encoding) ? '\p{Word}' : '\w'
93
- LC_WORD_RE = '[_a-z0-9]'
94
- ATTR_NAME = "\\A\\s*(#{WORD_RE}(?:#{WORD_RE}|:|-)*)"
95
+ ATTR_NAME = '\\A\\s*(\p{Word}(?:\p{Word}|:|-)*)'
95
96
  QUOTED_ATTR_RE = /#{ATTR_NAME}\s*=(=?)\s*("|')/
96
97
  CODE_ATTR_RE = /#{ATTR_NAME}\s*=(=?)\s*/
97
98
 
@@ -221,7 +222,11 @@ module Slim
221
222
  # Found an output block.
222
223
  # We expect the line to be broken or the next line to be indented.
223
224
  @line = $'
224
- trailing_ws = $2.include?('\'') || $2.include?('>')
225
+ trailing_ws = $2.include?('>')
226
+ if $2.include?('\'')
227
+ deprecated_syntax '=\' for trailing whitespace is deprecated in favor of =>'
228
+ trailing_ws = true
229
+ end
225
230
  block = [:multi]
226
231
  @stacks.last << [:static, ' '] if $2.include?('<')
227
232
  @stacks.last << [:slim, :output, $1.empty?, parse_broken_line, block]
@@ -324,7 +329,12 @@ module Slim
324
329
 
325
330
  @line =~ /\A[<>']*/
326
331
  @line = $'
327
- trailing_ws = $&.include?('\'') || $&.include?('>')
332
+ trailing_ws = $&.include?('>')
333
+ if $&.include?('\'')
334
+ deprecated_syntax 'tag\' for trailing whitespace is deprecated in favor of tag>'
335
+ trailing_ws = true
336
+ end
337
+
328
338
  leading_ws = $&.include?('<')
329
339
 
330
340
  parse_attributes(attributes)
@@ -354,7 +364,11 @@ module Slim
354
364
  when /\A\s*=(=?)(['<>]*)/
355
365
  # Handle output code
356
366
  @line = $'
357
- trailing_ws2 = $2.include?('\'') || $2.include?('>')
367
+ trailing_ws2 = $2.include?('>')
368
+ if $2.include?('\'')
369
+ deprecated_syntax '=\' for trailing whitespace is deprecated in favor of =>'
370
+ trailing_ws2 = true
371
+ end
358
372
  block = [:multi]
359
373
  @stacks.last.insert(-2, [:static, ' ']) if !leading_ws && $2.include?('<')
360
374
  tag << [:slim, :output, $1 != '=', parse_broken_line, block]
@@ -495,6 +509,16 @@ module Slim
495
509
  raise
496
510
  end
497
511
 
512
+ def deprecated_syntax(message)
513
+ line = @orig_line.lstrip
514
+ column = (@orig_line && @line ? @orig_line.size - @line.size : 0) + line.size - @orig_line.size
515
+ warn %{Deprecated syntax: #{message}
516
+ #{options[:file]}, Line #{@lineno}, Column #{@column}
517
+ #{line}
518
+ #{' ' * column}^
519
+ }
520
+ end
521
+
498
522
  def expect_next_line
499
523
  next_line || syntax_error!('Unexpected end of file')
500
524
  @line.strip!