railsdog-less 1.2.17
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/CHANGELOG +62 -0
- data/LICENSE +179 -0
- data/README.md +48 -0
- data/Rakefile +61 -0
- data/VERSION +1 -0
- data/bin/lessc +102 -0
- data/lib/less.rb +44 -0
- data/lib/less/command.rb +110 -0
- data/lib/less/engine.rb +54 -0
- data/lib/less/engine/grammar/common.tt +29 -0
- data/lib/less/engine/grammar/entity.tt +142 -0
- data/lib/less/engine/grammar/less.tt +338 -0
- data/lib/less/engine/nodes.rb +9 -0
- data/lib/less/engine/nodes/element.rb +281 -0
- data/lib/less/engine/nodes/entity.rb +79 -0
- data/lib/less/engine/nodes/function.rb +84 -0
- data/lib/less/engine/nodes/literal.rb +171 -0
- data/lib/less/engine/nodes/property.rb +229 -0
- data/lib/less/engine/nodes/ruleset.rb +12 -0
- data/lib/less/engine/nodes/selector.rb +44 -0
- data/lib/less/ext.rb +60 -0
- data/railsdog-less.gemspec +125 -0
- data/spec/command_spec.rb +102 -0
- data/spec/css/accessors.css +18 -0
- data/spec/css/big.css +3768 -0
- data/spec/css/colors.css +14 -0
- data/spec/css/comments.css +9 -0
- data/spec/css/css-3.css +20 -0
- data/spec/css/css.css +50 -0
- data/spec/css/functions.css +6 -0
- data/spec/css/import.css +12 -0
- data/spec/css/lazy-eval.css +1 -0
- data/spec/css/mixins-args.css +32 -0
- data/spec/css/mixins.css +28 -0
- data/spec/css/operations.css +28 -0
- data/spec/css/parens.css +20 -0
- data/spec/css/rulesets.css +17 -0
- data/spec/css/scope.css +11 -0
- data/spec/css/selectors.css +13 -0
- data/spec/css/strings.css +12 -0
- data/spec/css/variables.css +8 -0
- data/spec/css/whitespace.css +7 -0
- data/spec/engine_spec.rb +126 -0
- data/spec/less/accessors.less +20 -0
- data/spec/less/big.less +4810 -0
- data/spec/less/colors.less +35 -0
- data/spec/less/comments.less +46 -0
- data/spec/less/css-3.less +51 -0
- data/spec/less/css.less +104 -0
- data/spec/less/exceptions/mixed-units-error.less +3 -0
- data/spec/less/exceptions/name-error-1.0.less +3 -0
- data/spec/less/exceptions/syntax-error-1.0.less +3 -0
- data/spec/less/functions.less +6 -0
- data/spec/less/hidden.less +25 -0
- data/spec/less/import.less +8 -0
- data/spec/less/import/import-test-a.less +2 -0
- data/spec/less/import/import-test-b.less +8 -0
- data/spec/less/import/import-test-c.less +7 -0
- data/spec/less/import/import-test-d.css +1 -0
- data/spec/less/lazy-eval.less +6 -0
- data/spec/less/literal-css.less +11 -0
- data/spec/less/mixins-args.less +59 -0
- data/spec/less/mixins.less +43 -0
- data/spec/less/operations.less +39 -0
- data/spec/less/parens.less +26 -0
- data/spec/less/rulesets.less +30 -0
- data/spec/less/scope.less +32 -0
- data/spec/less/selectors.less +24 -0
- data/spec/less/strings.less +14 -0
- data/spec/less/variables.less +29 -0
- data/spec/less/whitespace.less +34 -0
- data/spec/spec.css +50 -0
- data/spec/spec_helper.rb +8 -0
- metadata +150 -0
data/spec/css/colors.css
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#yelow #short { color: #ffeeaa; }
|
2
|
+
#yelow #long { color: #ffeeaa; }
|
3
|
+
#yelow #rgba { color: rgba(255, 238, 170, 0.1); }
|
4
|
+
#blue #short { color: #0000ff; }
|
5
|
+
#blue #long { color: #0000ff; }
|
6
|
+
#blue #rgba { color: rgba(0, 0, 255, 0.1); }
|
7
|
+
#overflow .a { color: #000000; }
|
8
|
+
#overflow .b { color: #ffffff; }
|
9
|
+
#overflow .c { color: #ffffff; }
|
10
|
+
#overflow .d { color: #00ff00; }
|
11
|
+
#grey {
|
12
|
+
color: #c8c8c8;
|
13
|
+
background-color: #323232;
|
14
|
+
}
|
data/spec/css/css-3.css
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
.comma-delimited {
|
2
|
+
background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
|
3
|
+
text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
|
4
|
+
-moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
|
5
|
+
}
|
6
|
+
@font-face {
|
7
|
+
font-family: Headline;
|
8
|
+
src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg");
|
9
|
+
}
|
10
|
+
.other { -moz-transform: translate(0, 11em) rotate(-90deg); }
|
11
|
+
p:not([class*="lead"]) { color: black; }
|
12
|
+
input[type="text"].class#id[attr=32]:not(1) { color: white; }
|
13
|
+
div#id.class[a=1][b=2].class:not(1) { color: white; }
|
14
|
+
ul.comma > li:not(:only-child)::after { color: white; }
|
15
|
+
ol.comma > li:nth-last-child(2)::after { color: white; }
|
16
|
+
li:nth-child(4n+1) { color: white; }
|
17
|
+
li:nth-child(-5n) { color: white; }
|
18
|
+
li:nth-child(-n+2) { color: white; }
|
19
|
+
a[href^="http://"], a[href$="http://"] { color: black; }
|
20
|
+
p::before { color: black; }
|
data/spec/css/css.css
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
div { color: black; }
|
2
|
+
div { width: 99%; }
|
3
|
+
* { min-width: 45em; }
|
4
|
+
h1 { color: none; }
|
5
|
+
h2 > a > p { color: none; }
|
6
|
+
h3 { color: none; }
|
7
|
+
div.class { color: blue; }
|
8
|
+
div#id { color: green; }
|
9
|
+
.class#id { color: purple; }
|
10
|
+
.one.two.three { color: grey; }
|
11
|
+
@media print { font-size: 3em; }
|
12
|
+
@media screen { font-size: 10px; }
|
13
|
+
@font-face {
|
14
|
+
font-family: 'Garamond Pro';
|
15
|
+
src: url("/fonts/garamond-pro.ttf");
|
16
|
+
}
|
17
|
+
a:hover { color: #999999; }
|
18
|
+
a:link { color: #999999; }
|
19
|
+
p { text-transform: none; }
|
20
|
+
p:first-child { text-transform: none; }
|
21
|
+
q:lang(no) { quotes: none; }
|
22
|
+
p + h1 { font-size: 2.2em; }
|
23
|
+
input[type="text"] { font-weight: normal; }
|
24
|
+
h2[title] { font-size: 100%; }
|
25
|
+
[disabled] { color: transparent; }
|
26
|
+
#shorthands {
|
27
|
+
border: 1px solid #000000;
|
28
|
+
font: 12px/16px Arial;
|
29
|
+
margin: 1px 0;
|
30
|
+
padding: 0 auto;
|
31
|
+
background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
|
32
|
+
}
|
33
|
+
#more-shorthands {
|
34
|
+
margin: 0;
|
35
|
+
padding: 1px 0 2px 0;
|
36
|
+
font: normal small/20px 'Trebuchet MS', Verdana, sans-serif;
|
37
|
+
}
|
38
|
+
.misc {
|
39
|
+
-moz-border-radius: 2px;
|
40
|
+
display: -moz-inline-stack;
|
41
|
+
width: 0.1em;
|
42
|
+
background-color: #009998;
|
43
|
+
background-image: url(images/image.jpg);
|
44
|
+
background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
|
45
|
+
}
|
46
|
+
#important {
|
47
|
+
color: red !important;
|
48
|
+
width: 100% !important;
|
49
|
+
height: 20px ! important;
|
50
|
+
}
|
data/spec/css/import.css
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.lazy-eval { width: 100%; }
|
@@ -0,0 +1,32 @@
|
|
1
|
+
.two-args {
|
2
|
+
color: blue;
|
3
|
+
width: 10px;
|
4
|
+
height: 99%;
|
5
|
+
}
|
6
|
+
.one-arg {
|
7
|
+
width: 15px;
|
8
|
+
height: 49%;
|
9
|
+
}
|
10
|
+
.no-parens {
|
11
|
+
width: 5px;
|
12
|
+
height: 49%;
|
13
|
+
}
|
14
|
+
.no-args {
|
15
|
+
width: 5px;
|
16
|
+
height: 49%;
|
17
|
+
}
|
18
|
+
.var-args {
|
19
|
+
width: 45;
|
20
|
+
height: 17%;
|
21
|
+
}
|
22
|
+
.multi-mix {
|
23
|
+
width: 10px;
|
24
|
+
height: 29%;
|
25
|
+
margin: 4;
|
26
|
+
padding: 5;
|
27
|
+
}
|
28
|
+
body {
|
29
|
+
padding: 30px;
|
30
|
+
color: #ff0000;
|
31
|
+
}
|
32
|
+
.scope-mix { width: 8; }
|
data/spec/css/mixins.css
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
.mixin { border: 1px solid black; }
|
2
|
+
.mixout { border-color: orange; }
|
3
|
+
.borders { border-style: dashed; }
|
4
|
+
#namespace .borders { border-style: dotted; }
|
5
|
+
#namespace .biohazard { content: "death"; }
|
6
|
+
#namespace .biohazard .man { color: transparent; }
|
7
|
+
#theme > .mixin { background-color: grey; }
|
8
|
+
#container {
|
9
|
+
color: black;
|
10
|
+
border: 1px solid black;
|
11
|
+
border-color: orange;
|
12
|
+
background-color: grey;
|
13
|
+
}
|
14
|
+
#header .milk {
|
15
|
+
color: white;
|
16
|
+
border: 1px solid black;
|
17
|
+
background-color: grey;
|
18
|
+
}
|
19
|
+
#header #cookie { border-style: dashed; }
|
20
|
+
#header #cookie .chips { border-style: dotted; }
|
21
|
+
#header #cookie .chips .calories {
|
22
|
+
color: black;
|
23
|
+
border: 1px solid black;
|
24
|
+
border-color: orange;
|
25
|
+
background-color: grey;
|
26
|
+
}
|
27
|
+
.secure-zone { color: transparent; }
|
28
|
+
.direct { border-style: dotted; }
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#operations {
|
2
|
+
color: #111111;
|
3
|
+
height: 9px;
|
4
|
+
width: 3em;
|
5
|
+
}
|
6
|
+
#operations .spacing {
|
7
|
+
height: 9px;
|
8
|
+
width: 3em;
|
9
|
+
}
|
10
|
+
.with-variables {
|
11
|
+
height: 16em;
|
12
|
+
width: 24em;
|
13
|
+
size: 1cm;
|
14
|
+
}
|
15
|
+
.negative {
|
16
|
+
height: 0px;
|
17
|
+
width: 4px;
|
18
|
+
}
|
19
|
+
.shorthands { padding: -1px 2px 0 -4px; }
|
20
|
+
.colors {
|
21
|
+
color: #112233;
|
22
|
+
border-color: #334455;
|
23
|
+
background-color: #000000;
|
24
|
+
}
|
25
|
+
.colors .other {
|
26
|
+
color: #222222;
|
27
|
+
border-color: #222222;
|
28
|
+
}
|
data/spec/css/parens.css
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
.parens {
|
2
|
+
border: 2px solid black;
|
3
|
+
margin: 1px 3px 16 3;
|
4
|
+
width: 36;
|
5
|
+
padding: 2px 36px;
|
6
|
+
}
|
7
|
+
.more-parens {
|
8
|
+
padding: 8 4 4 4px;
|
9
|
+
width: 96;
|
10
|
+
height: 113;
|
11
|
+
margin: 12;
|
12
|
+
}
|
13
|
+
.nested-parens {
|
14
|
+
width: 71;
|
15
|
+
height: 6;
|
16
|
+
}
|
17
|
+
.mixed-units {
|
18
|
+
margin: 2px 4em 1 5pc;
|
19
|
+
padding: 6px 1em 2px 2;
|
20
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#first > .one { font-size: 2em; }
|
2
|
+
#first > .one > #second .two > #deux { width: 50%; }
|
3
|
+
#first > .one > #second .two > #deux #third { height: 100%; }
|
4
|
+
#first > .one > #second .two > #deux #third:focus { color: black; }
|
5
|
+
#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth { color: purple; }
|
6
|
+
#first > .one > #second .two > #deux #fourth { color: #110000; }
|
7
|
+
#first > .one > #second .two > #deux #fourth .seven { border: 1px solid black; }
|
8
|
+
#first > .one > #second .two > #deux #fourth .eight > #nine { border: 1px solid black; }
|
9
|
+
#first > .one > #second .two > #deux #fourth #ten { color: red; }
|
10
|
+
#first > .one > #second .two > #deux #five { color: #110000; }
|
11
|
+
#first > .one > #second .two > #deux #five .seven { border: 1px solid black; }
|
12
|
+
#first > .one > #second .two > #deux #five .eight > #nine { border: 1px solid black; }
|
13
|
+
#first > .one > #second .two > #deux #five #ten { color: red; }
|
14
|
+
#first > .one > #second .two > #deux #six { color: #110000; }
|
15
|
+
#first > .one > #second .two > #deux #six .seven { border: 1px solid black; }
|
16
|
+
#first > .one > #second .two > #deux #six .eight > #nine { border: 1px solid black; }
|
17
|
+
#first > .one > #second .two > #deux #six #ten { color: red; }
|
data/spec/css/scope.css
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
h1 a:hover { color: red; }
|
2
|
+
h1 p:hover { color: red; }
|
3
|
+
h2 a:hover { color: red; }
|
4
|
+
h2 p:hover { color: red; }
|
5
|
+
h3 a:hover { color: red; }
|
6
|
+
h3 p:hover { color: red; }
|
7
|
+
#all, #the, #same { color: blue; }
|
8
|
+
ul, li, div, q, blockquote, textarea { margin: 0; }
|
9
|
+
td {
|
10
|
+
margin: 0;
|
11
|
+
padding: 0;
|
12
|
+
}
|
13
|
+
td, input { line-height: 1em; }
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#strings {
|
2
|
+
background-image: url("http://son-of-a-banana.com");
|
3
|
+
quotes: "~" "~";
|
4
|
+
content: "#*%:&^,)!.(~*})";
|
5
|
+
empty: "";
|
6
|
+
}
|
7
|
+
#comments { content: "/* hello */ // not-so-secret"; }
|
8
|
+
#single-quote {
|
9
|
+
quotes: "'" "'";
|
10
|
+
content: '""#!&""';
|
11
|
+
empty: '';
|
12
|
+
}
|
data/spec/engine_spec.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
|
3
|
+
module LessEngineSpecHelper
|
4
|
+
def lessify arg
|
5
|
+
if arg.is_a? String or arg.is_a? File
|
6
|
+
return Less::Engine.new(arg).to_css
|
7
|
+
else
|
8
|
+
lessify File.new("spec/less/#{arg.to_s.gsub('_', '-')}.less")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def css file
|
13
|
+
File.read("spec/css/#{file.to_s.gsub('_', '-')}.css")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Less::Engine do
|
18
|
+
include LessEngineSpecHelper
|
19
|
+
|
20
|
+
describe "to_css" do
|
21
|
+
it "should parse css" do
|
22
|
+
lessify(:css).should == css(:css)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should group selectors when it can" do
|
26
|
+
lessify(:selectors).should == css(:selectors)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should parse css 3" do
|
30
|
+
lessify(:css_3).should == css(:css_3)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should parse comments" do
|
34
|
+
lessify(:comments).should == css(:comments)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should deal with whitespace" do
|
38
|
+
lessify(:whitespace).should == css(:whitespace)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should parse nested rules" do
|
42
|
+
lessify(:rulesets).should == css(:rulesets)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should parse variables" do
|
46
|
+
lessify(:variables).should == css(:variables)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should parse operations" do
|
50
|
+
lessify(:operations).should == css(:operations)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should manage scope" do
|
54
|
+
lessify(:scope).should == css(:scope)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should parse parens" do
|
58
|
+
lessify(:parens).should == css(:parens)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should parse strings" do
|
62
|
+
lessify(:strings).should == css(:strings)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should parse accessors" do
|
66
|
+
lessify(:accessors).should == css(:accessors)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should parse colors in hex" do
|
70
|
+
lessify(:colors).should == css(:colors)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should parse mixins" do
|
74
|
+
lessify(:mixins).should == css(:mixins)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should parse mixins with arguments" do
|
78
|
+
lessify(:mixins_args).should == css(:mixins_args)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should evaluate variables lazily" do
|
82
|
+
lessify(:lazy_eval).should == css(:lazy_eval)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should handle custom functions" do
|
86
|
+
module Less::Functions
|
87
|
+
def color args
|
88
|
+
arg = args.first
|
89
|
+
Less::Node::Color.new("99", "99", "99") if arg == "evil red"
|
90
|
+
end
|
91
|
+
|
92
|
+
def increment a
|
93
|
+
Less::Node::Number.new(a.evaluate.to_i + 1)
|
94
|
+
end
|
95
|
+
|
96
|
+
def add a, b
|
97
|
+
Less::Node::Number.new(a.evaluate + b.evaluate)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
lessify(:functions).should == css(:functions)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should work with import" do
|
104
|
+
lessify(:import).should == css(:import)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should work tih import using extra paths" do
|
108
|
+
lambda {
|
109
|
+
lessify(:import_with_extra_paths).should == css(:import_with_extra_paths)
|
110
|
+
}.should raise_error(Less::ImportError)
|
111
|
+
# finding a partial in another location
|
112
|
+
Less.source_paths = ["spec/less/extra_import_path"]
|
113
|
+
lessify(:import_with_extra_paths).should == css(:import_with_extra_paths)
|
114
|
+
# overriding a partial in another location so this takes priority over the same named partial in the same directory
|
115
|
+
puts '-'
|
116
|
+
puts '-'
|
117
|
+
puts '-'*100
|
118
|
+
lessify(:import).should == css(:import_with_partial_in_extra_path)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should parse a big file"
|
122
|
+
it "should handle complex color operations"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
|