Skip to content

Commit 81ffdf0

Browse files
committed
[TASK] Warn about duplicate link targets
releases: main, 1.0
1 parent 0083923 commit 81ffdf0

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

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

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@
2424
use phpDocumentor\Guides\Nodes\PrefixedLinkTargetNode;
2525
use phpDocumentor\Guides\Nodes\SectionNode;
2626
use phpDocumentor\Guides\ReferenceResolvers\AnchorNormalizer;
27+
use Psr\Log\LoggerInterface;
2728
use SplStack;
2829
use Webmozart\Assert\Assert;
2930

31+
use function sprintf;
32+
3033
/** @implements NodeTransformer<DocumentNode|AnchorNode|SectionNode> */
3134
final class CollectLinkTargetsTransformer implements NodeTransformer
3235
{
@@ -35,6 +38,7 @@ final class CollectLinkTargetsTransformer implements NodeTransformer
3538

3639
public function __construct(
3740
private readonly AnchorNormalizer $anchorReducer,
41+
private LoggerInterface|null $logger = null,
3842
) {
3943
/*
4044
* TODO: remove stack here, as we should not have sub documents in this way, sub documents are
@@ -74,18 +78,45 @@ public function enterNode(Node $node, CompilerContext $compilerContext): Node
7478
$prefix = $node->getPrefix();
7579
}
7680

77-
$compilerContext->getProjectNode()->addLinkTarget(
78-
$anchor,
79-
new InternalTarget(
80-
$currentDocument->getFilePath(),
81+
if ($compilerContext->getProjectNode()->hasInternalTarget($anchor, $node->getLinkType())) {
82+
$this->logger?->warning(
83+
sprintf(
84+
'Duplicate anchor "%s" for link type "%s" in document "%s". The anchor is already used at "%s"',
85+
$anchor,
86+
$node->getLinkType(),
87+
$compilerContext->getDocumentNode()->getFilePath(),
88+
$compilerContext->getProjectNode()->getInternalTarget($anchor, $node->getLinkType())?->getDocumentPath(),
89+
),
90+
$compilerContext->getLoggerInformation(),
91+
);
92+
} else {
93+
$compilerContext->getProjectNode()->addLinkTarget(
8194
$anchor,
82-
$node->getLinkText(),
83-
$node->getLinkType(),
84-
$prefix,
85-
),
86-
);
95+
new InternalTarget(
96+
$currentDocument->getFilePath(),
97+
$anchor,
98+
$node->getLinkText(),
99+
$node->getLinkType(),
100+
$prefix,
101+
),
102+
);
103+
}
104+
87105
if ($node instanceof MultipleLinkTargetsNode) {
88106
foreach ($node->getAdditionalIds() as $id) {
107+
if ($compilerContext->getProjectNode()->hasInternalTarget($id, $node->getLinkType())) {
108+
$this->logger?->warning(
109+
sprintf(
110+
'Duplicate anchor "%s" for link type "%s" in document "%s". The anchor is already used at "%s"',
111+
$anchor,
112+
$node->getLinkType(),
113+
$compilerContext->getDocumentNode()->getFilePath(),
114+
$compilerContext->getProjectNode()->getInternalTarget($anchor, $node->getLinkType())?->getDocumentPath(),
115+
),
116+
$compilerContext->getLoggerInformation(),
117+
);
118+
}
119+
89120
$compilerContext->getProjectNode()->addLinkTarget(
90121
$id,
91122
new InternalTarget(

packages/guides/src/Nodes/ProjectNode.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ public function addLinkTarget(string $anchorName, InternalTarget $target): void
152152
$this->internalLinkTargets[$target->getLinkType()][$anchorName] = $target;
153153
}
154154

155+
public function hasInternalTarget(string $anchorName, string $linkType = SectionNode::STD_LABEL): bool
156+
{
157+
return isset($this->internalLinkTargets[$linkType][$anchorName]);
158+
}
159+
155160
public function getInternalTarget(string $anchorName, string $linkType = SectionNode::STD_LABEL): InternalTarget|null
156161
{
157162
return $this->internalLinkTargets[$linkType][$anchorName] ?? null;

tests/Functional/tests/section-nesting/section-nesting.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ <h1>
3737
<h1>
3838
Level 1 Test 4
3939
</h1>
40-
<div class="section" id="level-2-test-3">
40+
<div class="section" id="level-2-test-3b">
4141
<h2>
42-
Level 2 Test 3
42+
Level 2 Test 3b
4343
</h2>
4444
<div class="section" id="level-3-test-1">
4545
<h3>

tests/Functional/tests/section-nesting/section-nesting.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ Level 1 Test 3
2222
Level 1 Test 4
2323
==============
2424

25-
Level 2 Test 3
26-
--------------
25+
Level 2 Test 3b
26+
---------------
2727

2828
Level 3 Test 1
2929
**************

0 commit comments

Comments
 (0)