Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use phpDocumentor\Guides\ReferenceResolvers\DocumentNameResolverInterface;
use phpDocumentor\Guides\RestructuredText\Compiler\Passes\DirectiveProcessPass;
use phpDocumentor\Guides\RestructuredText\Directives\AdmonitionDirective;
use phpDocumentor\Guides\RestructuredText\Directives\AttentionDirective;
use phpDocumentor\Guides\RestructuredText\Directives\BaseDirective;
Expand Down Expand Up @@ -279,6 +280,7 @@
->tag('phpdoc.guides.parser.rst.body_element', ['priority' => ParagraphRule::PRIORITY + 1])
->set(DirectiveRule::class)
->arg('$directives', tagged_iterator('phpdoc.guides.directive'))
->arg('$startingRule', service(DirectiveContentRule::class))
->tag('phpdoc.guides.parser.rst.body_element', ['priority' => DirectiveRule::PRIORITY])
->set(CommentRule::class)
->tag('phpdoc.guides.parser.rst.body_element', ['priority' => CommentRule::PRIORITY])
Expand Down Expand Up @@ -377,6 +379,10 @@
->set(GlobSearcher::class)
->set(ToctreeBuilder::class)
->set(InlineMarkupRule::class)

->set(DirectiveProcessPass::class)
->arg('$directives', tagged_iterator('phpdoc.guides.directive'))
->tag('phpdoc.guides.compiler.nodeTransformers')
->set(DefaultCodeNodeOptionMapper::class)
->alias(CodeNodeOptionMapper::class, DefaultCodeNodeOptionMapper::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\RestructuredText\Compiler\Passes;

use phpDocumentor\Guides\Compiler\CompilerContext;
use phpDocumentor\Guides\Compiler\NodeTransformer;
use phpDocumentor\Guides\Compiler\ReverseNodeTransformer;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\RestructuredText\Directives\BaseDirective as DirectiveHandler;
use phpDocumentor\Guides\RestructuredText\Directives\GeneralDirective;
use phpDocumentor\Guides\RestructuredText\Nodes\DirectiveNode;
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
use Psr\Log\LoggerInterface;

use function array_merge;
use function strtolower;

/** @implements NodeTransformer<DirectiveNode> */
final class DirectiveProcessPass implements ReverseNodeTransformer

Check failure on line 30 in packages/guides-restructured-text/src/RestructuredText/Compiler/Passes/DirectiveProcessPass.php

View workflow job for this annotation

GitHub Actions / Static analysis / Static Code Analysis (8.2)

The @implements tag of class phpDocumentor\Guides\RestructuredText\Compiler\Passes\DirectiveProcessPass describes phpDocumentor\Guides\Compiler\NodeTransformer but the class implements: phpDocumentor\Guides\Compiler\ReverseNodeTransformer
{
/** @var array<string, DirectiveHandler> */
private array $directives;

/** @param iterable<DirectiveHandler> $directives */
public function __construct(
private readonly LoggerInterface $logger,

Check failure on line 37 in packages/guides-restructured-text/src/RestructuredText/Compiler/Passes/DirectiveProcessPass.php

View workflow job for this annotation

GitHub Actions / Static analysis / Static Code Analysis (8.2)

Property phpDocumentor\Guides\RestructuredText\Compiler\Passes\DirectiveProcessPass::$logger is never read, only written.
private readonly GeneralDirective $generalDirective,
iterable $directives = [],
) {
foreach ($directives as $directive) {
$this->registerDirective($directive);
}
}

private function registerDirective(DirectiveHandler $directive): void
{
$this->directives[strtolower($directive->getName())] = $directive;
foreach ($directive->getAliases() as $alias) {
$this->directives[strtolower($alias)] = $directive;
}
}

public function enterNode(Node $node, CompilerContext $compilerContext): Node
{
return $node;
}

public function leaveNode(Node $node, CompilerContext $compilerContext): Node|null
{
$newNode = $this->getDirectiveHandler($node->getDirective())->createNode($node);

Check failure on line 61 in packages/guides-restructured-text/src/RestructuredText/Compiler/Passes/DirectiveProcessPass.php

View workflow job for this annotation

GitHub Actions / Static analysis / Static Code Analysis (8.2)

Parameter #1 $directiveNode of method phpDocumentor\Guides\RestructuredText\Directives\BaseDirective::createNode() expects phpDocumentor\Guides\RestructuredText\Nodes\DirectiveNode, phpDocumentor\Guides\Nodes\Node given.

Check failure on line 61 in packages/guides-restructured-text/src/RestructuredText/Compiler/Passes/DirectiveProcessPass.php

View workflow job for this annotation

GitHub Actions / Static analysis / Static Code Analysis (8.2)

Call to an undefined method phpDocumentor\Guides\Nodes\Node::getDirective().
if ($newNode === null) {
return null;
}

$newNode->setClasses(array_merge($newNode->getClasses(), $node->getClasses()));

return $newNode;
}

private function getDirectiveHandler(Directive $directive): DirectiveHandler
{
return $this->directives[strtolower($directive->getName())] ?? $this->generalDirective;
}

public function supports(Node $node): bool
{
return $node instanceof DirectiveNode;
}

public function getPriority(): int
{
return 100;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use phpDocumentor\Guides\Nodes\CollectionNode;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\Nodes\ParagraphNode;
use phpDocumentor\Guides\RestructuredText\Nodes\DirectiveNode;
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\Rule;
Expand All @@ -25,7 +26,7 @@

abstract class AbstractAdmonitionDirective extends SubDirective
{
public function __construct(protected Rule $startingRule, private readonly string $name, private readonly string $text)

Check failure on line 29 in packages/guides-restructured-text/src/RestructuredText/Directives/AbstractAdmonitionDirective.php

View workflow job for this annotation

GitHub Actions / Static analysis / Static Code Analysis (8.2)

Property phpDocumentor\Guides\RestructuredText\Directives\AbstractAdmonitionDirective::$name is never read, only written.
{
parent::__construct($startingRule);
}
Expand All @@ -39,22 +40,30 @@
CollectionNode $collectionNode,
Directive $directive,
): Node|null {
$children = $collectionNode->getChildren();
return $this->createNode(
new DirectiveNode(
$directive,
$collectionNode->getChildren(),
),
);
}

if ($directive->getDataNode() !== null) {
array_unshift($children, new ParagraphNode([$directive->getDataNode()]));
public function createNode(DirectiveNode $directiveNode): Node|null
{
$children = $directiveNode->getChildren();
if ($directiveNode->getDirective()->getDataNode() !== null) {
array_unshift($children, new ParagraphNode([$directiveNode->getDirective()->getDataNode()]));
}

return new AdmonitionNode(
$this->name,
$node = new AdmonitionNode(
$directiveNode->getDirective()->getName(),
null,
$this->text,
$children,
);
}

final public function getName(): string
{
return $this->name;
$node->setClasses([$directiveNode->getDirective()->getOptionString('class')]);

return $node;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@

namespace phpDocumentor\Guides\RestructuredText\Directives;

use Doctrine\Deprecations\Deprecation;
use LogicException;
use phpDocumentor\Guides\Nodes\CollectionNode;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\RestructuredText\Nodes\DirectiveNode;
use phpDocumentor\Guides\RestructuredText\Nodes\VersionChangeNode;
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\Rule;

use function sprintf;

/** @see https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-versionadded */
abstract class AbstractVersionChangeDirective extends SubDirective
{
Expand All @@ -37,16 +42,39 @@ final protected function processSub(
CollectionNode $collectionNode,
Directive $directive,
): Node|null {
return new VersionChangeNode(
$this->type,
$this->label,
$directive->getData(),
$collectionNode->getChildren(),
return $this->createNode(
new DirectiveNode(
$directive,
$collectionNode->getChildren(),
),
);
}

final public function getName(): string
public function getName(): string
{
try {
return parent::getName();
} catch (LogicException) {
Deprecation::trigger(
'phpdocumentor/guides-restructured-text',
'TODO: link',
sprintf(
'Directives without attributes are deprecated, consult the documentation for more information on how to update your directives. Directive: %s',
$this->type,
),
);

return $this->type;
}
}

public function createNode(DirectiveNode $directiveNode): Node|null
{
return $this->type;
return new VersionChangeNode(
$this->type,
$this->label,
$directiveNode->getDirective()->getData(),
$directiveNode->getChildren(),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use phpDocumentor\Guides\Nodes\AdmonitionNode;
use phpDocumentor\Guides\Nodes\CollectionNode;
use phpDocumentor\Guides\Nodes\Node;
use phpDocumentor\Guides\RestructuredText\Nodes\DirectiveNode;
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
use phpDocumentor\Guides\RestructuredText\Parser\Directive;

Expand All @@ -34,13 +35,9 @@
*
* @see https://docutils.sourceforge.io/docs/ref/rst/directives.html#generic-admonition
*/
#[Attributes\Directive(name: 'admonition')]
final class AdmonitionDirective extends SubDirective
{
public function getName(): string
{
return 'admonition';
}

/** {@inheritDoc}
*
* @param Directive $directive
Expand All @@ -50,22 +47,32 @@ protected function processSub(
CollectionNode $collectionNode,
Directive $directive,
): Node|null {
return $this->createNode(
new DirectiveNode(
$directive,
$collectionNode->getChildren(),
),
);
}

public function createNode(DirectiveNode $directiveNode): Node|null
{
// The title argument is required per the RST spec.
// Skip rendering if no title is provided.
if ($directive->getData() === '') {
if ($directiveNode->getDirective()->getData() === '') {
return null;
}

$name = trim(
preg_replace('/[^0-9a-zA-Z]+/', '-', strtolower($directive->getData())) ?? '',
preg_replace('/[^0-9a-zA-Z]+/', '-', strtolower($directiveNode->getDirective()->getData())) ?? '',
'-',
);

return new AdmonitionNode(
$name,
$directive->getDataNode(),
$directive->getData(),
$collectionNode->getChildren(),
$directiveNode->getDirective()->getDataNode(),
$directiveNode->getDirective()->getData(),
$directiveNode->getChildren(),
true,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* This is an attention admonition.
* ```
*/
#[Attributes\Directive(name: 'attention')]
final class AttentionDirective extends AbstractAdmonitionDirective
{
public function __construct(protected Rule $startingRule)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\RestructuredText\Directives\Attributes;

use Attribute;

#[Attribute(Attribute::TARGET_CLASS)]
final class Directive
{
/** @param string[] $aliases */
public function __construct(
public readonly string $name,
public readonly array $aliases = [],
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\RestructuredText\Directives\Attributes;

use Attribute;
use phpDocumentor\Guides\RestructuredText\Directives\OptionType;

#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
final class Option
{
public function __construct(
public readonly string $name,
public readonly OptionType $type = OptionType::String,
public readonly mixed $default = null,
public readonly string $description = '',
public readonly string|null $example = null,
) {
}
}
Loading
Loading