slim 2.1.0 → 3.0.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
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!