lesslateral 1.2.21
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/.gitignore +4 -0
- data/CHANGELOG +62 -0
- data/LICENSE +179 -0
- data/README.md +48 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/bin/lessc +103 -0
- data/less.gemspec +134 -0
- data/lib/less.rb +36 -0
- data/lib/less/command.rb +108 -0
- data/lib/less/engine.rb +52 -0
- data/lib/less/engine/grammar/common.tt +29 -0
- data/lib/less/engine/grammar/entity.tt +144 -0
- data/lib/less/engine/grammar/less.tt +341 -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 +93 -0
- data/lib/less/engine/nodes/literal.rb +171 -0
- data/lib/less/engine/nodes/property.rb +232 -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/lib/less/notification.rb +59 -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 +21 -0
- data/spec/css/css.css +50 -0
- data/spec/css/dash-prefix.css +12 -0
- data/spec/css/functions.css +6 -0
- data/spec/css/import-with-extra-paths.css +8 -0
- data/spec/css/import-with-partial-in-extra-path.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 +127 -0
- data/spec/less/accessors.less +20 -0
- data/spec/less/big.less +1264 -0
- data/spec/less/colors.less +35 -0
- data/spec/less/comments.less +46 -0
- data/spec/less/css-3.less +52 -0
- data/spec/less/css.less +104 -0
- data/spec/less/dash-prefix.less +21 -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/extra_import_path/extra.less +1 -0
- data/spec/less/extra_import_path/import/import-test-a.css +1 -0
- data/spec/less/extra_import_path/import/import-test-a.less +4 -0
- data/spec/less/functions.less +6 -0
- data/spec/less/hidden.less +25 -0
- data/spec/less/import-with-extra-paths.less +4 -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 +159 -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,21 @@
|
|
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+1) { color: white; }
|
19
|
+
li:nth-child(-n+2) { color: white; }
|
20
|
+
a[href^="http://"], a[href$="http://"] { color: black; }
|
21
|
+
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
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
.test1 {
|
2
|
+
background-image: -moz-linear-gradient(top, bottom, from(#030303), to(#010101));
|
3
|
+
background-image: -webkit-gradient(linear, left top, left bottom, from(#030303), to(#010101));
|
4
|
+
}
|
5
|
+
.test2 {
|
6
|
+
background-image: -moz-linear-gradient(top, bottom, from(#020202), to(#010101));
|
7
|
+
background-image: -webkit-gradient(linear, left top, left bottom, from(#020202), to(#010101));
|
8
|
+
}
|
9
|
+
.test3 {
|
10
|
+
background-image: -moz-linear-gradient(top, bottom, from(red), to(green));
|
11
|
+
background-image: -webkit-gradient(linear, left top, left bottom, from(red), to(green));
|
12
|
+
}
|
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,127 @@
|
|
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 handle properties prefixed with a dash" do
|
34
|
+
lessify(:dash_prefix).should == css(:dash_prefix)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should parse comments" do
|
38
|
+
lessify(:comments).should == css(:comments)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should deal with whitespace" do
|
42
|
+
lessify(:whitespace).should == css(:whitespace)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should parse nested rules" do
|
46
|
+
lessify(:rulesets).should == css(:rulesets)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should parse variables" do
|
50
|
+
lessify(:variables).should == css(:variables)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should parse operations" do
|
54
|
+
lessify(:operations).should == css(:operations)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should manage scope" do
|
58
|
+
lessify(:scope).should == css(:scope)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should parse parens" do
|
62
|
+
lessify(:parens).should == css(:parens)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should parse strings" do
|
66
|
+
lessify(:strings).should == css(:strings)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should parse accessors" do
|
70
|
+
lessify(:accessors).should == css(:accessors)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should parse colors in hex" do
|
74
|
+
lessify(:colors).should == css(:colors)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should parse mixins" do
|
78
|
+
lessify(:mixins).should == css(:mixins)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should parse mixins with arguments" do
|
82
|
+
lessify(:mixins_args).should == css(:mixins_args)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should evaluate variables lazily" do
|
86
|
+
lessify(:lazy_eval).should == css(:lazy_eval)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should handle custom functions" do
|
90
|
+
module Less::Functions
|
91
|
+
def color args
|
92
|
+
arg = args.first
|
93
|
+
Less::Node::Color.new("99", "99", "99") if arg == "evil red"
|
94
|
+
end
|
95
|
+
|
96
|
+
def increment a
|
97
|
+
Less::Node::Number.new(a.evaluate.to_i + 1)
|
98
|
+
end
|
99
|
+
|
100
|
+
def add a, b
|
101
|
+
Less::Node::Number.new(a.evaluate + b.evaluate)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
lessify(:functions).should == css(:functions)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should work with import" do
|
108
|
+
lessify(:import).should == css(:import)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should work tih import using extra paths" do
|
112
|
+
lambda {
|
113
|
+
lessify(:import_with_extra_paths).should == css(:import_with_extra_paths)
|
114
|
+
}.should raise_error(Less::ImportError)
|
115
|
+
# finding a partial in another location
|
116
|
+
$LESS_LOAD_PATH = ["spec/less/extra_import_path"]
|
117
|
+
lessify(:import_with_extra_paths).should == css(:import_with_extra_paths)
|
118
|
+
# overriding a partial in another location so this takes priority over the same named partial in the same directory
|
119
|
+
lessify(:import).should == css(:import_with_partial_in_extra_path)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should parse a big file"
|
123
|
+
it "should handle complex color operations"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|