1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Symfony\Component\Console\Formatter;
13:
14: 15: 16: 17: 18: 19: 20:
21: class OutputFormatter implements OutputFormatterInterface
22: {
23: 24: 25:
26: const FORMAT_PATTERN = '#<([a-z][a-z0-9_=;-]+)>(.*?)</\\1?>#is';
27:
28: private $decorated;
29: private $styles = array();
30:
31: 32: 33: 34: 35: 36: 37: 38:
39: public function __construct($decorated = null, array $styles = array())
40: {
41: $this->decorated = (Boolean) $decorated;
42:
43: $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
44: $this->setStyle('info', new OutputFormatterStyle('green'));
45: $this->setStyle('comment', new OutputFormatterStyle('yellow'));
46: $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
47:
48: foreach ($styles as $name => $style) {
49: $this->setStyle($name, $style);
50: }
51: }
52:
53: 54: 55: 56: 57: 58: 59:
60: public function setDecorated($decorated)
61: {
62: $this->decorated = (Boolean) $decorated;
63: }
64:
65: 66: 67: 68: 69: 70: 71:
72: public function isDecorated()
73: {
74: return $this->decorated;
75: }
76:
77: 78: 79: 80: 81: 82: 83: 84:
85: public function setStyle($name, OutputFormatterStyleInterface $style)
86: {
87: $this->styles[strtolower($name)] = $style;
88: }
89:
90: 91: 92: 93: 94: 95: 96: 97: 98:
99: public function hasStyle($name)
100: {
101: return isset($this->styles[strtolower($name)]);
102: }
103:
104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114:
115: public function getStyle($name)
116: {
117: if (!$this->hasStyle($name)) {
118: throw new \InvalidArgumentException('Undefined style: '.$name);
119: }
120:
121: return $this->styles[strtolower($name)];
122: }
123:
124: 125: 126: 127: 128: 129: 130: 131: 132:
133: public function format($message)
134: {
135: return preg_replace_callback(self::FORMAT_PATTERN, array($this, 'replaceStyle'), $message);
136: }
137:
138: 139: 140: 141: 142: 143: 144:
145: private function replaceStyle($match)
146: {
147: if (!$this->isDecorated()) {
148: return $match[2];
149: }
150:
151: if (isset($this->styles[strtolower($match[1])])) {
152: $style = $this->styles[strtolower($match[1])];
153: } else {
154: $style = $this->createStyleFromString($match[1]);
155:
156: if (false === $style) {
157: return $match[0];
158: }
159: }
160:
161: return $style->apply($this->format($match[2]));
162: }
163:
164: 165: 166: 167: 168: 169: 170:
171: private function createStyleFromString($string)
172: {
173: if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
174: return false;
175: }
176:
177: $style = new OutputFormatterStyle();
178: foreach ($matches as $match) {
179: array_shift($match);
180:
181: if ('fg' == $match[0]) {
182: $style->setForeground($match[1]);
183: } elseif ('bg' == $match[0]) {
184: $style->setBackground($match[1]);
185: } else {
186: $style->setOption($match[1]);
187: }
188: }
189:
190: return $style;
191: }
192: }
193: