cloudhead-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 -1
- 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 +25 -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 +5 -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' => true, 'background' => false, 'border' => false }
|
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,15 @@ 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
|
+
# Disallow operations certain compound declarations
|
73
|
+
if COMPOUND[key]
|
74
|
+
next value
|
75
|
+
else
|
76
|
+
raise CompoundOperationError, "#{key}: #{value}"
|
77
|
+
end if COMPOUND.include? key
|
78
|
+
|
70
79
|
if (unit = operation.scan(/#{REGEX[:numeric]}|(#)/i).flatten.compact.uniq).size <= 1
|
71
80
|
unit = unit.join
|
72
81
|
operation = if unit == '#'
|
@@ -95,26 +104,29 @@ module Less
|
|
95
104
|
#
|
96
105
|
# Evaluate variables
|
97
106
|
#
|
98
|
-
def evaluate key,
|
99
|
-
if
|
100
|
-
|
107
|
+
def evaluate key, expression, path, node
|
108
|
+
if expression.is_a? String and expression.include? '@' # There's a var to evaluate
|
109
|
+
expression.scan /#{REGEX[:path]}#{REGEX[:variable]}/ do |var|
|
110
|
+
name = var.last
|
101
111
|
var = var.join.delete ' '
|
102
|
-
|
103
|
-
|
112
|
+
|
113
|
+
value = if var.include? '>'
|
114
|
+
@tree.find :var, var.split('>') # Try finding it in a specific namespace
|
104
115
|
else
|
105
|
-
node.var(
|
116
|
+
node.var(var) or @tree.nearest var, path # Try local first, then nearest scope
|
106
117
|
end
|
107
|
-
|
108
|
-
if
|
109
|
-
|
118
|
+
|
119
|
+
if value
|
120
|
+
# Substitute variable with value
|
121
|
+
node[ key ] = node[ key ].gsub /#{REGEX[:path]}@#{name}/, value
|
110
122
|
else
|
111
|
-
node.delete key
|
123
|
+
node.delete key # Discard the declaration if the variable wasn't found
|
112
124
|
end
|
113
125
|
end
|
114
126
|
end
|
115
127
|
end
|
116
128
|
|
117
|
-
def to_css chain
|
129
|
+
def to_css chain = :desc
|
118
130
|
self.compile.to_css chain
|
119
131
|
end
|
120
132
|
|
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; font: 12px/16px; 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,11 @@ body {
|
|
74
74
|
.operations {
|
75
75
|
@ten: 10;
|
76
76
|
@dark: #111;
|
77
|
+
@box: 100px;
|
78
|
+
@border_width: 10px;
|
79
|
+
font: 12px/16px; // 12px/16px
|
80
|
+
width: @box + @border_width; // 110px
|
81
|
+
div { width: @box - 2 * @border_width; } // 80px
|
77
82
|
border-width: .borders > @thick * 5 - 4px; // 16px
|
78
83
|
font-size: 10 - 4 + 6 * @ten; // 66
|
79
84
|
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: cloudhead-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 -07: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.2.0
|
|
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
|