less 0.8.7 → 0.8.8
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 +1 -0
- data/Rakefile +20 -0
- data/VERSION +1 -1
- data/bin/lessc +0 -1
- data/less.gemspec +18 -3
- data/lib/less.rb +6 -3
- data/lib/less/command.rb +21 -14
- data/lib/less/engine.rb +19 -13
- data/lib/less/tree.rb +1 -1
- data/spec/command_spec.rb +106 -0
- data/spec/css/less-0.8.5.css +24 -0
- data/spec/css/less-0.8.6.css +24 -0
- data/spec/css/less-0.8.7.css +24 -0
- data/spec/css/less-0.8.8.css +25 -0
- data/spec/engine_spec.rb +35 -0
- data/spec/spec.css +25 -0
- data/spec/spec.less +4 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/tree_spec.rb +5 -0
- metadata +16 -4
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -38,4 +38,24 @@ begin
|
|
38
38
|
end
|
39
39
|
rescue LoadError
|
40
40
|
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
41
|
+
end
|
42
|
+
|
43
|
+
begin
|
44
|
+
require 'spec/rake/spectask'
|
45
|
+
|
46
|
+
Spec::Rake::SpecTask.new("spec") do |t|
|
47
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
48
|
+
t.spec_opts = ['--color', '--format=specdoc']
|
49
|
+
end
|
50
|
+
|
51
|
+
task :test do
|
52
|
+
Rake::Task['spec'].invoke
|
53
|
+
end
|
54
|
+
|
55
|
+
Spec::Rake::SpecTask.new("rcov_spec") do |t|
|
56
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
57
|
+
t.spec_opts = ['--color']
|
58
|
+
t.rcov = true
|
59
|
+
t.rcov_opts = ['--exclude', '^spec,/gems/']
|
60
|
+
end
|
41
61
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.8.
|
1
|
+
0.8.8
|
data/bin/lessc
CHANGED
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.8.
|
5
|
+
s.version = "0.8.8"
|
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-06-
|
9
|
+
s.date = %q{2009-06-17}
|
10
10
|
s.default_executable = %q{lessc}
|
11
11
|
s.description = %q{LESS is leaner CSS}
|
12
12
|
s.email = %q{alexis@cloudhead.net}
|
@@ -27,7 +27,16 @@ Gem::Specification.new do |s|
|
|
27
27
|
"lib/less/command.rb",
|
28
28
|
"lib/less/engine.rb",
|
29
29
|
"lib/less/tree.rb",
|
30
|
-
"spec/
|
30
|
+
"spec/command_spec.rb",
|
31
|
+
"spec/css/less-0.8.5.css",
|
32
|
+
"spec/css/less-0.8.6.css",
|
33
|
+
"spec/css/less-0.8.7.css",
|
34
|
+
"spec/css/less-0.8.8.css",
|
35
|
+
"spec/engine_spec.rb",
|
36
|
+
"spec/spec.css",
|
37
|
+
"spec/spec.less",
|
38
|
+
"spec/spec_helper.rb",
|
39
|
+
"spec/tree_spec.rb"
|
31
40
|
]
|
32
41
|
s.has_rdoc = true
|
33
42
|
s.homepage = %q{http://www.lesscss.org}
|
@@ -36,6 +45,12 @@ Gem::Specification.new do |s|
|
|
36
45
|
s.rubyforge_project = %q{less}
|
37
46
|
s.rubygems_version = %q{1.3.1}
|
38
47
|
s.summary = %q{LESS compiler}
|
48
|
+
s.test_files = [
|
49
|
+
"spec/command_spec.rb",
|
50
|
+
"spec/engine_spec.rb",
|
51
|
+
"spec/spec_helper.rb",
|
52
|
+
"spec/tree_spec.rb"
|
53
|
+
]
|
39
54
|
|
40
55
|
if s.respond_to? :specification_version then
|
41
56
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
data/lib/less.rb
CHANGED
@@ -1,20 +1,23 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
1
3
|
require 'cgi'
|
2
4
|
|
3
5
|
require 'less/command'
|
4
6
|
require 'less/engine'
|
5
7
|
require 'less/tree'
|
6
8
|
|
7
|
-
module Less
|
9
|
+
module Less
|
8
10
|
MixedUnitsError = Class.new(Exception)
|
9
11
|
PathError = Class.new(Exception)
|
10
|
-
|
12
|
+
CompoundOperationError = Class.new(Exception)
|
13
|
+
|
11
14
|
def self.version
|
12
15
|
File.read( File.join( File.dirname(__FILE__), '..', 'VERSION') )
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
16
19
|
class Hash
|
17
|
-
# Convert a hash into a Tree
|
20
|
+
# Convert a hash into a Tree
|
18
21
|
def to_tree
|
19
22
|
Less::Tree.new self
|
20
23
|
end
|
data/lib/less/command.rb
CHANGED
@@ -1,15 +1,20 @@
|
|
1
1
|
module Less
|
2
2
|
class Command
|
3
|
+
CSS = '.css'
|
4
|
+
|
5
|
+
attr_accessor :source, :destination, :options
|
6
|
+
|
3
7
|
def initialize options
|
4
|
-
@source
|
8
|
+
@source = options[:source]
|
9
|
+
@destination = (options[:destination] || options[:source]).gsub /\.(less|lss)/, CSS
|
5
10
|
@options = options
|
6
11
|
end
|
7
|
-
|
12
|
+
|
8
13
|
def watch?() @options[:watch] end
|
9
14
|
def compress?() @options[:compress] end
|
10
15
|
def debug?() @options[:debug] end
|
11
|
-
|
12
|
-
# little function which allows us to
|
16
|
+
|
17
|
+
# little function which allows us to
|
13
18
|
# Ctrl-C exit inside the passed block
|
14
19
|
def watch &block
|
15
20
|
begin
|
@@ -22,18 +27,18 @@ module Less
|
|
22
27
|
|
23
28
|
def run!
|
24
29
|
compile(true) unless File.exist? @destination
|
25
|
-
|
30
|
+
|
26
31
|
if watch?
|
27
32
|
log "Watching for changes in #@source ...Ctrl-C to abort.\n"
|
28
|
-
|
33
|
+
|
29
34
|
# Main watch loop
|
30
35
|
loop do
|
31
36
|
watch { sleep 1 }
|
32
|
-
|
37
|
+
|
33
38
|
# File has changed
|
34
39
|
if File.stat( @source ).mtime > File.stat( @destination ).mtime
|
35
40
|
log "Change detected... "
|
36
|
-
|
41
|
+
|
37
42
|
# Loop until error is fixed
|
38
43
|
until compile
|
39
44
|
log "Press [enter] to continue..."
|
@@ -45,13 +50,13 @@ module Less
|
|
45
50
|
compile
|
46
51
|
end
|
47
52
|
end
|
48
|
-
|
53
|
+
|
49
54
|
def compile new = false
|
50
55
|
begin
|
51
56
|
# Create a new Less object with the contents of a file
|
52
57
|
css = Less::Engine.new( File.read( @source ) ).to_css @options[:inheritance]
|
53
58
|
css = css.delete " \n" if compress?
|
54
|
-
|
59
|
+
|
55
60
|
File.open( @destination, "w" ) do |file|
|
56
61
|
file.write css
|
57
62
|
end
|
@@ -59,24 +64,26 @@ module Less
|
|
59
64
|
rescue Errno::ENOENT => e
|
60
65
|
abort "#{e}"
|
61
66
|
rescue SyntaxError
|
62
|
-
error = debug?? $! : $!.message.split("\n")[1..-1].collect {|e|
|
63
|
-
e.gsub(/\(eval\)\:(\d+)\:\s/, 'line \1: ')
|
67
|
+
error = debug?? $! : $!.message.split("\n")[1..-1].collect {|e|
|
68
|
+
e.gsub(/\(eval\)\:(\d+)\:\s/, 'line \1: ')
|
64
69
|
} * "\n"
|
65
70
|
err "errors were found in the .less file! \n#{error}\n"
|
66
71
|
rescue MixedUnitsError => e
|
67
72
|
err "`#{e}` you're mixing units together! What do you expect?\n"
|
73
|
+
rescue CompoundOperationError => e
|
74
|
+
err "`#{e}` operations in compound declarations aren't allowed, sorry!\n"
|
68
75
|
rescue PathError => e
|
69
76
|
err "`#{e}` was not found.\n"
|
70
77
|
else
|
71
78
|
true
|
72
79
|
end
|
73
80
|
end
|
74
|
-
|
81
|
+
|
75
82
|
# Just a logging function to avoid typing '}'
|
76
83
|
def log s = ''
|
77
84
|
print '* ' + s.to_s
|
78
85
|
end
|
79
|
-
|
86
|
+
|
80
87
|
def err s = ''
|
81
88
|
print "!! #{s}"
|
82
89
|
end
|
data/lib/less/engine.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
module Less
|
2
2
|
class Engine < String
|
3
|
+
# Compound properties, such as `border: 1px solid black`
|
4
|
+
COMPOUND = ['font', 'background', 'border']
|
3
5
|
REGEX = {
|
4
|
-
:path => /([#.][->#.\w ]+)?( ?> ?)
|
6
|
+
:path => /([#.][->#.\w ]+)?( ?> ?)?/, # #header > .title
|
5
7
|
:selector => /[-\w #.,>*:\(\)]/, # .cow .milk > a
|
6
8
|
:variable => /@([-\w]+)/, # @milk-white
|
7
9
|
:property => /@[-\w]+|[-a-z]+/, # font-size
|
@@ -65,8 +67,9 @@ module Less
|
|
65
67
|
# Evaluate operations (2+2)
|
66
68
|
#
|
67
69
|
# Units are: 1px, 1em, 1%, #111
|
68
|
-
@tree = @tree.traverse :leaf do |key, value, path, node|
|
70
|
+
@tree = @tree.traverse :leaf do |key, value, path, node|
|
69
71
|
node[ key ] = value.gsub /(#{REGEX[:operand]}(\s?)[-+\/*](\4))+(#{REGEX[:operand]})/ do |operation|
|
72
|
+
raise CompoundOperationError, "#{key}: #{value}" if COMPOUND.include? key # Disallow operations on compound declarations
|
70
73
|
if (unit = operation.scan(/#{REGEX[:numeric]}|(#)/i).flatten.compact.uniq).size <= 1
|
71
74
|
unit = unit.join
|
72
75
|
operation = if unit == '#'
|
@@ -95,26 +98,29 @@ module Less
|
|
95
98
|
#
|
96
99
|
# Evaluate variables
|
97
100
|
#
|
98
|
-
def evaluate key,
|
99
|
-
if
|
100
|
-
|
101
|
+
def evaluate key, expression, path, node
|
102
|
+
if expression.is_a? String and expression.include? '@' # There's a var to evaluate
|
103
|
+
expression.scan /#{REGEX[:path]}#{REGEX[:variable]}/ do |var|
|
104
|
+
name = var.last
|
101
105
|
var = var.join.delete ' '
|
102
|
-
|
103
|
-
|
106
|
+
|
107
|
+
value = if var.include? '>'
|
108
|
+
@tree.find :var, var.split('>') # Try finding it in a specific namespace
|
104
109
|
else
|
105
|
-
node.var(
|
110
|
+
node.var(var) or @tree.nearest var, path # Try local first, then nearest scope
|
106
111
|
end
|
107
|
-
|
108
|
-
if
|
109
|
-
|
112
|
+
|
113
|
+
if value
|
114
|
+
# Substitute variable with value
|
115
|
+
node[ key ] = node[ key ].gsub /#{REGEX[:path]}@#{name}/, value
|
110
116
|
else
|
111
|
-
node.delete key
|
117
|
+
node.delete key # Discard the declaration if the variable wasn't found
|
112
118
|
end
|
113
119
|
end
|
114
120
|
end
|
115
121
|
end
|
116
122
|
|
117
|
-
def to_css chain
|
123
|
+
def to_css chain = :desc
|
118
124
|
self.compile.to_css chain
|
119
125
|
end
|
120
126
|
|
data/lib/less/tree.rb
CHANGED
@@ -69,7 +69,7 @@ module Less
|
|
69
69
|
#
|
70
70
|
# Convert the tree to css, using full paths
|
71
71
|
#
|
72
|
-
def to_css chain
|
72
|
+
def to_css chain, css = []
|
73
73
|
self.traverse :branch do |path, node|
|
74
74
|
properties = node.inject("") do |s, (k, v)|
|
75
75
|
v.is_a?(String) ? (s + "#{k}: #{CGI.unescape(v)}; ") : s # Add the property to the list
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
module LessCommandSpecHelper
|
4
|
+
def required_options
|
5
|
+
{:source => File.dirname(__FILE__) + '/spec.less'}
|
6
|
+
end
|
7
|
+
|
8
|
+
def valid_options
|
9
|
+
{:destination => File.dirname(__FILE__) + '/spec.css', :watch => true, :chain => true, :debug => false}.merge(required_options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Less::Command do
|
14
|
+
include LessCommandSpecHelper
|
15
|
+
|
16
|
+
describe "required options" do
|
17
|
+
before(:each) do
|
18
|
+
@command = Less::Command.new(required_options)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should set the source" do
|
22
|
+
@command.source.should == required_options[:source]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set the destination using a gsub" do
|
26
|
+
@command.destination.should == valid_options[:destination]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should set the options with what was passed" do
|
30
|
+
@command.options.should == required_options
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "valid options" do
|
35
|
+
before(:each) do
|
36
|
+
@command = Less::Command.new(valid_options)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should set the @source" do
|
40
|
+
@command.source.should == required_options[:source]
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should set the @destionation" do
|
44
|
+
@command.destination.should == valid_options[:destination]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should set the watch" do
|
48
|
+
@command.options[:watch].should == valid_options[:watch]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set the chain" do
|
52
|
+
@command.options[:chain].should == valid_options[:chain]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should set the debug" do
|
56
|
+
@command.options[:debug].should == valid_options[:debug]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should set the options with what was passed" do
|
60
|
+
@command.options.should == valid_options
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "executing run!" do
|
65
|
+
before(:each) do
|
66
|
+
@command = Less::Command.new(required_options)
|
67
|
+
end
|
68
|
+
after(:each) do
|
69
|
+
@command.run!
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "when not watching" do
|
73
|
+
describe "and the destination file doesn't exist" do
|
74
|
+
before(:each) do
|
75
|
+
@command.stub!(:watch?).and_return(false)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should verify if we need to watch the file or not" do
|
79
|
+
@command.should_receive(:watch?).and_return(false)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should attempt to re-compile" do
|
83
|
+
@command.should_receive(:compile).with().once
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "and the destination file does exist" do
|
88
|
+
it "should not attempt to create a new file"
|
89
|
+
it "should attempt to re-compile"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "when watching" do
|
94
|
+
describe "and the destination file doesn't exist" do
|
95
|
+
it "should attempt to compile to a new file"
|
96
|
+
it "should begin to watch the file"
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "and the destination file does exist" do
|
100
|
+
it "should not attempt to compile to a new file"
|
101
|
+
it "should begin to watch the existing file"
|
102
|
+
it "should re-compile when the existing file changes"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
ul li:first-child { border-top: none; }
|
2
|
+
q:lang(no) { quotes: '~' '~'; }
|
3
|
+
.no-semi-column { color: orange; }
|
4
|
+
body { text-shadow: #333 -1px 1px 2px; border-color: #888; font-size: 10px; margin: -5px 0 5px 10px; background-color: #aaa; border: solid 1px #000; -moz-border-radius: 3px; font-family: 'Lucida Grande', 'Helvetica', Verdana, sans-serif; color: #ccc; }
|
5
|
+
td, tr, table { border-width: 4px; }
|
6
|
+
.space { color: purple; font-color: yellow; }
|
7
|
+
blockquote:before { color: red; }
|
8
|
+
.root > a:hover, a:focus { color: orange; }
|
9
|
+
.root > a { display: none; color: blue; }
|
10
|
+
.root > .first > .second > .third { border-color: blue; font-size: 8px; background-color: blue; color: red; }
|
11
|
+
.root > .first > .second { }
|
12
|
+
.root > .first { color: green; }
|
13
|
+
.root { }
|
14
|
+
.p:first-letter { color: red; }
|
15
|
+
.extra > .dark-borders { border-color: #444444; }
|
16
|
+
.extra > .light-borders { border-color: #888; }
|
17
|
+
.extra { }
|
18
|
+
ul li:first-child, ul li:last-child { background-color: #333; }
|
19
|
+
.borders { }
|
20
|
+
.root:hover a { display: block; }
|
21
|
+
.operations { colorb: #333333; font-size: 66; colorc: #777777; line-height: 7px; border-width: 16px; color: #eeeeee; }
|
22
|
+
:focus { outline: 0; content: '*}#f~ '; }
|
23
|
+
.theme { background-color: #aaa; color: #ccc; }
|
24
|
+
.transparent_box { opacity: 0.6; background-color: #FFF; filter: alpha(opacity=60); }
|
@@ -0,0 +1,24 @@
|
|
1
|
+
ul li:first-child { border-top: none; }
|
2
|
+
q:lang(no) { quotes: '~' '~'; }
|
3
|
+
.no-semi-column { color: orange; }
|
4
|
+
body { text-shadow: #333 -1px 1px 2px; border-color: #888; font-size: 10px; margin: -5px 0 5px 10px; background-color: #aaa; border: solid 1px #000; -moz-border-radius: 3px; font-family: 'Lucida Grande', 'Helvetica', Verdana, sans-serif; color: #ccc; }
|
5
|
+
td, tr, table { border-width: 4px; }
|
6
|
+
.space { color: purple; font-color: yellow; }
|
7
|
+
blockquote:before { color: red; }
|
8
|
+
.root a:hover, a:focus { color: orange; }
|
9
|
+
.root a { display: none; color: blue; }
|
10
|
+
.root .first .second .third { border-color: blue; font-size: 8px; background-color: blue; color: red; }
|
11
|
+
.root .first .second { }
|
12
|
+
.root .first { color: green; }
|
13
|
+
.root { }
|
14
|
+
.p:first-letter { color: red; }
|
15
|
+
.extra .dark-borders { border-color: #444444; }
|
16
|
+
.extra .light-borders { border-color: #888; }
|
17
|
+
.extra { }
|
18
|
+
ul li:first-child, ul li:last-child { background-color: #333; }
|
19
|
+
.borders { }
|
20
|
+
.root:hover a { display: block; }
|
21
|
+
.operations { colorb: #333333; font-size: 66; colorc: #777777; line-height: 7px; border-width: 16px; color: #eeeeee; }
|
22
|
+
:focus { outline: 0; content: '*}#f~ '; }
|
23
|
+
.theme { background-color: #aaa; color: #ccc; }
|
24
|
+
.transparent_box { opacity: 0.6; background-color: #FFF; filter: alpha(opacity=60); }
|
@@ -0,0 +1,24 @@
|
|
1
|
+
ul li:first-child { border-top: none; }
|
2
|
+
q:lang(no) { quotes: '~' '~'; }
|
3
|
+
.no-semi-column { color: orange; }
|
4
|
+
body { text-shadow: #333 -1px 1px 2px; border-color: #888; font-size: 10px; margin: -5px 0 5px 10px; background-color: #aaa; border: solid 1px #000; -moz-border-radius: 3px; font-family: 'Lucida Grande', 'Helvetica', Verdana, sans-serif; color: #ccc; }
|
5
|
+
td, tr, table { border-width: 4px; }
|
6
|
+
.space { color: purple; font-color: yellow; }
|
7
|
+
blockquote:before { color: red; }
|
8
|
+
.root a:hover, a:focus { color: orange; }
|
9
|
+
.root a { display: none; color: blue; }
|
10
|
+
.root .first .second .third { border-color: blue; font-size: 8px; background-color: blue; color: red; }
|
11
|
+
.root .first .second { }
|
12
|
+
.root .first { color: green; }
|
13
|
+
.root { }
|
14
|
+
.p:first-letter { color: red; }
|
15
|
+
.extra .dark-borders { border-color: #444444; }
|
16
|
+
.extra .light-borders { border-color: #888; }
|
17
|
+
.extra { }
|
18
|
+
ul li:first-child, ul li:last-child { background-color: #333; }
|
19
|
+
.borders { }
|
20
|
+
.root:hover a { display: block; }
|
21
|
+
.operations { colorb: #333333; font-size: 66; colorc: #777777; line-height: 7px; border-width: 16px; color: #eeeeee; }
|
22
|
+
:focus { outline: 0; content: '*}#f~ '; }
|
23
|
+
.theme { background-color: #aaa; color: #ccc; }
|
24
|
+
.transparent_box { opacity: 0.6; background-color: #FFF; filter: alpha(opacity=60); }
|
@@ -0,0 +1,25 @@
|
|
1
|
+
ul li:first-child { border-top: none; }
|
2
|
+
q:lang(no) { quotes: '~' '~'; }
|
3
|
+
.no-semi-column { color: orange; }
|
4
|
+
body { text-shadow: #333 -1px 1px 2px; border-color: #888; font-size: 10px; margin: -5px 0 5px 10px; background-color: #aaa; border: solid 1px #000; -moz-border-radius: 3px; font-family: 'Lucida Grande', 'Helvetica', Verdana, sans-serif; color: #ccc; }
|
5
|
+
td, tr, table { border-width: 4px; }
|
6
|
+
.space { color: purple; font-color: yellow; }
|
7
|
+
blockquote:before { color: red; }
|
8
|
+
.root a:hover, a:focus { color: orange; }
|
9
|
+
.root a { display: none; color: blue; }
|
10
|
+
.root .first .second .third { border-color: blue; font-size: 8px; background-color: blue; color: red; }
|
11
|
+
.root .first .second { }
|
12
|
+
.root .first { color: green; }
|
13
|
+
.root { }
|
14
|
+
.p:first-letter { color: red; }
|
15
|
+
.extra .dark-borders { border-color: #444444; }
|
16
|
+
.extra .light-borders { border-color: #888; }
|
17
|
+
.extra { }
|
18
|
+
ul li:first-child, ul li:last-child { background-color: #333; }
|
19
|
+
.borders { }
|
20
|
+
.root:hover a { display: block; }
|
21
|
+
.operations div { width: 80px; }
|
22
|
+
.operations { colorb: #333333; font-size: 66; colorc: #777777; line-height: 7px; border-width: 16px; color: #eeeeee; width: 110px; }
|
23
|
+
:focus { outline: 0; content: '*}#f~ '; }
|
24
|
+
.theme { background-color: #aaa; color: #ccc; }
|
25
|
+
.transparent_box { opacity: 0.6; background-color: #FFF; filter: alpha(opacity=60); }
|
data/spec/engine_spec.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
module LessEngineSpecHelper
|
4
|
+
def lessify(string)
|
5
|
+
return Less::Engine.new(string).to_css(:desc)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Less::Engine do
|
10
|
+
include LessEngineSpecHelper
|
11
|
+
|
12
|
+
describe "to_css" do
|
13
|
+
it "should return p {} for p {}" do
|
14
|
+
lessify('p {}').should == 'p { }'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return css with variable usage" do
|
18
|
+
lessify("@brand_color: #4D926F;\n #header { color: @brand_color; }").should == "#header { color: #4D926F; }"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return css as shown on home page" do
|
22
|
+
lessify("#header { \n color: red;\n a {\n font-weight: bold;\n text-decoration: none;\n }\n}").should == "#header a { font-weight: bold; text-decoration: none; }\n#header { color: red; }"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should handle :hover" do
|
26
|
+
lessify("a:hover {\n color: red; }").should == "a:hover { color: red; }"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should handle instances of double-quotes" do
|
30
|
+
lessify("blockquote:before, blockquote:after, q:before, q:after {\n content: \"\"; }").should == "blockquote:before, blockquote:after, q:before, q:after { content: ''; }"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
data/spec/spec.css
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
.theme { color: #ccc; background-color: #aaa; }
|
2
|
+
.extra > .dark-borders { border-color: #444444; }
|
3
|
+
.extra > .light-borders { border-color: #888; }
|
4
|
+
.extra { }
|
5
|
+
.borders { }
|
6
|
+
.root > a { color: blue; display: none; }
|
7
|
+
.root > a:hover, a:focus { color: orange; }
|
8
|
+
.root > .first > .second > .third { background-color: blue; font-size: 8px; color: red; border-color: blue; }
|
9
|
+
.root > .first > .second { }
|
10
|
+
.root > .first { color: green; }
|
11
|
+
.root { }
|
12
|
+
.root:hover a { display: block; }
|
13
|
+
body { font-size: 10px; font-family: 'Lucida Grande', 'Helvetica', Verdana, sans-serif; margin: -5px 0 5px 10px; border: solid 1px #000; text-shadow: #333 -1px 1px 2px; -moz-border-radius: 3px; color: #ccc; background-color: #aaa; border-color: #888; }
|
14
|
+
.operations > div { width: 80px; }
|
15
|
+
.operations { width: 110px; border-width: 16px; font-size: 66; line-height: 7px; color: #eeeeee; colorb: #333333; colorc: #777777; }
|
16
|
+
td, tr, table { border-width: 4px; }
|
17
|
+
ul li:first-child { border-top: none; }
|
18
|
+
ul li:first-child, ul li:last-child { background-color: #333; }
|
19
|
+
.p:first-letter { color: red; }
|
20
|
+
:focus { outline: 0; content: '*}#f~ '; }
|
21
|
+
q:lang(no) { quotes: '~' '~'; }
|
22
|
+
blockquote:before { color: red; }
|
23
|
+
.transparent_box { background-color: #FFF; filter: alpha(opacity=60); opacity: 0.6; }
|
24
|
+
.space { color: purple; font-color: yellow; }
|
25
|
+
.no-semi-column { color: orange; }
|
data/spec/spec.less
CHANGED
@@ -74,6 +74,10 @@ body {
|
|
74
74
|
.operations {
|
75
75
|
@ten: 10;
|
76
76
|
@dark: #111;
|
77
|
+
@box: 100px;
|
78
|
+
@border_width: 10px;
|
79
|
+
width: @box + @border_width; // 110px
|
80
|
+
div { width: @box - 2 * @border_width; } // 80px
|
77
81
|
border-width: .borders > @thick * 5 - 4px; // 16px
|
78
82
|
font-size: 10 - 4 + 6 * @ten; // 66
|
79
83
|
line-height: @ten - .operations > @ten + .root > .first > @size - 1; // 7px
|
data/spec/spec_helper.rb
ADDED
data/spec/tree_spec.rb
ADDED
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.
|
4
|
+
version: 0.8.8
|
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-06-
|
12
|
+
date: 2009-06-17 00:00:00 -04:00
|
13
13
|
default_executable: lessc
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -34,7 +34,16 @@ files:
|
|
34
34
|
- lib/less/command.rb
|
35
35
|
- lib/less/engine.rb
|
36
36
|
- lib/less/tree.rb
|
37
|
+
- spec/command_spec.rb
|
38
|
+
- spec/css/less-0.8.5.css
|
39
|
+
- spec/css/less-0.8.6.css
|
40
|
+
- spec/css/less-0.8.7.css
|
41
|
+
- spec/css/less-0.8.8.css
|
42
|
+
- spec/engine_spec.rb
|
43
|
+
- spec/spec.css
|
37
44
|
- spec/spec.less
|
45
|
+
- spec/spec_helper.rb
|
46
|
+
- spec/tree_spec.rb
|
38
47
|
has_rdoc: true
|
39
48
|
homepage: http://www.lesscss.org
|
40
49
|
post_install_message:
|
@@ -61,5 +70,8 @@ rubygems_version: 1.3.1
|
|
61
70
|
signing_key:
|
62
71
|
specification_version: 2
|
63
72
|
summary: LESS compiler
|
64
|
-
test_files:
|
65
|
-
|
73
|
+
test_files:
|
74
|
+
- spec/command_spec.rb
|
75
|
+
- spec/engine_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
- spec/tree_spec.rb
|