function parse_child($value = '')
{
$block_imports = array();
// 1. Ищем «детей» (вложенные селекторы)
preg_match_all('@
[^};]*?
{
(
(
([^\\{\\}]+)|(?R)
)*
)
}
@ismx', $value, $nested);
// TODO: возможно, вынести отдельной функцией, т.к. часто повторяется
foreach ($nested[0] as $key => &$nest) {
$value = str_replace($nest, '', $value);
if (strpos(trim($nest), '@include') === 0) {
$value = str_replace($nest, '', $value);
$old_nest = $nested[1][$key];
$new_nest = $this->parse_child($nested[1][$key]);
$nest = str_replace($old_nest, $new_nest, $nest);
$block_imports[] = $nest;
unset($nested[0][$key]);
unset($nested[1][$key]);
}
}
// Сохраняем всех «детей» в строку для последующей замены
// TODO: убрать, если без этого можно обойтись
$nested_string = implode('', $nested[0]);
// Рекурсия, ahoj!
// Сортируем содержимое «детей»
foreach ($nested[1] as &$child) {
$old_child = $child;
$new_child = $this->parse_child($child);
$nested_string = str_replace($old_child, $new_child, $nested_string);
}
// Остались без «детей»
// 2. Выносим переменные в отдельный массив $vars
preg_match_all('@
(comment\\d*__)*
\\s*(\\$|\\@)[^;\\}]+?:[^;]+?;
(inlinecomment\\d*__)*
@ismx', $value, $vars);
// Удаляем их из общей строки
foreach ($vars[0] as $var) {
$value = str_replace($var, '', $value);
}
// 3. Выносим импорты в отдельный массив $imports
// TODO: объединить в одно выражение
// Включения, следующие сразу за {
preg_match_all('@
(^\\s*(comment\\d*__)*\\s*\\@[^;]+?[;](inlinecomment\\d*__)*)
|
(^\\s*(comment\\d*__)*\\s*\\.[^;:]+?[;](inlinecomment\\d*__)*)
@isx', $value, $first_imports);
// Все остальные
preg_match_all('@
(?<=inlinecomment\\d__|[;}])
((comment\\d*__)?\\s*\\@[^;]+?[;](inlinecomment\\d*__)?)
|
(?<=inlinecomment\\d__|[;}])
((comment\\d*__)?\\s*\\.[^;:]+?[;](inlinecomment\\d*__)?)
@ismx', $value, $imports);
// Удаляем их из общей строки
foreach ($first_imports[0] as &$first_import) {
$value = str_replace($first_import, '', $value);
}
foreach ($imports[0] as &$import) {
$value = str_replace($import, '', $value);
}
// 4. Выносим простые свойства в массив $properties
preg_match_all('@
(comment\\d*__)?
\\s*[^;]+?:[^;]+?;
(inlinecomment\\d*__)?
@ismx', $value, $properties);
// Удаляем их из общей строки
foreach ($properties[0] as &$property) {
$value = str_replace($property, '', $value);
}
// Сортируем свойства
$props = $properties[0];
$props = $this->resort_properties($props);
// 6. Склеиваем всё обратно в следующем порядке:
// переменные, включения, простые свойства, вложенные {}
$value = implode('', $vars[0]) . implode('', $first_imports[0]) . implode('', $imports[0]) . implode('', $block_imports) . implode('', $props) . $nested_string . $value;
return $value;
}