Skip to content

Commit 098b439

Browse files
committed
[TASK] Warn about duplicate link targets
releases: main, 1.0 (cherry picked from commit 9daa2a3)
1 parent cd75fcd commit 098b439

File tree

4 files changed

+47
-12
lines changed

4 files changed

+47
-12
lines changed

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

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@
2323
use phpDocumentor\Guides\Nodes\Node;
2424
use phpDocumentor\Guides\Nodes\SectionNode;
2525
use phpDocumentor\Guides\ReferenceResolvers\AnchorNormalizer;
26+
use Psr\Log\LoggerInterface;
2627
use SplStack;
2728
use Webmozart\Assert\Assert;
2829

30+
use function sprintf;
31+
2932
/** @implements NodeTransformer<DocumentNode|AnchorNode|SectionNode> */
3033
final class CollectLinkTargetsTransformer implements NodeTransformer
3134
{
@@ -34,6 +37,7 @@ final class CollectLinkTargetsTransformer implements NodeTransformer
3437

3538
public function __construct(
3639
private readonly AnchorNormalizer $anchorReducer,
40+
private LoggerInterface|null $logger = null,
3741
) {
3842
/*
3943
* TODO: remove stack here, as we should not have sub documents in this way, sub documents are
@@ -68,17 +72,43 @@ public function enterNode(Node $node, CompilerContext $compilerContext): Node
6872
$currentDocument = $this->documentStack->top();
6973
Assert::notNull($currentDocument);
7074
$anchor = $node->getId();
71-
$compilerContext->getProjectNode()->addLinkTarget(
72-
$anchor,
73-
new InternalTarget(
74-
$currentDocument->getFilePath(),
75+
if ($compilerContext->getProjectNode()->hasInternalTarget($anchor, $node->getLinkType())) {
76+
$this->logger?->warning(
77+
sprintf(
78+
'Duplicate anchor "%s" for link type "%s" in document "%s". The anchor is already used at "%s"',
79+
$anchor,
80+
$node->getLinkType(),
81+
$compilerContext->getDocumentNode()->getFilePath(),
82+
$compilerContext->getProjectNode()->getInternalTarget($anchor, $node->getLinkType())?->getDocumentPath(),
83+
),
84+
$compilerContext->getLoggerInformation(),
85+
);
86+
} else {
87+
$compilerContext->getProjectNode()->addLinkTarget(
7588
$anchor,
76-
$node->getLinkText(),
77-
$node->getLinkType(),
78-
),
79-
);
89+
new InternalTarget(
90+
$currentDocument->getFilePath(),
91+
$anchor,
92+
$node->getLinkText(),
93+
$node->getLinkType(),
94+
),
95+
);
96+
}
8097
if ($node instanceof MultipleLinkTargetsNode) {
8198
foreach ($node->getAdditionalIds() as $id) {
99+
if ($compilerContext->getProjectNode()->hasInternalTarget($id, $node->getLinkType())) {
100+
$this->logger?->warning(
101+
sprintf(
102+
'Duplicate anchor "%s" for link type "%s" in document "%s". The anchor is already used at "%s"',
103+
$anchor,
104+
$node->getLinkType(),
105+
$compilerContext->getDocumentNode()->getFilePath(),
106+
$compilerContext->getProjectNode()->getInternalTarget($anchor, $node->getLinkType())?->getDocumentPath(),
107+
),
108+
$compilerContext->getLoggerInformation(),
109+
);
110+
}
111+
82112
$compilerContext->getProjectNode()->addLinkTarget(
83113
$id,
84114
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)