68 lines
1.9 KiB
PHP
68 lines
1.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace KbAntoraImporter\Antora;
|
|
|
|
final class AntoraNavParser
|
|
{
|
|
public function parse(string $nav): array
|
|
{
|
|
$root = [];
|
|
$stack = [];
|
|
|
|
foreach (preg_split('/\R/', $nav) ?: [] as $line) {
|
|
if (! preg_match('/^(\*+)\s+(.+)$/', trim($line), $matches)) {
|
|
continue;
|
|
}
|
|
|
|
$level = strlen($matches[1]);
|
|
$raw = trim($matches[2]);
|
|
$item = [
|
|
'title' => $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;
|
|
}
|
|
}
|