Completed
Push — master ( 9b96f1...c65fad )
by Michał
02:07
created

Style::setColor()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 3
eloc 5
nc 2
nop 2
1
<?php namespace nyx\console\output\formatting;
2
3
/**
4
 * Output Formatting Style
5
 *
6
 * Used internally by the Output Formatter to apply the respective styles onto text within style tags,
7
 * but it can also be used to manually stylize strings.
8
 *
9
 * Note: The class does not check if the given strings already contain any sort of color codes or other escape
10
 * sequences. Applying a style onto an already decorated string can therefore yield unexpected results.
11
 *
12
 * @version     0.1.0
13
 * @author      Michal Chojnacki <[email protected]>
14
 * @copyright   2012-2017 Nyx Dev Team
15
 * @link        https://github.com/unyx/nyx
16
 */
17
class Style implements interfaces\Style
18
{
19
    /**
20
     * @var array   The available foreground colors. The actual color representations may vary from the names as it
21
     *              depends on the terminal used to display them.
22
     */
23
    protected static $foregrounds = [
24
        'black'   => 30,
25
        'red'     => 31,
26
        'green'   => 32,
27
        'yellow'  => 33,
28
        'blue'    => 34,
29
        'magenta' => 35,
30
        'cyan'    => 36,
31
        'white'   => 37,
32
        'default' => 39
33
    ];
34
35
    /**
36
     * @var array   The available background colors.
37
     */
38
    protected static $backgrounds = [
39
        'black'   => 40,
40
        'red'     => 41,
41
        'green'   => 42,
42
        'yellow'  => 43,
43
        'blue'    => 44,
44
        'magenta' => 45,
45
        'cyan'    => 46,
46
        'white'   => 47,
47
        'default' => 49
48
    ];
49
50
    /**
51
     * @var array   The available additional emphasis options (Note: support for those depends on the type
52
     *              of the terminal used to display the application).
53
     */
54
    protected static $options = [
55
        'bold'       => [1, 22],
56
        'italic'     => [3, 23],
57
        'underscore' => [4, 24],
58
        'blink'      => [5, 25],
59
        'reverse'    => [7, 27],
60
        'conceal'    => [8, 28]
61
    ];
62
63
    /**
64
     * @var int     The currently set foreground color of this Style.
65
     */
66
    private $foreground;
67
68
    /**
69
     * @var int     The currently set background color of this Style.
70
     */
71
    private $background;
72
73
    /**
74
     * @var array   The currently set additional emphasis options of this Style.
75
     */
76
    private $emphasis = [];
77
78
    /**
79
     * Constructs a new Output Formatting Style.
80
     *
81
     * @param   string  $foreground     The foreground color to be set.
82
     * @param   string  $background     The background color to be set.
83
     * @param   array   $options        An array of additional options emphasis to be set.
84
     */
85
    public function __construct(?string $foreground, string $background = null, array $options = null)
86
    {
87
        if (isset($foreground)) {
88
            $this->setForeground($foreground);
89
        }
90
91
        if (isset($background)) {
92
            $this->setBackground($background);
93
        }
94
95
        if (isset($options)) {
96
            $this->setEmphasis($options);
97
        }
98
    }
99
100
    /**
101
     * {@inheritDoc}
102
     */
103
    public function setForeground(?string $color) : interfaces\Style
104
    {
105
        return $this->setColor('foreground', $color);
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111
    public function setBackground(?string $color) : interfaces\Style
112
    {
113
        return $this->setColor('background', $color);
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function setEmphasis(array $options) : interfaces\Style
120
    {
121
        foreach ($options as $option) {
122
            if (!isset(static::$options[$option])) {
123
                throw new \InvalidArgumentException("The emphasis option [$option] is not recognized.");
124
            }
125
126
            // Only add the option when it is not already set.
127
            if (false === array_search($option, $this->emphasis)) {
128
                $this->emphasis[] = $option;
129
            }
130
        }
131
132
        return $this;
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138
    public function apply(string $text) : string
139
    {
140
        $set   = [];
141
        $unset = [];
142
143
        if (isset($this->foreground)) {
144
            $set[]   = static::$foregrounds[$this->foreground];
145
            $unset[] = 39;
146
        }
147
148
        if (isset($this->background)) {
149
            $set[]   = static::$backgrounds[$this->background];
150
            $unset[] = 49;
151
        }
152
153
        if (!empty($this->emphasis)) {
154
            foreach ($this->emphasis as $option) {
155
                $set[]   = static::$options[$option][0];
156
                $unset[] = static::$options[$option][1];
157
            }
158
        }
159
160
        // Return the text wrapped by the appropriate escape sequences.
161
        return !empty($set)
162
            ? sprintf("\e[%sm%s\e[%sm", implode(';', $set), $text, implode(';', $unset))
163
            : $text;
164
    }
165
166
    /**
167
     * Sets a specific type of color on this Style.
168
     *
169
     * @param   string  $type   The type of the color to set.
170
     * @param   string  $color  The color to set.
171
     * @return  $this
172
     */
173
    protected function setColor(string $type, ?string $color) : interfaces\Style
174
    {
175
        if (isset($color) && !isset(static::${$type.'s'}[$color])) {
176
            throw new \InvalidArgumentException("The $type color [$color] is not recognized.");
177
        }
178
179
        $this->$type = $color;
180
181
        return $this;
182
    }
183
}
184