Completed
Push — 1.5 ( f40f61...09e907 )
by Colin
02:28
created

GatherFootnotesListener   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 64
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 10

Test Coverage

Coverage 96.77%

Importance

Changes 0
Metric Value
wmc 9
lcom 0
cbo 10
dl 0
loc 64
ccs 30
cts 31
cp 0.9677
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B onDocumentParsed() 0 53 8
A getFootnotesContainer() 0 7 1
1
<?php
2
3
/*
4
 * This file is part of the league/commonmark package.
5
 *
6
 * (c) Colin O'Dell <[email protected]>
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
13
declare(strict_types=1);
14
15
namespace League\CommonMark\Extension\Footnote\Event;
16
17
use League\CommonMark\Block\Element\Document;
18
use League\CommonMark\Event\DocumentParsedEvent;
19
use League\CommonMark\Extension\Footnote\Node\Footnote;
20
use League\CommonMark\Extension\Footnote\Node\FootnoteBackref;
21
use League\CommonMark\Extension\Footnote\Node\FootnoteContainer;
22
use League\CommonMark\Reference\Reference;
23
24
final class GatherFootnotesListener
25
{
26 42
    public function onDocumentParsed(DocumentParsedEvent $event): void
27
    {
28 42
        $document = $event->getDocument();
29 42
        $walker = $document->walker();
30
31 42
        $footnotes = [];
32 42
        while ($event = $walker->next()) {
33 42
            if (!$event->isEntering()) {
34 42
                continue;
35
            }
36
37 42
            $node = $event->getNode();
38 42
            if (!$node instanceof Footnote) {
39 42
                continue;
40
            }
41
42
            // Look for existing reference with footnote label
43 36
            $ref = $document->getReferenceMap()->getReference($node->getReference()->getLabel());
44 36
            if ($ref !== null) {
45
                // Use numeric title to get footnotes order
46 36
                $footnotes[\intval($ref->getTitle())] = $node;
47
            } else {
48
                // Footnote call is missing, append footnote at the end
49
                $footnotes[INF] = $node;
50
            }
51
52
            /*
53
             * Look for all footnote refs pointing to this footnote
54
             * and create each footnote backrefs.
55
             */
56 36
            $backrefs = $document->getData('#fn:' . $node->getReference()->getDestination(), []);
57
            /** @var Reference $backref */
58 36
            foreach ($backrefs as $backref) {
59 18
                $node->addBackref(new FootnoteBackref(new Reference(
60 18
                    $backref->getLabel(),
61 18
                    '#fnref:' . $backref->getLabel(),
62 18
                    $backref->getTitle()
63
                )));
64
            }
65
        }
66
67
        // Only add a footnote container if there are any
68 42
        if (\count($footnotes) === 0) {
69 6
            return;
70
        }
71
72 36
        $container = $this->getFootnotesContainer($document);
73
74 36
        \ksort($footnotes);
75 36
        foreach ($footnotes as $footnote) {
76 36
            $container->appendChild($footnote);
77
        }
78 36
    }
79
80 36
    private function getFootnotesContainer(Document $document): FootnoteContainer
81
    {
82 36
        $footnoteContainer = new FootnoteContainer();
83 36
        $document->appendChild($footnoteContainer);
84
85 36
        return $footnoteContainer;
86
    }
87
}
88