Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- lessSorter($argv[1] ?? 'php://stdin');
- function lessSorter($filename)
- {
- $f = fopen($filename, 'rb');
- $stack = [];
- $current = (object) ['type' => 'root', 'content' => []];
- $buffer = '';
- $dqOpen = false;
- $sqOpen = false;
- $counter = 1000000;
- while (!feof($f)) {
- $input = fread($f, 20480);
- while ($input) {
- $pos = [
- 'open' => strpos($input, '{'),
- 'close' => strpos($input, '}'),
- 'end' => strpos($input, ';'),
- 'sq' => strpos($input, "'"),
- 'dq' => strpos($input, '"'),
- ];
- $pos = array_filter($pos, 'is_numeric');
- if (!$pos) {
- $buffer .= $input;
- $input = false;
- continue;
- }
- asort($pos);
- $firstPos = reset($pos);
- switch (key($pos)) {
- case 'open':
- $row = $buffer . substr($input, 0, $firstPos);
- $buffer = '';
- $input = substr($input, $firstPos + 1);
- if ($current) {
- $stack[] = $current;
- }
- $current = (object) [
- 'type' => 'block',
- 'key' => trim($row),
- 'content' => [],
- ];
- break;
- case 'close':
- $row = trim($buffer . substr($input, 0, $firstPos));
- $buffer = '';
- $input = substr($input, $firstPos + 1);
- if (!$current || !$stack) {
- throw new \RuntimeException('css closed non-open block');
- }
- if ($row) {
- $sortValue = trim(strstr($row, ':', true)) . '-' . $counter++;
- $current->content[$sortValue] = $row . ';';
- }
- asort($current->content);
- $old = $current;
- $current = array_pop($stack);
- $prefix = in_array($old->key[0], ['#', '.']) ? '' : '*';
- $current->content[$prefix . $old->key . '-' . $counter++] = $old->key . ' {' . PHP_EOL .
- "\t" . trim (str_replace("\n", "\n\t", implode(PHP_EOL, $old->content))) . PHP_EOL .
- '}' . PHP_EOL;
- break;
- case 'end':
- $row = $buffer . substr($input, 0, $firstPos + 1);
- $buffer = '';
- $input = substr($input, $firstPos + 1);
- if (!$current || $current->type === 'root') {
- throw new \RuntimeException('css outside block: ' . $row);
- }
- $sortValue = '~' . trim(strstr($row, ':', true)) . '-' . $counter++;
- $current->content[$sortValue] = trim($row);
- break;
- case 'sq':
- $buffer .= substr($input, 0, $firstPos + 1);
- $input = substr($input, $firstPos + 1);
- $sqOpen = !$sqOpen;
- break;
- case 'dq':
- $buffer .= substr($input, 0, $firstPos + 1);
- $input = substr($input, $firstPos + 1);
- $dqOpen = !$dqOpen;
- break;
- default:
- die('unknown key');
- }
- }
- }
- fclose($f);
- if (trim($buffer)) {
- throw new \RuntimeException('Unexpected end of file: ' . $buffer);
- }
- if (!$current || $stack || $current->type !== 'root') {
- throw new \RuntimeException('Wrong number of blocks closed. stack size: ' . count($stack));
- }
- asort($current->content);
- echo implode(PHP_EOL, $current->content);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement