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 +1 -1
- data/bin/lessc +5 -4
- data/less.gemspec +1 -1
- data/lib/less.rb +2 -0
- data/lib/less/command.rb +13 -17
- data/lib/less/engine.rb +53 -50
- data/lib/less/tree.rb +1 -1
- data/spec/spec.less +18 -5
- metadata +1 -1
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
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
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
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
data/lib/less.rb
CHANGED
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
|
-
|
7
|
+
|
8
|
+
def watch?() @options[:watch] end
|
8
9
|
def compress?() @options[:compress] end
|
9
10
|
|
10
|
-
# little function which allows us to
|
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
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
44
|
-
end
|
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}
|
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
|
5
|
-
:selector => /[-\w
|
6
|
-
:
|
7
|
-
:
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
99
|
-
|
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(
|
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]*)(#{
|
126
|
-
gsub(/([.#][->\w .#]+);/, '"\\1" => :mixin,')
|
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: @
|
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:
|
19
|
-
@darker-color: @base-color
|
20
|
-
@another-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:
|
41
|
+
font-size: "};(*#)";
|
29
42
|
@some-color: blue;
|
30
43
|
#header {
|
31
44
|
.foo;
|