Skip to content

Commit

Permalink
Merge pull request #791 from phpDocumentor/feature/interlinkparser
Browse files Browse the repository at this point in the history
[FEATURE] Introduce exchangeable InterlinkParser
  • Loading branch information
jaapio authored Dec 31, 2023
2 parents 434b877 + b1c2e0a commit 21fa962
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
use phpDocumentor\Guides\RestructuredText\MarkupLanguageParser;
use phpDocumentor\Guides\RestructuredText\Parser\DocumentParserContextFactory;
use phpDocumentor\Guides\RestructuredText\Parser\InlineParser;
use phpDocumentor\Guides\RestructuredText\Parser\Interlink\DefaultInterlinkParser;
use phpDocumentor\Guides\RestructuredText\Parser\Interlink\InterlinkParser;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\AnnotationRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\BlockQuoteRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\CommentRule;
Expand Down Expand Up @@ -232,6 +234,8 @@
->set('phpdoc.guides.parser.rst.body_elements', RuleContainer::class)
->set('phpdoc.guides.parser.rst.structural_elements', RuleContainer::class)

->set(InterlinkParser::class, DefaultInterlinkParser::class)

->set(AnnotationRule::class)
->tag('phpdoc.guides.parser.rst.body_element', ['priority' => AnnotationRule::PRIORITY])
->set(LinkRule::class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\RestructuredText\Parser\Interlink;

use function preg_match;

final class DefaultInterlinkParser implements InterlinkParser
{
/** @see https://regex101.com/r/htMn5p/1 */
private const INTERLINK_REGEX = '/^([a-zA-Z0-9-_]+):(.*$)/';

public function extractInterlink(string $fullReference): InterlinkData
{
if (!preg_match(self::INTERLINK_REGEX, $fullReference, $matches)) {
return new InterlinkData($fullReference, '');
}

return new InterlinkData($matches[2], $matches[1] ?? '');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\RestructuredText\Parser\Interlink;

class InterlinkData
{
public function __construct(
public readonly string $reference,
public readonly string $interlink,
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\RestructuredText\Parser\Interlink;

interface InterlinkParser
{
public function extractInterlink(string $fullReference): InterlinkData;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ abstract class AbstractReferenceTextRole implements TextRole
{
use EmbeddedUriParser;

/** @see https://regex101.com/r/htMn5p/1 */
public const INTERLINK_REGEX = '/^([a-zA-Z0-9-_]+):(.*$)/';

public function processNode(
DocumentParserContext $documentParserContext,
string $role,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@

use phpDocumentor\Guides\Nodes\Inline\AbstractLinkInlineNode;
use phpDocumentor\Guides\Nodes\Inline\DocReferenceNode;

use function preg_match;
use phpDocumentor\Guides\RestructuredText\Parser\Interlink\InterlinkParser;

class DocReferenceTextRole extends AbstractReferenceTextRole
{
final public const NAME = 'doc';

public function __construct(
private readonly InterlinkParser $interlinkParser,
) {
}

public function getName(): string
{
return self::NAME;
Expand All @@ -27,15 +31,8 @@ public function getAliases(): array
/** @return DocReferenceNode */
protected function createNode(string $referenceTarget, string|null $referenceName, string $role): AbstractLinkInlineNode
{
$pattern = AbstractReferenceTextRole::INTERLINK_REGEX;
if (preg_match($pattern, $referenceTarget, $matches)) {
$interlinkDomain = $matches[1];
$path = $matches[2];
} else {
$interlinkDomain = '';
$path = $referenceTarget;
}

return new DocReferenceNode($path, $referenceName ?? '', $interlinkDomain);
$interlinkData = $this->interlinkParser->extractInterlink($referenceTarget);

return new DocReferenceNode($interlinkData->reference, $referenceName ?? '', $interlinkData->interlink);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
use phpDocumentor\Guides\Nodes\Inline\AbstractLinkInlineNode;
use phpDocumentor\Guides\Nodes\Inline\ReferenceNode;
use phpDocumentor\Guides\ReferenceResolvers\AnchorReducer;
use phpDocumentor\Guides\RestructuredText\Parser\Interlink\InterlinkParser;

use function array_keys;
use function preg_match;

class GenericReferenceTextRole extends AbstractReferenceTextRole
{
public function __construct(
private readonly GenericLinkProvider $genericLinkProvider,
private readonly AnchorReducer $anchorReducer,
private readonly InterlinkParser $interlinkParser,
) {
}

Expand All @@ -34,15 +35,9 @@ public function getAliases(): array
protected function createNode(string $referenceTarget, string|null $referenceName, string $role): AbstractLinkInlineNode
{
$linkType = $this->genericLinkProvider->getLinkType($role);
$pattern = '/^([a-zA-Z0-9]+):(.*$)/';
if (preg_match(AbstractReferenceTextRole::INTERLINK_REGEX, $referenceTarget, $matches)) {
$interlinkDomain = $matches[1];
$id = $this->anchorReducer->reduceAnchor($matches[2]);
} else {
$interlinkDomain = '';
$id = $this->anchorReducer->reduceAnchor($referenceTarget);
}

return new ReferenceNode($id, $referenceName ?? '', $interlinkDomain, $linkType);
$interlinkData = $this->interlinkParser->extractInterlink($referenceTarget);
$reference = $this->anchorReducer->reduceAnchor($interlinkData->reference);

return new ReferenceNode($reference, $referenceName ?? '', $interlinkData->interlink, $linkType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use phpDocumentor\Guides\Nodes\InlineCompoundNode;
use phpDocumentor\Guides\ParserContext;
use phpDocumentor\Guides\RestructuredText\MarkupLanguageParser;
use phpDocumentor\Guides\RestructuredText\Parser\Interlink\DefaultInterlinkParser;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\InlineRules\AnnotationRoleRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\InlineRules\AnonymousPhraseRule;
use phpDocumentor\Guides\RestructuredText\Parser\Productions\InlineRules\AnonymousReferenceRule;
Expand Down Expand Up @@ -53,7 +54,7 @@ public function setUp(): void
new LiteralTextRole(),
[
new ReferenceTextRole(),
new DocReferenceTextRole(),
new DocReferenceTextRole(new DefaultInterlinkParser()),
],
);
$this->documentParserContext = new DocumentParserContext(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use phpDocumentor\Guides\Nodes\Inline\DocReferenceNode;
use phpDocumentor\Guides\RestructuredText\Parser\DocumentParserContext;
use phpDocumentor\Guides\RestructuredText\Parser\Interlink\DefaultInterlinkParser;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
Expand All @@ -18,7 +19,7 @@ class DocReferenceTextRoleTest extends TestCase
public function setUp(): void
{
$this->documentParserContext = $this->createMock(DocumentParserContext::class);
$this->docReferenceTextRole = new DocReferenceTextRole();
$this->docReferenceTextRole = new DocReferenceTextRole(new DefaultInterlinkParser());
}

#[DataProvider('docReferenceProvider')]
Expand Down

0 comments on commit 21fa962

Please sign in to comment.