Completed
Pull Request — master (#6)
by Vladimir
02:02 queued 01:03
created

ParsedownHighlight::blockFencedCodeComplete()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 6.0029

Importance

Changes 0
Metric Value
dl 0
loc 40
ccs 22
cts 23
cp 0.9565
rs 8.6577
c 0
b 0
f 0
cc 6
nc 16
nop 1
crap 6.0029
1
<?php
2
3
namespace sixlive;
4
5
use Parsedown;
6
use DomainException;
7
use Highlight\Highlighter;
8
use function HighlightUtilities\splitCodeIntoArray;
9
10
class ParsedownHighlight extends Parsedown
11
{
12
    protected $highlighter;
13
14 5
    public function __construct()
15
    {
16 5
        $this->highlighter = new Highlighter;
17 5
    }
18
19 5
    protected function blockFencedCodeComplete($block)
20
    {
21 5
        if (! isset($block['element']['element']['attributes'])) {
22
            return $block;
23
        }
24
25 5
        $code = $block['element']['element']['text'];
26 5
        $blockClass = $block['element']['element']['attributes']['class']; // language-php{1,4-5}
27 5
        $infoString = $this->parseInfoString($blockClass);
28 5
        $language = $infoString['language'];
29
30
        try {
31 5
            $highlighted = $this->highlighter->highlight($language, $code);
32 5
            $highlightedCode = $highlighted->value;
33
34 5
            if (! empty($infoString['lines'])) {
35 3
                $loc = splitCodeIntoArray($highlightedCode);
36
37 3
                foreach ($loc as $i => &$line) {
38 3
                    $line = vsprintf('<span class="loc%s">%s</span>', [
39 3
                        isset($infoString['lines'][$i + 1]) ? ' highlighted' : '',
40 3
                        $line,
41
                    ]);
42
                }
43
44 3
                $highlightedCode = implode("\n", $loc);
45
            }
46
47 5
            $block['element']['element']['attributes']['class'] = vsprintf('language-%s hljs %s', [
48 5
                $highlighted->language,
49 5
                $highlighted->language,
50
            ]);
51 5
            $block['element']['element']['rawHtml'] = $highlightedCode;
52 5
            unset($block['element']['element']['text']);
53 2
        } catch (DomainException $e) {
54
            //
55
        }
56
57 5
        return $block;
58
    }
59
60 5
    private function parseInfoString($languageClass)
61
    {
62
        $infoString = [
63 5
            'language' => '',
64
            'lines' => [],
65
        ];
66
67
        // The length of the following prefix attached by Parsedown: `language-`
68 5
        $prefixLength = 9;
69
70 5
        if (($bracePos = strpos($languageClass, '{'))) {
71 3
            $infoString['language'] = substr($languageClass, $prefixLength, $bracePos - $prefixLength);
72
73 3
            $rawLineDef = substr($languageClass, $bracePos + 1, -1);
74 3
            $lineDefs = explode(',', $rawLineDef);
75
76 3
            foreach ($lineDefs as $lineDef) {
77 3
                if (($hyphenPos = strpos($lineDef, '-')) !== false) {
78 2
                    $start = intval(substr($lineDef, 0, $hyphenPos));
79 2
                    $end = intval(substr($lineDef, $hyphenPos + 1));
80
81 2
                    for ($i = $start; $i <= $end; $i++) {
82 2
                        $infoString['lines'][$i] = true;
83
                    }
84
                } else {
85 2
                    $infoString['lines'][intval($lineDef)] = true;
86
                }
87
            }
88
        } else {
89 2
            $infoString['language'] = substr($languageClass, $prefixLength);
90
        }
91
92 5
        return $infoString;
93
    }
94
}
95