Skip to content

Commit 3ef4ee0

Browse files
committed
[BUGFIX] Make links to special objects prefixable
If we have both an anchor like '.. _demo:' and a confval of the same name we would get duplicate id's and the links to those two elements could not be distinguished. Sphinx solves this by prefixing all confval links with "confval-". Therefore, I introduce the possibility of prefixing links to distinguished linkable objects. related #924 releases: main, 1.0
1 parent 9e47fbc commit 3ef4ee0

File tree

229 files changed

+5745
-5305
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

229 files changed

+5745
-5305
lines changed

packages/guides-restructured-text/resources/template/html/body/directive/confval.html.twig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<dl class="confval">
2-
<dt id="{{ node.id }}">
2+
<dt id="{{ node.anchor }}">
33
<code class="sig-name descname"><span class="pre">{{ node.plainContent }}</span></code></dt>
44
<dd>
55
<div class="line-block">

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function __construct(
4444
) {
4545
parent::__construct($startingRule);
4646

47-
$genericLinkProvider->addGenericLink(self::NAME, ConfvalNode::LINK_TYPE);
47+
$genericLinkProvider->addGenericLink(self::NAME, ConfvalNode::LINK_TYPE, ConfvalNode::LINK_PREFIX);
4848
}
4949

5050
public function getName(): string

packages/guides-restructured-text/src/RestructuredText/Nodes/ConfvalNode.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616
use phpDocumentor\Guides\Nodes\CompoundNode;
1717
use phpDocumentor\Guides\Nodes\InlineCompoundNode;
18-
use phpDocumentor\Guides\Nodes\LinkTargetNode;
1918
use phpDocumentor\Guides\Nodes\Node;
19+
use phpDocumentor\Guides\Nodes\PrefixedLinkTargetNode;
2020

2121
/**
2222
* The confval directive configuration values.
@@ -25,9 +25,10 @@
2525
*
2626
* @extends CompoundNode<Node>
2727
*/
28-
final class ConfvalNode extends CompoundNode implements LinkTargetNode
28+
final class ConfvalNode extends CompoundNode implements PrefixedLinkTargetNode
2929
{
3030
public const LINK_TYPE = 'std:confval';
31+
public const LINK_PREFIX = 'confval-';
3132

3233
/**
3334
* @param list<Node> $value
@@ -60,6 +61,11 @@ public function getId(): string
6061
return $this->id;
6162
}
6263

64+
public function getAnchor(): string
65+
{
66+
return self::LINK_PREFIX . $this->id;
67+
}
68+
6369
public function getLinkText(): string
6470
{
6571
return $this->plainContent;
@@ -85,4 +91,9 @@ public function getAdditionalOptions(): array
8591
{
8692
return $this->additionalOptions;
8793
}
94+
95+
public function getPrefix(): string
96+
{
97+
return self::LINK_PREFIX;
98+
}
8899
}

packages/guides-restructured-text/src/RestructuredText/TextRoles/GenericLinkProvider.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@ final class GenericLinkProvider
3030
private array $textRoleLinkTypeMapping = [
3131
'ref' => SectionNode::STD_LABEL,
3232
];
33+
/** @var array<string, string> */
34+
private array $prefixLinkTypeMapping = ['ref' => ''];
3335

34-
public function addGenericLink(string $textRole, string $linkType): void
36+
public function addGenericLink(string $textRole, string $linkType, string $prefix = ''): void
3537
{
3638
$this->textRoleLinkTypeMapping[$textRole] = $linkType;
39+
$this->prefixLinkTypeMapping[$textRole] = $prefix;
3740
}
3841

3942
/** @return string[] */
@@ -46,4 +49,9 @@ public function getLinkType(string $textRole): string
4649
{
4750
return $this->textRoleLinkTypeMapping[$textRole] ?? SectionNode::STD_LABEL;
4851
}
52+
53+
public function getLinkPrefix(string $textRole): string
54+
{
55+
return $this->prefixLinkTypeMapping[$textRole] ?? '';
56+
}
4957
}

packages/guides-restructured-text/src/RestructuredText/TextRoles/GenericReferenceTextRole.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ protected function createNode(string $referenceTarget, string|null $referenceNam
4646
$linkType = $this->genericLinkProvider->getLinkType($role);
4747
$interlinkData = $this->interlinkParser->extractInterlink($referenceTarget);
4848
$reference = $this->anchorReducer->reduceAnchor($interlinkData->reference);
49+
$prefix = $this->genericLinkProvider->getLinkPrefix($role);
4950

50-
return new ReferenceNode($reference, $referenceName ?? '', $interlinkData->interlink, $linkType);
51+
return new ReferenceNode($reference, $referenceName ?? '', $interlinkData->interlink, $linkType, $prefix);
5152
}
5253
}

packages/guides/src/Compiler/NodeTransformers/CollectLinkTargetsTransformer.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use phpDocumentor\Guides\Nodes\LinkTargetNode;
2222
use phpDocumentor\Guides\Nodes\MultipleLinkTargetsNode;
2323
use phpDocumentor\Guides\Nodes\Node;
24+
use phpDocumentor\Guides\Nodes\PrefixedLinkTargetNode;
2425
use phpDocumentor\Guides\Nodes\SectionNode;
2526
use phpDocumentor\Guides\ReferenceResolvers\AnchorNormalizer;
2627
use Psr\Log\LoggerInterface;
@@ -97,13 +98,19 @@ public function enterNode(Node $node, CompilerContext $compilerContext): Node
9798
$currentDocument = $this->documentStack->top();
9899
Assert::notNull($currentDocument);
99100
$anchor = $this->anchorReducer->reduceAnchor($node->getId());
101+
$prefix = '';
102+
if ($node instanceof PrefixedLinkTargetNode) {
103+
$prefix = $node->getPrefix();
104+
}
105+
100106
$this->addLinkTargetToProject(
101107
$compilerContext,
102108
new InternalTarget(
103109
$currentDocument->getFilePath(),
104110
$anchor,
105111
$node->getLinkText(),
106112
$node->getLinkType(),
113+
$prefix,
107114
),
108115
);
109116
if ($node instanceof MultipleLinkTargetsNode) {

packages/guides/src/Meta/InternalTarget.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public function __construct(
2424
protected string $anchorName,
2525
private readonly string|null $title = null,
2626
private readonly string $linkType = SectionNode::STD_LABEL,
27+
private readonly string $prefix = '',
2728
) {
2829
}
2930

@@ -63,4 +64,9 @@ public function getLinkType(): string
6364
{
6465
return $this->linkType;
6566
}
67+
68+
public function getPrefix(): string
69+
{
70+
return $this->prefix;
71+
}
6672
}

packages/guides/src/Nodes/Inline/ReferenceNode.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public function __construct(
3737
string $value = '',
3838
private readonly string $interlinkDomain = '',
3939
private readonly string $linkType = SectionNode::STD_LABEL,
40+
private readonly string $prefix = '',
4041
) {
4142
parent::__construct(self::TYPE, $targetReference, $value);
4243
}
@@ -62,6 +63,11 @@ public function getDebugInformation(): array
6263

6364
public function getInterlinkGroup(): string
6465
{
65-
return 'std:label';
66+
return $this->linkType;
67+
}
68+
69+
public function getPrefix(): string
70+
{
71+
return $this->prefix;
6672
}
6773
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
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+
14+
namespace phpDocumentor\Guides\Nodes;
15+
16+
interface PrefixedLinkTargetNode extends LinkTargetNode
17+
{
18+
public function getPrefix(): string;
19+
}

packages/guides/src/ReferenceResolvers/AnchorReferenceResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function resolve(LinkInlineNode $node, RenderContext $renderContext, Mess
4646
return false;
4747
}
4848

49-
$node->setUrl($this->urlGenerator->generateCanonicalOutputUrl($renderContext, $target->getDocumentPath(), $target->getAnchor()));
49+
$node->setUrl($this->urlGenerator->generateCanonicalOutputUrl($renderContext, $target->getDocumentPath(), $target->getPrefix() . $target->getAnchor()));
5050
if ($node->getValue() === '') {
5151
$node->setValue($target->getTitle() ?? '');
5252
}

0 commit comments

Comments
 (0)