Skip to content
Merged
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 @@ -6,8 +6,8 @@

use phpDocumentor\Guides\Nodes\Inline\AbstractLinkInlineNode;
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
use phpDocumentor\Guides\RestructuredText\Parser\EmbeddedUriParser;
use phpDocumentor\Guides\RestructuredText\Parser\InlineLexer;
use phpDocumentor\Guides\RestructuredText\Parser\References\EmbeddedReferenceParser;

/**
* Rule to parse for anonymous references
Expand All @@ -21,7 +21,7 @@
*/
class AnonymousPhraseRule extends ReferenceRule
{
use EmbeddedUriParser;
use EmbeddedReferenceParser;

public function applies(InlineLexer $lexer): bool
{
Expand Down Expand Up @@ -61,16 +61,10 @@ public function apply(BlockContext $blockContext, InlineLexer $lexer): AbstractL

private function createAnonymousReference(BlockContext $blockContext, string $value): AbstractLinkInlineNode
{
$parsed = $this->extractEmbeddedUri($value);
$link = $parsed['text'];
$uri = $parsed['uri'];
if ($link === null) {
$link = $uri;
$uri = null;
}
$referenceData = $this->extractEmbeddedReference($value);

$node = $this->createReference($blockContext, $link, $uri, false);
$blockContext->getDocumentParserContext()->pushAnonymous($link);
$node = $this->createReference($blockContext, $referenceData->reference, $referenceData->text, false);
$blockContext->getDocumentParserContext()->pushAnonymous($referenceData->reference);

return $node;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

use phpDocumentor\Guides\Nodes\Inline\InlineNode;
use phpDocumentor\Guides\RestructuredText\Parser\BlockContext;
use phpDocumentor\Guides\RestructuredText\Parser\EmbeddedUriParser;
use phpDocumentor\Guides\RestructuredText\Parser\InlineLexer;
use phpDocumentor\Guides\RestructuredText\Parser\References\EmbeddedReferenceParser;

/**
* Rule to parse for named references
Expand All @@ -21,7 +21,7 @@
*/
class NamedPhraseRule extends ReferenceRule
{
use EmbeddedUriParser;
use EmbeddedReferenceParser;

public function applies(InlineLexer $lexer): bool
{
Expand All @@ -45,15 +45,9 @@ public function apply(BlockContext $blockContext, InlineLexer $lexer): InlineNod

$lexer->moveNext();

$parsed = $this->extractEmbeddedUri($value);
$text = $parsed['text'];
$uri = $parsed['uri'];
if ($text === null) {
$text = $uri;
$uri = null;
}
$referenceData = $this->extractEmbeddedReference($value);

return $this->createReference($blockContext, $text, $uri);
return $this->createReference($blockContext, $referenceData->reference, $referenceData->text);

case InlineLexer::WHITESPACE:
$value .= ' ';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,23 @@

abstract class ReferenceRule extends AbstractInlineRule
{
protected function createReference(BlockContext $blockContext, string $link, string|null $embeddedUrl = null, bool $registerLink = true): AbstractLinkInlineNode
protected function createReference(BlockContext $blockContext, string $reference, string|null $text = null, bool $registerLink = true): AbstractLinkInlineNode
{
// the link may have a new line in it, so we need to strip it
// before setting the link and adding a token to be replaced
$link = str_replace("\n", ' ', $link);
$link = trim(preg_replace('/\s+/', ' ', $link) ?? '');
$reference = str_replace("\n", ' ', $reference);
$reference = trim(preg_replace('/\s+/', ' ', $reference) ?? '');

$targetLink = $embeddedUrl ?? $link;
if (str_ends_with($targetLink, '.rst') && filter_var($targetLink, FILTER_VALIDATE_URL) === false) {
$targetLink = substr($targetLink, 0, -4);
if (str_ends_with($reference, '.rst') && filter_var($reference, FILTER_VALIDATE_URL) === false) {
$reference = substr($reference, 0, -4);

return new DocReferenceNode($targetLink, $link);
return new DocReferenceNode($reference, $text ?? $reference);
}

if ($registerLink && $embeddedUrl !== null) {
$blockContext->getDocumentParserContext()->setLink($link, $embeddedUrl);
if ($registerLink && $text !== null) {
$blockContext->getDocumentParserContext()->setLink($text, $reference);
}

return new HyperLinkNode($link, $targetLink);
return new HyperLinkNode($text ?? $reference, $reference);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,26 @@

declare(strict_types=1);

namespace phpDocumentor\Guides\RestructuredText\Parser;
namespace phpDocumentor\Guides\RestructuredText\Parser\References;

use function preg_match;

trait EmbeddedUriParser
trait EmbeddedReferenceParser
{
/** @return array{text:?string,uri:string} */
private function extractEmbeddedUri(string $text): array
private function extractEmbeddedReference(string $text): ReferenceData
{
preg_match('/^(.*?)(?:(?:\s|^)<([^<]+)>)?$/s', $text, $matches);

$text = $matches[1] === '' ? null : $matches[1];
$uri = $matches[1];
$reference = $matches[1];

if (isset($matches[2])) {
// there is an embedded URI, text and URI are different
$uri = $matches[2];
$reference = $matches[2];
} else {
$text = null;
}

return ['text' => $text, 'uri' => $uri];
return new ReferenceData($reference, $text);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace phpDocumentor\Guides\RestructuredText\Parser\References;

final class ReferenceData
{
public function __construct(
public readonly string $reference,
public readonly string|null $text,
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@

use phpDocumentor\Guides\Nodes\Inline\AbstractLinkInlineNode;
use phpDocumentor\Guides\RestructuredText\Parser\DocumentParserContext;
use phpDocumentor\Guides\RestructuredText\Parser\EmbeddedUriParser;
use phpDocumentor\Guides\RestructuredText\Parser\References\EmbeddedReferenceParser;

/** @see https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#embedded-uris-and-aliases */
abstract class AbstractReferenceTextRole implements TextRole
{
use EmbeddedUriParser;
use EmbeddedReferenceParser;

public function processNode(
DocumentParserContext $documentParserContext,
string $role,
string $content,
string $rawContent,
): AbstractLinkInlineNode {
$parsed = $this->extractEmbeddedUri($content);
$referenceData = $this->extractEmbeddedReference($content);

return $this->createNode($parsed['uri'], $parsed['text'], $role);
return $this->createNode($referenceData->reference, $referenceData->text, $role);
}

abstract protected function createNode(string $referenceTarget, string|null $referenceName, string $role): AbstractLinkInlineNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

use phpDocumentor\Guides\Nodes\Menu\MenuDefinitionLineNode;
use phpDocumentor\Guides\ParserContext;
use phpDocumentor\Guides\RestructuredText\Parser\EmbeddedUriParser;
use phpDocumentor\Guides\RestructuredText\Parser\LinesIterator;
use phpDocumentor\Guides\RestructuredText\Parser\References\EmbeddedReferenceParser;

use function array_filter;
use function array_map;

class ToctreeBuilder
{
use EmbeddedUriParser;
use EmbeddedReferenceParser;

/**
* @param mixed[] $options
Expand Down Expand Up @@ -45,8 +45,8 @@ private function parseToctreeEntryLines(LinesIterator $lines): array

$result = [];
foreach ($linesArray as $line) {
$parsed = $this->extractEmbeddedUri($line);
$result[] = new MenuDefinitionLineNode($parsed['uri'], $parsed['text']);
$referenceData = $this->extractEmbeddedReference($line);
$result[] = new MenuDefinitionLineNode($referenceData->reference, $referenceData->text);
}

return $result;
Expand Down