Completed
Push — master ( 2378d4...3741f7 )
by Colin
28:04 queued 26:46
created

HeadingPermalinkProcessor::setConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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