94 lines
2.4 KiB
PHP
94 lines
2.4 KiB
PHP
|
<?php
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace Doctrine\RST\Toc;
|
||
|
|
||
|
use Doctrine\RST\Environment;
|
||
|
use Doctrine\RST\Nodes\Node;
|
||
|
|
||
|
use function array_filter;
|
||
|
use function array_map;
|
||
|
use function array_reverse;
|
||
|
use function asort;
|
||
|
use function explode;
|
||
|
use function in_array;
|
||
|
use function strpos;
|
||
|
|
||
|
final class ToctreeBuilder
|
||
|
{
|
||
|
/** @var GlobSearcher */
|
||
|
private $globSearcher;
|
||
|
|
||
|
public function __construct(GlobSearcher $globSearcher)
|
||
|
{
|
||
|
$this->globSearcher = $globSearcher;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param mixed[] $options
|
||
|
*
|
||
|
* @return string[]
|
||
|
*/
|
||
|
public function buildToctreeFiles(
|
||
|
Environment $environment,
|
||
|
Node $node,
|
||
|
array $options
|
||
|
): array {
|
||
|
$toctreeFiles = [];
|
||
|
|
||
|
foreach ($this->parseToctreeFiles($node) as $file) {
|
||
|
if ($this->isGlob($options, $file)) {
|
||
|
$globPattern = $file;
|
||
|
|
||
|
$globFiles = $this->globSearcher
|
||
|
->globSearch($environment, $globPattern);
|
||
|
|
||
|
asort($globFiles);
|
||
|
|
||
|
foreach ($globFiles as $globFile) {
|
||
|
// if glob finds a file already explicitly defined
|
||
|
// don't duplicate it in the toctree again
|
||
|
if (in_array($globFile, $toctreeFiles, true)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ($globFile === $environment->absoluteUrl($environment->getCurrentFileName())) {
|
||
|
// filter out the current file from being added as a glob
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$toctreeFiles[] = $globFile;
|
||
|
}
|
||
|
} else {
|
||
|
$absoluteUrl = $environment->absoluteUrl($file);
|
||
|
|
||
|
$toctreeFiles[] = $absoluteUrl;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((bool) ($options['reversed'] ?? false)) {
|
||
|
$toctreeFiles = array_reverse($toctreeFiles);
|
||
|
}
|
||
|
|
||
|
return $toctreeFiles;
|
||
|
}
|
||
|
|
||
|
/** @return string[] */
|
||
|
private function parseToctreeFiles(Node $node): array
|
||
|
{
|
||
|
return array_filter(array_map('trim', explode(
|
||
|
"\n",
|
||
|
$node->getValueString()
|
||
|
)), static function (string $file): bool {
|
||
|
return $file !== '';
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/** @param mixed[] $options */
|
||
|
private function isGlob(array $options, string $file): bool
|
||
|
{
|
||
|
return isset($options['glob']) && strpos($file, '*') !== false;
|
||
|
}
|
||
|
}
|