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

HeadingPermalinkProcessor   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 10
dl 0
loc 74
ccs 33
cts 33
cp 1
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setConfiguration() 0 4 1
A __invoke() 0 13 4
A useNormalizerFromConfigurationIfProvided() 0 9 2
A addHeadingLink() 0 20 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