less 0.7.0 → 0.8.7
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.
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/lessc +17 -5
- data/less.gemspec +2 -2
- data/lib/less/command.rb +32 -25
- data/lib/less/engine.rb +71 -61
- data/lib/less/tree.rb +29 -14
- data/lib/less.rb +8 -3
- data/spec/spec.less +120 -53
- metadata +2 -2
data/README.md
CHANGED
|
@@ -20,8 +20,8 @@ LESS allows you to write CSS the way (I think) it was meant to, that is: with *v
|
|
|
20
20
|
### And the CSS output it produces:
|
|
21
21
|
|
|
22
22
|
.outline { border: 1px solid black }
|
|
23
|
-
.article
|
|
24
|
-
.article
|
|
23
|
+
.article a { text-decoration: none }
|
|
24
|
+
.article p { color: #110011 }
|
|
25
25
|
.article { border: 1px solid black }
|
|
26
26
|
|
|
27
27
|
If you have CSS nightmares, just
|
data/Rakefile
CHANGED
|
@@ -27,7 +27,7 @@ begin
|
|
|
27
27
|
config = YAML.load(
|
|
28
28
|
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
|
29
29
|
)
|
|
30
|
-
|
|
30
|
+
options << '--line-numbers' << '--inline-source'
|
|
31
31
|
host = "#{config['username']}@rubyforge.org"
|
|
32
32
|
remote_dir = "/var/www/gforge-projects/the-perfect-gem/"
|
|
33
33
|
local_dir = 'rdoc'
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.7
|
|
1
|
+
0.8.7
|
data/bin/lessc
CHANGED
|
@@ -10,7 +10,9 @@ CSS = '.css'
|
|
|
10
10
|
# Argument defaults
|
|
11
11
|
options = {
|
|
12
12
|
:watch => false,
|
|
13
|
-
:compress => false
|
|
13
|
+
:compress => false,
|
|
14
|
+
:debug => false,
|
|
15
|
+
:inheritance => :desc
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
# Get arguments
|
|
@@ -23,11 +25,17 @@ opts = OptionParser.new do |o|
|
|
|
23
25
|
options[:watch] = true
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
#
|
|
27
|
-
o.on("-c", "--
|
|
28
|
-
options[:
|
|
28
|
+
# Child-type inheritance
|
|
29
|
+
o.on("-c", "--child", "nesting uses child-type inheritance") do
|
|
30
|
+
options[:chain] = :child
|
|
29
31
|
end
|
|
30
32
|
|
|
33
|
+
# Compression needs a proper algorithm
|
|
34
|
+
#
|
|
35
|
+
# o.on("-x", "--compress", "compress css file") do
|
|
36
|
+
# options[:compress] = true
|
|
37
|
+
# end
|
|
38
|
+
|
|
31
39
|
o.separator ""
|
|
32
40
|
|
|
33
41
|
# Help
|
|
@@ -35,10 +43,14 @@ opts = OptionParser.new do |o|
|
|
|
35
43
|
puts opts
|
|
36
44
|
exit
|
|
37
45
|
end
|
|
46
|
+
|
|
47
|
+
o.on_tail("-d", "--debug", "show full error messages") do
|
|
48
|
+
options[:debug] = true
|
|
49
|
+
end
|
|
38
50
|
|
|
39
51
|
# Version
|
|
40
52
|
o.on_tail("-v", "--version", "show version") do
|
|
41
|
-
puts "
|
|
53
|
+
puts "lessc " + Less.version
|
|
42
54
|
exit
|
|
43
55
|
end
|
|
44
56
|
end
|
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 = "0.7
|
|
5
|
+
s.version = "0.8.7"
|
|
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-
|
|
9
|
+
s.date = %q{2009-06-15}
|
|
10
10
|
s.default_executable = %q{lessc}
|
|
11
11
|
s.description = %q{LESS is leaner CSS}
|
|
12
12
|
s.email = %q{alexis@cloudhead.net}
|
data/lib/less/command.rb
CHANGED
|
@@ -4,10 +4,13 @@ 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
|
|
10
|
+
def debug?() @options[:debug] end
|
|
9
11
|
|
|
10
|
-
# little function which allows us to
|
|
12
|
+
# little function which allows us to
|
|
13
|
+
# Ctrl-C exit inside the passed block
|
|
11
14
|
def watch &block
|
|
12
15
|
begin
|
|
13
16
|
block.call
|
|
@@ -16,54 +19,54 @@ module Less
|
|
|
16
19
|
exit 0
|
|
17
20
|
end
|
|
18
21
|
end
|
|
19
|
-
|
|
22
|
+
|
|
20
23
|
def run!
|
|
24
|
+
compile(true) unless File.exist? @destination
|
|
25
|
+
|
|
21
26
|
if watch?
|
|
22
27
|
log "Watching for changes in #@source ...Ctrl-C to abort.\n"
|
|
23
|
-
|
|
28
|
+
|
|
24
29
|
# Main watch loop
|
|
25
|
-
#
|
|
26
30
|
loop do
|
|
27
31
|
watch { sleep 1 }
|
|
28
32
|
|
|
29
33
|
# File has changed
|
|
30
34
|
if File.stat( @source ).mtime > File.stat( @destination ).mtime
|
|
31
35
|
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
|
|
36
|
+
|
|
37
|
+
# Loop until error is fixed
|
|
38
|
+
until compile
|
|
39
|
+
log "Press [enter] to continue..."
|
|
40
|
+
watch { $stdin.gets }
|
|
42
41
|
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
45
44
|
else
|
|
46
45
|
compile
|
|
47
46
|
end
|
|
48
47
|
end
|
|
49
48
|
|
|
50
|
-
def compile
|
|
49
|
+
def compile new = false
|
|
51
50
|
begin
|
|
52
51
|
# Create a new Less object with the contents of a file
|
|
53
|
-
css = Less::Engine.new( File.read( @source ) ).to_css
|
|
52
|
+
css = Less::Engine.new( File.read( @source ) ).to_css @options[:inheritance]
|
|
54
53
|
css = css.delete " \n" if compress?
|
|
55
54
|
|
|
56
55
|
File.open( @destination, "w" ) do |file|
|
|
57
56
|
file.write css
|
|
58
57
|
end
|
|
59
|
-
puts "#{@destination.split('/').last}
|
|
58
|
+
puts "#{new ? '* [Created]' : ' [Updated]'} #{@destination.split('/').last}" if watch?
|
|
60
59
|
rescue Errno::ENOENT => e
|
|
61
60
|
abort "#{e}"
|
|
62
61
|
rescue SyntaxError
|
|
63
|
-
error = $!.message.split("\n")[1..-1].collect {|e|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
error = debug?? $! : $!.message.split("\n")[1..-1].collect {|e|
|
|
63
|
+
e.gsub(/\(eval\)\:(\d+)\:\s/, 'line \1: ')
|
|
64
|
+
} * "\n"
|
|
65
|
+
err "errors were found in the .less file! \n#{error}\n"
|
|
66
|
+
rescue MixedUnitsError => e
|
|
67
|
+
err "`#{e}` you're mixing units together! What do you expect?\n"
|
|
68
|
+
rescue PathError => e
|
|
69
|
+
err "`#{e}` was not found.\n"
|
|
67
70
|
else
|
|
68
71
|
true
|
|
69
72
|
end
|
|
@@ -71,7 +74,11 @@ module Less
|
|
|
71
74
|
|
|
72
75
|
# Just a logging function to avoid typing '}'
|
|
73
76
|
def log s = ''
|
|
74
|
-
print '
|
|
77
|
+
print '* ' + s.to_s
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def err s = ''
|
|
81
|
+
print "!! #{s}"
|
|
75
82
|
end
|
|
76
83
|
end
|
|
77
84
|
end
|
data/lib/less/engine.rb
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
module Less
|
|
2
2
|
class Engine < String
|
|
3
|
-
|
|
4
|
-
:path
|
|
5
|
-
:selector => /[-\w
|
|
6
|
-
:
|
|
7
|
-
:
|
|
3
|
+
REGEX = {
|
|
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
|
+
: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
|
}
|
|
12
|
+
REGEX[:numeric] = /#{REGEX[:number]}(#{REGEX[:unit]})?/
|
|
13
|
+
REGEX[:operand] = /#{REGEX[:color]}|#{REGEX[:numeric]}/
|
|
9
14
|
|
|
10
15
|
def initialize s
|
|
11
16
|
super
|
|
12
17
|
@tree = Tree.new self.hashify
|
|
13
18
|
end
|
|
14
|
-
|
|
19
|
+
|
|
15
20
|
def compile
|
|
16
21
|
#
|
|
17
22
|
# Parse the variables and mixins
|
|
@@ -23,8 +28,8 @@ 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(
|
|
27
|
-
node[:variables] ||=
|
|
31
|
+
matched = if match = key.match( REGEX[:variable] )
|
|
32
|
+
node[:variables] ||= Tree.new
|
|
28
33
|
node[:variables][ match.captures.first ] = value
|
|
29
34
|
elsif value == :mixin
|
|
30
35
|
node[:mixins] ||= []
|
|
@@ -44,71 +49,73 @@ module Less
|
|
|
44
49
|
end
|
|
45
50
|
end
|
|
46
51
|
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
# Call `evaluate` on variables, such as '@dark: @light / 2'
|
|
53
|
+
@tree = @tree.traverse :branch do |path, node|
|
|
54
|
+
node.vars.each do |key, value|
|
|
55
|
+
evaluate key, value, path, node.vars
|
|
56
|
+
end if node.vars?
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Call `evaluate` on css properties, such as 'font-size: @big'
|
|
50
60
|
@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
|
|
61
|
+
evaluate key, value, path, node
|
|
79
62
|
end
|
|
80
63
|
|
|
81
64
|
#
|
|
82
65
|
# Evaluate operations (2+2)
|
|
83
66
|
#
|
|
84
67
|
# Units are: 1px, 1em, 1%, #111
|
|
85
|
-
@tree = @tree.traverse :leaf do |key, value, path, node|
|
|
86
|
-
|
|
87
|
-
if (unit =
|
|
88
|
-
unit = unit.join
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
|
71
|
+
unit = unit.join
|
|
72
|
+
operation = if unit == '#'
|
|
73
|
+
evaluate = lambda do |v|
|
|
74
|
+
result = eval v
|
|
75
|
+
unit + ( result.zero?? '000' : result.to_s(16) )
|
|
76
|
+
end
|
|
77
|
+
operation.gsub REGEX[:color] do
|
|
78
|
+
hex = $1 * ( $1.size < 6 ? 6 / $1.size : 1 )
|
|
92
79
|
hex.to_i(16)
|
|
93
80
|
end.delete unit
|
|
94
|
-
evaluate = lambda {|v| unit + eval( v ).to_s(16) }
|
|
95
81
|
else
|
|
96
|
-
value.gsub(/px|em|%/, '')
|
|
97
82
|
evaluate = lambda {|v| eval( v ).to_s + unit }
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
83
|
+
operation.gsub REGEX[:unit], ''
|
|
84
|
+
end.to_s
|
|
85
|
+
next if operation.match /[a-z]/i
|
|
86
|
+
evaluate.call operation
|
|
101
87
|
else
|
|
102
|
-
raise MixedUnitsError
|
|
88
|
+
raise MixedUnitsError, value
|
|
103
89
|
end
|
|
104
90
|
end
|
|
105
91
|
end
|
|
106
|
-
|
|
107
92
|
end
|
|
108
93
|
alias render compile
|
|
109
94
|
|
|
110
|
-
|
|
111
|
-
|
|
95
|
+
#
|
|
96
|
+
# Evaluate variables
|
|
97
|
+
#
|
|
98
|
+
def evaluate key, value, path, node
|
|
99
|
+
if value.is_a? String and value.include? '@' # There's a var to evaluate
|
|
100
|
+
value.scan REGEX[:path] do |var|
|
|
101
|
+
var = var.join.delete ' '
|
|
102
|
+
var = if var.include? '>'
|
|
103
|
+
@tree.find :var, var.split('>') # Try finding it in a specific namespace
|
|
104
|
+
else
|
|
105
|
+
node.var( var ) or @tree.nearest var, path # Try local first, then nearest scope
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
if var
|
|
109
|
+
node[ key ] = value.gsub REGEX[:path], var # Substitute variable with value
|
|
110
|
+
else
|
|
111
|
+
node.delete key # Discard the declaration if the variable wasn't found
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def to_css chain
|
|
118
|
+
self.compile.to_css chain
|
|
112
119
|
end
|
|
113
120
|
|
|
114
121
|
def hashify
|
|
@@ -119,13 +126,16 @@ module Less
|
|
|
119
126
|
# less: color: black;
|
|
120
127
|
# hashify: "color" => "black"
|
|
121
128
|
#
|
|
122
|
-
hash = self.gsub(
|
|
123
|
-
gsub(
|
|
129
|
+
hash = self.gsub(/\t+/, ' '). # Tabs
|
|
130
|
+
gsub(/\r\n/, "\n"). # m$
|
|
131
|
+
gsub(/\/\/.*/, ''). # Comments //
|
|
132
|
+
gsub(/\/\*.*?\*\//m, ''). # Comments /*
|
|
133
|
+
gsub(/"/, "'"). # " => '
|
|
134
|
+
gsub(/("|')(.+?)(\1)/) { $1 + CGI.escape( $2 ) + $1 }. # Escape string values
|
|
135
|
+
gsub(/(#{REGEX[:property]}):\s*(.+?)\s*(;|(?=\}))/,'"\1"=>"\2",'). # Rules
|
|
124
136
|
gsub(/\}/, "},"). # Closing }
|
|
125
|
-
gsub(/(
|
|
126
|
-
gsub(/([.#][->\w .#]+);/, '"\\1" => :mixin,')
|
|
127
|
-
gsub("\n\n", "\n"). # New-lines
|
|
128
|
-
gsub(/\/\/.*\n/, '') # Comments
|
|
137
|
+
gsub(/( *)(#{REGEX[:selector]}+?)[ \n]*(?=\{)/m, '\1"\2"=>'). # Selectors
|
|
138
|
+
gsub(/([.#][->\w .#]+);/, '"\\1" => :mixin,') # Mixins
|
|
129
139
|
eval "{" + hash + "}" # Return {hash}
|
|
130
140
|
end
|
|
131
141
|
end
|
data/lib/less/tree.rb
CHANGED
|
@@ -16,50 +16,65 @@ module Less
|
|
|
16
16
|
self[:variables] ? self[:variables] : nil
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
#
|
|
20
|
+
# Find a variable or mixin from a specific path
|
|
21
|
+
#
|
|
19
22
|
def find what = :var, path = []
|
|
20
23
|
path.inject(self) do |branch, k|
|
|
21
24
|
if what == :var && k == path.last
|
|
22
25
|
branch[:variables][ k ]
|
|
23
26
|
else
|
|
24
|
-
branch = branch[ k ]
|
|
27
|
+
branch = branch[ k ] or raise PathError, path.join(' > ')
|
|
25
28
|
end
|
|
26
29
|
end
|
|
27
30
|
end
|
|
28
31
|
|
|
32
|
+
#
|
|
33
|
+
# Find the nearest variable in the hierarchy
|
|
34
|
+
#
|
|
35
|
+
def nearest var, path
|
|
36
|
+
values = []
|
|
37
|
+
path.inject(self) do |branch, k|
|
|
38
|
+
values << branch.var( var )
|
|
39
|
+
branch[ k ]
|
|
40
|
+
end
|
|
41
|
+
values.compact.last
|
|
42
|
+
end
|
|
43
|
+
|
|
29
44
|
def traverse by = :leaf, path = [], &blk
|
|
30
45
|
#
|
|
31
46
|
# Traverse the whole tree, returning each leaf or branch (recursive)
|
|
32
47
|
#
|
|
33
48
|
###
|
|
34
|
-
# Aside from the key & value,
|
|
35
|
-
#
|
|
36
|
-
#
|
|
49
|
+
# Aside from the key & value, we yield the full path of the leaf,
|
|
50
|
+
# aswell as the branch which contains it (self).
|
|
51
|
+
# Note that in :branch mode, we only return 'twigs', branches which contain leaves.
|
|
37
52
|
#
|
|
38
53
|
self.each do |key, value| # `self` is the current node, starting with the trunk
|
|
39
54
|
if value.is_a? Hash and key != :variables # If the node is a branch, we can go deeper
|
|
40
55
|
path << key # Add the current branch to the path
|
|
41
56
|
self[ key ] = value.to_tree. # Make sure any change is saved to the main tree
|
|
42
|
-
traverse by, path, &blk # Recurse, with the current node becoming `self`
|
|
43
|
-
if by == :branch
|
|
44
|
-
|
|
45
|
-
path.pop
|
|
46
|
-
end
|
|
57
|
+
traverse by, path, &blk # Recurse, with the current node becoming `self`
|
|
58
|
+
yield path, self[ key ] if by == :branch # The node is a branch, yield it to the block
|
|
59
|
+
path.pop # We're returning from a branch, pop the last path element
|
|
47
60
|
elsif by == :leaf and key.is_a? String
|
|
48
61
|
yield key, value, path, self # The node is a leaf, yield it to the block
|
|
49
|
-
path.pop
|
|
50
62
|
else
|
|
51
63
|
next
|
|
52
64
|
end
|
|
53
65
|
end
|
|
54
66
|
self
|
|
55
67
|
end
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# Convert the tree to css, using full paths
|
|
71
|
+
#
|
|
72
|
+
def to_css chain = :desc, css = []
|
|
58
73
|
self.traverse :branch do |path, node|
|
|
59
74
|
properties = node.inject("") do |s, (k, v)|
|
|
60
|
-
v.is_a?(String) ? (s + "#{k}: #{v}; ") : s
|
|
75
|
+
v.is_a?(String) ? (s + "#{k}: #{CGI.unescape(v)}; ") : s # Add the property to the list
|
|
61
76
|
end
|
|
62
|
-
css << path * ' > ' + " { " + properties + "}"
|
|
77
|
+
css << path * ( chain == :desc ? ' ' : ' > ') + " { " + properties + "}" # Add the rule-set to the CSS
|
|
63
78
|
end
|
|
64
79
|
css.join "\n"
|
|
65
80
|
end
|
data/lib/less.rb
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
|
|
1
3
|
require 'less/command'
|
|
2
4
|
require 'less/engine'
|
|
3
5
|
require 'less/tree'
|
|
4
6
|
|
|
5
|
-
module Less
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
module Less
|
|
8
|
+
MixedUnitsError = Class.new(Exception)
|
|
9
|
+
PathError = Class.new(Exception)
|
|
10
|
+
|
|
11
|
+
def self.version
|
|
12
|
+
File.read( File.join( File.dirname(__FILE__), '..', 'VERSION') )
|
|
8
13
|
end
|
|
9
14
|
end
|
|
10
15
|
|
data/spec/spec.less
CHANGED
|
@@ -1,57 +1,124 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.
|
|
13
|
-
|
|
14
|
-
color:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@another-color: * > @base-color;
|
|
21
|
-
}
|
|
22
|
-
.altfoo { color: .alt > @base-color; }
|
|
23
|
-
.foo { border: 1px solid black; color: @base-color; }
|
|
24
|
-
.foo2 {
|
|
25
|
-
width: 10px * 2;
|
|
26
|
-
}
|
|
27
|
-
#content {
|
|
28
|
-
font-size: 12px;
|
|
29
|
-
@some-color: blue;
|
|
30
|
-
#header {
|
|
31
|
-
.foo;
|
|
32
|
-
font-size: #222 / 2;
|
|
1
|
+
// ------------------------------------------------
|
|
2
|
+
// LESS Spec
|
|
3
|
+
// www.lesscss.org
|
|
4
|
+
// ------------------------------------------------
|
|
5
|
+
|
|
6
|
+
// Global vars
|
|
7
|
+
@main-color: #444;
|
|
8
|
+
@dark-color: #111;
|
|
9
|
+
@between-color: @main-color - @dark-color;
|
|
10
|
+
|
|
11
|
+
// Mixins
|
|
12
|
+
.theme {
|
|
13
|
+
color: #ccc;
|
|
14
|
+
background-color: #aaa;
|
|
15
|
+
}
|
|
16
|
+
.extra {
|
|
17
|
+
@main: #888;
|
|
18
|
+
.dark-borders {
|
|
19
|
+
border-color: .extra > @main / 2;
|
|
33
20
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
.small {
|
|
38
|
-
color: @base-color;
|
|
39
|
-
font-size: 12 / 2;
|
|
40
|
-
.hover_controls {
|
|
41
|
-
line-height: 16px;
|
|
42
|
-
display: none;
|
|
43
|
-
color: #content > @some-color;
|
|
44
|
-
border: 1px solid #fff;
|
|
45
|
-
}
|
|
21
|
+
.light-borders {
|
|
22
|
+
border-color: .extra > @main;
|
|
46
23
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Namespaces
|
|
27
|
+
.borders {
|
|
28
|
+
@thick: 4px;
|
|
29
|
+
@thin: 2px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Hierarchy
|
|
33
|
+
.root {
|
|
34
|
+
a {
|
|
35
|
+
color: blue;
|
|
36
|
+
display: none;
|
|
37
|
+
}
|
|
38
|
+
a:hover, a:focus {
|
|
39
|
+
color: orange;
|
|
53
40
|
}
|
|
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
|
+
background-color: @color; // blue
|
|
50
|
+
font-size: @size; // 8px
|
|
51
|
+
color: @main-color; // red
|
|
52
|
+
border-color: .root > .first > .second > @color; // 'blue'
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
.root:hover a {
|
|
58
|
+
display: block;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Standard CSS properties and shorthand
|
|
62
|
+
body {
|
|
63
|
+
font-size: 10px;
|
|
64
|
+
font-family: "Lucida Grande", 'Helvetica', Verdana, sans-serif;
|
|
65
|
+
margin: -5px 0 5px 10px;
|
|
66
|
+
border: solid 1px #000;
|
|
67
|
+
text-shadow: #333 -1px 1px 2px;
|
|
68
|
+
-moz-border-radius: 3px; /* CSS3 for older Firefox */
|
|
69
|
+
.theme;
|
|
70
|
+
.extra > .light-borders;
|
|
54
71
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
|
|
73
|
+
// Operations
|
|
74
|
+
.operations {
|
|
75
|
+
@ten: 10;
|
|
76
|
+
@dark: #111;
|
|
77
|
+
border-width: .borders > @thick * 5 - 4px; // 16px
|
|
78
|
+
font-size: 10 - 4 + 6 * @ten; // 66
|
|
79
|
+
line-height: @ten - .operations > @ten + .root > .first > @size - 1; // 7px
|
|
80
|
+
color: #fff - #111; // #eeeeee
|
|
81
|
+
colorb: #111 + #222222; // #333333
|
|
82
|
+
colorc: @dark + #222 * 3; // #777777
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
td, tr, table {
|
|
86
|
+
border-width: .borders > @thick;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// More complex CSS selectors
|
|
90
|
+
ul li:first-child {
|
|
91
|
+
border-top: none;
|
|
92
|
+
}
|
|
93
|
+
ul li:first-child, ul li:last-child {
|
|
94
|
+
background-color: #333;
|
|
95
|
+
}
|
|
96
|
+
.p:first-letter {
|
|
97
|
+
color: red;
|
|
98
|
+
}
|
|
99
|
+
:focus {
|
|
100
|
+
outline: 0;
|
|
101
|
+
content: "*}#f~ ";
|
|
102
|
+
}
|
|
103
|
+
q:lang(no) {
|
|
104
|
+
quotes: "~" "~";
|
|
105
|
+
}
|
|
106
|
+
blockquote:before {
|
|
107
|
+
color: red;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/*input[type="text"] {
|
|
111
|
+
background-color: blue;
|
|
112
|
+
}*/
|
|
113
|
+
.transparent_box {
|
|
114
|
+
background-color:#FFF;
|
|
115
|
+
filter:alpha(opacity=60); /* for IE */
|
|
116
|
+
opacity:0.6; /* CSS3 standard */
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Spacing
|
|
120
|
+
.space
|
|
121
|
+
{ color: purple ;font-color:yellow; }
|
|
122
|
+
|
|
123
|
+
// No semi-column
|
|
124
|
+
.no-semi-column { color: orange }
|
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.7
|
|
4
|
+
version: 0.8.7
|
|
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-
|
|
12
|
+
date: 2009-06-15 00:00:00 -04:00
|
|
13
13
|
default_executable: lessc
|
|
14
14
|
dependencies: []
|
|
15
15
|
|