cloudhead-less 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.0
1
+ 0.8.1
data/bin/lessc CHANGED
@@ -23,10 +23,11 @@ opts = OptionParser.new do |o|
23
23
  options[:watch] = true
24
24
  end
25
25
 
26
- # Compress
27
- o.on("-c", "--compress", "compress css file") do
28
- options[:compress] = true
29
- end
26
+ # Compression needs a proper algorithm
27
+ #
28
+ # o.on("-c", "--compress", "compress css file") do
29
+ # options[:compress] = true
30
+ # end
30
31
 
31
32
  o.separator ""
32
33
 
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.7.0"
5
+ s.version = "0.8.0"
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.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'cgi'
2
+
1
3
  require 'less/command'
2
4
  require 'less/engine'
3
5
  require 'less/tree'
data/lib/less/command.rb CHANGED
@@ -4,10 +4,12 @@ module Less
4
4
  @source, @destination = options[:source], options[:destination]
5
5
  @options = options
6
6
  end
7
- def watch?() @options[:watch] end
7
+
8
+ def watch?() @options[:watch] end
8
9
  def compress?() @options[:compress] end
9
10
 
10
- # little function which allows us to Ctrl-C exit inside the passed block
11
+ # little function which allows us to
12
+ # Ctrl-C exit inside the passed block
11
13
  def watch &block
12
14
  begin
13
15
  block.call
@@ -20,28 +22,22 @@ module Less
20
22
  def run!
21
23
  if watch?
22
24
  log "Watching for changes in #@source ...Ctrl-C to abort.\n"
23
- #
25
+
24
26
  # Main watch loop
25
- #
26
27
  loop do
27
28
  watch { sleep 1 }
28
29
 
29
30
  # File has changed
30
31
  if File.stat( @source ).mtime > File.stat( @destination ).mtime
31
32
  log "Change detected... "
32
- #
33
- # Error loop
34
- #
35
- loop do
36
- unless compile
37
- log "Press [enter] to continue..."
38
- watch { $stdin.gets }
39
- next # continue within the error loop, until the error is fixed
40
- end
41
- break # break to main loop, as no errors were encountered
33
+
34
+ # Loop until error is fixed
35
+ while not compile
36
+ log "Press [enter] to continue..."
37
+ watch { $stdin.gets }
42
38
  end
43
- end # if
44
- end # loop
39
+ end
40
+ end
45
41
  else
46
42
  compile
47
43
  end
@@ -56,7 +52,7 @@ module Less
56
52
  File.open( @destination, "w" ) do |file|
57
53
  file.write css
58
54
  end
59
- puts "#{@destination.split('/').last} was updated!" if watch?
55
+ puts " [Updated] #{@destination.split('/').last}" if watch?
60
56
  rescue Errno::ENOENT => e
61
57
  abort "#{e}"
62
58
  rescue SyntaxError
data/lib/less/engine.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  module Less
2
2
  class Engine < String
3
3
  REGEXP = {
4
- :path => /([#.][->#.\w]+)?( ?> ?)?@([\w\-]+)/, # #header > .title > @var
5
- :selector => /[-\w #.>*_:]/, # .cow .milk > a
6
- :values => /[-\w \(\)@>\/*+#%.,'"]/, # 10px solid #fff
7
- :variable => /^@([\w\-]+)/ # @milk-white
4
+ :path => /([#.][->#.\w ]+)?( ?> ?)?@([-\w]+)/, # #header > .title > @var
5
+ :selector => /[-\w #.>*:]/, # .cow .milk > a
6
+ :variable => /@([-\w]+)/, # @milk-white
7
+ :property => /@[-\w]+|[-a-z]+/ # font-size
8
8
  }
9
9
 
10
10
  def initialize s
@@ -23,8 +23,8 @@ module Less
23
23
  # can then be deleted.
24
24
  #
25
25
  @tree = @tree.traverse :leaf do |key, value, path, node|
26
- matched = if match = key.match( REGEXP[:variable] )
27
- node[:variables] ||= {}
26
+ matched = if match = key.match( REGEXP[:variable] )
27
+ node[:variables] ||= Tree.new
28
28
  node[:variables][ match.captures.first ] = value
29
29
  elsif value == :mixin
30
30
  node[:mixins] ||= []
@@ -44,38 +44,16 @@ module Less
44
44
  end
45
45
  end
46
46
 
47
- #
48
- # Evaluate variables
49
- #
47
+ # Call `evaluate` on variables, such as '@dark: @light / 2'
48
+ @tree = @tree.traverse :branch do |path, node|
49
+ node.vars.each do |key, value|
50
+ evaluate key, value, node.vars
51
+ end if node.vars?
52
+ end
53
+
54
+ # Call `evaluate` on css properties, such as 'font-size: @big'
50
55
  @tree = @tree.traverse :leaf do |key, value, path, node|
51
- convert = lambda do |key, value, node| # We declare this as a lambda, for re-use
52
- if value.is_a?(String) && value.include?('@') # There's a var to evaluate
53
-
54
- # Find its value
55
- var = value.delete(' ').match( REGEXP[:path] ).captures.join
56
- var = unless var.include? '>'
57
- node.var( var ) || @tree.var( var ) # Try local first, then global
58
- else
59
- @tree.find :var, var.split('>') # Try finding it in a specific namespace
60
- end
61
-
62
- if var
63
- node[ key ] = value.gsub REGEXP[:path], var # Substitute variable with value
64
- else
65
- node.delete key # Discard the declaration if the variable wasn't found
66
- end
67
- end
68
- end
69
-
70
- # Call `convert` on css properties, such as 'font-size: @big'
71
- convert.call key, value, node
72
-
73
- # Call `convert` on variables, such as '@dark: @light / 2'
74
- if node.vars?
75
- node.vars.each do |key, value|
76
- convert.call key, value, node
77
- end
78
- end
56
+ evaluate key, value, node
79
57
  end
80
58
 
81
59
  #
@@ -85,28 +63,52 @@ module Less
85
63
  @tree = @tree.traverse :leaf do |key, value, path, node|
86
64
  if value.match /[-+\/*]/
87
65
  if (unit = value.scan(/(%)|\d+(px)|\d+(em)|(#)/i).flatten.compact.uniq).size <= 1
88
- unit = unit.join
66
+ unit = unit.join
89
67
  value = if unit == '#'
68
+ evaluate = lambda do |v|
69
+ result = eval v
70
+ unit + ( result.zero?? '000' : result.to_s(16) )
71
+ end
90
72
  value.gsub(/#([a-z0-9]+)/i) do
91
- hex = $1 * ( $1.size == 3 ? 2 : 1 )
73
+ hex = $1 * ( $1.size < 6 ? 6 / $1.size : 1 )
92
74
  hex.to_i(16)
93
75
  end.delete unit
94
- evaluate = lambda {|v| unit + eval( v ).to_s(16) }
95
76
  else
96
- value.gsub(/px|em|%/, '')
97
77
  evaluate = lambda {|v| eval( v ).to_s + unit }
98
- end.to_s
99
- next if value.match /[a-z]/i
78
+ value.gsub(/px|em|%/, '')
79
+ end.to_s
80
+ next if value.match /[a-z]/i
100
81
  node[ key ] = evaluate.call value
101
82
  else
102
83
  raise MixedUnitsError
103
84
  end
104
85
  end
105
86
  end
106
-
107
87
  end
108
88
  alias render compile
109
89
 
90
+ #
91
+ # Evaluate variables
92
+ #
93
+ def evaluate key, value, node
94
+ if value.is_a? String and value.include? '@' # There's a var to evaluate
95
+ value.scan REGEXP[:path] do |p|
96
+ p = p.join.delete ' '
97
+ var = if p.include? '>'
98
+ @tree.find :var, p.split('>') # Try finding it in a specific namespace
99
+ else
100
+ node.var( p ) || @tree.var( p ) # Try local first, then global
101
+ end
102
+
103
+ if var
104
+ node[ key ] = value.gsub REGEXP[:path], var # Substitute variable with value
105
+ else
106
+ node.delete key # Discard the declaration if the variable wasn't found
107
+ end
108
+ end
109
+ end
110
+ end
111
+
110
112
  def to_css
111
113
  self.compile.to_css
112
114
  end
@@ -119,13 +121,14 @@ module Less
119
121
  # less: color: black;
120
122
  # hashify: "color" => "black"
121
123
  #
122
- hash = self.gsub(/"/, "'"). # ""
123
- gsub(/([@a-z\-]+):[ \t]*(#{ REGEXP[:values] }+);/, '"\\1" => "\\2",'). # Properties
124
+ hash = self.gsub(/\/\/.*\n/, ''). # Comments //
125
+ gsub(/\/\*.*?\//m, ''). # Comments /*
126
+ gsub(/"/, "'"). # " => '
127
+ gsub(/("|')(.+?)(\1)/) { $1 + CGI.escape( $2 ) + $1 }. # Escape string values
128
+ gsub(/(#{REGEXP[:property]}):[ \t]*(.+?);/, '"\\1" => "\\2",'). # Declarations
124
129
  gsub(/\}/, "},"). # Closing }
125
- gsub(/([ \t]*)(#{ REGEXP[:selector] }+?)[ \t\n]*\{/m, '\\1"\\2" => {'). # Selectors
126
- gsub(/([.#][->\w .#]+);/, '"\\1" => :mixin,'). # Mixins
127
- gsub("\n\n", "\n"). # New-lines
128
- gsub(/\/\/.*\n/, '') # Comments
130
+ gsub(/([ \t]*)(#{REGEXP[:selector]}+?)[ \t\n]*\{/m, '\\1"\\2" => {'). # Selectors
131
+ gsub(/([.#][->\w .#]+);/, '"\\1" => :mixin,') # Mixins
129
132
  eval "{" + hash + "}" # Return {hash}
130
133
  end
131
134
  end
data/lib/less/tree.rb CHANGED
@@ -57,7 +57,7 @@ module Less
57
57
  def to_css css = []
58
58
  self.traverse :branch do |path, node|
59
59
  properties = node.inject("") do |s, (k, v)|
60
- v.is_a?(String) ? (s + "#{k}: #{v}; ") : s # Add the property to the list
60
+ v.is_a?(String) ? (s + "#{k}: #{CGI.unescape(v)}; ") : s # Add the property to the list
61
61
  end
62
62
  css << path * ' > ' + " { " + properties + "}" # Add the rule-set to the CSS
63
63
  end
data/spec/spec.less CHANGED
@@ -2,7 +2,11 @@
2
2
  // the main color
3
3
  @base-color: #fff;
4
4
  @darker-color: @base-color / 2;
5
+ /*
5
6
 
7
+ lala
8
+
9
+ */
6
10
  .dookoo a {
7
11
  color: black;
8
12
  }
@@ -10,14 +14,23 @@
10
14
  font-family: "Verdana", 'Baka', serif;
11
15
  }
12
16
  .dookoo {
17
+ @fi: @fa;
13
18
  @fa: grey;
14
- color: @fa;
19
+ color: .alt > @base-color - .alt > @base-color;
15
20
  line-height: 1999px;
21
+ .blah {
22
+ .bloop {
23
+ @supernested: iceberg;
24
+ }
25
+ }
16
26
  }
17
27
  .alt {
18
- @base-color: green;
19
- @darker-color: @base-color / 2;
20
- @another-color: * > @base-color;
28
+ @base-color: #876956 - #111;
29
+ @darker-color: @base-color - @base-color;
30
+ @another-color: @base-color;
31
+ }
32
+ #kelkoo {
33
+ color: .dookoo > .blah > .bloop > @supernested;
21
34
  }
22
35
  .altfoo { color: .alt > @base-color; }
23
36
  .foo { border: 1px solid black; color: @base-color; }
@@ -25,7 +38,7 @@
25
38
  width: 10px * 2;
26
39
  }
27
40
  #content {
28
- font-size: 12px;
41
+ font-size: "};(*#)";
29
42
  @some-color: blue;
30
43
  #header {
31
44
  .foo;
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: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - cloudhead