1<?php
2
3/*
4 * This file is part of the league/commonmark package.
5 *
6 * (c) Colin O'Dell <colinodell@gmail.com>
7 * (c) Rezo Zero / Ambroise Maupate
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13declare(strict_types=1);
14
15namespace League\CommonMark\Extension\Footnote\Event;
16
17use League\CommonMark\Event\DocumentParsedEvent;
18use League\CommonMark\Extension\Footnote\Node\FootnoteRef;
19use League\CommonMark\Reference\Reference;
20
21final class NumberFootnotesListener
22{
23    public function onDocumentParsed(DocumentParsedEvent $event): void
24    {
25        $document     = $event->getDocument();
26        $nextCounter  = 1;
27        $usedLabels   = [];
28        $usedCounters = [];
29
30        foreach ($document->iterator() as $node) {
31            if (! $node instanceof FootnoteRef) {
32                continue;
33            }
34
35            $existingReference   = $node->getReference();
36            $label               = $existingReference->getLabel();
37            $counter             = $nextCounter;
38            $canIncrementCounter = true;
39
40            if (\array_key_exists($label, $usedLabels)) {
41                /*
42                 * Reference is used again, we need to point
43                 * to the same footnote. But with a different ID
44                 */
45                $counter             = $usedCounters[$label];
46                $label              .= '__' . ++$usedLabels[$label];
47                $canIncrementCounter = false;
48            }
49
50            // rewrite reference title to use a numeric link
51            $newReference = new Reference(
52                $label,
53                $existingReference->getDestination(),
54                (string) $counter
55            );
56
57            // Override reference with numeric link
58            $node->setReference($newReference);
59            $document->getReferenceMap()->add($newReference);
60
61            /*
62             * Store created references in document for
63             * creating FootnoteBackrefs
64             */
65            $document->data->append($existingReference->getDestination(), $newReference);
66
67            $usedLabels[$label]   = 1;
68            $usedCounters[$label] = $nextCounter;
69
70            if ($canIncrementCounter) {
71                $nextCounter++;
72            }
73        }
74    }
75}
76