$raw, 'target' => '', 'children' => [], ]; if (preg_match('/xref:([^\[]+)\[([^\]]*)\]/', $raw, $xref)) { $item['target'] = trim($xref[1]); $item['title'] = trim($xref[2]) ?: basename($item['target']); } while (count($stack) >= $level) { array_pop($stack); } if (empty($stack)) { $root[] = $item; $stack[$level - 1] = &$root[array_key_last($root)]; } else { $parent = &$stack[array_key_last($stack)]; $parent['children'][] = $item; $stack[$level - 1] = &$parent['children'][array_key_last($parent['children'])]; } unset($parent); } return $root; } public function flatten(array $tree): array { $items = []; $walk = static function (array $nodes, int $level = 1) use (&$walk, &$items): void { foreach ($nodes as $node) { $items[] = [ 'title' => (string) ($node['title'] ?? ''), 'target' => (string) ($node['target'] ?? ''), 'level' => $level, ]; $walk((array) ($node['children'] ?? []), $level + 1); } }; $walk($tree); return $items; } }