Passed
Push — master ( 3eb4db...99d5ff )
by Kirill
03:12
created

Highlighter::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Exceptions;
13
14
/**
15
 * Highlights portion of PHP file using given Style.
16
 */
17
class Highlighter
18
{
19
    /** @var StyleInterface */
20
    private $r = null;
21
22
    /**
23
     * @param StyleInterface $renderer
24
     */
25
    public function __construct(StyleInterface $renderer)
26
    {
27
        $this->r = $renderer;
28
    }
29
30
    /**
31
     * Highlight PHP source and return N lines around target line.
32
     *
33
     * @param string $source
34
     * @param int    $line
35
     * @param int    $around
36
     * @return string
37
     */
38
    public function highlightLines(string $source, int $line, int $around = 5): string
39
    {
40
        $lines = explode("\n", str_replace("\r\n", "\n", $this->highlight($source)));
41
42
        $result = '';
43
        foreach ($lines as $number => $code) {
44
            $human = $number + 1;
45
            if (!empty($around) && ($human < $line - $around || $human >= $line + $around + 1)) {
46
                //Not included in a range
47
                continue;
48
            }
49
50
            $result .= $this->r->line($human, mb_convert_encoding($code, 'utf-8'), $human === $line);
51
        }
52
53
        return $result;
54
    }
55
56
    /**
57
     * Returns highlighted PHP source.
58
     *
59
     * @param string $source
60
     * @return string
61
     */
62
    public function highlight(string $source): string
63
    {
64
        $result = '';
65
        $previous = [];
66
        foreach ($this->getTokens($source) as $token) {
67
            $result .= $this->r->token($token, $previous);
68
            $previous = $token;
69
        }
70
71
        return $result;
72
    }
73
74
    /**
75
     * Get all tokens from PHP source normalized to always include line number.
76
     *
77
     * @param string $source
78
     * @return array
79
     */
80
    private function getTokens(string $source): array
81
    {
82
        $tokens = [];
83
        $line = 0;
84
85
        foreach (token_get_all($source) as $token) {
86
            if (isset($token[2])) {
87
                $line = $token[2];
88
            }
89
90
            if (!is_array($token)) {
91
                $token = [$token, $token, $line];
92
            }
93
94
            $tokens[] = $token;
95
        }
96
97
        return $tokens;
98
    }
99
}
100