Skip to content

Commit 1823455

Browse files
committed
Add support for directive content.
1 parent 938b396 commit 1823455

23 files changed

Lines changed: 133 additions & 56 deletions

packages/guides-restructured-text/resources/config/guides-restructured-text.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use phpDocumentor\Guides\Graphs\Directives\UmlDirective;
66
use phpDocumentor\Guides\ReferenceResolvers\DocumentNameResolverInterface;
7+
use phpDocumentor\Guides\RestructuredText\Compiler\Passes\DirectiveProcessPass;
78
use phpDocumentor\Guides\RestructuredText\Directives\AdmonitionDirective;
89
use phpDocumentor\Guides\RestructuredText\Directives\AttentionDirective;
910
use phpDocumentor\Guides\RestructuredText\Directives\BaseDirective;
@@ -277,6 +278,7 @@
277278
->tag('phpdoc.guides.parser.rst.body_element', ['priority' => ParagraphRule::PRIORITY + 1])
278279
->set(DirectiveRule::class)
279280
->arg('$directives', tagged_iterator('phpdoc.guides.directive'))
281+
->arg('$startingRule', service(DirectiveContentRule::class))
280282
->tag('phpdoc.guides.parser.rst.body_element', ['priority' => DirectiveRule::PRIORITY])
281283
->set(CommentRule::class)
282284
->tag('phpdoc.guides.parser.rst.body_element', ['priority' => CommentRule::PRIORITY])
@@ -375,7 +377,7 @@
375377
->set(ToctreeBuilder::class)
376378
->set(InlineMarkupRule::class)
377379

378-
->set(\phpDocumentor\Guides\RestructuredText\Compiler\Passes\DirectiveProcessPass::class)
380+
->set(DirectiveProcessPass::class)
379381
->arg('$directives', tagged_iterator('phpdoc.guides.directive'))
380382
->tag('phpdoc.guides.compiler.nodeTransformers')
381383
->set(DefaultCodeNodeOptionMapper::class)

packages/guides-restructured-text/src/RestructuredText/Compiler/Passes/DirectiveProcessPass.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
declare(strict_types=1);
44

5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link https://phpdoc.org
12+
*/
13+
514
namespace phpDocumentor\Guides\RestructuredText\Compiler\Passes;
615

716
use phpDocumentor\Guides\Compiler\CompilerContext;
@@ -13,7 +22,12 @@
1322
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
1423
use Psr\Log\LoggerInterface;
1524

16-
class DirectiveProcessPass implements NodeTransformer
25+
use function strtolower;
26+
27+
use const PHP_INT_MAX;
28+
29+
/** @implements NodeTransformer<DirectiveNode> */
30+
final class DirectiveProcessPass implements NodeTransformer
1731
{
1832
/** @var array<string, DirectiveHandler> */
1933
private array $directives;
@@ -44,7 +58,14 @@ public function enterNode(Node $node, CompilerContext $compilerContext): Node
4458

4559
public function leaveNode(Node $node, CompilerContext $compilerContext): Node|null
4660
{
47-
return $this->getDirectiveHandler($node->getDirective())->createNode($node->getDirective());
61+
$newNode = $this->getDirectiveHandler($node->getDirective())->createNode($node);
62+
if ($newNode === null) {
63+
return null;
64+
}
65+
66+
$newNode->setClasses($node->getClasses());
67+
68+
return $newNode;
4869
}
4970

5071
private function getDirectiveHandler(Directive $directive): DirectiveHandler

packages/guides-restructured-text/src/RestructuredText/Directives/AbstractAdmonitionDirective.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use phpDocumentor\Guides\Nodes\CollectionNode;
1818
use phpDocumentor\Guides\Nodes\Node;
1919
use phpDocumentor\Guides\Nodes\ParagraphNode;
20+
use phpDocumentor\Guides\RestructuredText\Nodes\DirectiveNode;
2021
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
2122
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
2223
use phpDocumentor\Guides\RestructuredText\Parser\Productions\Rule;
@@ -53,8 +54,18 @@ final protected function processSub(
5354
);
5455
}
5556

56-
final public function getName(): string
57+
public function createNode(DirectiveNode $directiveNode): Node|null
5758
{
58-
return $this->name;
59+
$children = $directiveNode->getChildren();
60+
if ($directiveNode->getDirective()->getDataNode() !== null) {
61+
array_unshift($children, new ParagraphNode([$directiveNode->getDirective()->getDataNode()]));
62+
}
63+
64+
return new AdmonitionNode(
65+
$directiveNode->getDirective()->getName(),
66+
null,
67+
$this->text,
68+
$children,
69+
);
5970
}
6071
}

packages/guides-restructured-text/src/RestructuredText/Directives/AdmonitionDirective.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,9 @@
3434
*
3535
* @see https://docutils.sourceforge.io/docs/ref/rst/directives.html#generic-admonition
3636
*/
37+
#[Attributes\Directive(name: 'admonition')]
3738
final class AdmonitionDirective extends SubDirective
3839
{
39-
public function getName(): string
40-
{
41-
return 'admonition';
42-
}
43-
4440
/** {@inheritDoc}
4541
*
4642
* @param Directive $directive

packages/guides-restructured-text/src/RestructuredText/Directives/AttentionDirective.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* This is an attention admonition.
2727
* ```
2828
*/
29+
#[Attributes\Directive(name: 'attention')]
2930
final class AttentionDirective extends AbstractAdmonitionDirective
3031
{
3132
public function __construct(protected Rule $startingRule)

packages/guides-restructured-text/src/RestructuredText/Directives/Attributes/Directive.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,26 @@
22

33
declare(strict_types=1);
44

5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link https://phpdoc.org
12+
*/
13+
514
namespace phpDocumentor\Guides\RestructuredText\Directives\Attributes;
615

716
use Attribute;
817

918
#[Attribute(Attribute::TARGET_CLASS)]
1019
final class Directive
1120
{
21+
/** @param string[] $aliases */
1222
public function __construct(
1323
public readonly string $name,
1424
public readonly array $aliases = [],
1525
) {
16-
1726
}
1827
}

packages/guides-restructured-text/src/RestructuredText/Directives/Attributes/Option.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
declare(strict_types=1);
44

5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link https://phpdoc.org
12+
*/
13+
514
namespace phpDocumentor\Guides\RestructuredText\Directives\Attributes;
615

716
use Attribute;
@@ -19,4 +28,3 @@ public function __construct(
1928
) {
2029
}
2130
}
22-

packages/guides-restructured-text/src/RestructuredText/Directives/BaseDirective.php

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,21 @@
1313

1414
namespace phpDocumentor\Guides\RestructuredText\Directives;
1515

16+
use LogicException;
1617
use phpDocumentor\Guides\Nodes\GenericNode;
1718
use phpDocumentor\Guides\Nodes\Node;
1819
use phpDocumentor\Guides\RestructuredText\Directives\Attributes\Option;
20+
use phpDocumentor\Guides\RestructuredText\Nodes\DirectiveNode;
1921
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
2022
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
2123
use phpDocumentor\Guides\RestructuredText\Parser\DirectiveOption;
24+
use ReflectionClass;
2225

2326
use function array_map;
27+
use function count;
28+
use function filter_var;
29+
30+
use const FILTER_VALIDATE_BOOL;
2431

2532
/**
2633
* A directive is like a function you can call or apply to a block
@@ -37,11 +44,12 @@
3744
*/
3845
abstract class BaseDirective
3946
{
40-
/** @var array<string, Option|null> Cache of Option attributes indexed by option name */
47+
/** @var array<string, Option> Cache of Option attributes indexed by option name */
4148
private array $optionAttributeCache;
4249

4350
private string $name;
4451

52+
/** @var string[] */
4553
private array $aliases;
4654

4755
/**
@@ -53,14 +61,15 @@ public function getName(): string
5361
return $this->name;
5462
}
5563

56-
$reflection = new \ReflectionClass($this);
64+
$reflection = new ReflectionClass($this);
5765
$attributes = $reflection->getAttributes(Attributes\Directive::class);
5866

5967
if (count($attributes) === 0) {
60-
throw new \LogicException('Directive class must have a Directive attribute');
68+
throw new LogicException('Directive class must have a Directive attribute');
6169
}
6270

6371
$this->name = $attributes[0]->newInstance()->name;
72+
6473
return $this->name;
6574
}
6675

@@ -77,7 +86,7 @@ public function getAliases(): array
7786
return $this->aliases;
7887
}
7988

80-
$reflection = new \ReflectionClass($this);
89+
$reflection = new ReflectionClass($this);
8190
$attributes = $reflection->getAttributes(Attributes\Directive::class);
8291
$this->aliases = [];
8392
if (count($attributes) !== 0) {
@@ -98,7 +107,7 @@ public function getAliases(): array
98107
*/
99108
final public function isUpgraded(): bool
100109
{
101-
$reflection = new \ReflectionClass($this);
110+
$reflection = new ReflectionClass($this);
102111
$attributes = $reflection->getAttributes(Attributes\Directive::class);
103112

104113
return count($attributes) === 1;
@@ -136,7 +145,7 @@ public function processNode(
136145
return new GenericNode($directive->getVariable(), $directive->getData());
137146
}
138147

139-
public function createNode(Directive $directive): Node|null
148+
public function createNode(DirectiveNode $directiveNode): Node|null
140149
{
141150
return null;
142151
}
@@ -170,13 +179,14 @@ final protected function readOption(Directive $directive, string $optionName): m
170179
return $this->getOptionValue($directive, $optionAttribute);
171180
}
172181

182+
/** @return array<string, mixed> */
173183
final protected function readAllOptions(Directive $directive): array
174184
{
175185
$this->initialize();
176186

177187
return array_map(
178188
fn (Option $option) => $this->getOptionValue($directive, $option),
179-
$this->optionAttributeCache
189+
$this->optionAttributeCache,
180190
);
181191
}
182192

@@ -198,19 +208,17 @@ private function getOptionValue(Directive $directive, Option|null $option): mixe
198208
OptionType::Boolean => $value === null || filter_var($value, FILTER_VALIDATE_BOOL),
199209
OptionType::String => (string) $value,
200210
OptionType::Array => (array) $value,
201-
default => $value,
202211
};
203212
}
204213

205-
206214
/**
207215
* Finds the Option attribute for the given option name on the current class.
208216
*
209217
* @param string $optionName The option name to look for
210218
*
211219
* @return Option|null The Option attribute if found, null otherwise
212220
*/
213-
private function findOptionAttribute(string $optionName): ?Option
221+
private function findOptionAttribute(string $optionName): Option|null
214222
{
215223
$this->initialize();
216224

@@ -223,7 +231,7 @@ private function initialize(): void
223231
return;
224232
}
225233

226-
$reflection = new \ReflectionClass($this);
234+
$reflection = new ReflectionClass($this);
227235
$attributes = $reflection->getAttributes(Option::class);
228236
$this->optionAttributeCache = [];
229237
foreach ($attributes as $attribute) {
@@ -232,5 +240,3 @@ private function initialize(): void
232240
}
233241
}
234242
}
235-
236-

packages/guides-restructured-text/src/RestructuredText/Directives/CautionDirective.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* This is a caution admonition.
2727
* ```
2828
*/
29+
#[Attributes\Directive(name: 'caution')]
2930
final class CautionDirective extends AbstractAdmonitionDirective
3031
{
3132
public function __construct(protected Rule $startingRule)

packages/guides-restructured-text/src/RestructuredText/Directives/CsvTableDirective.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use phpDocumentor\Guides\Nodes\Table\TableColumn;
2121
use phpDocumentor\Guides\Nodes\Table\TableRow;
2222
use phpDocumentor\Guides\Nodes\TableNode;
23-
use phpDocumentor\Guides\RestructuredText\Directives\Attributes\Option;
2423
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
2524
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
2625
use phpDocumentor\Guides\RestructuredText\Parser\Productions\RuleContainer;

0 commit comments

Comments
 (0)