1
|
|
|
<?php |
2
|
|
|
// +---------------------------------------------------------------------- |
3
|
|
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ] |
4
|
|
|
// +---------------------------------------------------------------------- |
5
|
|
|
// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. |
6
|
|
|
// +---------------------------------------------------------------------- |
7
|
|
|
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) |
8
|
|
|
// +---------------------------------------------------------------------- |
9
|
|
|
// | Author: yunwuxin <[email protected]> |
10
|
|
|
// +---------------------------------------------------------------------- |
11
|
|
|
|
12
|
|
|
namespace think\console\output\formatter; |
13
|
|
|
|
14
|
|
|
class Style |
15
|
|
|
{ |
16
|
|
|
protected static $availableForegroundColors = [ |
17
|
|
|
'black' => ['set' => 30, 'unset' => 39], |
18
|
|
|
'red' => ['set' => 31, 'unset' => 39], |
19
|
|
|
'green' => ['set' => 32, 'unset' => 39], |
20
|
|
|
'yellow' => ['set' => 33, 'unset' => 39], |
21
|
|
|
'blue' => ['set' => 34, 'unset' => 39], |
22
|
|
|
'magenta' => ['set' => 35, 'unset' => 39], |
23
|
|
|
'cyan' => ['set' => 36, 'unset' => 39], |
24
|
|
|
'white' => ['set' => 37, 'unset' => 39], |
25
|
|
|
]; |
26
|
|
|
|
27
|
|
|
protected static $availableBackgroundColors = [ |
28
|
|
|
'black' => ['set' => 40, 'unset' => 49], |
29
|
|
|
'red' => ['set' => 41, 'unset' => 49], |
30
|
|
|
'green' => ['set' => 42, 'unset' => 49], |
31
|
|
|
'yellow' => ['set' => 43, 'unset' => 49], |
32
|
|
|
'blue' => ['set' => 44, 'unset' => 49], |
33
|
|
|
'magenta' => ['set' => 45, 'unset' => 49], |
34
|
|
|
'cyan' => ['set' => 46, 'unset' => 49], |
35
|
|
|
'white' => ['set' => 47, 'unset' => 49], |
36
|
|
|
]; |
37
|
|
|
|
38
|
|
|
protected static $availableOptions = [ |
39
|
|
|
'bold' => ['set' => 1, 'unset' => 22], |
40
|
|
|
'underscore' => ['set' => 4, 'unset' => 24], |
41
|
|
|
'blink' => ['set' => 5, 'unset' => 25], |
42
|
|
|
'reverse' => ['set' => 7, 'unset' => 27], |
43
|
|
|
'conceal' => ['set' => 8, 'unset' => 28], |
44
|
|
|
]; |
45
|
|
|
|
46
|
|
|
private $foreground; |
47
|
|
|
private $background; |
48
|
|
|
private $options = []; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* 初始化输出的样式 |
52
|
|
|
* @param string|null $foreground 字体颜色 |
53
|
|
|
* @param string|null $background 背景色 |
54
|
|
|
* @param array $options 格式 |
55
|
|
|
* @api |
56
|
|
|
*/ |
57
|
|
|
public function __construct($foreground = null, $background = null, array $options = []) |
58
|
|
|
{ |
59
|
|
|
if (null !== $foreground) { |
60
|
|
|
$this->setForeground($foreground); |
61
|
|
|
} |
62
|
|
|
if (null !== $background) { |
63
|
|
|
$this->setBackground($background); |
64
|
|
|
} |
65
|
|
|
if (count($options)) { |
66
|
|
|
$this->setOptions($options); |
67
|
|
|
} |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* 设置字体颜色 |
72
|
|
|
* @param string|null $color 颜色名 |
73
|
|
|
* @throws \InvalidArgumentException |
74
|
|
|
* @api |
75
|
|
|
*/ |
76
|
|
View Code Duplication |
public function setForeground($color = null) |
|
|
|
|
77
|
|
|
{ |
78
|
|
|
if (null === $color) { |
79
|
|
|
$this->foreground = null; |
80
|
|
|
|
81
|
|
|
return; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
if (!isset(static::$availableForegroundColors[$color])) { |
85
|
|
|
throw new \InvalidArgumentException(sprintf('Invalid foreground color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableForegroundColors)))); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
$this->foreground = static::$availableForegroundColors[$color]; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* 设置背景色 |
93
|
|
|
* @param string|null $color 颜色名 |
94
|
|
|
* @throws \InvalidArgumentException |
95
|
|
|
* @api |
96
|
|
|
*/ |
97
|
|
View Code Duplication |
public function setBackground($color = null) |
|
|
|
|
98
|
|
|
{ |
99
|
|
|
if (null === $color) { |
100
|
|
|
$this->background = null; |
101
|
|
|
|
102
|
|
|
return; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
if (!isset(static::$availableBackgroundColors[$color])) { |
106
|
|
|
throw new \InvalidArgumentException(sprintf('Invalid background color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableBackgroundColors)))); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
$this->background = static::$availableBackgroundColors[$color]; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* 设置字体格式 |
114
|
|
|
* @param string $option 格式名 |
115
|
|
|
* @throws \InvalidArgumentException When the option name isn't defined |
116
|
|
|
* @api |
117
|
|
|
*/ |
118
|
|
|
public function setOption(string $option): void |
119
|
|
|
{ |
120
|
|
|
if (!isset(static::$availableOptions[$option])) { |
121
|
|
|
throw new \InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions)))); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
if (!in_array(static::$availableOptions[$option], $this->options)) { |
125
|
|
|
$this->options[] = static::$availableOptions[$option]; |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* 重置字体格式 |
131
|
|
|
* @param string $option 格式名 |
132
|
|
|
* @throws \InvalidArgumentException |
133
|
|
|
*/ |
134
|
|
|
public function unsetOption(string $option): void |
135
|
|
|
{ |
136
|
|
|
if (!isset(static::$availableOptions[$option])) { |
137
|
|
|
throw new \InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions)))); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
$pos = array_search(static::$availableOptions[$option], $this->options); |
141
|
|
|
if (false !== $pos) { |
142
|
|
|
unset($this->options[$pos]); |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* 批量设置字体格式 |
148
|
|
|
* @param array $options |
149
|
|
|
*/ |
150
|
|
|
public function setOptions(array $options) |
151
|
|
|
{ |
152
|
|
|
$this->options = []; |
153
|
|
|
|
154
|
|
|
foreach ($options as $option) { |
155
|
|
|
$this->setOption($option); |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* 应用样式到文字 |
161
|
|
|
* @param string $text 文字 |
162
|
|
|
* @return string |
163
|
|
|
*/ |
164
|
|
|
public function apply(string $text): string |
165
|
|
|
{ |
166
|
|
|
$setCodes = []; |
167
|
|
|
$unsetCodes = []; |
168
|
|
|
|
169
|
|
|
if (null !== $this->foreground) { |
170
|
|
|
$setCodes[] = $this->foreground['set']; |
171
|
|
|
$unsetCodes[] = $this->foreground['unset']; |
172
|
|
|
} |
173
|
|
|
if (null !== $this->background) { |
174
|
|
|
$setCodes[] = $this->background['set']; |
175
|
|
|
$unsetCodes[] = $this->background['unset']; |
176
|
|
|
} |
177
|
|
|
if (count($this->options)) { |
178
|
|
|
foreach ($this->options as $option) { |
179
|
|
|
$setCodes[] = $option['set']; |
180
|
|
|
$unsetCodes[] = $option['unset']; |
181
|
|
|
} |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
if (0 === count($setCodes)) { |
185
|
|
|
return $text; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes)); |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.