diff --git a/packages/typo3-docs-theme/src/Compiler/NodeTransformers/RedirectsNodeTransformer.php b/packages/typo3-docs-theme/src/Compiler/NodeTransformers/RedirectsNodeTransformer.php index 8f99f3e89..cf744e44d 100644 --- a/packages/typo3-docs-theme/src/Compiler/NodeTransformers/RedirectsNodeTransformer.php +++ b/packages/typo3-docs-theme/src/Compiler/NodeTransformers/RedirectsNodeTransformer.php @@ -17,6 +17,7 @@ use phpDocumentor\Guides\Compiler\NodeTransformer; use phpDocumentor\Guides\Nodes\Inline\CrossReferenceNode; use phpDocumentor\Guides\Nodes\Inline\ReferenceNode; +use phpDocumentor\Guides\Nodes\InlineCompoundNode; use phpDocumentor\Guides\Nodes\Node; use phpDocumentor\Guides\Nodes\PrefixedLinkTargetNode; use T3Docs\Typo3DocsTheme\Inventory\Typo3VersionService; @@ -50,8 +51,8 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext) if ($node instanceof PrefixedLinkTargetNode) { $prefix = $node->getPrefix(); } - assert(is_string($node->getValue())); - return new ReferenceNode('guide-' . $node->getTargetReference(), $node->getValue(), $node->getInterlinkDomain(), $node->getInterlinkGroup(), $prefix); + assert($node instanceof InlineCompoundNode); + return new ReferenceNode('guide-' . $node->getTargetReference(), $node->getChildren(), $node->getInterlinkDomain(), $node->getInterlinkGroup(), $prefix); } return $node; } diff --git a/packages/typo3-docs-theme/src/Compiler/NodeTransformers/RemoveInterlinkSelfReferencesFromCrossReferenceNodeTransformer.php b/packages/typo3-docs-theme/src/Compiler/NodeTransformers/RemoveInterlinkSelfReferencesFromCrossReferenceNodeTransformer.php index 145e490b5..cafbdb977 100644 --- a/packages/typo3-docs-theme/src/Compiler/NodeTransformers/RemoveInterlinkSelfReferencesFromCrossReferenceNodeTransformer.php +++ b/packages/typo3-docs-theme/src/Compiler/NodeTransformers/RemoveInterlinkSelfReferencesFromCrossReferenceNodeTransformer.php @@ -49,7 +49,7 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext) if ($node instanceof ReferenceNode) { $newRef = new ReferenceNode( $node->getTargetReference(), - $node->getValue(), + $node->getChildren(), '', $node->getLinkType(), $node->getPrefix() @@ -59,7 +59,7 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext) if ($node instanceof DocReferenceNode) { $newDocRef = new DocReferenceNode( $node->getTargetReference(), - $node->getValue(), + $node->getChildren(), ); return $newDocRef; } diff --git a/packages/typo3-docs-theme/src/Compiler/NodeTransformers/ReplacePermalinksNodeTransformer.php b/packages/typo3-docs-theme/src/Compiler/NodeTransformers/ReplacePermalinksNodeTransformer.php index 4edb1c41c..22572c483 100644 --- a/packages/typo3-docs-theme/src/Compiler/NodeTransformers/ReplacePermalinksNodeTransformer.php +++ b/packages/typo3-docs-theme/src/Compiler/NodeTransformers/ReplacePermalinksNodeTransformer.php @@ -38,10 +38,9 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext) if (!str_starts_with($node->getTargetReference(), 'https://docs.typo3.org/permalink/')) { return $node; } - $value = $node->getValue(); - if ($value === $node->getTargetReference()) { - $value = ''; - } + // When the link's visible label equals its URL (auto-linkified plain URL), + // drop the children so the resolver fills in the canonical title. + $children = $node->toString() === $node->getTargetReference() ? [] : $node->getChildren(); $url = str_replace('https://docs.typo3.org/permalink/', '', ($node->getTargetReference())); $version = null; $interlink = null; @@ -54,7 +53,7 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext) if ($version !== null && $interlink !== null) { $interlink = $interlink . '/' . $version; } - $node = new ReferenceNode($url, $value, $interlink ?? ''); + $node = new ReferenceNode($url, $children, $interlink ?? ''); return $node; } diff --git a/packages/typo3-docs-theme/src/Nodes/Inline/FileInlineNode.php b/packages/typo3-docs-theme/src/Nodes/Inline/FileInlineNode.php index 9d56b895f..872383b7e 100644 --- a/packages/typo3-docs-theme/src/Nodes/Inline/FileInlineNode.php +++ b/packages/typo3-docs-theme/src/Nodes/Inline/FileInlineNode.php @@ -18,7 +18,7 @@ public function __construct( private string $interlinkDomain, private string $linkType ) { - parent::__construct(self::TYPE, $fileLink, $fileLabel, [new PlainTextInlineNode($fileLabel)]); + parent::__construct(self::TYPE, $fileLink, [new PlainTextInlineNode($fileLabel)]); } public function getFileLink(): string diff --git a/packages/typo3-docs-theme/src/TextRoles/ApiClassTextRole.php b/packages/typo3-docs-theme/src/TextRoles/ApiClassTextRole.php index 50446da3a..a051ea7da 100644 --- a/packages/typo3-docs-theme/src/TextRoles/ApiClassTextRole.php +++ b/packages/typo3-docs-theme/src/TextRoles/ApiClassTextRole.php @@ -14,6 +14,7 @@ namespace T3Docs\Typo3DocsTheme\TextRoles; use phpDocumentor\Guides\Nodes\Inline\AbstractLinkInlineNode; +use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode; use phpDocumentor\Guides\Nodes\Inline\ReferenceNode; use phpDocumentor\Guides\ReferenceResolvers\AnchorNormalizer; use phpDocumentor\Guides\RestructuredText\Parser\Interlink\InterlinkParser; @@ -54,6 +55,6 @@ protected function createNode(string $referenceTarget, string|null $referenceNam $interlink = 'api'; } - return new ReferenceNode($reference, $referenceName ?? '', $interlink, self::TYPE, $prefix); + return new ReferenceNode($reference, $referenceName ? [new PlainTextInlineNode($referenceName)] : [], $interlink, self::TYPE, $prefix); } } diff --git a/packages/typo3-docs-theme/src/TextRoles/CustomLinkTextRole.php b/packages/typo3-docs-theme/src/TextRoles/CustomLinkTextRole.php index 4764454b3..516c3615b 100644 --- a/packages/typo3-docs-theme/src/TextRoles/CustomLinkTextRole.php +++ b/packages/typo3-docs-theme/src/TextRoles/CustomLinkTextRole.php @@ -5,6 +5,7 @@ namespace T3Docs\Typo3DocsTheme\TextRoles; use phpDocumentor\Guides\Nodes\Inline\AbstractLinkInlineNode; +use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode; use phpDocumentor\Guides\Nodes\Inline\ReferenceNode; use phpDocumentor\Guides\ReferenceResolvers\AnchorNormalizer; use phpDocumentor\Guides\RestructuredText\Parser\DocumentParserContext; @@ -56,7 +57,7 @@ protected function createNode(DocumentParserContext $documentParserContext, stri $id = $this->anchorReducer->reduceAnchor($referenceTarget); } - return new ReferenceNode($id, $referenceName ?? '', $interlinkDomain, 'php:' . $this->getName()); + return new ReferenceNode($id, $referenceName ? [new PlainTextInlineNode($referenceName)] : [], $interlinkDomain, 'php:' . $this->getName()); } /** @return array{text:?string,uri:string} */ diff --git a/packages/typo3-docs-theme/src/TextRoles/FileTextRole.php b/packages/typo3-docs-theme/src/TextRoles/FileTextRole.php index 5f3a6246c..02ac1b4ff 100644 --- a/packages/typo3-docs-theme/src/TextRoles/FileTextRole.php +++ b/packages/typo3-docs-theme/src/TextRoles/FileTextRole.php @@ -20,11 +20,11 @@ public function getAliases(): array protected function createNode(DocumentParserContext $documentParserContext, string $referenceTarget, string|null $referenceName, string $role): AbstractLinkInlineNode { - return $this->createNodeWithInterlink($documentParserContext, $referenceTarget, '', $referenceName); + return $this->createNodeWithInterlink($documentParserContext, $referenceTarget, '', $referenceName ?? $referenceTarget); } - private function createNodeWithInterlink(DocumentParserContext $documentParserContext, string $referenceTarget, string $interlinkDomain, string|null $referenceName): AbstractLinkInlineNode + private function createNodeWithInterlink(DocumentParserContext $documentParserContext, string $referenceTarget, string $interlinkDomain, string $fileLabel): AbstractLinkInlineNode { - return new FileInlineNode($referenceTarget, $referenceName ?? $referenceTarget, $interlinkDomain, 'typo3:file'); + return new FileInlineNode($referenceTarget, $fileLabel, $interlinkDomain, 'typo3:file'); } } diff --git a/packages/typo3-docs-theme/src/TextRoles/IssueReferenceTextRole.php b/packages/typo3-docs-theme/src/TextRoles/IssueReferenceTextRole.php index 7fbe523b3..fc1f863ea 100644 --- a/packages/typo3-docs-theme/src/TextRoles/IssueReferenceTextRole.php +++ b/packages/typo3-docs-theme/src/TextRoles/IssueReferenceTextRole.php @@ -6,6 +6,7 @@ use phpDocumentor\Guides\Nodes\Inline\AbstractLinkInlineNode; use phpDocumentor\Guides\Nodes\Inline\HyperLinkNode; +use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode; use phpDocumentor\Guides\RestructuredText\TextRoles\AbstractReferenceTextRole; use Psr\Log\LoggerInterface; @@ -37,8 +38,10 @@ protected function createNode(string $referenceTarget, string|null $referenceNam { if ((int)$referenceTarget <= 0) { $this->logger->warning(sprintf('Expected a positive integer as issue number. Found %s', $referenceTarget)); - return new HyperLinkNode($referenceName ?? 'Forge', self::FORGE_URL); + $label = $referenceName ?? 'Forge'; + return new HyperLinkNode([new PlainTextInlineNode($label)], self::FORGE_URL); } - return new HyperLinkNode($referenceName ?? sprintf(self::FORGE_DEFAULT_LABEL, $referenceTarget), sprintf(self::FORGE_ISSUE_URL, $referenceTarget)); + $label = $referenceName ?? sprintf(self::FORGE_DEFAULT_LABEL, $referenceTarget); + return new HyperLinkNode([new PlainTextInlineNode($label)], sprintf(self::FORGE_ISSUE_URL, $referenceTarget)); } } diff --git a/packages/typo3-docs-theme/src/TextRoles/T3extTextRole.php b/packages/typo3-docs-theme/src/TextRoles/T3extTextRole.php index e1bc4115d..64cf06bee 100644 --- a/packages/typo3-docs-theme/src/TextRoles/T3extTextRole.php +++ b/packages/typo3-docs-theme/src/TextRoles/T3extTextRole.php @@ -3,6 +3,7 @@ namespace T3Docs\Typo3DocsTheme\TextRoles; use phpDocumentor\Guides\Nodes\Inline\HyperLinkNode; +use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode; use phpDocumentor\Guides\RestructuredText\Parser\DocumentParserContext; use phpDocumentor\Guides\RestructuredText\Parser\References\EmbeddedReferenceParser; use phpDocumentor\Guides\RestructuredText\TextRoles\TextRole; @@ -46,6 +47,6 @@ protected function createNode( } $terLink = sprintf('https://extensions.typo3.org/extension/%s', $extKey); $extName = $referenceName ?? 'EXT:' . $extKey; - return new HyperLinkNode($extName, $terLink); + return new HyperLinkNode([new PlainTextInlineNode($extName)], $terLink); } } diff --git a/packages/typo3-docs-theme/src/TextRoles/T3srcTextRole.php b/packages/typo3-docs-theme/src/TextRoles/T3srcTextRole.php index 19542e018..a4747cad5 100644 --- a/packages/typo3-docs-theme/src/TextRoles/T3srcTextRole.php +++ b/packages/typo3-docs-theme/src/TextRoles/T3srcTextRole.php @@ -3,6 +3,7 @@ namespace T3Docs\Typo3DocsTheme\TextRoles; use phpDocumentor\Guides\Nodes\Inline\HyperLinkNode; +use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode; use phpDocumentor\Guides\RestructuredText\Parser\DocumentParserContext; use phpDocumentor\Guides\RestructuredText\Parser\References\EmbeddedReferenceParser; use phpDocumentor\Guides\RestructuredText\TextRoles\TextRole; @@ -55,6 +56,6 @@ protected function createNode( } $gitHubLink = sprintf('https://github.com/typo3/typo3/blob/%s/%s', $typo3Version, $fileLink); $fileName = $referenceName ?? str_replace('typo3/sysext/', 'EXT:', $fileLink) . ' (GitHub)'; - return new HyperLinkNode($fileName, $gitHubLink); + return new HyperLinkNode([new PlainTextInlineNode($fileName)], $gitHubLink); } } diff --git a/packages/typo3-docs-theme/src/TextRoles/ViewhelperArgumentTextRole.php b/packages/typo3-docs-theme/src/TextRoles/ViewhelperArgumentTextRole.php index 2664f3504..0ceb0ac65 100644 --- a/packages/typo3-docs-theme/src/TextRoles/ViewhelperArgumentTextRole.php +++ b/packages/typo3-docs-theme/src/TextRoles/ViewhelperArgumentTextRole.php @@ -4,6 +4,8 @@ namespace T3Docs\Typo3DocsTheme\TextRoles; +use phpDocumentor\Guides\Nodes\Inline\InlineNodeInterface; +use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode; use phpDocumentor\Guides\Nodes\Inline\ReferenceNode; use phpDocumentor\Guides\ReferenceResolvers\AnchorNormalizer; use phpDocumentor\Guides\RestructuredText\Parser\DocumentParserContext; @@ -21,17 +23,19 @@ public function __construct( protected function createNode(DocumentParserContext $documentParserContext, string $referenceTarget, string|null $referenceName, string $role): ReferenceNode { + $children = $referenceName ? [new PlainTextInlineNode($referenceName)] : []; if (preg_match(self::INTERLINK_NAME_REGEX, $referenceTarget, $matches)) { - return $this->createNodeWithInterlink($documentParserContext, $matches[2], $matches[1], $referenceName); + return $this->createNodeWithInterlink($documentParserContext, $matches[2], $matches[1], $children); } - return $this->createNodeWithInterlink($documentParserContext, $referenceTarget, '', $referenceName); + return $this->createNodeWithInterlink($documentParserContext, $referenceTarget, '', $children); } - private function createNodeWithInterlink(DocumentParserContext $documentParserContext, string $referenceTarget, string $interlinkDomain, string|null $referenceName): ReferenceNode + /** @param list $children */ + private function createNodeWithInterlink(DocumentParserContext $documentParserContext, string $referenceTarget, string $interlinkDomain, array $children): ReferenceNode { $id = $this->anchorNormalizer->reduceAnchor($referenceTarget); - return new ReferenceNode($id, $referenceName ?? '', $interlinkDomain, 'typo3:' . $this->getName()); + return new ReferenceNode($id, $children, $interlinkDomain, 'typo3:' . $this->getName()); } public function getName(): string diff --git a/packages/typo3-docs-theme/src/TextRoles/ViewhelperTextRole.php b/packages/typo3-docs-theme/src/TextRoles/ViewhelperTextRole.php index e1abeec82..b0bb9ba80 100644 --- a/packages/typo3-docs-theme/src/TextRoles/ViewhelperTextRole.php +++ b/packages/typo3-docs-theme/src/TextRoles/ViewhelperTextRole.php @@ -4,6 +4,8 @@ namespace T3Docs\Typo3DocsTheme\TextRoles; +use phpDocumentor\Guides\Nodes\Inline\InlineNodeInterface; +use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode; use phpDocumentor\Guides\Nodes\Inline\ReferenceNode; use phpDocumentor\Guides\ReferenceResolvers\AnchorNormalizer; use phpDocumentor\Guides\RestructuredText\Parser\DocumentParserContext; @@ -25,17 +27,19 @@ public function __construct( protected function createNode(DocumentParserContext $documentParserContext, string $referenceTarget, string|null $referenceName, string $role): ReferenceNode { + $children = $referenceName ? [new PlainTextInlineNode($referenceName)] : []; if (preg_match(self::INTERLINK_NAME_REGEX, $referenceTarget, $matches)) { - return $this->createNodeWithInterlink($documentParserContext, $matches[2], $matches[1], $referenceName); + return $this->createNodeWithInterlink($documentParserContext, $matches[2], $matches[1], $children); } - return $this->createNodeWithInterlink($documentParserContext, $referenceTarget, '', $referenceName); + return $this->createNodeWithInterlink($documentParserContext, $referenceTarget, '', $children); } - private function createNodeWithInterlink(DocumentParserContext $documentParserContext, string $referenceTarget, string $interlinkDomain, string|null $referenceName): ReferenceNode + /** @param list $children */ + private function createNodeWithInterlink(DocumentParserContext $documentParserContext, string $referenceTarget, string $interlinkDomain, array $children): ReferenceNode { $id = $this->anchorNormalizer->reduceAnchor($referenceTarget); - return new ReferenceNode($id, $referenceName ?? '', $interlinkDomain, 'typo3:' . $this->getName()); + return new ReferenceNode($id, $children, $interlinkDomain, 'typo3:' . $this->getName()); } public function getName(): string diff --git a/packages/typo3-docs-theme/tests/unit/Inventory/Typo3InventoryRepositoryTest.php b/packages/typo3-docs-theme/tests/unit/Inventory/Typo3InventoryRepositoryTest.php index 885a586b1..08fd7c65c 100644 --- a/packages/typo3-docs-theme/tests/unit/Inventory/Typo3InventoryRepositoryTest.php +++ b/packages/typo3-docs-theme/tests/unit/Inventory/Typo3InventoryRepositoryTest.php @@ -82,7 +82,7 @@ public static function providerForInventoryKeysWithVersions(): \Generator public function versionInventoryCreatesVersionedUrl(string $inventoryKey, string $expected): void { $messages = new Messages(); - $node = new ReferenceNode('someReference', '', $inventoryKey); + $node = new ReferenceNode('someReference', [], $inventoryKey); self::assertEquals($expected, $this->subject->previewUrl($inventoryKey)); self::assertCount(0, $messages->getWarnings()); }