line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
2
|
|
|
|
|
|
|
package CSS::LESSp; |
3
|
|
|
|
|
|
|
|
4
|
2
|
|
|
2
|
|
79586
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
65
|
|
5
|
2
|
|
|
2
|
|
10
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
74
|
|
6
|
2
|
|
|
2
|
|
9
|
use Exporter; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
15194
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
9
|
|
|
|
|
|
|
our @EXPORT_OK = qw('parse'); |
10
|
|
|
|
|
|
|
our $VERSION = '0.86'; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
my $id = 1; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# |
15
|
|
|
|
|
|
|
# specs check |
16
|
|
|
|
|
|
|
# |
17
|
|
|
|
|
|
|
# accessors.less ( ok ) |
18
|
|
|
|
|
|
|
# big.less ( ok ) |
19
|
|
|
|
|
|
|
# colors.less ( ok ) exceptions : no hsl |
20
|
|
|
|
|
|
|
# comments.less ( ok ) |
21
|
|
|
|
|
|
|
# css-3.less ( ok ) |
22
|
|
|
|
|
|
|
# css.less ( ok ) |
23
|
|
|
|
|
|
|
# dash-prefix.less ( ok ) |
24
|
|
|
|
|
|
|
# functions.less ( unsupported ) |
25
|
|
|
|
|
|
|
# hidden.less ( unsupported ) |
26
|
|
|
|
|
|
|
# import-with-extra-paths.less ( unsupported ) |
27
|
|
|
|
|
|
|
# import.less ( unsupported ) |
28
|
|
|
|
|
|
|
# lazy-eval.less ( unsupported ) |
29
|
|
|
|
|
|
|
# literal-css.less ( unsupported ) |
30
|
|
|
|
|
|
|
# mixins-args.less ( ok ) |
31
|
|
|
|
|
|
|
# mixins.less ( ok ) |
32
|
|
|
|
|
|
|
# operations.less ( ok ) |
33
|
|
|
|
|
|
|
# parens.less ( ok ) |
34
|
|
|
|
|
|
|
# rulesets.less ( ok ) |
35
|
|
|
|
|
|
|
# scope.less ( ok ) |
36
|
|
|
|
|
|
|
# selectors.less ( ok ) |
37
|
|
|
|
|
|
|
# strings.less ( ok ) |
38
|
|
|
|
|
|
|
# variables.less ( ok ) |
39
|
|
|
|
|
|
|
# whitespace.less ( ok ) exceptions : doesn't merge same lines |
40
|
|
|
|
|
|
|
# |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub new { |
43
|
3
|
|
|
3
|
1
|
7
|
my $class = shift; |
44
|
3
|
|
|
|
|
19
|
my $self = { |
45
|
|
|
|
|
|
|
'variables' => {}, |
46
|
|
|
|
|
|
|
'rules' => [], |
47
|
|
|
|
|
|
|
'type' => 'child', |
48
|
|
|
|
|
|
|
'children' => [] |
49
|
|
|
|
|
|
|
}; |
50
|
3
|
|
|
|
|
8
|
bless $self, $class; |
51
|
3
|
|
|
|
|
6
|
return $self; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub isFunction { |
55
|
57
|
|
|
57
|
1
|
78
|
my ($self) = @_; |
56
|
57
|
50
|
|
|
|
148
|
if ( $self->{'type'} eq 'function' ) { return 1; } |
|
0
|
|
|
|
|
0
|
|
57
|
57
|
|
|
|
|
153
|
return 0; |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub insertChild { |
61
|
37
|
|
|
37
|
1
|
71
|
my ($self, $name, $parents) = @_; |
62
|
37
|
50
|
|
|
|
77
|
my @parents = @{$parents} if $parents; |
|
37
|
|
|
|
|
85
|
|
63
|
37
|
|
|
|
|
57
|
$id++; |
64
|
37
|
100
|
|
|
|
109
|
$self->{'children'} = [] if !defined($self->{'children'}); |
65
|
|
|
|
|
|
|
|
66
|
37
|
|
|
|
|
57
|
$name =~ s/\n/ /mg; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# |
69
|
|
|
|
|
|
|
# Find the full name |
70
|
37
|
|
|
|
|
44
|
my $fullName = $name; |
71
|
37
|
100
|
|
|
|
85
|
if ( defined($self->{'id'}) ) { |
72
|
2
|
50
|
|
|
|
8
|
my @names = $name =~ /\,/ ? split(/\s*\,\s*/, $name) : ( $name ); |
73
|
2
|
|
|
|
|
4
|
for my $parent ( reverse @parents ) { |
74
|
6
|
100
|
|
|
|
25
|
next if !defined($parent->{'name'}); |
75
|
2
|
50
|
|
|
|
7
|
my @prenames = $parent->{'name'} =~ /\,/ ? split(/\s*\,\s*/, $parent->{'name'}) : ($parent->{'name'}); |
76
|
2
|
|
|
|
|
4
|
my @postnames = (); |
77
|
2
|
|
|
|
|
3
|
for my $prename ( @prenames ) { |
78
|
2
|
|
|
|
|
4
|
for my $name ( @names ) { |
79
|
2
|
50
|
|
|
|
12
|
push @postnames, $prename.( $name =~ /^\:/ ? "" : " " ).$name; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
} |
82
|
2
|
|
|
|
|
4
|
@names = @postnames; |
83
|
2
|
|
|
|
|
5
|
$fullName = join(", ", @names); |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
37
|
|
|
|
|
42
|
push @{$self->{'children'}}, { |
|
37
|
|
|
|
|
246
|
|
88
|
|
|
|
|
|
|
'name' => $name, |
89
|
|
|
|
|
|
|
'fullname' => $fullName, |
90
|
|
|
|
|
|
|
'type' => 'child', |
91
|
|
|
|
|
|
|
'id' => $id, |
92
|
|
|
|
|
|
|
'variables' => {} |
93
|
|
|
|
|
|
|
}; |
94
|
37
|
|
|
|
|
69
|
return bless $self->{'children'}->[$#{$self->{'children'}}]; |
|
37
|
|
|
|
|
154
|
|
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub insertVariable { |
98
|
0
|
|
|
0
|
1
|
0
|
my ($self, $variable, $value) = @_; |
99
|
|
|
|
|
|
|
|
100
|
0
|
0
|
|
|
|
0
|
if ( $self->isFunction ) { |
101
|
0
|
|
|
|
|
0
|
push @{$self->{'variables'}}, { $variable => $value }; |
|
0
|
|
|
|
|
0
|
|
102
|
|
|
|
|
|
|
} else { |
103
|
0
|
|
|
|
|
0
|
$self->{'variables'}->{$variable} = $value; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
0
|
|
|
|
|
0
|
return $self; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub insertRule { |
110
|
57
|
|
|
57
|
1
|
98
|
my ($self, $property, $value) = @_; |
111
|
|
|
|
|
|
|
|
112
|
57
|
100
|
|
|
|
210
|
$self->{'rules'} = [] if !defined($self->{'rules'}); |
113
|
|
|
|
|
|
|
|
114
|
57
|
|
|
|
|
554
|
push @{$self->{'rules'}}, { $property => $value }; |
|
57
|
|
|
|
|
238
|
|
115
|
|
|
|
|
|
|
|
116
|
57
|
|
|
|
|
241
|
return $self; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub insertFunction { |
120
|
0
|
|
|
0
|
1
|
0
|
my ($self, $name, $parents) = @_; |
121
|
0
|
0
|
|
|
|
0
|
my @parents = @{$parents} if $parents; |
|
0
|
|
|
|
|
0
|
|
122
|
|
|
|
|
|
|
#my @variables = @{$variables} if $variables; |
123
|
|
|
|
|
|
|
|
124
|
0
|
|
|
|
|
0
|
$name =~ s/\n/ /mg; |
125
|
0
|
0
|
|
|
|
0
|
$self->{'functions'} = [] if !defined($self->{'functions'}); |
126
|
|
|
|
|
|
|
|
127
|
0
|
|
|
|
|
0
|
push @{$self->{'functions'}}, { |
|
0
|
|
|
|
|
0
|
|
128
|
|
|
|
|
|
|
'name' => $name, |
129
|
|
|
|
|
|
|
'type' => 'function', |
130
|
|
|
|
|
|
|
'variables' => [] |
131
|
|
|
|
|
|
|
}; |
132
|
0
|
|
|
|
|
0
|
return bless $self->{'functions'}->[$#{$self->{'functions'}}]; |
|
0
|
|
|
|
|
0
|
|
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub getVariable { |
136
|
0
|
|
|
0
|
1
|
0
|
my ($self, $variable, $parents) = @_; |
137
|
0
|
0
|
|
|
|
0
|
my @parents = @{$parents} if $parents; |
|
0
|
|
|
|
|
0
|
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# |
140
|
|
|
|
|
|
|
# First try to see if the variable is here |
141
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'variables'}->{$variable}) ) { |
142
|
0
|
|
|
|
|
0
|
return $self->{'variables'}->{$variable}; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
# |
146
|
|
|
|
|
|
|
# If we have parents parse them too |
147
|
0
|
|
|
|
|
0
|
for my $parent ( reverse @parents ) { |
148
|
0
|
0
|
|
|
|
0
|
return $parent->{'variables'}->{$variable} if defined($parent->{'variables'}->{$variable}); |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
0
|
return 0; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub getSelector { |
155
|
0
|
|
|
0
|
1
|
0
|
my ($self, $name, $parents) = @_; |
156
|
0
|
0
|
|
|
|
0
|
my @parents = @{$parents} if $parents; |
|
0
|
|
|
|
|
0
|
|
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# |
159
|
|
|
|
|
|
|
# First try to see if it's a previous sibling |
160
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'children'}) ) { |
161
|
0
|
|
|
|
|
0
|
for my $style ( @{$self->{'children'}} ) { |
|
0
|
|
|
|
|
0
|
|
162
|
0
|
0
|
|
|
|
0
|
return $style if ($style->{'name'} eq $name); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# |
167
|
|
|
|
|
|
|
# Next try to find from parents |
168
|
0
|
|
|
|
|
0
|
for my $parent ( reverse @parents ) { |
169
|
0
|
|
|
|
|
0
|
for my $style ( @{$parent->{'children'}} ) { |
|
0
|
|
|
|
|
0
|
|
170
|
0
|
0
|
|
|
|
0
|
return $style if ($style->{'name'} eq $name); |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# |
175
|
|
|
|
|
|
|
# Last we start search of everything if it is root |
176
|
0
|
0
|
|
|
|
0
|
my $root = $parents[0] if !defined($parents[0]->{'id'}); |
177
|
0
|
0
|
|
|
|
0
|
if ( defined($root->{'children'}) ) { |
178
|
0
|
|
|
|
|
0
|
my $return; |
179
|
|
|
|
|
|
|
my $fullNameSelector; |
180
|
|
|
|
|
|
|
$root->process(sub { |
181
|
0
|
|
|
0
|
|
0
|
my ($style) = @_; |
182
|
0
|
0
|
0
|
|
|
0
|
if ( defined($style->{'name'}) and $style->{'name'} eq $name ) { |
183
|
0
|
|
|
|
|
0
|
$return = $style; |
184
|
|
|
|
|
|
|
} |
185
|
0
|
0
|
0
|
|
|
0
|
if ( defined($style->{'fullname'}) and $style->{'fullname'} eq $name ) { |
186
|
0
|
|
|
|
|
0
|
$fullNameSelector = $style; |
187
|
|
|
|
|
|
|
} |
188
|
0
|
|
|
|
|
0
|
}); |
189
|
0
|
0
|
|
|
|
0
|
return $return if $return; |
190
|
0
|
0
|
|
|
|
0
|
return $fullNameSelector if $fullNameSelector; |
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
# |
194
|
|
|
|
|
|
|
# If we can't find ... then try for functions the same way |
195
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'functions'}) ) { |
196
|
0
|
|
|
|
|
0
|
for my $function ( @{$self->{'functions'}} ) { |
|
0
|
|
|
|
|
0
|
|
197
|
0
|
0
|
|
|
|
0
|
return $function if ($function->{'name'} eq $name); |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
} |
200
|
0
|
|
|
|
|
0
|
for my $parent ( reverse @parents ) { |
201
|
0
|
0
|
|
|
|
0
|
if ( defined($parent->{'functions'}) ) { |
202
|
0
|
|
|
|
|
0
|
for my $function ( @{$parent->{'functions'}} ) { |
|
0
|
|
|
|
|
0
|
|
203
|
0
|
0
|
|
|
|
0
|
return $function if ($function->{'name'} eq $name); |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
} |
207
|
0
|
0
|
|
|
|
0
|
if ( defined($root->{'children'}) ) { |
208
|
0
|
|
|
|
|
0
|
my $return; |
209
|
|
|
|
|
|
|
my $fullNameSelector; |
210
|
|
|
|
|
|
|
$root->process(sub { |
211
|
0
|
|
|
0
|
|
0
|
my ($style) = @_; |
212
|
0
|
0
|
|
|
|
0
|
if ( defined($style->{'functions'}) ) { |
213
|
0
|
|
|
|
|
0
|
for my $function ( @{$style->{'functions'}} ) { |
|
0
|
|
|
|
|
0
|
|
214
|
0
|
0
|
0
|
|
|
0
|
if ( defined($function->{'name'}) and $function->{'name'} eq $name ) { |
215
|
0
|
|
|
|
|
0
|
$return = $function; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
} |
219
|
0
|
|
|
|
|
0
|
}); |
220
|
0
|
0
|
|
|
|
0
|
return $return if $return; |
221
|
0
|
0
|
|
|
|
0
|
return $fullNameSelector if $fullNameSelector; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
0
|
|
|
|
|
0
|
return 0; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
sub getValue { |
228
|
0
|
|
|
0
|
1
|
0
|
my ($self, $property) = @_; |
229
|
0
|
|
|
|
|
0
|
my $value; |
230
|
|
|
|
|
|
|
|
231
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'rules'}) ) { |
232
|
0
|
|
|
|
|
0
|
for my $rule ( @{$self->{'rules'}} ) { |
|
0
|
|
|
|
|
0
|
|
233
|
0
|
0
|
|
|
|
0
|
$value = join('', values %{$rule}) if join('', keys %{$rule}) eq $property; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
0
|
|
|
|
|
0
|
return $value; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
sub process { |
241
|
3
|
|
|
3
|
1
|
5
|
my ($styles, $function) = @_; |
242
|
|
|
|
|
|
|
|
243
|
3
|
|
|
|
|
5
|
my @parents = (); |
244
|
3
|
|
|
|
|
7
|
push @parents, $styles->{'children'}; |
245
|
3
|
|
|
|
|
13
|
$styles = $styles->{'children'}; |
246
|
3
|
|
|
|
|
5
|
my $level = 0; |
247
|
3
|
|
|
|
|
5
|
push my @position, 0; |
248
|
|
|
|
|
|
|
|
249
|
3
|
|
|
|
|
4
|
while ( 1 ) { |
250
|
37
|
|
|
|
|
54
|
my $style = $styles->[$position[$level]]; |
251
|
37
|
|
|
|
|
87
|
&$function($style, $level, (\@parents, \@position)); |
252
|
37
|
100
|
|
|
|
81
|
if ( defined($style->{'children'}) ) { |
253
|
1
|
|
|
|
|
32
|
$level++; |
254
|
1
|
|
|
|
|
3
|
$position[$level] = 0; |
255
|
1
|
|
|
|
|
2
|
push @parents, $styles; |
256
|
1
|
|
|
|
|
3
|
$styles = $style->{'children'}; |
257
|
|
|
|
|
|
|
} else { |
258
|
36
|
|
|
|
|
47
|
while ( $position[$level] == $#{$styles} ) { |
|
37
|
|
|
|
|
99
|
|
259
|
4
|
100
|
|
|
|
15
|
return 1 if $level == 0; |
260
|
1
|
|
|
|
|
3
|
$styles = pop @parents; |
261
|
1
|
|
|
|
|
4
|
$level--; |
262
|
|
|
|
|
|
|
} |
263
|
33
|
|
|
|
|
53
|
$position[$level]++; |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
} |
266
|
0
|
|
|
|
|
0
|
return 0; |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
sub copyTo { |
270
|
0
|
|
|
0
|
1
|
0
|
my ($self, $targetSelector) = @_; |
271
|
0
|
|
|
|
|
0
|
my ($rules, $children, $variables); |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
# copy rules |
274
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'rules'}) ) { |
275
|
0
|
0
|
|
|
|
0
|
$targetSelector->{'rules'} = [] if !defined($targetSelector->{'rules'}); |
276
|
0
|
|
|
|
|
0
|
for my $rule ( @{$self->{'rules'}} ) { |
|
0
|
|
|
|
|
0
|
|
277
|
0
|
|
|
|
|
0
|
push @{$targetSelector->{'rules'}}, {%{$rule}}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
# copy variables |
282
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'variables'}) ) { |
283
|
0
|
|
|
|
|
0
|
for my $variable ( keys %{$self->{'variables'}} ) { |
|
0
|
|
|
|
|
0
|
|
284
|
0
|
|
|
|
|
0
|
$targetSelector->{'variables'}->{$variable} = $variables->{$variable}; |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
# copy children |
289
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'children'}) ) { |
290
|
0
|
|
|
|
|
0
|
my @targets = (); |
291
|
0
|
|
|
|
|
0
|
push @targets, $targetSelector; |
292
|
0
|
|
|
|
|
0
|
my $target = $targetSelector; |
293
|
0
|
|
|
|
|
0
|
my $l = 0; |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
$self->process(sub { |
296
|
0
|
|
|
0
|
|
0
|
my ($style, $level) = @_; |
297
|
0
|
|
|
|
|
0
|
$target = $target->insertChild($style->{'name'}, \@targets); |
298
|
|
|
|
|
|
|
# |
299
|
|
|
|
|
|
|
# adding variables |
300
|
0
|
0
|
|
|
|
0
|
if ( defined($style->{'variables'}) ) { |
301
|
0
|
|
|
|
|
0
|
for my $variable ( keys %{$style->{'variables'}} ) { |
|
0
|
|
|
|
|
0
|
|
302
|
0
|
|
|
|
|
0
|
$target->insertVariable($variable, $style->{'variables'}->{$variable}); |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
# |
306
|
|
|
|
|
|
|
# adding rules |
307
|
0
|
0
|
|
|
|
0
|
if ( defined($style->{'rules'}) ) { |
308
|
0
|
|
|
|
|
0
|
for my $rule ( @{$style->{'rules'}} ) { |
|
0
|
|
|
|
|
0
|
|
309
|
0
|
|
|
|
|
0
|
my $property = join("", keys %{$rule}); |
|
0
|
|
|
|
|
0
|
|
310
|
0
|
|
|
|
|
0
|
my $value = join("", values %{$rule}); |
|
0
|
|
|
|
|
0
|
|
311
|
0
|
|
|
|
|
0
|
$target->insertRule($property, $value); |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
# |
315
|
|
|
|
|
|
|
# children leveling |
316
|
0
|
0
|
|
|
|
0
|
if ( defined($style->{'children'}) ) { |
317
|
0
|
|
|
|
|
0
|
push @targets, $target; |
318
|
|
|
|
|
|
|
} else { |
319
|
0
|
0
|
|
|
|
0
|
if ( $l != $level ) { |
320
|
0
|
|
|
|
|
0
|
$l = $level; |
321
|
0
|
|
|
|
|
0
|
$target = pop @targets; |
322
|
|
|
|
|
|
|
} |
323
|
|
|
|
|
|
|
} |
324
|
0
|
|
|
|
|
0
|
}); |
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
|
327
|
0
|
|
|
|
|
0
|
return 0; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
sub copyFunction { |
331
|
0
|
|
|
0
|
1
|
0
|
my ($self, $targetSelector, $variables, $parents) = @_; |
332
|
0
|
|
|
|
|
0
|
my ($rules, $children); |
333
|
0
|
|
|
|
|
0
|
my @variables = @{$variables}; |
|
0
|
|
|
|
|
0
|
|
334
|
0
|
|
|
|
|
0
|
my @parents = @{$parents}; |
|
0
|
|
|
|
|
0
|
|
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
# copy vars |
337
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'variables'}) ) { |
338
|
0
|
|
|
|
|
0
|
for ( my $position = 0; $position <= $#{$self->{'variables'}}; $position++ ) { |
|
0
|
|
|
|
|
0
|
|
339
|
0
|
|
|
|
|
0
|
my $variable = join("",keys %{$self->{'variables'}->[$position]}); |
|
0
|
|
|
|
|
0
|
|
340
|
0
|
|
|
|
|
0
|
my $value = join("", values %{$self->{'variables'}->[$position]}); |
|
0
|
|
|
|
|
0
|
|
341
|
0
|
0
|
|
|
|
0
|
$value = $variables[$position] if $variables[$position]; |
342
|
0
|
|
|
|
|
0
|
$targetSelector->{'variables'}->{$variable} = $value; |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
# copy rules |
347
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'rules'}) ) { |
348
|
0
|
0
|
|
|
|
0
|
$targetSelector->{'rules'} = [] if !defined($targetSelector->{'rules'}); |
349
|
0
|
|
|
|
|
0
|
for my $rule ( @{$self->{'rules'}} ) { |
|
0
|
|
|
|
|
0
|
|
350
|
0
|
|
|
|
|
0
|
my $property = join("", keys %{$rule}); |
|
0
|
|
|
|
|
0
|
|
351
|
0
|
|
|
|
|
0
|
my $value = join("", values %{$rule}); |
|
0
|
|
|
|
|
0
|
|
352
|
0
|
|
|
|
|
0
|
while ( $value =~ /\@(\w+\-*\w*)/ ) { |
353
|
0
|
|
|
|
|
0
|
my $word = $1; |
354
|
|
|
|
|
|
|
# get the variable |
355
|
0
|
|
|
|
|
0
|
my $var = $targetSelector->getVariable($word, \@parents); |
356
|
0
|
|
|
|
|
0
|
$value =~ s/\@$word/$var/; |
357
|
|
|
|
|
|
|
# if variable value is negative |
358
|
0
|
0
|
|
|
|
0
|
if ( $var =~ s/^\-// ) { |
359
|
0
|
|
|
|
|
0
|
$value =~ s/\-\s*\-$var/\+ $var/g; |
360
|
0
|
|
|
|
|
0
|
$value =~ s/\+\s*\-$var/\- $var/g; |
361
|
|
|
|
|
|
|
} |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
# parse for other stuff |
364
|
0
|
|
|
|
|
0
|
$value = _parse_value($value); |
365
|
0
|
|
|
|
|
0
|
push @{$targetSelector->{'rules'}}, {$property => $value}; |
|
0
|
|
|
|
|
0
|
|
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
# copy children |
370
|
0
|
0
|
|
|
|
0
|
if ( defined($self->{'children'}) ) { |
371
|
0
|
|
|
|
|
0
|
my @targets = (); |
372
|
0
|
|
|
|
|
0
|
push @targets, $targetSelector; |
373
|
0
|
|
|
|
|
0
|
my $target = $targetSelector; |
374
|
0
|
|
|
|
|
0
|
my $l = 0; |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
$self->process(sub { |
377
|
0
|
|
|
0
|
|
0
|
my ($style, $level) = @_; |
378
|
0
|
|
|
|
|
0
|
$target = $target->insertChild($style->{'name'}); |
379
|
|
|
|
|
|
|
# |
380
|
|
|
|
|
|
|
# adding variables |
381
|
0
|
0
|
|
|
|
0
|
if ( defined($style->{'variables'}) ) { |
382
|
0
|
|
|
|
|
0
|
for my $variable ( keys %{$style->{'variables'}} ) { |
|
0
|
|
|
|
|
0
|
|
383
|
0
|
|
|
|
|
0
|
$target->insertVariable($variable, $style->{'variables'}->{$variable}); |
384
|
|
|
|
|
|
|
} |
385
|
|
|
|
|
|
|
} |
386
|
|
|
|
|
|
|
# |
387
|
|
|
|
|
|
|
# adding rules |
388
|
0
|
0
|
|
|
|
0
|
if ( defined($style->{'rules'}) ) { |
389
|
0
|
|
|
|
|
0
|
for my $rule ( @{$style->{'rules'}} ) { |
|
0
|
|
|
|
|
0
|
|
390
|
0
|
|
|
|
|
0
|
my $property = join("", keys %{$rule}); |
|
0
|
|
|
|
|
0
|
|
391
|
0
|
|
|
|
|
0
|
my $value = join("", values %{$rule}); |
|
0
|
|
|
|
|
0
|
|
392
|
0
|
|
|
|
|
0
|
$target->insertRule($property, $value); |
393
|
|
|
|
|
|
|
} |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
# |
396
|
|
|
|
|
|
|
# children leveling |
397
|
0
|
0
|
|
|
|
0
|
if ( defined($style->{'children'}) ) { |
398
|
0
|
|
|
|
|
0
|
push @targets, $target; |
399
|
|
|
|
|
|
|
} else { |
400
|
0
|
0
|
|
|
|
0
|
if ( $l != $level ) { |
401
|
0
|
|
|
|
|
0
|
$l = $level; |
402
|
0
|
|
|
|
|
0
|
$target = pop @targets; |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
} |
405
|
0
|
|
|
|
|
0
|
}); |
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
|
408
|
0
|
|
|
|
|
0
|
return 0; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
sub dump { |
412
|
3
|
|
|
3
|
1
|
6
|
my ($self) = @_; |
413
|
3
|
|
|
|
|
7
|
my @return = (); |
414
|
|
|
|
|
|
|
|
415
|
3
|
50
|
|
|
|
11
|
if ( defined($self->{'rules'}) ) { |
416
|
3
|
|
|
|
|
5
|
for my $rule ( @{$self->{'rules'}} ) { |
|
3
|
|
|
|
|
9
|
|
417
|
0
|
|
|
|
|
0
|
push @return, join('', keys %{$rule}).join('', values %{$rule}).";\n"; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
418
|
|
|
|
|
|
|
} |
419
|
3
|
|
|
|
|
6
|
push @return, "\n"; |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
$self->process(sub { |
423
|
37
|
|
|
37
|
|
69
|
my ($style, $level, @arrays) = @_; |
424
|
37
|
|
|
|
|
38
|
my @parents = @{$arrays[0]}; |
|
37
|
|
|
|
|
64
|
|
425
|
37
|
|
|
|
|
50
|
my @position = @{$arrays[1]}; |
|
37
|
|
|
|
|
54
|
|
426
|
37
|
50
|
|
|
|
104
|
if ( defined($style->{'rules'}) ) { |
427
|
37
|
|
|
|
|
92
|
push @return, $style->{'fullname'} ." { "; |
428
|
37
|
100
|
|
|
|
37
|
push @return, "\n" if $#{$style->{'rules'}} > 0; |
|
37
|
|
|
|
|
97
|
|
429
|
37
|
|
|
|
|
48
|
for my $rule ( @{$style->{'rules'}} ) { |
|
37
|
|
|
|
|
66
|
|
430
|
57
|
100
|
|
|
|
59
|
push @return, "\t" if $#{$style->{'rules'}} > 0; |
|
57
|
|
|
|
|
454
|
|
431
|
57
|
|
|
|
|
68
|
push @return, join('', keys %{$rule}).": ".join('', values %{$rule})."; "; |
|
57
|
|
|
|
|
275
|
|
|
57
|
|
|
|
|
152
|
|
432
|
57
|
100
|
|
|
|
74
|
push @return, "\n" if $#{$style->{'rules'}} > 0; |
|
57
|
|
|
|
|
195
|
|
433
|
|
|
|
|
|
|
} |
434
|
37
|
|
|
|
|
108
|
push @return, "}\n"; |
435
|
|
|
|
|
|
|
} |
436
|
3
|
|
|
|
|
32
|
}); |
437
|
3
|
|
|
|
|
182
|
return @return; |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
sub _parse_value { |
441
|
57
|
|
|
57
|
|
79
|
my $value = shift; |
442
|
|
|
|
|
|
|
# convert rgb(255,255,255) to #ffffff ( hsl doesn't work right now ) |
443
|
57
|
|
|
|
|
132
|
while ( $value =~ /rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/ ) { |
444
|
1
|
|
|
|
|
12
|
my $color = sprintf("#%0.2X%0.2X%0.2X", $1,$2,$3); |
445
|
1
|
|
|
|
|
9
|
$value =~ s/rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/$color/; |
446
|
|
|
|
|
|
|
} |
447
|
|
|
|
|
|
|
# expand colors ( from #fff to #ffffff ) |
448
|
57
|
|
|
|
|
142
|
while ( $value =~ /\#([abcdef0123456789]{3})([^abcdef0123456789]|$)/i ) { |
449
|
4
|
|
|
|
|
12
|
my $color = $1; |
450
|
4
|
|
|
|
|
30
|
my $replace = join('', map { $_ x 2 } split(//, $color)); # equals to : for ( split(//, $color) ) { $replace .= $_ x 2; } |
|
12
|
|
|
|
|
48
|
|
451
|
4
|
|
|
|
|
163
|
$value =~ s/\#$color/\#$replace/; |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
# expressions in brackets |
454
|
57
|
|
|
|
|
160
|
while ( $value =~ /\(\s*(\-?\d+\s*((px|pt|em|cm|%))*\s*[\+\*\/\-]\s*\-?\d+\s*((px|pt|em|cm|%))*)\s*\)/ ) { |
455
|
2
|
|
|
|
|
5
|
my $expression = my $eval = $1; |
456
|
2
|
|
|
|
|
12
|
my ($removed) = $eval =~ m/(px|pt|em|cm|%)/; |
457
|
2
|
|
|
|
|
8
|
$eval =~ s/(px|pt|em|cm|%)//; |
458
|
2
|
50
|
33
|
|
|
123
|
if ( $eval !~ /[a-z]/i and defined(my $result = eval($eval)) ) { |
459
|
2
|
50
|
33
|
|
|
13
|
$result .= "$removed" if defined $result and $removed; |
460
|
2
|
|
|
|
|
59
|
$value =~ s/(\(\Q$expression\E\))/$result/; |
461
|
|
|
|
|
|
|
}; |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
# expression (+,-,*,/) ; whole expressions |
464
|
57
|
100
|
66
|
|
|
476
|
if ( $value =~ /(\d+)\s*(px|pt|em|cm|%)*\s*(\+|\*|\/)\s*((\d+)\s*(px|pt|em|cm|%)*|\d+)/ or $value =~ /(\d+)\s*(px|pt|em|cm|%)*\s*(\-)\s+((\d+)\s*(px|pt|em|cm|%)*|\d+)/ ) { |
465
|
1
|
|
|
|
|
3
|
my $eval = $value; |
466
|
1
|
50
|
|
|
|
15
|
my $removed = $1 if $eval =~ s/(px|pt|em|cm|%)//g; |
467
|
1
|
50
|
|
|
|
6
|
if ( $eval !~ /[a-z]/i ) { |
468
|
0
|
|
|
|
|
0
|
my $result = eval($eval); |
469
|
0
|
0
|
0
|
|
|
0
|
$result .= "$removed" if defined($result) and $removed; |
470
|
0
|
0
|
0
|
|
|
0
|
$value = $result if !$@ and defined $result; |
471
|
|
|
|
|
|
|
} |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
# expression with color |
474
|
57
|
100
|
100
|
|
|
281
|
if ( $value =~ /\#[abcdef0123456789]{6}/i and $value =~ /(\+|\-|\*|\/)/ ) { |
475
|
2
|
|
|
|
|
8
|
my @rgb = ( $value, $value, $value ); |
476
|
2
|
|
|
|
|
19
|
$rgb[0] =~ s/\#([abcdef0123456789]{2})[abcdef0123456789]{4}/\#$1/ig; |
477
|
2
|
|
|
|
|
16
|
$rgb[1] =~ s/\#[abcdef0123456789]{2}([abcdef0123456789]{2})[abcdef0123456789]{2}/\#$1/ig; |
478
|
2
|
|
|
|
|
16
|
$rgb[2] =~ s/\#[abcdef0123456789]{4}([abcdef0123456789]{2})/\#$1/ig; |
479
|
2
|
|
|
|
|
6
|
my $return = ""; |
480
|
2
|
|
|
|
|
5
|
for ( @rgb ) { |
481
|
6
|
|
|
|
|
19
|
while ( /\#([abcdef0123456789]{2})/i ) { |
482
|
12
|
|
|
|
|
23
|
my $dec = hex($1); |
483
|
12
|
|
|
|
|
156
|
s/\#$1/$dec/; |
484
|
|
|
|
|
|
|
} |
485
|
6
|
50
|
|
|
|
23
|
if ( !/[a-z]/i ) { |
486
|
0
|
|
|
|
|
0
|
my $eval = eval; |
487
|
0
|
0
|
|
|
|
0
|
if ( $eval < 0 ) { $eval = 0 }; |
|
0
|
|
|
|
|
0
|
|
488
|
0
|
0
|
|
|
|
0
|
if ( $eval > 255 ) { $eval = 255 }; |
|
0
|
|
|
|
|
0
|
|
489
|
0
|
|
|
|
|
0
|
$return .= sprintf("%0.2X", $eval); |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
} |
492
|
2
|
50
|
|
|
|
14
|
$value = "#".lc $return if $return; |
493
|
|
|
|
|
|
|
} |
494
|
57
|
|
|
|
|
140
|
return $value; |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
sub parse { |
498
|
3
|
|
|
3
|
1
|
3856
|
my $self = shift; |
499
|
3
|
|
|
|
|
5
|
my $string = shift; |
500
|
3
|
|
|
|
|
12
|
my $styles = CSS::LESSp->new(); |
501
|
3
|
|
|
|
|
5
|
my $selector = $styles; |
502
|
3
|
|
|
|
|
5
|
my @parents; |
503
|
3
|
|
|
|
|
4
|
push @parents, $styles; |
504
|
|
|
|
|
|
|
# real parsing |
505
|
3
|
|
|
|
|
7
|
my $lastChar = my $buffer = my $mode = my $stop = ""; |
506
|
3
|
|
|
|
|
7
|
$string =~ s/^\xEF\xBB\xBF\x0A//; # removing special characters from front of file |
507
|
3
|
|
|
|
|
497
|
for ( split //, $string ) { |
508
|
2716
|
|
|
|
|
3348
|
$buffer .= $_; |
509
|
2716
|
100
|
|
|
|
10870
|
if ( $mode ) { |
510
|
573
|
100
|
|
|
|
1039
|
$buffer =~ s/.$// if $mode eq "delete"; |
511
|
573
|
100
|
100
|
|
|
1840
|
if ( length($stop) == 1 and $_ eq $stop ) { $mode = "" }; |
|
41
|
|
|
|
|
52
|
|
512
|
573
|
100
|
100
|
|
|
1435
|
if ( length($stop) == 2 and $lastChar.$_ eq $stop ) { $mode = "" } else { $lastChar = $_ }; |
|
1
|
|
|
|
|
2
|
|
|
572
|
|
|
|
|
646
|
|
513
|
573
|
|
|
|
|
698
|
next; |
514
|
|
|
|
|
|
|
} |
515
|
2143
|
100
|
|
|
|
4436
|
next if /\n/; |
516
|
|
|
|
|
|
|
# |
517
|
|
|
|
|
|
|
# The program |
518
|
|
|
|
|
|
|
# |
519
|
1981
|
100
|
100
|
|
|
9458
|
if ( /\}/ or /\;/ ) { |
520
|
|
|
|
|
|
|
# clearing some buffer data |
521
|
94
|
|
|
|
|
366
|
$buffer =~ s/.$//; |
522
|
94
|
|
|
|
|
836
|
$buffer =~ s/^\s*|\s*$//g; # remove any spaces from front or back |
523
|
94
|
|
|
|
|
139
|
$buffer =~ s/\s*\n\s*/ /g; # removes any new line |
524
|
94
|
100
|
|
|
|
178
|
if ( $buffer ) { |
525
|
|
|
|
|
|
|
# if it's a property and rule |
526
|
57
|
50
|
|
|
|
317
|
if ( $buffer =~ s/^\s*([^:]*)\s*\:\s*(.*)\s*$// ) { |
527
|
57
|
|
|
|
|
132
|
my $property = $1; |
528
|
57
|
|
|
|
|
97
|
my $value = $2; |
529
|
57
|
|
|
|
|
81
|
$value =~ s/\n/ /g; |
530
|
57
|
|
|
|
|
289
|
$property =~ s/\s*$//; # remove any additional spaces left |
531
|
|
|
|
|
|
|
# different rule-set property ( mixins ) |
532
|
57
|
50
|
|
|
|
146
|
if ( $value =~ /^(#|.)(.*)\[(.*)\]$/ ) { |
533
|
0
|
|
|
|
|
0
|
my $targetSelectorName = $1.$2; |
534
|
0
|
|
|
|
|
0
|
my $targetProperty = $3; |
535
|
0
|
|
|
|
|
0
|
my $return; |
536
|
0
|
|
|
|
|
0
|
$targetProperty =~ s/['"]//g; |
537
|
0
|
|
|
|
|
0
|
$targetProperty =~ s/\s*//g; |
538
|
|
|
|
|
|
|
# get the target mixin selector |
539
|
0
|
|
|
|
|
0
|
my $targetSelector = $selector->getSelector($targetSelectorName, \@parents); |
540
|
|
|
|
|
|
|
# get the value |
541
|
0
|
0
|
|
|
|
0
|
if ( $targetProperty =~ /^\@/ ) { |
542
|
0
|
|
|
|
|
0
|
$targetProperty =~ s/^\@//; |
543
|
0
|
|
|
|
|
0
|
$return = $targetSelector->getVariable($targetProperty); |
544
|
|
|
|
|
|
|
} else { |
545
|
0
|
|
|
|
|
0
|
$return = $targetSelector->getValue($targetProperty); |
546
|
|
|
|
|
|
|
} |
547
|
0
|
0
|
|
|
|
0
|
$value = $return if $return; |
548
|
|
|
|
|
|
|
} |
549
|
|
|
|
|
|
|
# variable access |
550
|
57
|
50
|
|
|
|
158
|
if ( !$selector->isFunction ) { |
551
|
57
|
|
|
|
|
149
|
while ( $value =~ /\@(\w+\-*\w*)/ ) { |
552
|
0
|
|
|
|
|
0
|
my $word = $1; |
553
|
|
|
|
|
|
|
# get the variable |
554
|
0
|
|
|
|
|
0
|
my $var = $selector->getVariable($word, \@parents); |
555
|
0
|
|
|
|
|
0
|
$value =~ s/\@$word/$var/; |
556
|
|
|
|
|
|
|
# if variable value is negative |
557
|
0
|
0
|
|
|
|
0
|
if ( $var =~ s/^\-// ) { |
558
|
0
|
|
|
|
|
0
|
$value =~ s/\-\s*\-$var/\+ $var/g; |
559
|
0
|
|
|
|
|
0
|
$value =~ s/\+\s*\-$var/\- $var/g; |
560
|
|
|
|
|
|
|
} |
561
|
|
|
|
|
|
|
} |
562
|
|
|
|
|
|
|
# parse for other stuff |
563
|
57
|
|
|
|
|
173
|
$value = _parse_value($value); |
564
|
|
|
|
|
|
|
} |
565
|
|
|
|
|
|
|
# variable definition check ( after we have parsed the stuff ) |
566
|
57
|
50
|
|
|
|
132
|
if ( $property =~ /^\@(\w+\-*\w*)/ ) { |
567
|
0
|
|
|
|
|
0
|
$selector->insertVariable($1, $value); |
568
|
0
|
|
|
|
|
0
|
$property = $value = ""; |
569
|
|
|
|
|
|
|
} else { |
570
|
57
|
|
|
|
|
130
|
$selector->insertRule($property, $value); |
571
|
|
|
|
|
|
|
} |
572
|
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
# nested rules (mixins) |
574
|
57
|
50
|
33
|
|
|
259
|
if ( $buffer =~ s/^(\..*)$// or $buffer =~ s/^(\#.*)$// ) { |
575
|
0
|
|
|
|
|
0
|
my $source = $1; |
576
|
0
|
|
|
|
|
0
|
$source =~ s/\s*\:\s*/\:/g; |
577
|
|
|
|
|
|
|
# for multiple mixins |
578
|
0
|
|
|
|
|
0
|
while ( $source =~ /\(.*,.*\)/ ) { |
579
|
0
|
|
|
|
|
0
|
$source =~ s/\(\s*(.*)\s*,\s*(.*)\s*\)/($1;$2)/ |
580
|
|
|
|
|
|
|
}; |
581
|
0
|
0
|
|
|
|
0
|
my @sources = $source =~ /\,/ ? split(/\s*\,\s*/, $source) : ( $source ); |
582
|
0
|
|
|
|
|
0
|
for my $source ( @sources ) { |
583
|
0
|
|
|
|
|
0
|
my @vars; # this is if any functions are found |
584
|
0
|
|
|
|
|
0
|
my $sourceSelector = $selector->getSelector($source , \@parents); |
585
|
0
|
0
|
0
|
|
|
0
|
if ( $source =~ /\>/ && !$sourceSelector ) { |
586
|
0
|
|
|
|
|
0
|
my ( $parent, $child ) = split(/\s*\>\s*/, $source); |
587
|
0
|
|
|
|
|
0
|
my $pSelector = $selector->getSelector($parent, \@parents); |
588
|
0
|
0
|
|
|
|
0
|
$sourceSelector = $pSelector->getSelector($child) if $pSelector; |
589
|
|
|
|
|
|
|
} |
590
|
0
|
0
|
0
|
|
|
0
|
if ( $source =~ /(.*)\((.*)\)/ && !$sourceSelector ) { |
591
|
0
|
|
|
|
|
0
|
my $function = $1; |
592
|
0
|
|
|
|
|
0
|
my $vars = $2; |
593
|
0
|
0
|
|
|
|
0
|
@vars = $vars =~ /\;/ ? split(/\;/, $vars) : ( $vars ); |
594
|
0
|
|
|
|
|
0
|
$sourceSelector = $selector->getSelector($function, \@parents); |
595
|
|
|
|
|
|
|
} |
596
|
0
|
0
|
|
|
|
0
|
next if !$sourceSelector; |
597
|
0
|
0
|
|
|
|
0
|
if ( $sourceSelector->isFunction ) { |
598
|
0
|
|
|
|
|
0
|
$sourceSelector->copyFunction($selector, \@vars, \@parents); |
599
|
|
|
|
|
|
|
} else { |
600
|
0
|
|
|
|
|
0
|
$sourceSelector->copyTo($selector); |
601
|
|
|
|
|
|
|
} |
602
|
|
|
|
|
|
|
} |
603
|
|
|
|
|
|
|
} |
604
|
|
|
|
|
|
|
# other stuff |
605
|
57
|
50
|
|
|
|
108
|
$selector->insertRule($buffer,"") if $buffer; |
606
|
|
|
|
|
|
|
} |
607
|
94
|
100
|
|
|
|
261
|
$selector = pop @parents if /\}/; |
608
|
94
|
|
|
|
|
142
|
$buffer = ""; |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
# |
611
|
|
|
|
|
|
|
# selectors |
612
|
1981
|
100
|
|
|
|
3978
|
if ( /\{/ ) { |
613
|
|
|
|
|
|
|
# clearing some buffer data |
614
|
37
|
|
|
|
|
351
|
$buffer =~ s/.$//g; |
615
|
37
|
|
|
|
|
357
|
$buffer =~ s/^\s*|\s*$//g; |
616
|
|
|
|
|
|
|
# insert the child |
617
|
37
|
50
|
|
|
|
100
|
if ( $buffer ) { |
618
|
37
|
|
|
|
|
61
|
push @parents, $selector; |
619
|
37
|
50
|
66
|
|
|
166
|
if ( $buffer =~ /(.*)\s*\((\@*.*)\)/ and $buffer !~ /^.*[:].*\(/ ) { |
620
|
0
|
|
|
|
|
0
|
my $function = $1; |
621
|
0
|
|
|
|
|
0
|
my $vars = $2; |
622
|
0
|
|
|
|
|
0
|
$function =~ s/^\s*|\s*$//g; |
623
|
0
|
|
|
|
|
0
|
$selector = $selector->insertFunction($function, \@parents); |
624
|
0
|
0
|
|
|
|
0
|
my @vars = $vars =~ /\,/ ? split(/\s*\,\s*/, $vars) : ( $vars ); |
625
|
0
|
|
|
|
|
0
|
for my $var ( @vars ) { |
626
|
0
|
0
|
|
|
|
0
|
next if !$var; |
627
|
0
|
|
|
|
|
0
|
my ($variable, $value) = split(/\s*\:\s*/, $var); |
628
|
0
|
|
|
|
|
0
|
$variable =~ s/^\@//; |
629
|
0
|
|
|
|
|
0
|
$selector->insertVariable($variable, $value); |
630
|
|
|
|
|
|
|
} |
631
|
|
|
|
|
|
|
} else { |
632
|
37
|
|
|
|
|
186
|
$selector = $selector->insertChild($buffer, \@parents); |
633
|
|
|
|
|
|
|
} |
634
|
|
|
|
|
|
|
} |
635
|
37
|
|
|
|
|
55
|
$buffer = ""; |
636
|
|
|
|
|
|
|
} |
637
|
|
|
|
|
|
|
# |
638
|
|
|
|
|
|
|
# |
639
|
|
|
|
|
|
|
# |
640
|
1981
|
100
|
100
|
|
|
11564
|
if ( /\"/ or /\'/ ) { $mode = "skip"; $stop = $_ }; |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
16
|
|
641
|
1981
|
100
|
|
|
|
4042
|
if ( /\(/ ) { $mode = "skip"; $stop = ")" }; |
|
35
|
|
|
|
|
38
|
|
|
35
|
|
|
|
|
49
|
|
642
|
1981
|
50
|
66
|
|
|
17627
|
if ( $lastChar =~ /\// and /\// ) { $mode = "delete"; $stop = "\n"; $buffer =~ s/..$// } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
643
|
1981
|
100
|
100
|
|
|
4243
|
if ( $lastChar =~ /\// and /\*/ ) { $mode = "delete"; $stop = "*/"; $buffer =~ s/..$// }; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
644
|
1981
|
|
|
|
|
2605
|
$lastChar = $_; |
645
|
|
|
|
|
|
|
} |
646
|
3
|
|
|
|
|
222
|
return $styles->dump(); |
647
|
|
|
|
|
|
|
} |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
1; |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
=head1 NAME |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
CSS::LESSp - LESS for perl. Parse .less files and returns valid css (lesscss.org for more info about less files) |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
=head1 SYNOPSIS |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
use CSS::LESSp; |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
my $buffer; |
660
|
|
|
|
|
|
|
open(IN, "file.less"); |
661
|
|
|
|
|
|
|
for ( ) { $buffer .= $_ }; |
662
|
|
|
|
|
|
|
close(IN); |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
my @css = CSS::LESSp->parse($buffer); |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
print join("", @css); |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
or you could simply use the lessp.pl tool in the package |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
$ lessp.pl css.less > css.css |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
=head1 DESCRIPTION |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
This module is designed to parse and compile .less files in to .css files. |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
About the documentation and syntax of less files please visit lesscss.org |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
=head1 DIFFERENCE WITH THE ORIGINAL LESS FOR RUBY |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
What is the benefits of LESS for perl ... |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
It's extremely fast : |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
# time ./lessp.pl big.less > big.css |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
real 0m2.198s |
687
|
|
|
|
|
|
|
user 0m2.174s |
688
|
|
|
|
|
|
|
sys 0m0.020s |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
# time lessc big.less big.css |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
real 0m18.805s |
693
|
|
|
|
|
|
|
user 0m18.437s |
694
|
|
|
|
|
|
|
sys 0m0.184s |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
=head1 METHODS |
697
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
=head3 parse |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
Main parse method, returns array of the css file |
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
=head3 copyFunction |
703
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
=head3 copyTo |
705
|
|
|
|
|
|
|
|
706
|
|
|
|
|
|
|
=head3 dump |
707
|
|
|
|
|
|
|
=head3 getSelector |
708
|
|
|
|
|
|
|
=head3 getValue |
709
|
|
|
|
|
|
|
=head3 getVariable |
710
|
|
|
|
|
|
|
=head3 insertChild |
711
|
|
|
|
|
|
|
=head3 insertFunction |
712
|
|
|
|
|
|
|
=head3 insertRule |
713
|
|
|
|
|
|
|
=head3 insertVariable |
714
|
|
|
|
|
|
|
=head3 isFunction |
715
|
|
|
|
|
|
|
=head3 new |
716
|
|
|
|
|
|
|
=head3 process |
717
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
=head1 BUGS |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
a ) You can not import other less files ... |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
You can't do this |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
@import url('/other.less') |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
It might be added in future versions |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
b ) You can not use hsl as a color |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
You can't do this |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
color: hsl(125,125,125); |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
All other bugs should be reported via |
735
|
|
|
|
|
|
|
L |
736
|
|
|
|
|
|
|
or L. |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
=head1 AUTHOR |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
Ivan Drinchev |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
=head1 CONTRIBUTORS |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
People who've helped with this project : |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
Michael Schout |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
Copyright (c) 2010. |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
753
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
754
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
=cut |