Skip to content

Commit a39efb6

Browse files
authored
[FEATURE] Allow glob patterns in include (#697)
1 parent d8ed436 commit a39efb6

File tree

9 files changed

+152
-3
lines changed

9 files changed

+152
-3
lines changed

packages/typo3-docs-theme/src/Directives/IncludeDirective.php

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
namespace T3Docs\Typo3DocsTheme\Directives;
1515

16+
use League\Flysystem\Adapter\AbstractAdapter;
17+
use League\Flysystem\Filesystem;
18+
use League\Flysystem\FilesystemInterface;
1619
use phpDocumentor\Guides\Nodes\CodeNode;
1720
use phpDocumentor\Guides\Nodes\CollectionNode;
1821
use phpDocumentor\Guides\Nodes\LiteralBlockNode;
@@ -42,10 +45,76 @@ public function getName(): string
4245
/** {@inheritDoc} */
4346
public function processNode(
4447
BlockContext $blockContext,
45-
Directive $directive,
48+
Directive $directive,
4649
): Node {
50+
$inputPath = $directive->getData();
51+
if (str_contains($inputPath, '*')) {
52+
return $this->resolveGlobInclude($blockContext, $inputPath, $directive);
53+
}
54+
return $this->resolveBasicInclude($blockContext, $inputPath, $directive);
55+
}
56+
57+
58+
/**
59+
* @throws \League\Flysystem\FileNotFoundException
60+
*/
61+
public function resolveGlobInclude(BlockContext $blockContext, string $inputPath, Directive $directive): LiteralBlockNode|CollectionNode|CodeNode
62+
{
4763
$parserContext = $blockContext->getDocumentParserContext()->getParser()->getParserContext();
48-
$path = $parserContext->absoluteRelativePath($directive->getData());
64+
$path = $parserContext->absoluteRelativePath($inputPath);
65+
66+
$origin = $parserContext->getOrigin();
67+
68+
assert($origin instanceof Filesystem);
69+
$adapter = $origin->getAdapter();
70+
assert($adapter instanceof AbstractAdapter);
71+
$absoluteRootPath = $adapter->getPathPrefix();
72+
73+
// Create the absolute glob pattern
74+
$absolutePattern = $absoluteRootPath . ltrim($path, '/');
75+
76+
$files = glob($absolutePattern);
77+
78+
if (!is_array($files) || empty($files)) {
79+
throw new RuntimeException(
80+
sprintf('No files matched the glob pattern "%s".', $path),
81+
);
82+
}
83+
84+
sort($files);
85+
$nodes = [];
86+
87+
// Loop through each matched file
88+
foreach ($files as $file) {
89+
// Convert the absolute file path to a path relative to the origin's root
90+
$relativePath = str_replace($absoluteRootPath ?? '', '', $file);
91+
92+
if (!$origin->has($relativePath)) {
93+
throw new RuntimeException(
94+
sprintf('Include "%s" (%s) does not exist or is not readable.', $directive->getData(), $relativePath),
95+
);
96+
}
97+
98+
// Get the collection of nodes from each path
99+
$nodes[] = $this->getCollectionFromPath($origin, $relativePath, $directive, $blockContext);
100+
}
101+
102+
// If only one node is found, return it directly
103+
if (count($nodes) === 1) {
104+
return $nodes[0];
105+
}
106+
107+
// Otherwise, return a CollectionNode of all nodes
108+
return new CollectionNode($nodes);
109+
}
110+
111+
/**
112+
* @throws \League\Flysystem\FileNotFoundException
113+
*/
114+
public function resolveBasicInclude(BlockContext $blockContext, string $inputPath, Directive $directive): LiteralBlockNode|CollectionNode|CodeNode
115+
{
116+
$parserContext = $blockContext->getDocumentParserContext()->getParser()->getParserContext();
117+
$path = $parserContext->absoluteRelativePath($inputPath);
49118

50119
$origin = $parserContext->getOrigin();
51120
if (!$origin->has($path)) {
@@ -54,6 +123,14 @@ public function processNode(
54123
);
55124
}
56125

126+
return $this->getCollectionFromPath($origin, $path, $directive, $blockContext);
127+
}
128+
129+
/**
130+
* @throws \League\Flysystem\FileNotFoundException
131+
*/
132+
public function getCollectionFromPath(FilesystemInterface $origin, string $path, Directive $directive, BlockContext $blockContext): LiteralBlockNode|CollectionNode|CodeNode
133+
{
57134
$contents = $origin->read($path);
58135

59136
if ($contents === false) {
@@ -71,7 +148,7 @@ public function processNode(
71148
$codeNode = new CodeNode(
72149
explode('\n', $contents),
73150
);
74-
$codeNode->setLanguage((string) $directive->getOption('code')->getValue());
151+
$codeNode->setLanguage((string)$directive->getOption('code')->getValue());
75152

76153
return $codeNode;
77154
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<!-- content start -->
2+
<section class="section" id="includes-with-glob">
3+
<h1>Includes with glob<a class="headerlink" href="#includes-with-glob" data-bs-toggle="modal" data-bs-target="#linkReferenceModal" title="Reference this headline"></a></h1>
4+
<div class="float-end">
5+
<a href="https://github.com/TYPO3-Documentation/TYPO3CMS-Reference-CoreApi/edit/documentation-draft/Documentation/_includes/_a.rst.txt" class="btn btn-light" title="Edit following section on GitHub">
6+
<i class="icon fa-brands fa-github"></i>
7+
</a>
8+
</div>
9+
<p>A</p>
10+
<div class="float-end">
11+
<a href="https://github.com/TYPO3-Documentation/TYPO3CMS-Reference-CoreApi/edit/documentation-draft/Documentation/_includes/_b.rst.txt" class="btn btn-light" title="Edit following section on GitHub">
12+
<i class="icon fa-brands fa-github"></i>
13+
</a>
14+
</div>
15+
<p>B</p>
16+
<div class="float-end">
17+
<a href="https://github.com/TYPO3-Documentation/TYPO3CMS-Reference-CoreApi/edit/documentation-draft/Documentation/_includes/_ba.rst.txt" class="btn btn-light" title="Edit following section on GitHub">
18+
<i class="icon fa-brands fa-github"></i>
19+
</a>
20+
</div>
21+
<p>Ba</p>
22+
<div class="float-end">
23+
<a href="https://github.com/TYPO3-Documentation/TYPO3CMS-Reference-CoreApi/edit/documentation-draft/Documentation/_includes/_be.rst.txt" class="btn btn-light" title="Edit following section on GitHub">
24+
<i class="icon fa-brands fa-github"></i>
25+
</a>
26+
</div>
27+
<p>Be</p>
28+
29+
<div class="toctree-wrapper compound">
30+
<ul class="menu-level">
31+
<li class="toc-item">
32+
<a href="page/index.html#includes-with-glob">Includes with glob</a>
33+
34+
35+
</li>
36+
</ul>
37+
</div>
38+
</section>
39+
<!-- content end -->
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
B
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Ba
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Be
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<guides xmlns="https://www.phpdoc.org/guides"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="https://www.phpdoc.org/guides vendor/phpdocumentor/guides-cli/resources/schema/guides.xsd"
5+
links-are-relative="true"
6+
>
7+
8+
<extension class="\T3Docs\Typo3DocsTheme\DependencyInjection\Typo3DocsThemeExtension"
9+
edit-on-github="TYPO3-Documentation/TYPO3CMS-Reference-CoreApi"
10+
edit-on-github-branch="documentation-draft"
11+
/>
12+
</guides>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
==================
2+
Includes with glob
3+
==================
4+
5+
.. include:: _includes/_*.rst.txt
6+
:show-buttons: true
7+
8+
.. toctree::
9+
:glob:
10+
11+
*/index
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
==================
2+
Includes with glob
3+
==================
4+
5+
.. include:: ../_includes/_b*.rst.txt
6+
:show-buttons: true

0 commit comments

Comments
 (0)