cloudhead-less 1.0.10 → 1.0.13

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 (50) hide show
  1. data/VERSION +1 -1
  2. data/less.gemspec +40 -30
  3. data/lib/less/engine/less.tt +29 -27
  4. data/lib/less/engine/nodes/element.rb +47 -11
  5. data/lib/less/engine/nodes/property.rb +26 -6
  6. data/lib/less/engine/nodes/ruleset.rb +12 -0
  7. data/lib/less/engine/nodes.rb +1 -0
  8. data/lib/less/engine/parser.rb +166 -132
  9. data/lib/less/engine.rb +2 -2
  10. data/spec/css/{accessors-1.0.css → accessors.css} +0 -0
  11. data/spec/css/{big-1.0.css → big.css} +0 -0
  12. data/spec/css/{colors-1.0.css → colors.css} +0 -0
  13. data/spec/css/{comments-1.0.css → comments.css} +0 -0
  14. data/spec/css/css-3.css +2 -0
  15. data/spec/css/{css-1.0.css → css.css} +1 -0
  16. data/spec/css/{functions-1.0.css → functions.css} +0 -0
  17. data/spec/css/{import-1.0.css → import.css} +1 -0
  18. data/spec/css/lazy-eval.css +1 -0
  19. data/spec/css/mixins-args.css +0 -0
  20. data/spec/css/{mixins-1.0.css → mixins.css} +0 -0
  21. data/spec/css/{operations-1.0.css → operations.css} +0 -0
  22. data/spec/css/{rulesets-1.0.css → rulesets.css} +0 -0
  23. data/spec/css/{scope-1.0.css → scope.css} +1 -4
  24. data/spec/css/selectors.css +8 -0
  25. data/spec/css/{strings-1.0.css → strings.css} +0 -0
  26. data/spec/css/{variables-1.0.css → variables.css} +0 -0
  27. data/spec/css/{whitespace-1.0.css → whitespace.css} +1 -4
  28. data/spec/engine_spec.rb +15 -3
  29. data/spec/less/{accessors-1.0.less → accessors.less} +0 -0
  30. data/spec/less/{big-1.0.less → big.less} +0 -0
  31. data/spec/less/{colors-1.0.less → colors.less} +0 -0
  32. data/spec/less/{comments-1.0.less → comments.less} +0 -0
  33. data/spec/less/css-3.less +11 -0
  34. data/spec/less/{css-1.0.less → css.less} +1 -0
  35. data/spec/less/{functions-1.0.less → functions.less} +0 -0
  36. data/spec/less/import/import-test-c.less +1 -0
  37. data/spec/less/import/import-test-d.css +1 -0
  38. data/spec/less/{import-1.0.less → import.less} +0 -0
  39. data/spec/less/lazy-eval.less +6 -0
  40. data/spec/less/mixins-args.less +0 -0
  41. data/spec/less/{mixins-1.0.less → mixins.less} +0 -0
  42. data/spec/less/{operations-1.0.less → operations.less} +0 -0
  43. data/spec/less/{rulesets-1.0.less → rulesets.less} +0 -0
  44. data/spec/less/{scope-1.0.less → scope.less} +1 -2
  45. data/spec/less/selectors.less +15 -0
  46. data/spec/less/{strings-1.0.less → strings.less} +0 -0
  47. data/spec/less/{variables-1.0.less → variables.less} +0 -0
  48. data/spec/less/{whitespace-1.0.less → whitespace.less} +0 -0
  49. data/spec/spec.css +1 -3
  50. metadata +40 -30
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.11
1
+ 1.0.13
data/less.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{less}
5
- s.version = "1.0.10"
5
+ s.version = "1.0.13"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["cloudhead"]
9
- s.date = %q{2009-07-16}
9
+ s.date = %q{2009-07-20}
10
10
  s.default_executable = %q{lessc}
11
11
  s.description = %q{LESS is leaner CSS}
12
12
  s.email = %q{self@cloudhead.net}
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  "lib/less/engine/nodes/function.rb",
35
35
  "lib/less/engine/nodes/literal.rb",
36
36
  "lib/less/engine/nodes/property.rb",
37
+ "lib/less/engine/nodes/ruleset.rb",
37
38
  "lib/less/engine/nodes/selector.rb",
38
39
  "lib/less/engine/parser.rb",
39
40
  "lib/vendor/treetop/.gitignore",
@@ -127,41 +128,50 @@ Gem::Specification.new do |s|
127
128
  "lib/vendor/treetop/spec/spec_suite.rb",
128
129
  "lib/vendor/treetop/treetop.gemspec",
129
130
  "spec/command_spec.rb",
130
- "spec/css/accessors-1.0.css",
131
- "spec/css/big-1.0.css",
132
- "spec/css/colors-1.0.css",
133
- "spec/css/comments-1.0.css",
134
- "spec/css/css-1.0.css",
135
- "spec/css/functions-1.0.css",
136
- "spec/css/import-1.0.css",
137
- "spec/css/mixins-1.0.css",
138
- "spec/css/operations-1.0.css",
139
- "spec/css/rulesets-1.0.css",
140
- "spec/css/scope-1.0.css",
141
- "spec/css/strings-1.0.css",
142
- "spec/css/variables-1.0.css",
143
- "spec/css/whitespace-1.0.css",
131
+ "spec/css/accessors.css",
132
+ "spec/css/big.css",
133
+ "spec/css/colors.css",
134
+ "spec/css/comments.css",
135
+ "spec/css/css-3.css",
136
+ "spec/css/css.css",
137
+ "spec/css/functions.css",
138
+ "spec/css/import.css",
139
+ "spec/css/lazy-eval.css",
140
+ "spec/css/mixins-args.css",
141
+ "spec/css/mixins.css",
142
+ "spec/css/operations.css",
143
+ "spec/css/rulesets.css",
144
+ "spec/css/scope.css",
145
+ "spec/css/selectors.css",
146
+ "spec/css/strings.css",
147
+ "spec/css/variables.css",
148
+ "spec/css/whitespace.css",
144
149
  "spec/engine_spec.rb",
145
- "spec/less/accessors-1.0.less",
146
- "spec/less/big-1.0.less",
147
- "spec/less/colors-1.0.less",
148
- "spec/less/comments-1.0.less",
149
- "spec/less/css-1.0.less",
150
+ "spec/less/accessors.less",
151
+ "spec/less/big.less",
152
+ "spec/less/colors.less",
153
+ "spec/less/comments.less",
154
+ "spec/less/css-3.less",
155
+ "spec/less/css.less",
150
156
  "spec/less/exceptions/mixed-units-error.less",
151
157
  "spec/less/exceptions/name-error-1.0.less",
152
158
  "spec/less/exceptions/syntax-error-1.0.less",
153
- "spec/less/functions-1.0.less",
154
- "spec/less/import-1.0.less",
159
+ "spec/less/functions.less",
160
+ "spec/less/import.less",
155
161
  "spec/less/import/import-test-a.less",
156
162
  "spec/less/import/import-test-b.less",
157
163
  "spec/less/import/import-test-c.less",
158
- "spec/less/mixins-1.0.less",
159
- "spec/less/operations-1.0.less",
160
- "spec/less/rulesets-1.0.less",
161
- "spec/less/scope-1.0.less",
162
- "spec/less/strings-1.0.less",
163
- "spec/less/variables-1.0.less",
164
- "spec/less/whitespace-1.0.less",
164
+ "spec/less/import/import-test-d.css",
165
+ "spec/less/lazy-eval.less",
166
+ "spec/less/mixins-args.less",
167
+ "spec/less/mixins.less",
168
+ "spec/less/operations.less",
169
+ "spec/less/rulesets.less",
170
+ "spec/less/scope.less",
171
+ "spec/less/selectors.less",
172
+ "spec/less/strings.less",
173
+ "spec/less/variables.less",
174
+ "spec/less/whitespace.less",
165
175
  "spec/spec.css",
166
176
  "spec/spec.less",
167
177
  "spec/spec_helper.rb"
@@ -14,13 +14,13 @@ grammar Less
14
14
  selectors "{" ws primary ws "}" ws {
15
15
  def build env
16
16
  # Build the ruleset for each selector
17
- selectors.build(env, :tree).each do |sel|
17
+ selectors.build(env, :ruleset).each do |sel|
18
18
  primary.build sel
19
19
  end
20
20
  end
21
21
  } / ws selectors ';' ws {
22
22
  def build env
23
- selectors.build(env, :path).each do |path|
23
+ selectors.build(env, :mixin).each do |path|
24
24
  rules = path.inject(env.root) do |current, node|
25
25
  current.descend(node.selector, node) or raise MixinNameError, path.join
26
26
  end.rules
@@ -34,7 +34,7 @@ grammar Less
34
34
  "@import" S url:(string / url) medias? s ';' ws {
35
35
  def build env
36
36
  path = File.join(env.root.file, url.value)
37
- path += '.less' unless path =~ /\.less$/
37
+ path += '.less' unless path =~ /\.(le|c)ss$/
38
38
  if File.exist? path
39
39
  imported = Less::Engine.new(File.new path).to_tree
40
40
  env.rules += imported.rules
@@ -79,16 +79,16 @@ grammar Less
79
79
  # div > p a {...}
80
80
  #
81
81
  rule selector
82
- (s select element s)+ {
83
- def tree env
84
- elements.inject(env) do |node, e|
82
+ sel:(s select element s)+ arguments? {
83
+ def ruleset env
84
+ sel.elements.inject(env) do |node, e|
85
85
  node << Node::Element.new(e.element.text_value, e.select.text_value)
86
86
  node.last
87
87
  end
88
88
  end
89
89
 
90
- def path env
91
- elements.map do |e|
90
+ def mixin env
91
+ sel.elements.map do |e|
92
92
  Node::Element.new(e.element.text_value, e.select.text_value)
93
93
  end
94
94
  end
@@ -102,7 +102,7 @@ grammar Less
102
102
  rule declaration
103
103
  ws name:(ident / variable) s ':' s expression s (';'/ ws &'}') ws {
104
104
  def build env
105
- env << (name.text_value =~ /^@/ ? Node::Variable : Node::Property).new(name.text_value)
105
+ env << (name.text_value =~ /^@/ ? Node::Variable : Node::Property).new(name.text_value, [])
106
106
  expression.build env
107
107
  end
108
108
  # Empty rule
@@ -156,7 +156,7 @@ grammar Less
156
156
  rule variable
157
157
  '@' [-a-zA-Z0-9_]+ {
158
158
  def build env
159
- env.identifiers.last << env.nearest(text_value)
159
+ env.identifiers.last << Node::Variable.new(text_value)
160
160
  end
161
161
  }
162
162
  end
@@ -248,7 +248,7 @@ grammar Less
248
248
  # `blue`, `small`, `normal` etc.
249
249
  #
250
250
  rule keyword
251
- [a-zA-Z] [-a-zA-Z]* !ns {
251
+ [-a-zA-Z]+ !ns {
252
252
  def build env
253
253
  env.identifiers.last << Node::Keyword.new(text_value)
254
254
  end
@@ -294,10 +294,9 @@ grammar Less
294
294
  def build env
295
295
  env.identifiers.last << Node::Color.new(*rgb.build)
296
296
  end
297
- } / fn:(('hsl'/'rgb') 'a'?) '(' arguments ')' {
297
+ } / fn:(('hsl'/'rgb') 'a'?) arguments {
298
298
  def build env
299
- args = arguments.build env
300
- env.identifiers.last << Node::Function.new(fn.text_value, args.flatten)
299
+ env.identifiers.last << Node::Function.new(fn.text_value, arguments.build.flatten)
301
300
  end
302
301
  }
303
302
  end
@@ -325,43 +324,46 @@ grammar Less
325
324
  # Functions and arguments
326
325
  #
327
326
  rule function
328
- name:([-a-zA-Z_]+) '(' arguments ')' {
327
+ name:([-a-zA-Z_]+) arguments {
329
328
  def build env
330
- args = arguments.build env
331
- env.identifiers.last << Node::Function.new(name.text_value, [args].flatten)
329
+ env.identifiers.last << Node::Function.new(name.text_value, [arguments.build].flatten)
332
330
  end
333
331
  }
334
332
  end
335
333
 
336
334
  rule arguments
337
- argument s ',' s arguments {
338
- def build env
339
- elements.map do |e|
340
- e.build env if e.respond_to? :build
335
+ '(' s argument s tail:(',' s argument s)* ')' {
336
+ def build
337
+ all.map do |e|
338
+ e.build if e.respond_to? :build
341
339
  end.compact
342
340
  end
343
- } / argument
341
+
342
+ def all
343
+ [argument] + tail.elements.map {|e| e.argument }
344
+ end
345
+ }
344
346
  end
345
347
 
346
348
  rule argument
347
349
  color {
348
- def build env
350
+ def build
349
351
  Node::Color.new text_value
350
352
  end
351
353
  } / number unit {
352
- def build env
354
+ def build
353
355
  Node::Number.new number.text_value, unit.text_value
354
356
  end
355
357
  } / string {
356
- def build env
358
+ def build
357
359
  Node::String.new text_value
358
360
  end
359
361
  } / [a-zA-Z]+ '=' dimension {
360
- def build env
362
+ def build
361
363
  Node::Anonymous.new text_value
362
364
  end
363
365
  } / [-a-zA-Z0-9_%$/.&=:;#+?]+ {
364
- def build env
366
+ def build
365
367
  Node::String.new text_value
366
368
  end
367
369
  }
@@ -12,12 +12,12 @@ module Less
12
12
  include Enumerable
13
13
  include Entity
14
14
 
15
- attr_accessor :rules, :selector, :partial, :file
15
+ attr_accessor :rules, :selector, :partial, :file, :set
16
16
 
17
17
  def initialize name = "", selector = ''
18
- super name
19
-
20
- @partial = false
18
+ super name
19
+
20
+ @set = []
21
21
  @rules = [] # Holds all the nodes under this element's hierarchy
22
22
  @selector = Selector[selector.strip].new # descendant | child | adjacent
23
23
  end
@@ -32,7 +32,7 @@ module Less
32
32
 
33
33
  # Top-most node?
34
34
  def root?
35
- self == '' && parent.nil?
35
+ parent.nil?
36
36
  end
37
37
 
38
38
  def empty?
@@ -42,6 +42,43 @@ module Less
42
42
  def leaf?
43
43
  elements.empty?
44
44
  end
45
+
46
+ # Group similar rulesets together
47
+ # This is horrible, horrible code,
48
+ # but it'll have to do until I find
49
+ # a proper way to do it.
50
+ def group
51
+ matched = false
52
+ stack, result = elements.dup, []
53
+ return self unless elements.size > 1
54
+
55
+ elements.each do
56
+ e = stack.first
57
+ result << e unless matched
58
+
59
+ matched = stack[1..-1].each do |ee|
60
+ if e.rules.size == ee.rules.size and
61
+ e.elements.size == 0 and
62
+ !e.rules.zip(ee.rules).map {|a, b|
63
+ a.to_css == b.to_css
64
+ }.include?(false)
65
+
66
+ # Add to set unless it's a duplicate
67
+ if e == ee
68
+ # Do something with dups
69
+ else
70
+ self[e].set << ee
71
+ end
72
+ stack.shift
73
+ else
74
+ stack.shift
75
+ break false
76
+ end
77
+ end if stack.size > 1
78
+ end
79
+ @rules -= (elements - result)
80
+ self
81
+ end
45
82
 
46
83
  #
47
84
  # Accessors for the different nodes in @rules
@@ -84,7 +121,7 @@ module Less
84
121
 
85
122
  def last; elements.last end
86
123
  def first; elements.first end
87
- def to_s; super end
124
+ def to_s; root?? '*' : super end
88
125
 
89
126
  #
90
127
  # Entry point for the css conversion
@@ -95,15 +132,15 @@ module Less
95
132
  content = properties.map do |i|
96
133
  ' ' * 2 + i.to_css
97
134
  end.compact.reject(&:empty?) * "\n"
98
-
135
+
99
136
  content = content.include?("\n") ?
100
137
  "\n#{content}\n" : " #{content.strip} "
101
138
  ruleset = !content.strip.empty??
102
- "#{path.reject(&:empty?).join.strip} {#{content}}\n" : ""
103
-
139
+ "#{[path.reject(&:empty?).join.strip, *@set] * ', '} {#{content}}\n" : ""
140
+
104
141
  css = ruleset + elements.map do |i|
105
142
  i.to_css(path)
106
- end.reject(&:empty?).join
143
+ end.reject(&:empty?).join
107
144
  path.pop; path.pop
108
145
  css
109
146
  end
@@ -132,7 +169,6 @@ module Less
132
169
  end
133
170
  self
134
171
  end
135
- alias :traverse :each
136
172
 
137
173
  def inspect depth = 0
138
174
  indent = lambda {|i| '. ' * i }
@@ -7,12 +7,13 @@ module Less
7
7
 
8
8
  def initialize key, value = nil
9
9
  super key
10
- @value = Expression.new(value ? [value] : [])
10
+ @value = Expression.new(value ? [value].flatten : [])
11
11
  @eval = false # Store the first evaluation in here
12
12
  end
13
13
 
14
14
  def << token
15
15
  token = Node::Anonymous.new(*token) unless token.is_a? Entity or token.is_a? Operator
16
+ token.parent = self if token.respond_to? :parent
16
17
  @value << token
17
18
  end
18
19
 
@@ -27,9 +28,13 @@ module Less
27
28
  super
28
29
  end
29
30
 
31
+ def nearest node
32
+ parent.nearest node
33
+ end
34
+
30
35
  # TODO: @eval and @value should be merged
31
36
  def evaluate
32
- @eval || @eval = value.evaluate
37
+ @eval ||= value.evaluate
33
38
  end
34
39
 
35
40
  def to_css
@@ -37,8 +42,11 @@ module Less
37
42
  end
38
43
  end
39
44
 
40
- class Variable < Property
41
- def initialize key, value = nil
45
+ class Variable < Property
46
+ attr_reader :declaration
47
+
48
+ def initialize key, value = nil
49
+ @declaration = value ? true : false
42
50
  super key.delete('@'), value
43
51
  end
44
52
 
@@ -50,16 +58,28 @@ module Less
50
58
  "@#{super}"
51
59
  end
52
60
 
61
+ def evaluate
62
+ if declaration
63
+ @eval ||= value.evaluate
64
+ else
65
+ @eval ||= self.parent.nearest(to_s).evaluate
66
+ end
67
+ end
68
+
53
69
  def to_ruby
54
- value.evaluate.to_ruby
70
+ evaluate.to_ruby
55
71
  end
56
72
 
57
73
  def to_css
58
- value.evaluate.to_css
74
+ evaluate.to_css
59
75
  end
60
76
  end
61
77
 
62
78
  class Expression < Array
79
+ def initialize ary
80
+ super [ary].flatten
81
+ end
82
+
63
83
  def operators; select {|i| i.is_a? Operator } end
64
84
  def entities; select {|i| i.kind_of? Entity } end
65
85
  def literals; select {|i| i.kind_of? Literal } end
@@ -0,0 +1,12 @@
1
+ module Less
2
+ module Node
3
+ class Ruleset < Array
4
+ def initialize elements = []
5
+ super elements
6
+ end
7
+
8
+ def to_css
9
+ end
10
+ end
11
+ end
12
+ end
@@ -2,6 +2,7 @@ $:.unshift File.dirname(__FILE__)
2
2
 
3
3
  require 'engine/nodes/entity'
4
4
  require 'engine/nodes/function'
5
+ require 'engine/nodes/ruleset'
5
6
  require 'engine/nodes/element'
6
7
  require 'engine/nodes/property'
7
8
  require 'engine/nodes/literal'
@@ -339,7 +339,7 @@ module Less
339
339
  module Ruleset1
340
340
  def build env
341
341
  # Build the ruleset for each selector
342
- selectors.build(env, :tree).each do |sel|
342
+ selectors.build(env, :ruleset).each do |sel|
343
343
  primary.build sel
344
344
  end
345
345
  end
@@ -361,7 +361,7 @@ module Less
361
361
 
362
362
  module Ruleset3
363
363
  def build env
364
- selectors.build(env, :path).each do |path|
364
+ selectors.build(env, :mixin).each do |path|
365
365
  rules = path.inject(env.root) do |current, node|
366
366
  current.descend(node.selector, node) or raise MixinNameError, path.join
367
367
  end.rules
@@ -492,7 +492,7 @@ module Less
492
492
  module Import1
493
493
  def build env
494
494
  path = File.join(env.root.file, url.value)
495
- path += '.less' unless path =~ /\.less$/
495
+ path += '.less' unless path =~ /\.(le|c)ss$/
496
496
  if File.exist? path
497
497
  imported = Less::Engine.new(File.new path).to_tree
498
498
  env.rules += imported.rules
@@ -925,15 +925,22 @@ module Less
925
925
  end
926
926
 
927
927
  module Selector1
928
- def tree env
929
- elements.inject(env) do |node, e|
928
+ def sel
929
+ elements[0]
930
+ end
931
+
932
+ end
933
+
934
+ module Selector2
935
+ def ruleset env
936
+ sel.elements.inject(env) do |node, e|
930
937
  node << Node::Element.new(e.element.text_value, e.select.text_value)
931
938
  node.last
932
939
  end
933
940
  end
934
941
 
935
- def path env
936
- elements.map do |e|
942
+ def mixin env
943
+ sel.elements.map do |e|
937
944
  Node::Element.new(e.element.text_value, e.select.text_value)
938
945
  end
939
946
  end
@@ -947,42 +954,60 @@ module Less
947
954
  return cached
948
955
  end
949
956
 
950
- s0, i0 = [], index
957
+ i0, s0 = index, []
958
+ s1, i1 = [], index
951
959
  loop do
952
- i1, s1 = index, []
953
- r2 = _nt_s
954
- s1 << r2
955
- if r2
956
- r3 = _nt_select
957
- s1 << r3
958
- if r3
959
- r4 = _nt_element
960
- s1 << r4
961
- if r4
962
- r5 = _nt_s
963
- s1 << r5
960
+ i2, s2 = index, []
961
+ r3 = _nt_s
962
+ s2 << r3
963
+ if r3
964
+ r4 = _nt_select
965
+ s2 << r4
966
+ if r4
967
+ r5 = _nt_element
968
+ s2 << r5
969
+ if r5
970
+ r6 = _nt_s
971
+ s2 << r6
964
972
  end
965
973
  end
966
974
  end
967
- if s1.last
968
- r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
969
- r1.extend(Selector0)
975
+ if s2.last
976
+ r2 = instantiate_node(SyntaxNode,input, i2...index, s2)
977
+ r2.extend(Selector0)
970
978
  else
971
- @index = i1
972
- r1 = nil
979
+ @index = i2
980
+ r2 = nil
973
981
  end
974
- if r1
975
- s0 << r1
982
+ if r2
983
+ s1 << r2
976
984
  else
977
985
  break
978
986
  end
979
987
  end
980
- if s0.empty?
981
- @index = i0
982
- r0 = nil
988
+ if s1.empty?
989
+ @index = i1
990
+ r1 = nil
983
991
  else
992
+ r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
993
+ end
994
+ s0 << r1
995
+ if r1
996
+ r8 = _nt_arguments
997
+ if r8
998
+ r7 = r8
999
+ else
1000
+ r7 = instantiate_node(SyntaxNode,input, index...index)
1001
+ end
1002
+ s0 << r7
1003
+ end
1004
+ if s0.last
984
1005
  r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
985
1006
  r0.extend(Selector1)
1007
+ r0.extend(Selector2)
1008
+ else
1009
+ @index = i0
1010
+ r0 = nil
986
1011
  end
987
1012
 
988
1013
  node_cache[:selector][start_index] = r0
@@ -1029,7 +1054,7 @@ module Less
1029
1054
 
1030
1055
  module Declaration2
1031
1056
  def build env
1032
- env << (name.text_value =~ /^@/ ? Node::Variable : Node::Property).new(name.text_value)
1057
+ env << (name.text_value =~ /^@/ ? Node::Variable : Node::Property).new(name.text_value, [])
1033
1058
  expression.build env
1034
1059
  end
1035
1060
  # Empty rule
@@ -1601,7 +1626,7 @@ module Less
1601
1626
 
1602
1627
  module Variable1
1603
1628
  def build env
1604
- env.identifiers.last << env.nearest(text_value)
1629
+ env.identifiers.last << Node::Variable.new(text_value)
1605
1630
  end
1606
1631
  end
1607
1632
 
@@ -3245,15 +3270,13 @@ module Less
3245
3270
  end
3246
3271
 
3247
3272
  def arguments
3248
- elements[2]
3273
+ elements[1]
3249
3274
  end
3250
-
3251
3275
  end
3252
3276
 
3253
3277
  module Color4
3254
3278
  def build env
3255
- args = arguments.build env
3256
- env.identifiers.last << Node::Function.new(fn.text_value, args.flatten)
3279
+ env.identifiers.last << Node::Function.new(fn.text_value, arguments.build.flatten)
3257
3280
  end
3258
3281
  end
3259
3282
 
@@ -3342,28 +3365,8 @@ module Less
3342
3365
  end
3343
3366
  s4 << r5
3344
3367
  if r5
3345
- if has_terminal?('(', false, index)
3346
- r11 = instantiate_node(SyntaxNode,input, index...(index + 1))
3347
- @index += 1
3348
- else
3349
- terminal_parse_failure('(')
3350
- r11 = nil
3351
- end
3368
+ r11 = _nt_arguments
3352
3369
  s4 << r11
3353
- if r11
3354
- r12 = _nt_arguments
3355
- s4 << r12
3356
- if r12
3357
- if has_terminal?(')', false, index)
3358
- r13 = instantiate_node(SyntaxNode,input, index...(index + 1))
3359
- @index += 1
3360
- else
3361
- terminal_parse_failure(')')
3362
- r13 = nil
3363
- end
3364
- s4 << r13
3365
- end
3366
- end
3367
3370
  end
3368
3371
  if s4.last
3369
3372
  r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
@@ -3584,15 +3587,13 @@ module Less
3584
3587
  end
3585
3588
 
3586
3589
  def arguments
3587
- elements[2]
3590
+ elements[1]
3588
3591
  end
3589
-
3590
3592
  end
3591
3593
 
3592
3594
  module Function1
3593
3595
  def build env
3594
- args = arguments.build env
3595
- env.identifiers.last << Node::Function.new(name.text_value, [args].flatten)
3596
+ env.identifiers.last << Node::Function.new(name.text_value, [arguments.build].flatten)
3596
3597
  end
3597
3598
  end
3598
3599
 
@@ -3627,28 +3628,8 @@ module Less
3627
3628
  end
3628
3629
  s0 << r1
3629
3630
  if r1
3630
- if has_terminal?('(', false, index)
3631
- r3 = instantiate_node(SyntaxNode,input, index...(index + 1))
3632
- @index += 1
3633
- else
3634
- terminal_parse_failure('(')
3635
- r3 = nil
3636
- end
3631
+ r3 = _nt_arguments
3637
3632
  s0 << r3
3638
- if r3
3639
- r4 = _nt_arguments
3640
- s0 << r4
3641
- if r4
3642
- if has_terminal?(')', false, index)
3643
- r5 = instantiate_node(SyntaxNode,input, index...(index + 1))
3644
- @index += 1
3645
- else
3646
- terminal_parse_failure(')')
3647
- r5 = nil
3648
- end
3649
- s0 << r5
3650
- end
3651
- end
3652
3633
  end
3653
3634
  if s0.last
3654
3635
  r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
@@ -3665,29 +3646,48 @@ module Less
3665
3646
  end
3666
3647
 
3667
3648
  module Arguments0
3649
+ def s
3650
+ elements[1]
3651
+ end
3652
+
3668
3653
  def argument
3669
- elements[0]
3654
+ elements[2]
3670
3655
  end
3671
3656
 
3657
+ def s
3658
+ elements[3]
3659
+ end
3660
+ end
3661
+
3662
+ module Arguments1
3672
3663
  def s
3673
3664
  elements[1]
3674
3665
  end
3675
3666
 
3667
+ def argument
3668
+ elements[2]
3669
+ end
3670
+
3676
3671
  def s
3677
3672
  elements[3]
3678
3673
  end
3679
3674
 
3680
- def arguments
3675
+ def tail
3681
3676
  elements[4]
3682
3677
  end
3678
+
3683
3679
  end
3684
3680
 
3685
- module Arguments1
3686
- def build env
3687
- elements.map do |e|
3688
- e.build env if e.respond_to? :build
3681
+ module Arguments2
3682
+ def build
3683
+ all.map do |e|
3684
+ e.build if e.respond_to? :build
3689
3685
  end.compact
3690
3686
  end
3687
+
3688
+ def all
3689
+ [argument] + tail.elements.map {|e| e.argument }
3690
+ end
3691
3691
  end
3692
3692
 
3693
3693
  def _nt_arguments
@@ -3698,51 +3698,85 @@ module Less
3698
3698
  return cached
3699
3699
  end
3700
3700
 
3701
- i0 = index
3702
- i1, s1 = index, []
3703
- r2 = _nt_argument
3704
- s1 << r2
3705
- if r2
3706
- r3 = _nt_s
3707
- s1 << r3
3708
- if r3
3709
- if has_terminal?(',', false, index)
3710
- r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
3711
- @index += 1
3712
- else
3713
- terminal_parse_failure(',')
3714
- r4 = nil
3715
- end
3716
- s1 << r4
3717
- if r4
3718
- r5 = _nt_s
3719
- s1 << r5
3720
- if r5
3721
- r6 = _nt_arguments
3722
- s1 << r6
3723
- end
3724
- end
3725
- end
3726
- end
3727
- if s1.last
3728
- r1 = instantiate_node(SyntaxNode,input, i1...index, s1)
3729
- r1.extend(Arguments0)
3730
- r1.extend(Arguments1)
3701
+ i0, s0 = index, []
3702
+ if has_terminal?('(', false, index)
3703
+ r1 = instantiate_node(SyntaxNode,input, index...(index + 1))
3704
+ @index += 1
3731
3705
  else
3732
- @index = i1
3706
+ terminal_parse_failure('(')
3733
3707
  r1 = nil
3734
3708
  end
3709
+ s0 << r1
3735
3710
  if r1
3736
- r0 = r1
3737
- else
3738
- r7 = _nt_argument
3739
- if r7
3740
- r0 = r7
3741
- else
3742
- @index = i0
3743
- r0 = nil
3711
+ r2 = _nt_s
3712
+ s0 << r2
3713
+ if r2
3714
+ r3 = _nt_argument
3715
+ s0 << r3
3716
+ if r3
3717
+ r4 = _nt_s
3718
+ s0 << r4
3719
+ if r4
3720
+ s5, i5 = [], index
3721
+ loop do
3722
+ i6, s6 = index, []
3723
+ if has_terminal?(',', false, index)
3724
+ r7 = instantiate_node(SyntaxNode,input, index...(index + 1))
3725
+ @index += 1
3726
+ else
3727
+ terminal_parse_failure(',')
3728
+ r7 = nil
3729
+ end
3730
+ s6 << r7
3731
+ if r7
3732
+ r8 = _nt_s
3733
+ s6 << r8
3734
+ if r8
3735
+ r9 = _nt_argument
3736
+ s6 << r9
3737
+ if r9
3738
+ r10 = _nt_s
3739
+ s6 << r10
3740
+ end
3741
+ end
3742
+ end
3743
+ if s6.last
3744
+ r6 = instantiate_node(SyntaxNode,input, i6...index, s6)
3745
+ r6.extend(Arguments0)
3746
+ else
3747
+ @index = i6
3748
+ r6 = nil
3749
+ end
3750
+ if r6
3751
+ s5 << r6
3752
+ else
3753
+ break
3754
+ end
3755
+ end
3756
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
3757
+ s0 << r5
3758
+ if r5
3759
+ if has_terminal?(')', false, index)
3760
+ r11 = instantiate_node(SyntaxNode,input, index...(index + 1))
3761
+ @index += 1
3762
+ else
3763
+ terminal_parse_failure(')')
3764
+ r11 = nil
3765
+ end
3766
+ s0 << r11
3767
+ end
3768
+ end
3769
+ end
3744
3770
  end
3745
3771
  end
3772
+ if s0.last
3773
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
3774
+ r0.extend(Arguments1)
3775
+ r0.extend(Arguments2)
3776
+ else
3777
+ @index = i0
3778
+ r0 = nil
3779
+ end
3746
3780
 
3747
3781
  node_cache[:arguments][start_index] = r0
3748
3782
 
@@ -3750,7 +3784,7 @@ module Less
3750
3784
  end
3751
3785
 
3752
3786
  module Argument0
3753
- def build env
3787
+ def build
3754
3788
  Node::Color.new text_value
3755
3789
  end
3756
3790
  end
@@ -3766,13 +3800,13 @@ module Less
3766
3800
  end
3767
3801
 
3768
3802
  module Argument2
3769
- def build env
3803
+ def build
3770
3804
  Node::Number.new number.text_value, unit.text_value
3771
3805
  end
3772
3806
  end
3773
3807
 
3774
3808
  module Argument3
3775
- def build env
3809
+ def build
3776
3810
  Node::String.new text_value
3777
3811
  end
3778
3812
  end
@@ -3784,13 +3818,13 @@ module Less
3784
3818
  end
3785
3819
 
3786
3820
  module Argument5
3787
- def build env
3821
+ def build
3788
3822
  Node::Anonymous.new text_value
3789
3823
  end
3790
3824
  end
3791
3825
 
3792
3826
  module Argument6
3793
- def build env
3827
+ def build
3794
3828
  Node::String.new text_value
3795
3829
  end
3796
3830
  end
data/lib/less/engine.rb CHANGED
@@ -34,13 +34,13 @@ module Less
34
34
  else
35
35
  raise SyntaxError, @parser.failure_message
36
36
  end
37
-
37
+
38
38
  @tree
39
39
  end
40
40
  alias :to_tree :parse
41
41
 
42
42
  def to_css
43
- @css || @css = self.parse.to_css
43
+ @css || @css = self.parse.group.to_css
44
44
  end
45
45
 
46
46
  def prepare
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,2 @@
1
+ p:not([class*="lead"]) { color: black; }
2
+ a[href^="http://"], a[href$="http://"] { color: black; }
@@ -37,6 +37,7 @@ h2[title] { font-size: 100%; }
37
37
  }
38
38
  .misc {
39
39
  -moz-border-radius: 2px;
40
+ display: -moz-inline-stack;
40
41
  width: 0.1em;
41
42
  background-color: #009998;
42
43
  color: red !important;
File without changes
@@ -1,3 +1,4 @@
1
+ #css { color: yellow; }
1
2
  #import { color: red; }
2
3
  .mixin {
3
4
  height: 10px;
@@ -0,0 +1 @@
1
+ .lazy-eval { width: 100%; }
File without changes
File without changes
File without changes
File without changes
@@ -1,7 +1,4 @@
1
- .tiny-scope {
2
- color: none;
3
- border-color: #998899;
4
- }
1
+ .tiny-scope { color: #998899; }
5
2
  .scope1 {
6
3
  color: blue;
7
4
  border-color: black;
@@ -0,0 +1,8 @@
1
+ h1 a:hover { color: red; }
2
+ h1 p:hover { color: red; }
3
+ h2 a:hover { color: red; }
4
+ h2 p:hover { color: red; }
5
+ h3 a:hover { color: red; }
6
+ h3 p:hover { color: red; }
7
+ #all, #the, #same { color: blue; }
8
+ ul, li, div, q, blockquote, textarea { margin: 0; }
File without changes
File without changes
@@ -1,11 +1,8 @@
1
+ .whitespace, .white, .space, .mania, .no-semi-column { color: white; }
1
2
  .whitespace { color: white; }
2
3
  .whitespace { color: white; }
3
4
  .whitespace { color: white; }
4
5
  .whitespace { color: white; }
5
- .whitespace { color: white; }
6
- .white { color: white; }
7
- .space { color: white; }
8
- .mania { color: white; }
9
6
  .no-semi-column { color: white; }
10
7
  .no-semi-column {
11
8
  color: white;
data/spec/engine_spec.rb CHANGED
@@ -5,12 +5,12 @@ module LessEngineSpecHelper
5
5
  if arg.is_a? String or arg.is_a? File
6
6
  return Less::Engine.new(arg).to_css
7
7
  else
8
- lessify File.new("spec/less/#{arg}-1.0.less")
8
+ lessify File.new("spec/less/#{arg.to_s.gsub('_', '-')}.less")
9
9
  end
10
10
  end
11
11
 
12
12
  def css file
13
- File.read("spec/css/#{file}-1.0.css")
13
+ File.read("spec/css/#{file.to_s.gsub('_', '-')}.css")
14
14
  end
15
15
  end
16
16
 
@@ -22,8 +22,12 @@ describe Less::Engine do
22
22
  lessify(:css).should == css(:css)
23
23
  end
24
24
 
25
+ it "should group selectors when it can" do
26
+ lessify(:selectors).should == css(:selectors)
27
+ end
28
+
25
29
  it "should parse css 3" do
26
- lessify(:css3).should == css(:css3)
30
+ lessify(:css_3).should == css(:css_3)
27
31
  end
28
32
 
29
33
  it "should parse comments" do
@@ -65,6 +69,14 @@ describe Less::Engine do
65
69
  it "should parse mixins" do
66
70
  lessify(:mixins).should == css(:mixins)
67
71
  end
72
+
73
+ it "should parse mixins with arguments" do
74
+ lessify(:mixins_args).should == css(:mixins_args)
75
+ end
76
+
77
+ it "should evaluate variables lazily" do
78
+ lessify(:lazy_eval).should == css(:lazy_eval)
79
+ end
68
80
 
69
81
  it "should handle custom functions" do
70
82
  module Less::Functions
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,11 @@
1
+ p:not([class*="lead"]) {
2
+ color: black;
3
+ }
4
+
5
+ a[href^="http://"] {
6
+ color: black;
7
+ }
8
+
9
+ a[href$="http://"] {
10
+ color: black;
11
+ }
@@ -88,6 +88,7 @@ h2[title] {
88
88
 
89
89
  .misc {
90
90
  -moz-border-radius: 2px;
91
+ display: -moz-inline-stack;
91
92
  width: .1em;
92
93
  background-color: #009998;
93
94
  color: red !important;
File without changes
@@ -1,3 +1,4 @@
1
+ @import "import-test-d.css";
1
2
  @c: red;
2
3
 
3
4
  #import {
@@ -0,0 +1 @@
1
+ #css { color: yellow; }
File without changes
@@ -0,0 +1,6 @@
1
+ @var: @a;
2
+ @a: 100%;
3
+
4
+ .lazy-eval {
5
+ width: @var;
6
+ }
File without changes
File without changes
File without changes
File without changes
@@ -7,9 +7,8 @@
7
7
  }
8
8
 
9
9
  .tiny-scope {
10
- color: @mix; // none
10
+ color: @mix; // #989
11
11
  .mixin;
12
- border-color: @mix; // #989
13
12
  }
14
13
 
15
14
  .scope1 {
@@ -0,0 +1,15 @@
1
+ h1, h2, h3 {
2
+ a, p {
3
+ :hover {
4
+ color: red;
5
+ }
6
+ }
7
+ }
8
+
9
+ #all { color: blue; }
10
+ #the { color: blue; }
11
+ #same { color: blue; }
12
+
13
+ ul, li, div, q, blockquote, textarea {
14
+ margin: 0;
15
+ }
File without changes
File without changes
File without changes
data/spec/spec.css CHANGED
@@ -40,9 +40,7 @@ body {
40
40
  colorc: #777777;
41
41
  }
42
42
  #operations div { width: 80px; }
43
- td { border-width: 88px; }
44
- tr { border-width: 88px; }
45
- table { border-width: 88px; }
43
+ td, tr, table { border-width: 88px; }
46
44
  blockquote:before { content: ""; }
47
45
  blockquote:after { content: ""; }
48
46
  q:before { content: ""; }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudhead-less
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.10
4
+ version: 1.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - cloudhead
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-16 00:00:00 -07:00
12
+ date: 2009-07-20 00:00:00 -07:00
13
13
  default_executable: lessc
14
14
  dependencies: []
15
15
 
@@ -41,6 +41,7 @@ files:
41
41
  - lib/less/engine/nodes/function.rb
42
42
  - lib/less/engine/nodes/literal.rb
43
43
  - lib/less/engine/nodes/property.rb
44
+ - lib/less/engine/nodes/ruleset.rb
44
45
  - lib/less/engine/nodes/selector.rb
45
46
  - lib/less/engine/parser.rb
46
47
  - lib/vendor/treetop/.gitignore
@@ -134,41 +135,50 @@ files:
134
135
  - lib/vendor/treetop/spec/spec_suite.rb
135
136
  - lib/vendor/treetop/treetop.gemspec
136
137
  - spec/command_spec.rb
137
- - spec/css/accessors-1.0.css
138
- - spec/css/big-1.0.css
139
- - spec/css/colors-1.0.css
140
- - spec/css/comments-1.0.css
141
- - spec/css/css-1.0.css
142
- - spec/css/functions-1.0.css
143
- - spec/css/import-1.0.css
144
- - spec/css/mixins-1.0.css
145
- - spec/css/operations-1.0.css
146
- - spec/css/rulesets-1.0.css
147
- - spec/css/scope-1.0.css
148
- - spec/css/strings-1.0.css
149
- - spec/css/variables-1.0.css
150
- - spec/css/whitespace-1.0.css
138
+ - spec/css/accessors.css
139
+ - spec/css/big.css
140
+ - spec/css/colors.css
141
+ - spec/css/comments.css
142
+ - spec/css/css-3.css
143
+ - spec/css/css.css
144
+ - spec/css/functions.css
145
+ - spec/css/import.css
146
+ - spec/css/lazy-eval.css
147
+ - spec/css/mixins-args.css
148
+ - spec/css/mixins.css
149
+ - spec/css/operations.css
150
+ - spec/css/rulesets.css
151
+ - spec/css/scope.css
152
+ - spec/css/selectors.css
153
+ - spec/css/strings.css
154
+ - spec/css/variables.css
155
+ - spec/css/whitespace.css
151
156
  - spec/engine_spec.rb
152
- - spec/less/accessors-1.0.less
153
- - spec/less/big-1.0.less
154
- - spec/less/colors-1.0.less
155
- - spec/less/comments-1.0.less
156
- - spec/less/css-1.0.less
157
+ - spec/less/accessors.less
158
+ - spec/less/big.less
159
+ - spec/less/colors.less
160
+ - spec/less/comments.less
161
+ - spec/less/css-3.less
162
+ - spec/less/css.less
157
163
  - spec/less/exceptions/mixed-units-error.less
158
164
  - spec/less/exceptions/name-error-1.0.less
159
165
  - spec/less/exceptions/syntax-error-1.0.less
160
- - spec/less/functions-1.0.less
161
- - spec/less/import-1.0.less
166
+ - spec/less/functions.less
167
+ - spec/less/import.less
162
168
  - spec/less/import/import-test-a.less
163
169
  - spec/less/import/import-test-b.less
164
170
  - spec/less/import/import-test-c.less
165
- - spec/less/mixins-1.0.less
166
- - spec/less/operations-1.0.less
167
- - spec/less/rulesets-1.0.less
168
- - spec/less/scope-1.0.less
169
- - spec/less/strings-1.0.less
170
- - spec/less/variables-1.0.less
171
- - spec/less/whitespace-1.0.less
171
+ - spec/less/import/import-test-d.css
172
+ - spec/less/lazy-eval.less
173
+ - spec/less/mixins-args.less
174
+ - spec/less/mixins.less
175
+ - spec/less/operations.less
176
+ - spec/less/rulesets.less
177
+ - spec/less/scope.less
178
+ - spec/less/selectors.less
179
+ - spec/less/strings.less
180
+ - spec/less/variables.less
181
+ - spec/less/whitespace.less
172
182
  - spec/spec.css
173
183
  - spec/spec.less
174
184
  - spec/spec_helper.rb