<?php
lessSorter($argv[1] ?? 'php://stdin');
function cleanRow($key, $row): string
{
return preg_replace(
'# +#',
' ',
str_replace(
["\t", "\n", "\r"],
' ',
str_replace(
':',
': ',
str_replace(
'>',
' > ',
trim($key)
) . ' { ' . $row . ' }'
)
)
);
}
function lessSorter($filename)
{
$f = fopen($filename, 'rb');
$lastKey = '';
$buffer = '';
$dqOpen = false;
$sqOpen = false;
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':
$lastKeys = explode(',', $buffer . substr($input, 0, $firstPos));
$buffer = '';
$input = substr($input, $firstPos + 1);
break;
case 'close':
$row = trim($buffer . substr($input, 0, $firstPos));
$buffer = '';
$input = substr($input, $firstPos + 1);
if ($row) {
foreach($lastKeys as $lastKey) {
echo cleanRow($lastKey, $row . ';'), PHP_EOL;
}
}
$lastKeys = [];
break;
case 'end':
$row = $buffer . substr($input, 0, $firstPos + 1);
$buffer = '';
$input = substr($input, $firstPos + 1);
foreach($lastKeys as $lastKey) {
echo cleanRow($lastKey, $row), PHP_EOL;
}
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)) {
$buffer = preg_replace('#/\*.*\*/#', '', $buffer);
if (trim($buffer)) {
throw new \RuntimeException('Unexpected end of file: ' . $buffer);
}
}
if ($lastKeys) {
throw new \RuntimeException('Last block not closed');
}
}
Comments