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

ConsoleStyle::getStyle()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
c 1
b 0
f 0
dl 0
loc 17
rs 9.2222
cc 6
nc 7
nop 2
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\Style;
13
14
use Codedungeon\PHPCliColors\Color;
15
use Spiral\Exceptions\StyleInterface;
16
17
/**
18
 * Colorful source code highlighter for CLI applications.
19
 */
20
class ConsoleStyle implements StyleInterface
21
{
22
    /** @var array */
23
    protected $templates = [
24
        'token'  => '%s%s' . Color::RESET,
25
        'line'   => Color::LIGHT_CYAN . ' %s ' . Color::RESET . " %s\n",
26
        'active' => Color::BG_RED . ' ' . Color::LIGHT_WHITE . '%s ' . Color::RESET . " %s\n",
27
    ];
28
29
    /** @var array */
30
    protected $style = [
31
        Color::YELLOW        => [
32
            T_STATIC,
33
            T_PUBLIC,
34
            T_PRIVATE,
35
            T_PROTECTED,
36
            T_CLASS,
37
            T_NEW,
38
            T_FINAL,
39
            T_ABSTRACT,
40
            T_IMPLEMENTS,
41
            T_CONST,
42
            T_ECHO,
43
            T_CASE,
44
            T_FUNCTION,
45
            T_GOTO,
46
            T_INCLUDE,
47
            T_REQUIRE,
48
            T_REQUIRE_ONCE,
49
            T_VAR,
50
            T_INSTANCEOF,
51
            T_INTERFACE,
52
            T_THROW,
53
            T_ARRAY,
54
            T_IF,
55
            T_ELSE,
56
            T_ELSEIF,
57
            T_TRY,
58
            T_CATCH,
59
            T_CLONE,
60
            T_WHILE,
61
            T_FOR,
62
            T_DO,
63
            T_UNSET,
64
            T_FOREACH,
65
            T_RETURN,
66
            T_EXIT,
67
            T_USE,
68
            T_OPEN_TAG,
69
            T_CLOSE_TAG,
70
            T_OPEN_TAG_WITH_ECHO,
71
            ';',
72
            ','
73
        ],
74
        Color::LIGHT_BLUE    => [
75
            T_DNUMBER,
76
            T_LNUMBER,
77
        ],
78
        Color::GREEN         => [
79
            T_CONSTANT_ENCAPSED_STRING,
80
            T_ENCAPSED_AND_WHITESPACE,
81
        ],
82
        Color::GRAY          => [
83
            T_COMMENT,
84
            T_DOC_COMMENT,
85
        ],
86
        Color::LIGHT_MAGENTA => [
87
            T_VARIABLE,
88
        ],
89
        Color::LIGHT_YELLOW  => [
90
            '->' . T_STRING,
91
            '::' . T_STRING
92
        ]
93
    ];
94
95
    /**
96
     * @inheritdoc
97
     */
98
    public function token(array $token, array $previous): string
99
    {
100
        $style = $this->getStyle($token, $previous);
101
102
        if (strpos($token[1], "\n") === false) {
103
            return sprintf($this->templates['token'], $style, $token[1]);
104
        }
105
106
        $lines = [];
107
        foreach (explode("\n", $token[1]) as $line) {
108
            $lines[] = sprintf($this->templates['token'], $style, $line);
109
        }
110
111
        return implode("\n", $lines);
112
    }
113
114
    /**
115
     * @inheritdoc
116
     */
117
    public function line(int $number, string $code, bool $target = false): string
118
    {
119
        return sprintf(
120
            $this->templates[$target ? 'active' : 'line'],
121
            str_pad((string)$number, 4, ' ', STR_PAD_LEFT),
122
            $code
123
        );
124
    }
125
126
    /**
127
     * Get styles for a given token.
128
     *
129
     * @param array $token
130
     * @param array $previous
131
     * @return string
132
     */
133
    private function getStyle(array $token, array $previous): string
134
    {
135
        if (!empty($previous)) {
136
            foreach ($this->style as $style => $tokens) {
137
                if (in_array($previous[1] . $token[0], $tokens)) {
138
                    return $style;
139
                }
140
            }
141
        }
142
143
        foreach ($this->style as $style => $tokens) {
144
            if (in_array($token[0], $tokens)) {
145
                return $style;
146
            }
147
        }
148
149
        return Color::WHITE;
150
    }
151
}
152