Completed
Push — master ( 0b6d3a...3ff1a5 )
by Colin
31:14 queued 11s
created

HeadingPermalinkProcessor::addHeadingLink()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 12
cts 12
cp 1
rs 9.6
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the league/commonmark package.
7
 *
8
 * (c) Colin O'Dell <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace League\CommonMark\Extension\HeadingPermalink;
15
16
use League\CommonMark\Configuration\ConfigurationAwareInterface;
17
use League\CommonMark\Configuration\ConfigurationInterface;
18
use League\CommonMark\Event\DocumentParsedEvent;
19
use League\CommonMark\Extension\CommonMark\Node\Block\Heading;
20
use League\CommonMark\Node\StringContainerHelper;
21
use League\CommonMark\Normalizer\SlugNormalizer;
22
use League\CommonMark\Normalizer\TextNormalizerInterface;
23
24
/**
25
 * Searches the Document for Heading elements and adds HeadingPermalinks to each one
26
 */
27
final class HeadingPermalinkProcessor implements ConfigurationAwareInterface
28
{
29
    public const INSERT_BEFORE = 'before';
30
    public const INSERT_AFTER  = 'after';
31
32
    /**
33
     * @var TextNormalizerInterface
34
     *
35
     * @psalm-readonly-allow-private-mutation
36
     */
37
    private $slugNormalizer;
38
39
    /**
40
     * @var ConfigurationInterface
41
     *
42
     * @psalm-readonly-allow-private-mutation
43
     */
44
    private $config;
45
46 75
    public function __construct(?TextNormalizerInterface $slugNormalizer = null)
47
    {
48 75
        $this->slugNormalizer = $slugNormalizer ?? new SlugNormalizer();
49 75
    }
50
51 75
    public function setConfiguration(ConfigurationInterface $configuration): void
52
    {
53 75
        $this->config = $configuration;
54 75
    }
55
56 75
    public function __invoke(DocumentParsedEvent $e): void
57
    {
58 75
        $this->useNormalizerFromConfigurationIfProvided();
59
60 72
        $walker = $e->getDocument()->walker();
61
62 72
        while ($event = $walker->next()) {
63 72
            $node = $event->getNode();
64 72
            if ($node instanceof Heading && $event->isEntering()) {
65 69
                $this->addHeadingLink($node);
66
            }
67
        }
68 69
    }
69
70 75
    private function useNormalizerFromConfigurationIfProvided(): void
71
    {
72 75
        $normalizer = $this->config->get('heading_permalink/slug_normalizer');
73 75
        if ($normalizer === null) {
74 69
            return;
75
        }
76
77 6
        $this->slugNormalizer = $normalizer;
78 3
    }
79
80
    private function addHeadingLink(Heading $heading): void
81 3
    {
82 3
        $text = StringContainerHelper::getChildText($heading);
83
        $slug = $this->slugNormalizer->normalize($text, $heading);
84 69
85
        $headingLinkAnchor = new HeadingPermalink($slug);
86 69
87
        switch ($this->config->get('heading_permalink/insert', 'before')) {
88 69
            case self::INSERT_BEFORE:
89
                $heading->prependChild($headingLinkAnchor);
90 69
91 69
                return;
92 57
            case self::INSERT_AFTER:
93
                $heading->appendChild($headingLinkAnchor);
94 57
95 12
                return;
96 9
            default:
97
                throw new \RuntimeException("Invalid configuration value for heading_permalink/insert; expected 'before' or 'after'");
98 9
        }
99
    }
100
}
101