Completed
Push — master ( 7b9015...c5b311 )
by Vladimir
26s queued 11s
created

SyntaxHighlighterTrait   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 97.22%

Importance

Changes 0
Metric Value
dl 0
loc 108
rs 10
c 0
b 0
f 0
ccs 35
cts 36
cp 0.9722
wmc 13
lcom 1
cbo 1

2 Methods

Rating   Name   Duplication   Size   Complexity  
B highlightCode() 0 41 7
B parseInfoString() 0 45 6
1
<?php
2
3
/**
4
 * @copyright 2018 Vladimir Jimenez
5
 * @license   https://github.com/stakx-io/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx\Markup;
9
10
use allejo\stakx\RuntimeStatus;
11
use allejo\stakx\Service;
12
use Highlight\Highlighter;
13
use function HighlightUtilities\splitCodeIntoArray;
14
15
/**
16
 * This trait provides functionality for parsing the language names in a consistent manner and providing identical
17
 * highlighted HTML across markup engines.
18
 *
19
 * @since 0.2.1
20
 */
21
trait SyntaxHighlighterTrait
22
{
23
    /** @var Highlighter */
24
    protected $highlighter;
25
26
    /**
27
     * @since 0.2.1
28
     *
29
     * @param string $infoString
30
     * @param string $rawCode
31
     *
32
     * @return string
33
     */
34 7
    protected function highlightCode($infoString, $rawCode)
35
    {
36 7
        $langDef = $this->parseInfoString($infoString);
37
38
        try
39
        {
40 7
            $highlighted = $this->highlighter->highlight($langDef['language'], $rawCode);
41 6
            $value = $highlighted->value;
42
43 6
            if (Service::hasRunTimeFlag(RuntimeStatus::USING_LINE_NUMBERS) || count($langDef['selectedLines']) > 0)
44
            {
45 4
                $lines = splitCodeIntoArray($value);
46 4
                $value = '';
47
48 4
                foreach ($lines as $i => $line)
49
                {
50
                    // `$i + 1` since our line numbers are indexed starting at 1
51 4
                    $value .= vsprintf("<div class=\"loc%s\"><span>%s</span></div>\n", [
52 4
                        isset($langDef['selectedLines'][$i + 1]) ? ' highlighted' : '',
53 4
                        $line,
54
                    ]);
55
                }
56
            }
57
58 6
            return vsprintf('<pre><code class="hljs language-%s">%s</code></pre>', [
59 6
                $langDef['language'],
60 6
                $value,
61
            ]);
62
        }
63
        // Exception thrown when language not supported
64 1
        catch (\DomainException $exception)
65
        {
66 1
            trigger_error("An unsupported language (${langDef['language']}) was detected in a code block", E_USER_WARNING);
67
        }
68
        catch (\Exception $e)
69
        {
70
            trigger_error('An error has occurred in the highlight.php language definition files', E_USER_WARNING);
71
        }
72
73
        return $rawCode;
74
    }
75
76
    /**
77
     * @since 0.2.1
78
     *
79
     * @param string $infoString
80
     *
81
     * @return array
82
     */
83
    private function parseInfoString($infoString)
84
    {
85 7
        $infoString = str_replace('language-', '', $infoString);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $infoString. This often makes code more readable.
Loading history...
86
        $definition = [
87 7
            'language' => $infoString,
88
            'selectedLines' => [],
89
        ];
90
91 7
        $bracePos = strpos($infoString, '{');
92
93 7
        if ($bracePos === false)
94
        {
95 3
            return $definition;
96
        }
97
98 4
        $definition['language'] = substr($infoString, 0, $bracePos);
99 4
        $lineDefinition = substr($infoString, $bracePos + 1, -1);
100 4
        $lineNumbers = explode(',', $lineDefinition);
101
102 4
        foreach ($lineNumbers as $lineNumber)
103
        {
104 4
            if (strpos($lineNumber, '-') === false)
105
            {
106 3
                $definition['selectedLines'][intval($lineNumber)] = true;
107 3
                continue;
108
            }
109
110 2
            $extremes = explode('-', $lineNumber);
111
112 2
            if (count($extremes) !== 2)
113
            {
114
                continue;
115
            }
116
117 2
            $start = intval($extremes[0]);
118 2
            $end = intval($extremes[1]);
119
120 2
            for ($i = $start; $i <= $end; ++$i)
121
            {
122 2
                $definition['selectedLines'][$i] = true;
123
            }
124
        }
125
126 4
        return $definition;
127
    }
128
}
129