less 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/VERSION +1 -1
  2. data/less.gemspec +1 -1
  3. data/lib/less/engine.rb +24 -19
  4. data/spec/spec.less +101 -61
  5. metadata +1 -1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.2
1
+ 0.8.3
data/less.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{less}
5
- s.version = "0.8.2"
5
+ s.version = "0.8.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["cloudhead"]
data/lib/less/engine.rb CHANGED
@@ -1,12 +1,17 @@
1
1
  module Less
2
2
  class Engine < String
3
- REGEXP = {
3
+ REGEX = {
4
4
  :path => /([#.][->#.\w ]+)?( ?> ?)?@([-\w]+)/, # #header > .title > @var
5
- :selector => /[-\w #.>*:]/, # .cow .milk > a
5
+ :selector => /[-\w #.,>*:\(\)]/, # .cow .milk > a
6
6
  :variable => /@([-\w]+)/, # @milk-white
7
- :property => /@[-\w]+|[-a-z]+/ # font-size
7
+ :property => /@[-\w]+|[-a-z]+/, # font-size
8
+ :color => /#([a-zA-Z0-9]{3,6})\b/, # #f0f0f0
9
+ :number => /\d+(?>\.\d+)?/, # 24.8
10
+ :unit => /px|em|pt|cm|mm|%/ # em
8
11
  }
9
-
12
+ REGEX[:numeric] = /#{REGEX[:number]}(#{REGEX[:unit]})?/
13
+ REGEX[:operand] = /#{REGEX[:color]}|#{REGEX[:numeric]}/
14
+
10
15
  def initialize s
11
16
  super
12
17
  @tree = Tree.new self.hashify
@@ -23,7 +28,7 @@ module Less
23
28
  # can then be deleted.
24
29
  #
25
30
  @tree = @tree.traverse :leaf do |key, value, path, node|
26
- matched = if match = key.match( REGEXP[:variable] )
31
+ matched = if match = key.match( REGEX[:variable] )
27
32
  node[:variables] ||= Tree.new
28
33
  node[:variables][ match.captures.first ] = value
29
34
  elsif value == :mixin
@@ -60,25 +65,25 @@ module Less
60
65
  # Evaluate operations (2+2)
61
66
  #
62
67
  # Units are: 1px, 1em, 1%, #111
63
- @tree = @tree.traverse :leaf do |key, value, path, node|
64
- if value =~ /(\s?)[-+\/*](\1)/
65
- if (unit = value.scan(/(%)|\d+(px)|\d+(em)|(#)/i).flatten.compact.uniq).size <= 1
68
+ @tree = @tree.traverse :leaf do |key, value, path, node|
69
+ node[ key ] = value.gsub /(#{REGEX[:operand]}(\s?)[-+\/*](\4))+(#{REGEX[:operand]})/ do |operation|
70
+ if (unit = operation.scan(/#{REGEX[:numeric]}|(#)/i).flatten.compact.uniq).size <= 1
66
71
  unit = unit.join
67
- value = if unit == '#'
72
+ operation = if unit == '#'
68
73
  evaluate = lambda do |v|
69
74
  result = eval v
70
75
  unit + ( result.zero?? '000' : result.to_s(16) )
71
76
  end
72
- value.gsub(/#([a-z0-9]+)/i) do
77
+ operation.gsub REGEX[:color] do
73
78
  hex = $1 * ( $1.size < 6 ? 6 / $1.size : 1 )
74
79
  hex.to_i(16)
75
80
  end.delete unit
76
81
  else
77
82
  evaluate = lambda {|v| eval( v ).to_s + unit }
78
- value.gsub(/px|em|%/, '')
83
+ operation.gsub REGEX[:unit], ''
79
84
  end.to_s
80
- next if value.match /[a-z]/i
81
- node[ key ] = evaluate.call value
85
+ next if operation.match /[a-z]/i
86
+ evaluate.call operation
82
87
  else
83
88
  raise MixedUnitsError
84
89
  end
@@ -92,7 +97,7 @@ module Less
92
97
  #
93
98
  def evaluate key, value, node
94
99
  if value.is_a? String and value.include? '@' # There's a var to evaluate
95
- value.scan REGEXP[:path] do |p|
100
+ value.scan REGEX[:path] do |p|
96
101
  p = p.join.delete ' '
97
102
  var = if p.include? '>'
98
103
  @tree.find :var, p.split('>') # Try finding it in a specific namespace
@@ -101,7 +106,7 @@ module Less
101
106
  end
102
107
 
103
108
  if var
104
- node[ key ] = value.gsub REGEXP[:path], var # Substitute variable with value
109
+ node[ key ] = value.gsub REGEX[:path], var # Substitute variable with value
105
110
  else
106
111
  node.delete key # Discard the declaration if the variable wasn't found
107
112
  end
@@ -121,13 +126,13 @@ module Less
121
126
  # less: color: black;
122
127
  # hashify: "color" => "black"
123
128
  #
124
- hash = self.gsub(/\/\/.*\n/, ''). # Comments //
125
- gsub(/\/\*.*?\//m, ''). # Comments /*
129
+ hash = self.gsub(/\/\/.*/, ''). # Comments //
130
+ gsub(/\/\*.*?\*\//m, ''). # Comments /*
126
131
  gsub(/"/, "'"). # " => '
127
132
  gsub(/("|')(.+?)(\1)/) { $1 + CGI.escape( $2 ) + $1 }. # Escape string values
128
- gsub(/(#{REGEXP[:property]}):[ \t]*(.+?);/, '"\\1" => "\\2",'). # Declarations
133
+ gsub(/(#{REGEX[:property]}):[ \t]*(.+?);/, '"\\1" => "\\2",'). # Declarations
129
134
  gsub(/\}/, "},"). # Closing }
130
- gsub(/([ \t]*)(#{REGEXP[:selector]}+?)[ \t\n]*\{/m, '\\1"\\2" => {'). # Selectors
135
+ gsub(/([ \t]*)(#{REGEX[:selector]}+?)[ \t\n]*\{/m, '\\1"\\2" => {'). # Selectors
131
136
  gsub(/([.#][->\w .#]+);/, '"\\1" => :mixin,') # Mixins
132
137
  eval "{" + hash + "}" # Return {hash}
133
138
  end
data/spec/spec.less CHANGED
@@ -1,71 +1,111 @@
1
- // LESS
2
- // the main color
3
- @base-color: #fff;
4
- @darker-color: @base-color / 2;
5
- /*
1
+ // ------------------------------------------------
2
+ // LESS Spec
3
+ // www.lesscss.org
4
+ // ------------------------------------------------
6
5
 
7
- lala
6
+ // Global vars
7
+ @main-color: #444;
8
+ @dark-color: #111;
9
+ @between-color: @main-color - @dark-color;
8
10
 
9
- */
10
- .dookoo a {
11
- color: black;
11
+ // Mixins
12
+ .theme {
13
+ color: #ccc;
14
+ background-color: #aaa;
12
15
  }
13
- .dookoo a {
14
- font-family: "Verdana", 'Baka', serif;
15
- }
16
- .dookoo {
17
- @fi: @fa;
18
- @fa: grey;
19
- color: .alt > @base-color - .alt > @base-color;
20
- margin: 10px -10px 4px 2px;
21
- line-height: 1999px;
22
- .blah {
23
- .bloop {
24
- @supernested: iceberg;
25
- }
16
+ .extra {
17
+ @main: #888;
18
+ .dark-borders {
19
+ border-color: .extra > @main / 2;
20
+ }
21
+ .light-borders {
22
+ border-color: .extra > @main;
26
23
  }
27
24
  }
28
- .alt {
29
- @base-color: #876956 - #111;
30
- @darker-color: @base-color - @base-color;
31
- @another-color: @base-color;
32
- }
33
- #kelkoo {
34
- color: .dookoo > .blah > .bloop > @supernested;
35
- }
36
- .altfoo { color: .alt > @base-color; }
37
- .foo { border: 1px solid black; color: @base-color; }
38
- .foo2 {
39
- width: 10px * 2;
25
+
26
+ // Namespaces
27
+ .borders {
28
+ @thick: 4px;
29
+ @thin: 2px;
40
30
  }
41
- #content {
42
- font-size: "};(*#)";
43
- @some-color: blue;
44
- #header {
45
- .foo;
46
- font-size: #222 / 2;
31
+
32
+ // Hierarchy
33
+ .root {
34
+ a {
35
+ color: blue;
36
+ display: none;
47
37
  }
48
- #main-page {
49
- #content > .small;
50
- }
51
- .small {
52
- color: @base-color;
53
- font-size: 12 / 2;
54
- .hover_controls {
55
- line-height: 16px;
56
- display: none;
57
- color: #content > @some-color;
58
- border: 1px solid #fff;
59
- }
38
+ a:hover, a:focus {
39
+ color: orange;
60
40
  }
61
- .small:hover {
62
- background-color: #eee + #content > @some-color;
63
- .hover_controls {
64
- .dookoo;
65
- display: inline-block;
41
+ .first {
42
+ @size: 8px;
43
+ @dark-color: green;
44
+ @main-color: red;
45
+ color: @dark-color; // 'green'
46
+ .second {
47
+ @color: blue;
48
+ .third {
49
+ color: @main-color; // #444
50
+ border-color: .root > .first > .second > @color; // 'blue'
51
+ }
66
52
  }
67
- }
53
+ }
54
+ }
55
+ .root:hover a {
56
+ display: block;
57
+ }
58
+
59
+ // Standard CSS properties and shorthand
60
+ body {
61
+ font-size: 10px;
62
+ font-family: "Lucida Grande", 'Helvetica', Verdana, sans-serif;
63
+ margin: -5px 0 5px 10px;
64
+ border: solid 1px #000;
65
+ text-shadow: #333 -1px 1px 2px;
66
+ -moz-border-radius: 3px; /* CSS3 for older Firefox */
67
+ .theme;
68
+ .extra > .light-borders;
68
69
  }
69
- .sidebar {
70
- #content > .small;
71
- }
70
+
71
+ // Operations
72
+ .operations {
73
+ @ten: 10;
74
+ @dark: #111;
75
+ border-width: .borders > @thick * 5 - 4px; // 16px
76
+ font-size: 10 - 4 + 6 * @ten; // 66
77
+ line-height: @ten - .operations > @ten + .root > .first > @size - 1; // 7px
78
+ color: #fff - #111; // #eeeeee
79
+ colorb: #111 + #222222; // #333333
80
+ colorc: @dark + #222 * 3; // #777777
81
+ }
82
+
83
+ td, tr, table {
84
+ border-width: .borders > @thick;
85
+ }
86
+
87
+ // More complex CSS selectors
88
+ ul li:first-child {
89
+ border-top: none;
90
+ }
91
+ ul li:first-child, ul li:last-child {
92
+ background-color: #333;
93
+ }
94
+ .p:first-letter {
95
+ color: red;
96
+ }
97
+ q:lang(no) {
98
+ quotes: "~" "~";
99
+ }
100
+ /*input[type="text"] {
101
+ background-color: blue;
102
+ }*/
103
+ .transparent_box {
104
+ background-color:#FFF;
105
+ filter:alpha(opacity=60); /* for IE */
106
+ opacity:0.6; /* CSS3 standard */
107
+ }
108
+
109
+ // Spacing
110
+ .space
111
+ { color: purple ;font-color:yellow; }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: less
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - cloudhead