PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.3.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.3.1
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / vendor / leafo / lessphp / lessify.inc.php
matomo / app / vendor / leafo / lessphp Last commit date
LICENSE 6 years ago Makefile 6 years ago README.md 6 years ago lessc.inc.php 6 years ago lessify 6 years ago lessify.inc.php 6 years ago plessc 6 years ago
lessify.inc.php
448 lines
1 <?php
2 /**
3 * lessify
4 * Convert a css file into a less file
5 * http://leafo.net/lessphp
6 * Copyright 2010, leaf corcoran <leafot@gmail.com>
7 *
8 * WARNING: THIS DOES NOT WORK ANYMORE. NEEDS TO BE UPDATED FOR
9 * LATEST VERSION OF LESSPHP.
10 *
11 */
12
13 require "lessc.inc.php";
14
15 //
16 // check if the merge during mixin is overwriting values. should or should it not?
17 //
18
19 //
20 // 1. split apart class tags
21 //
22
23 class easyparse {
24 var $buffer;
25 var $count;
26
27 function __construct($str) {
28 $this->count = 0;
29 $this->buffer = trim($str);
30 }
31
32 function seek($where = null) {
33 if ($where === null) return $this->count;
34 else $this->count = $where;
35 return true;
36 }
37
38 function preg_quote($what) {
39 return preg_quote($what, '/');
40 }
41
42 function match($regex, &$out, $eatWhitespace = true) {
43 $r = '/'.$regex.($eatWhitespace ? '\s*' : '').'/Ais';
44 if (preg_match($r, $this->buffer, $out, null, $this->count)) {
45 $this->count += strlen($out[0]);
46 return true;
47 }
48 return false;
49 }
50
51 function literal($what, $eatWhitespace = true) {
52 // this is here mainly prevent notice from { } string accessor
53 if ($this->count >= strlen($this->buffer)) return false;
54
55 // shortcut on single letter
56 if (!$eatWhitespace and strlen($what) == 1) {
57 if ($this->buffer{$this->count} == $what) {
58 $this->count++;
59 return true;
60 }
61 else return false;
62 }
63
64 return $this->match($this->preg_quote($what), $m, $eatWhitespace);
65 }
66
67 }
68
69 class tagparse extends easyparse {
70 static private $combinators = null;
71 static private $match_opts = null;
72
73 function parse() {
74 if (empty(self::$combinators)) {
75 self::$combinators = '('.implode('|', array_map(array($this, 'preg_quote'),
76 array('+', '>', '~'))).')';
77 self::$match_opts = '('.implode('|', array_map(array($this, 'preg_quote'),
78 array('=', '~=', '|=', '$=', '*='))).')';
79 }
80
81 // crush whitespace
82 $this->buffer = preg_replace('/\s+/', ' ', $this->buffer).' ';
83
84 $tags = array();
85 while ($this->tag($t)) $tags[] = $t;
86
87 return $tags;
88 }
89
90 static function compileString($string) {
91 list(, $delim, $str) = $string;
92 $str = str_replace($delim, "\\".$delim, $str);
93 $str = str_replace("\n", "\\\n", $str);
94 return $delim.$str.$delim;
95 }
96
97 static function compilePaths($paths) {
98 return implode(', ', array_map(array('self', 'compilePath'), $paths));
99 }
100
101 // array of tags
102 static function compilePath($path) {
103 return implode(' ', array_map(array('self', 'compileTag'), $path));
104 }
105
106
107 static function compileTag($tag) {
108 ob_start();
109 if (isset($tag['comb'])) echo $tag['comb']." ";
110 if (isset($tag['front'])) echo $tag['front'];
111 if (isset($tag['attr'])) {
112 echo '['.$tag['attr'];
113 if (isset($tag['op'])) {
114 echo $tag['op'].$tag['op_value'];
115 }
116 echo ']';
117 }
118 return ob_get_clean();
119 }
120
121 function string(&$out) {
122 $s = $this->seek();
123
124 if ($this->literal('"')) {
125 $delim = '"';
126 } elseif ($this->literal("'")) {
127 $delim = "'";
128 } else {
129 return false;
130 }
131
132 while (true) {
133 // step through letters looking for either end or escape
134 $buff = "";
135 $escapeNext = false;
136 $finished = false;
137 for ($i = $this->count; $i < strlen($this->buffer); $i++) {
138 $char = $this->buffer[$i];
139 switch ($char) {
140 case $delim:
141 if ($escapeNext) {
142 $buff .= $char;
143 $escapeNext = false;
144 break;
145 }
146 $finished = true;
147 break 2;
148 case "\\":
149 if ($escapeNext) {
150 $buff .= $char;
151 $escapeNext = false;
152 } else {
153 $escapeNext = true;
154 }
155 break;
156 case "\n":
157 if (!$escapeNext) {
158 break 3;
159 }
160
161 $buff .= $char;
162 $escapeNext = false;
163 break;
164 default:
165 if ($escapeNext) {
166 $buff .= "\\";
167 $escapeNext = false;
168 }
169 $buff .= $char;
170 }
171 }
172 if (!$finished) break;
173 $out = array('string', $delim, $buff);
174 $this->seek($i+1);
175 return true;
176 }
177
178 $this->seek($s);
179 return false;
180 }
181
182 function tag(&$out) {
183 $s = $this->seek();
184 $tag = array();
185 if ($this->combinator($op)) $tag['comb'] = $op;
186
187 if (!$this->match('(.*?)( |$|\[|'.self::$combinators.')', $match)) {
188 $this->seek($s);
189 return false;
190 }
191
192 if (!empty($match[3])) {
193 // give back combinator
194 $this->count-=strlen($match[3]);
195 }
196
197 if (!empty($match[1])) $tag['front'] = $match[1];
198
199 if ($match[2] == '[') {
200 if ($this->ident($i)) {
201 $tag['attr'] = $i;
202
203 if ($this->match(self::$match_opts, $m) && $this->value($v)) {
204 $tag['op'] = $m[1];
205 $tag['op_value'] = $v;
206 }
207
208 if ($this->literal(']')) {
209 $out = $tag;
210 return true;
211 }
212 }
213 } elseif (isset($tag['front'])) {
214 $out = $tag;
215 return true;
216 }
217
218 $this->seek($s);
219 return false;
220 }
221
222 function ident(&$out) {
223 // [-]?{nmstart}{nmchar}*
224 // nmstart: [_a-z]|{nonascii}|{escape}
225 // nmchar: [_a-z0-9-]|{nonascii}|{escape}
226 if ($this->match('(-?[_a-z][_\w]*)', $m)) {
227 $out = $m[1];
228 return true;
229 }
230 return false;
231 }
232
233 function value(&$out) {
234 if ($this->string($str)) {
235 $out = $this->compileString($str);
236 return true;
237 } elseif ($this->ident($id)) {
238 $out = $id;
239 return true;
240 }
241 return false;
242 }
243
244
245 function combinator(&$op) {
246 if ($this->match(self::$combinators, $m)) {
247 $op = $m[1];
248 return true;
249 }
250 return false;
251 }
252 }
253
254 class nodecounter {
255 var $count = 0;
256 var $children = array();
257
258 var $name;
259 var $child_blocks;
260 var $the_block;
261
262 function __construct($name) {
263 $this->name = $name;
264 }
265
266 function dump($stack = null) {
267 if (is_null($stack)) $stack = array();
268 $stack[] = $this->getName();
269 echo implode(' -> ', $stack)." ($this->count)\n";
270 foreach ($this->children as $child) {
271 $child->dump($stack);
272 }
273 }
274
275 static function compileProperties($c, $block) {
276 foreach($block as $name => $value) {
277 if ($c->isProperty($name, $value)) {
278 echo $c->compileProperty($name, $value)."\n";
279 }
280 }
281 }
282
283 function compile($c, $path = null) {
284 if (is_null($path)) $path = array();
285 $path[] = $this->name;
286
287 $isVisible = !is_null($this->the_block) || !is_null($this->child_blocks);
288
289 if ($isVisible) {
290 echo $c->indent(implode(' ', $path).' {');
291 $c->indentLevel++;
292 $path = array();
293
294 if ($this->the_block) {
295 $this->compileProperties($c, $this->the_block);
296 }
297
298 if ($this->child_blocks) {
299 foreach ($this->child_blocks as $block) {
300 echo $c->indent(tagparse::compilePaths($block['__tags']).' {');
301 $c->indentLevel++;
302 $this->compileProperties($c, $block);
303 $c->indentLevel--;
304 echo $c->indent('}');
305 }
306 }
307 }
308
309 // compile child nodes
310 foreach($this->children as $node) {
311 $node->compile($c, $path);
312 }
313
314 if ($isVisible) {
315 $c->indentLevel--;
316 echo $c->indent('}');
317 }
318
319 }
320
321 function getName() {
322 if (is_null($this->name)) return "[root]";
323 else return $this->name;
324 }
325
326 function getNode($name) {
327 if (!isset($this->children[$name])) {
328 $this->children[$name] = new nodecounter($name);
329 }
330
331 return $this->children[$name];
332 }
333
334 function findNode($path) {
335 $current = $this;
336 for ($i = 0; $i < count($path); $i++) {
337 $t = tagparse::compileTag($path[$i]);
338 $current = $current->getNode($t);
339 }
340
341 return $current;
342 }
343
344 function addBlock($path, $block) {
345 $node = $this->findNode($path);
346 if (!is_null($node->the_block)) throw new exception("can this happen?");
347
348 unset($block['__tags']);
349 $node->the_block = $block;
350 }
351
352 function addToNode($path, $block) {
353 $node = $this->findNode($path);
354 $node->child_blocks[] = $block;
355 }
356 }
357
358 /**
359 * create a less file from a css file by combining blocks where appropriate
360 */
361 class lessify extends lessc {
362 public function dump() {
363 print_r($this->env);
364 }
365
366 public function parse($str = null) {
367 $this->prepareParser($str ? $str : $this->buffer);
368 while (false !== $this->parseChunk());
369
370 $root = new nodecounter(null);
371
372 // attempt to preserve some of the block order
373 $order = array();
374
375 $visitedTags = array();
376 foreach (end($this->env) as $name => $block) {
377 if (!$this->isBlock($name, $block)) continue;
378 if (isset($visitedTags[$name])) continue;
379
380 foreach ($block['__tags'] as $t) {
381 $visitedTags[$t] = true;
382 }
383
384 // skip those with more than 1
385 if (count($block['__tags']) == 1) {
386 $p = new tagparse(end($block['__tags']));
387 $path = $p->parse();
388 $root->addBlock($path, $block);
389 $order[] = array('compressed', $path, $block);
390 continue;
391 } else {
392 $common = null;
393 $paths = array();
394 foreach ($block['__tags'] as $rawtag) {
395 $p = new tagparse($rawtag);
396 $paths[] = $path = $p->parse();
397 if (is_null($common)) $common = $path;
398 else {
399 $new_common = array();
400 foreach ($path as $tag) {
401 $head = array_shift($common);
402 if ($tag == $head) {
403 $new_common[] = $head;
404 } else break;
405 }
406 $common = $new_common;
407 if (empty($common)) {
408 // nothing in common
409 break;
410 }
411 }
412 }
413
414 if (!empty($common)) {
415 $new_paths = array();
416 foreach ($paths as $p) $new_paths[] = array_slice($p, count($common));
417 $block['__tags'] = $new_paths;
418 $root->addToNode($common, $block);
419 $order[] = array('compressed', $common, $block);
420 continue;
421 }
422
423 }
424
425 $order[] = array('none', $block['__tags'], $block);
426 }
427
428
429 $compressed = $root->children;
430 foreach ($order as $item) {
431 list($type, $tags, $block) = $item;
432 if ($type == 'compressed') {
433 $top = tagparse::compileTag(reset($tags));
434 if (isset($compressed[$top])) {
435 $compressed[$top]->compile($this);
436 unset($compressed[$top]);
437 }
438 } else {
439 echo $this->indent(implode(', ', $tags).' {');
440 $this->indentLevel++;
441 nodecounter::compileProperties($this, $block);
442 $this->indentLevel--;
443 echo $this->indent('}');
444 }
445 }
446 }
447 }
448