slim 1.3.4 → 1.3.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,10 @@
1
+ 1.3.5
2
+
3
+ * Logic-less:
4
+ - Rewrote logic-less mode (Issue #326, #327)
5
+ - Logic-less mode supports lambdas
6
+ - Option :dictionary_access made more powerful, value :wrapped deprecated
7
+
1
8
  1.3.4
2
9
 
3
10
  * Fixed #314
data/Gemfile CHANGED
@@ -20,7 +20,7 @@ if ENV['RAILS']
20
20
  gem 'activerecord-jdbc-adapter'
21
21
  gem 'activerecord-jdbcsqlite3-adapter'
22
22
  else
23
- gem 'sqlite3-ruby'
23
+ gem 'sqlite3'
24
24
  end
25
25
  end
26
26
 
data/README.md CHANGED
@@ -93,7 +93,7 @@ Indentation matters, but the indentation depth can be chosen as you like. If you
93
93
  ### Text `|`
94
94
 
95
95
  The pipe tells Slim to just copy the line. It essentially escapes any processing.
96
- Each following line that is indented greater than the backtick is copied over.
96
+ Each following line that is indented greater than the pipe is copied over.
97
97
 
98
98
  body
99
99
  p
@@ -104,7 +104,7 @@ Each following line that is indented greater than the backtick is copied over.
104
104
 
105
105
  <body><p>This is a test of the text block.</p></body>
106
106
 
107
- The left margin is set at the indent of the backtick + one space.
107
+ The left margin is set at the indent of the pipe + one space.
108
108
  Any additional spaces will be copied over.
109
109
 
110
110
  body
@@ -657,18 +657,34 @@ If the object is an array, the section will iterate
657
657
  - articles
658
658
  tr: td = title
659
659
 
660
- #### Wrapped dictionary - Resolution order
660
+ #### Lambdas
661
+
662
+ Like mustache, Slim supports lambdas.
663
+
664
+ = person
665
+ = name
666
+
667
+ The lambda method could be defined like this
668
+
669
+ def lambda_method
670
+ "<div class='person'>#{yield(:name => 'Andrew')}</div>"
671
+ end
672
+
673
+ You can optionally pass one or more hashes to `yield`. If you pass multiple hashes, the block will be iterated as described above.
674
+
675
+ #### Dictionary access
661
676
 
662
677
  Example code:
663
678
 
664
679
  - article
665
680
  h1 = title
666
681
 
667
- In wrapped dictionary acccess mode (the default, see the options), the dictionary object is accessed in the following order.
682
+ The dictionary object is accessed in the order given by the `:dictionary_access`. Default order:
668
683
 
669
- 1. If `article.respond_to?(:title)`, Slim will execute `article.send(:title)`
670
- 2. If `article.respond_to?(:has_key?)` and `article.has_key?(:title)`, Slim will execute `article[:title]`
671
- 3. If `article.instance_variable_defined?(@title)`, Slim will execute `article.instance_variable_get @title`
684
+ 1. `:symbol` - If `article.respond_to?(:has_key?)` and `article.has_key?(:title)`, Slim will execute `article[:title]`
685
+ 2. `:string` - If `article.respond_to?(:has_key?)` and `article.has_key?('title')`, Slim will execute `article['title']`
686
+ 3. `:method` - If `article.respond_to?(:title)`, Slim will execute `article.send(:title)`
687
+ 4. `:instance_variable` - If `article.instance_variable_defined?(@title)`, Slim will execute `article.instance_variable_get @title`
672
688
 
673
689
  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.
674
690
 
@@ -723,7 +739,7 @@ and activate logic less mode per render call in your application
723
739
  <tbody>
724
740
  <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>
725
741
  <tr><td>String</td><td>:dictionary</td><td>"self"</td><td>Dictionary where variables are looked up</td></tr>
726
- <tr><td>Symbol</td><td>:dictionary_access</td><td>:wrapped</td><td>Dictionary access mode (:string, :symbol, :wrapped)</td></tr>
742
+ <tr><td>Symbol/Array of Symbols</td><td>:dictionary_access</td><td>[:symbol, :string, :method, :instance_variable]</td><td>Dictionary access order (:symbol, :string, :method, :instance_variable)</td></tr>
727
743
  </tbody>
728
744
  </table>
729
745
 
@@ -1,6 +1,6 @@
1
1
  require 'slim'
2
2
  require 'slim/logic_less/filter'
3
- require 'slim/logic_less/wrapper'
3
+ require 'slim/logic_less/context'
4
4
 
5
5
  # Insert plugin filter into Slim engine chain
6
6
  Slim::Engine.after(Slim::Interpolation, Slim::LogicLess, :logic_less, :dictionary, :dictionary_access)
@@ -0,0 +1,119 @@
1
+ module Slim
2
+ class LogicLess
3
+ # @api private
4
+ class Context
5
+ def initialize(dict, lookup)
6
+ @scope = [Scope.new(dict, lookup)]
7
+ end
8
+
9
+ def [](name)
10
+ scope[name]
11
+ end
12
+
13
+ def lambda(name)
14
+ scope.lambda(name) do |*dict|
15
+ if dict.empty?
16
+ yield
17
+ else
18
+ new_scope do
19
+ dict.inject('') do |result, d|
20
+ scope.dict = d
21
+ result << yield
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def section(name)
29
+ if dict = scope[name]
30
+ if !dict.respond_to?(:has_key?) && dict.respond_to?(:each)
31
+ new_scope do
32
+ dict.each do |d|
33
+ scope.dict = d
34
+ yield
35
+ end
36
+ end
37
+ else
38
+ new_scope(dict) { yield }
39
+ end
40
+ end
41
+ end
42
+
43
+ def inverted_section(name)
44
+ value = scope[name]
45
+ yield if !value || (value.respond_to?(:empty?) && value.empty?)
46
+ end
47
+
48
+ private
49
+
50
+ class Scope
51
+ attr_reader :lookup
52
+ attr_writer :dict
53
+
54
+ def initialize(dict, lookup, parent = nil)
55
+ @dict, @lookup, @parent = dict, lookup, parent
56
+ end
57
+
58
+ def lambda(name, &block)
59
+ @lookup.each do |lookup|
60
+ case lookup
61
+ when :method
62
+ return @dict.send(name, &block) if @dict.respond_to?(name)
63
+ when :symbol
64
+ return @dict[name].call(&block) if has_key?(name)
65
+ when :string
66
+ return @dict[name.to_s].call(&block) if has_key?(name.to_s)
67
+ when :instance_variable
68
+ var_name = "@#{name}"
69
+ return @dict.instance_variable_get(var_name).call(&block) if instance_variable?(var_name)
70
+ end
71
+ end
72
+ @parent.lambda(name) if @parent
73
+ end
74
+
75
+ def [](name)
76
+ @lookup.each do |lookup|
77
+ case lookup
78
+ when :method
79
+ return @dict.send(name) if @dict.respond_to?(name)
80
+ when :symbol
81
+ return @dict[name] if has_key?(name)
82
+ when :string
83
+ return @dict[name.to_s] if has_key?(name.to_s)
84
+ when :instance_variable
85
+ var_name = "@#{name}"
86
+ return @dict.instance_variable_get(var_name) if instance_variable?(var_name)
87
+ end
88
+ end
89
+ @parent[name] if @parent
90
+ end
91
+
92
+ private
93
+
94
+ def has_key?(name)
95
+ @dict.respond_to?(:has_key?) && @dict.has_key?(name)
96
+ end
97
+
98
+ def instance_variable?(name)
99
+ begin
100
+ @dict.instance_variable_defined?(name)
101
+ rescue NameError
102
+ false
103
+ end
104
+ end
105
+ end
106
+
107
+ def scope
108
+ @scope.last
109
+ end
110
+
111
+ def new_scope(dict = nil)
112
+ @scope << Scope.new(dict, scope.lookup, scope)
113
+ yield
114
+ ensure
115
+ @scope.pop
116
+ end
117
+ end
118
+ end
119
+ end
@@ -3,24 +3,34 @@ module Slim
3
3
  # This filter can be activated with the option "logic_less"
4
4
  # @api private
5
5
  class LogicLess < Filter
6
+ # Default dictionary access order, change it with the option :dictionary_access
7
+ DEFAULT_ACCESS_ORDER = [:symbol, :string, :method, :instance_variable].freeze
8
+
6
9
  define_options :logic_less => true,
7
10
  :dictionary => 'self',
8
- :dictionary_access => :wrapped # :symbol, :string, :wrapped
11
+ :dictionary_access => DEFAULT_ACCESS_ORDER
9
12
 
10
13
  def initialize(opts = {})
11
14
  super
12
- unless [:string, :symbol, :wrapped].include?(options[:dictionary_access])
13
- raise ArgumentError, "Invalid dictionary access #{options[:dictionary_access].inspect}"
15
+ access = options[:dictionary_access]
16
+ if access == :wrapped
17
+ puts 'Slim::LogicLess - Wrapped dictionary access is deprecated'
18
+ access = DEFAULT_ACCESS_ORDER
19
+ else
20
+ access = [access].flatten.compact
21
+ access.each do |type|
22
+ raise ArgumentError, "Invalid dictionary access #{type.inspect}" unless DEFAULT_ACCESS_ORDER.include?(type)
23
+ end
24
+ raise ArgumentError, 'Option dictionary access is missing' if access.empty?
14
25
  end
26
+ @access = access.inspect
15
27
  end
16
28
 
17
29
  def call(exp)
18
30
  if options[:logic_less]
19
- @dict = unique_name
20
- dictionary = options[:dictionary]
21
- dictionary = "::Slim::LogicLess::Wrapper.new(#{dictionary})" if options[:dictionary_access] == :wrapped
31
+ @context = unique_name
22
32
  [:multi,
23
- [:code, "#{@dict} = #{dictionary}"],
33
+ [:code, "#{@context} = ::Slim::LogicLess::Context.new(#{options[:dictionary]}, #{@access})"],
24
34
  super]
25
35
  else
26
36
  exp
@@ -29,16 +39,19 @@ module Slim
29
39
 
30
40
  # Interpret control blocks as sections or inverted sections
31
41
  def on_slim_control(name, content)
32
- if name =~ /\A!\s*(.*)/
33
- on_slim_inverted_section($1, content)
34
- else
35
- on_slim_section(name, content)
36
- end
42
+ method =
43
+ if name =~ /\A!\s*(.*)/
44
+ name = $1
45
+ 'inverted_section'
46
+ else
47
+ 'section'
48
+ end
49
+ [:block, "#{@context}.#{method}(#{name.to_sym.inspect}) do", compile(content)]
37
50
  end
38
51
 
39
52
  def on_slim_output(escape, name, content)
40
- raise(Temple::FilterError, 'Output statements with content are forbidden in logic less mode') if !empty_exp?(content)
41
- [:slim, :output, escape, access(name), content]
53
+ [:slim, :output, escape, empty_exp?(content) ? access(name) :
54
+ "#{@context}.lambda(#{name.to_sym.inspect}) do", compile(content)]
42
55
  end
43
56
 
44
57
  def on_slim_attrvalue(escape, value)
@@ -57,41 +70,10 @@ module Slim
57
70
  raise Temple::FilterError, 'Embedded code is forbidden in logic less mode'
58
71
  end
59
72
 
60
- protected
61
-
62
- def on_slim_inverted_section(name, content)
63
- tmp = unique_name
64
- [:multi,
65
- [:code, "#{tmp} = #{access name}"],
66
- [:if, "!#{tmp} || #{tmp}.respond_to?(:empty) && #{tmp}.empty?",
67
- compile(content)]]
68
- end
69
-
70
- def on_slim_section(name, content)
71
- content = compile(content)
72
- tmp1, tmp2 = unique_name, unique_name
73
-
74
- [:if, "#{tmp1} = #{access name}",
75
- [:if, "#{tmp1} == true",
76
- content,
77
- [:multi,
78
- # Wrap map in array because maps implement each
79
- [:code, "#{tmp1} = [#{tmp1}] if #{tmp1}.respond_to?(:has_key?) || !#{tmp1}.respond_to?(:map)"],
80
- [:code, "#{tmp2} = #{@dict}"],
81
- [:block, "#{tmp1}.each do |#{@dict}|", content],
82
- [:code, "#{@dict} = #{tmp2}"]]]]
83
- end
84
-
85
73
  private
86
74
 
87
75
  def access(name)
88
- return name if name == 'yield'
89
- case options[:dictionary_access]
90
- when :string
91
- "#{@dict}[#{name.to_s.inspect}]"
92
- else
93
- "#{@dict}[#{name.to_sym.inspect}]"
94
- end
76
+ name == 'yield' ? name : "#{@context}[#{name.to_sym.inspect}]"
95
77
  end
96
78
  end
97
79
  end
@@ -1,5 +1,5 @@
1
1
  module Slim
2
2
  # Slim version string
3
3
  # @api public
4
- VERSION = '1.3.4'
4
+ VERSION = '1.3.5'
5
5
  end
@@ -13,6 +13,70 @@ class TestSlimLogicLess < TestSlim
13
13
  end
14
14
  end
15
15
 
16
+ def test_lambda
17
+ source = %q{
18
+ p
19
+ == person
20
+ .name = name
21
+ == simple
22
+ .hello= hello
23
+ == list
24
+ li = key
25
+ }
26
+
27
+ hash = {
28
+ :hello => 'Hello!',
29
+ :person => lambda do |&block|
30
+ %w(Joe Jack).map do |name|
31
+ "<b>#{block.call(:name => name)}</b>"
32
+ end.join
33
+ end,
34
+ :simple => lambda do |&block|
35
+ "<div class=\"simple\">#{block.call}</div>"
36
+ end,
37
+ :list => lambda do |&block|
38
+ list = [{:key => 'First'}, {:key => 'Second'}]
39
+ "<ul>#{block.call(*list)}</ul>"
40
+ end
41
+ }
42
+
43
+ assert_html '<p><b><div class="name">Joe</div></b><b><div class="name">Jack</div></b><div class="simple"><div class="hello">Hello!</div></div><ul><li>First</li><li>Second</li></ul></p>', source, :scope => hash
44
+ end
45
+
46
+ def test_symbol_hash
47
+ source = %q{
48
+ p
49
+ - person
50
+ .name = name
51
+ }
52
+
53
+ hash = {
54
+ :person => [
55
+ { :name => 'Joe', },
56
+ { :name => 'Jack', }
57
+ ]
58
+ }
59
+
60
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash
61
+ end
62
+
63
+ def test_string_access
64
+ source = %q{
65
+ p
66
+ - person
67
+ .name = name
68
+ }
69
+
70
+ hash = {
71
+ 'person' => [
72
+ { 'name' => 'Joe', },
73
+ { 'name' => 'Jack', }
74
+ ]
75
+ }
76
+
77
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash, :dictionary_access => :string
78
+ end
79
+
16
80
  def test_symbol_access
17
81
  source = %q{
18
82
  p
@@ -30,17 +94,46 @@ p
30
94
  assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash, :dictionary_access => :symbol
31
95
  end
32
96
 
33
- def test_dictionary_option
97
+ def test_method_access
34
98
  source = %q{
35
99
  p
36
100
  - person
37
101
  .name = name
38
102
  }
39
103
 
40
- assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => Scope.new, :dictionary => '@hash', :dictionary_access => :symbol
104
+ object = Object.new
105
+ def object.person
106
+ %w(Joe Jack).map do |name|
107
+ person = Object.new
108
+ person.instance_variable_set(:@name, name)
109
+ def person.name
110
+ @name
111
+ end
112
+ person
113
+ end
114
+ end
115
+
116
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => object, :dictionary_access => :method
41
117
  end
42
118
 
43
- def test_string_access
119
+ def test_instance_variable_access
120
+ source = %q{
121
+ p
122
+ - person
123
+ .name = name
124
+ }
125
+
126
+ object = Object.new
127
+ object.instance_variable_set(:@person, %w(Joe Jack).map do |name|
128
+ person = Object.new
129
+ person.instance_variable_set(:@name, name)
130
+ person
131
+ end)
132
+
133
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => object, :dictionary_access => :instance_variable
134
+ end
135
+
136
+ def test_string_hash
44
137
  source = %q{
45
138
  p
46
139
  - person
@@ -54,7 +147,17 @@ p
54
147
  ]
55
148
  }
56
149
 
57
- assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash, :dictionary_access => :string
150
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash
151
+ end
152
+
153
+ def test_dictionary_option
154
+ source = %q{
155
+ p
156
+ - person
157
+ .name = name
158
+ }
159
+
160
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => Scope.new, :dictionary => '@hash'
58
161
  end
59
162
 
60
163
  def test_flag_section
@@ -94,14 +197,6 @@ p
94
197
  assert_html '<p>No person No person 2</p>', source, :scope => hash
95
198
  end
96
199
 
97
- def test_output_with_content
98
- source = %{
99
- p = method_with_block do
100
- block
101
- }
102
- assert_runtime_error 'Output statements with content are forbidden in logic less mode', source
103
- end
104
-
105
200
  def test_escaped_interpolation
106
201
  source = %q{
107
202
  p text with \#{123} test
@@ -120,7 +215,7 @@ p
120
215
  Person
121
216
  }
122
217
 
123
- assert_html '<p><b name="Joe">Person</b><a id="Joe">1</a><span class="Joe"><Person></Person></span><b name="Jack">Person</b><a id="Jack">2</a><span class="Jack"><Person></Person></span></p>', source, :scope => Scope.new, :dictionary => '@hash', :dictionary_access => :symbol
218
+ assert_html '<p><b name="Joe">Person</b><a id="Joe">1</a><span class="Joe"><Person></Person></span><b name="Jack">Person</b><a id="Jack">2</a><span class="Jack"><Person></Person></span></p>', source, :scope => Scope.new, :dictionary => '@hash'
124
219
  end
125
220
 
126
221
  def test_boolean_attributes
@@ -130,6 +225,54 @@ p
130
225
  input checked=selected = name
131
226
  }
132
227
 
133
- assert_html '<p><input checked="checked">Joe</input><input>Jack</input></p>', source, :scope => Scope.new, :dictionary => '@hash', :dictionary_access => :symbol
228
+ assert_html '<p><input checked="checked">Joe</input><input>Jack</input></p>', source, :scope => Scope.new, :dictionary => '@hash'
229
+ end
230
+
231
+ def test_sections
232
+ source = %q{
233
+ p
234
+ - person
235
+ .name = name
236
+ }
237
+ assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :dictionary => 'ViewEnv.new'
238
+ end
239
+
240
+ def test_with_array
241
+ source = %q{
242
+ ul
243
+ - people_with_locations
244
+ li = name
245
+ li = city
246
+ }
247
+ assert_html '<ul><li>Andy</li><li>Atlanta</li><li>Fred</li><li>Melbourne</li><li>Daniel</li><li>Karlsruhe</li></ul>', source, :dictionary => 'ViewEnv.new'
248
+ end
249
+
250
+ def test_method
251
+ source = %q{
252
+ a href=output_number Link
253
+ }
254
+ assert_html '<a href="1337">Link</a>', source, :dictionary => 'ViewEnv.new'
255
+ end
256
+
257
+ def test_conditional_parent
258
+ source = %q{
259
+ - prev_page
260
+ li.previous
261
+ a href=prev_page Older
262
+ - next_page
263
+ li.next
264
+ a href=next_page Newer}
265
+ assert_html'<li class="previous"><a href="prev">Older</a></li><li class="next"><a href="next">Newer</a></li>', source, :scope => {:prev_page => 'prev', :next_page => 'next'}
266
+ end
267
+
268
+ def test_render_with_yield
269
+ source = %q{
270
+ div
271
+ == yield
272
+ }
273
+
274
+ assert_html '<div>This is the menu</div>', source do
275
+ 'This is the menu'
276
+ end
134
277
  end
135
278
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slim
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 1.3.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-11-15 00:00:00.000000000 Z
14
+ date: 2012-12-19 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: temple
18
- requirement: &6992320 !ruby/object:Gem::Requirement
18
+ requirement: !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ~>
@@ -23,10 +23,15 @@ dependencies:
23
23
  version: 0.5.5
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *6992320
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ version: 0.5.5
27
32
  - !ruby/object:Gem::Dependency
28
33
  name: tilt
29
- requirement: &6991480 !ruby/object:Gem::Requirement
34
+ requirement: !ruby/object:Gem::Requirement
30
35
  none: false
31
36
  requirements:
32
37
  - - ~>
@@ -34,10 +39,15 @@ dependencies:
34
39
  version: 1.3.3
35
40
  type: :runtime
36
41
  prerelease: false
37
- version_requirements: *6991480
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.3
38
48
  - !ruby/object:Gem::Dependency
39
49
  name: rake
40
- requirement: &7050740 !ruby/object:Gem::Requirement
50
+ requirement: !ruby/object:Gem::Requirement
41
51
  none: false
42
52
  requirements:
43
53
  - - ! '>='
@@ -45,10 +55,15 @@ dependencies:
45
55
  version: 0.8.7
46
56
  type: :development
47
57
  prerelease: false
48
- version_requirements: *7050740
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: 0.8.7
49
64
  - !ruby/object:Gem::Dependency
50
65
  name: sass
51
- requirement: &7050220 !ruby/object:Gem::Requirement
66
+ requirement: !ruby/object:Gem::Requirement
52
67
  none: false
53
68
  requirements:
54
69
  - - ! '>='
@@ -56,10 +71,15 @@ dependencies:
56
71
  version: 3.1.0
57
72
  type: :development
58
73
  prerelease: false
59
- version_requirements: *7050220
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: 3.1.0
60
80
  - !ruby/object:Gem::Dependency
61
81
  name: minitest
62
- requirement: &7049700 !ruby/object:Gem::Requirement
82
+ requirement: !ruby/object:Gem::Requirement
63
83
  none: false
64
84
  requirements:
65
85
  - - ! '>='
@@ -67,10 +87,15 @@ dependencies:
67
87
  version: '0'
68
88
  type: :development
69
89
  prerelease: false
70
- version_requirements: *7049700
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
71
96
  - !ruby/object:Gem::Dependency
72
97
  name: kramdown
73
- requirement: &7049220 !ruby/object:Gem::Requirement
98
+ requirement: !ruby/object:Gem::Requirement
74
99
  none: false
75
100
  requirements:
76
101
  - - ! '>='
@@ -78,10 +103,15 @@ dependencies:
78
103
  version: '0'
79
104
  type: :development
80
105
  prerelease: false
81
- version_requirements: *7049220
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
82
112
  - !ruby/object:Gem::Dependency
83
113
  name: creole
84
- requirement: &7048720 !ruby/object:Gem::Requirement
114
+ requirement: !ruby/object:Gem::Requirement
85
115
  none: false
86
116
  requirements:
87
117
  - - ! '>='
@@ -89,10 +119,15 @@ dependencies:
89
119
  version: '0'
90
120
  type: :development
91
121
  prerelease: false
92
- version_requirements: *7048720
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
93
128
  - !ruby/object:Gem::Dependency
94
129
  name: builder
95
- requirement: &7048140 !ruby/object:Gem::Requirement
130
+ requirement: !ruby/object:Gem::Requirement
96
131
  none: false
97
132
  requirements:
98
133
  - - ! '>='
@@ -100,7 +135,12 @@ dependencies:
100
135
  version: '0'
101
136
  type: :development
102
137
  prerelease: false
103
- version_requirements: *7048140
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
104
144
  description: Slim is a template language whose goal is reduce the syntax to the essential
105
145
  parts without becoming cryptic.
106
146
  email:
@@ -141,8 +181,8 @@ files:
141
181
  - lib/slim/grammar.rb
142
182
  - lib/slim/interpolation.rb
143
183
  - lib/slim/logic_less.rb
184
+ - lib/slim/logic_less/context.rb
144
185
  - lib/slim/logic_less/filter.rb
145
- - lib/slim/logic_less/wrapper.rb
146
186
  - lib/slim/parser.rb
147
187
  - lib/slim/splat_attributes.rb
148
188
  - lib/slim/template.rb
@@ -170,7 +210,6 @@ files:
170
210
  - test/literate/helper.rb
171
211
  - test/literate/run.rb
172
212
  - test/logic_less/test_logic_less.rb
173
- - test/logic_less/test_wrapper.rb
174
213
  - test/rails/Rakefile
175
214
  - test/rails/app/controllers/application_controller.rb
176
215
  - test/rails/app/controllers/parents_controller.rb
@@ -232,9 +271,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
232
271
  version: '0'
233
272
  requirements: []
234
273
  rubyforge_project: slim
235
- rubygems_version: 1.8.15
274
+ rubygems_version: 1.8.24
236
275
  signing_key:
237
276
  specification_version: 3
238
277
  summary: Slim is a template language.
239
278
  test_files: []
240
- has_rdoc:
@@ -1,64 +0,0 @@
1
- module Slim
2
- class LogicLess
3
- # For logic less mode, objects can be encased in the Wrapper class.
4
- # @api private
5
- class Wrapper
6
- attr_reader :value, :parent
7
-
8
- def initialize(value, parent = nil)
9
- @value, @parent = value, parent
10
- end
11
-
12
- # To find the reference, first check for standard method
13
- # access by using respond_to?.
14
- #
15
- # If not found, check to see if the value is a hash and if the
16
- # the name is a key on the hash.
17
- #
18
- # Not a hash, or not a key on the hash, then check to see if there
19
- # is an instance variable with the name.
20
- #
21
- # If the instance variable doesn't exist and there is a parent object,
22
- # go through the same steps on the parent object. This is useful when
23
- # you are iterating over objects.
24
- def [](name)
25
- return wrap(value.send(name)) if value.respond_to?(name)
26
- if value.respond_to?(:has_key?)
27
- return wrap(value[name.to_sym]) if value.has_key?(name.to_sym)
28
- return wrap(value[name.to_s]) if value.has_key?(name.to_s)
29
- end
30
- begin
31
- var_name = "@#{name}"
32
- return wrap(value.instance_variable_get(var_name)) if value.instance_variable_defined?(var_name)
33
- rescue NameError
34
- # Do nothing
35
- end
36
- parent[name] if parent
37
- end
38
-
39
- # Empty objects must appear empty for inverted sections
40
- def empty?
41
- value.respond_to?(:empty) && value.empty?
42
- end
43
-
44
- # Used for output
45
- def to_s
46
- value.to_s
47
- end
48
-
49
- private
50
-
51
- def wrap(response)
52
- # Primitives are not wrapped
53
- if [String, Numeric, TrueClass, FalseClass, NilClass].any? {|primitive| primitive === response }
54
- response
55
- # Enumerables are mapped with wrapped values (except Hash-like objects)
56
- elsif !response.respond_to?(:has_key?) && response.respond_to?(:map)
57
- response.map {|v| wrap(v) }
58
- else
59
- Wrapper.new(response, self)
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,31 +0,0 @@
1
- require 'helper'
2
- require 'slim/logic_less'
3
-
4
- class TestSlimWrapper < TestSlim
5
- def test_sections
6
- source = %q{
7
- p
8
- - person
9
- .name = name
10
- }
11
- assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :dictionary => 'ViewEnv.new'
12
- end
13
-
14
- def test_with_array
15
- source = %q{
16
- ul
17
- - people_with_locations
18
- li = name
19
- li = city
20
- }
21
- assert_html '<ul><li>Andy</li><li>Atlanta</li><li>Fred</li><li>Melbourne</li><li>Daniel</li><li>Karlsruhe</li></ul>', source, :dictionary => 'ViewEnv.new'
22
- end
23
-
24
- def test_method
25
- source = %q{
26
- a href=output_number Link
27
- }
28
- assert_html '<a href="1337">Link</a>', source, :dictionary => 'ViewEnv.new'
29
- end
30
-
31
- end