TYPO3  7.6
OutputFormatter.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
12 namespace Symfony\Component\Console\Formatter;
13 
22 {
23  private $decorated;
24  private $styles = array();
25  private $styleStack;
26 
34  public static function escape($text)
35  {
36  return preg_replace('/([^\\\\]?)</', '$1\\<', $text);
37  }
38 
47  public function __construct($decorated = false, array $styles = array())
48  {
49  $this->decorated = (bool) $decorated;
50 
51  $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
52  $this->setStyle('info', new OutputFormatterStyle('green'));
53  $this->setStyle('comment', new OutputFormatterStyle('yellow'));
54  $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
55 
56  foreach ($styles as $name => $style) {
57  $this->setStyle($name, $style);
58  }
59 
60  $this->styleStack = new OutputFormatterStyleStack();
61  }
62 
70  public function setDecorated($decorated)
71  {
72  $this->decorated = (bool) $decorated;
73  }
74 
82  public function isDecorated()
83  {
84  return $this->decorated;
85  }
86 
95  public function setStyle($name, OutputFormatterStyleInterface $style)
96  {
97  $this->styles[strtolower($name)] = $style;
98  }
99 
109  public function hasStyle($name)
110  {
111  return isset($this->styles[strtolower($name)]);
112  }
113 
125  public function getStyle($name)
126  {
127  if (!$this->hasStyle($name)) {
128  throw new \InvalidArgumentException(sprintf('Undefined style: %s', $name));
129  }
130 
131  return $this->styles[strtolower($name)];
132  }
133 
143  public function format($message)
144  {
145  $message = (string) $message;
146  $offset = 0;
147  $output = '';
148  $tagRegex = '[a-z][a-z0-9_=;-]*';
149  preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE);
150  foreach ($matches[0] as $i => $match) {
151  $pos = $match[1];
152  $text = $match[0];
153 
154  if (0 != $pos && '\\' == $message[$pos - 1]) {
155  continue;
156  }
157 
158  // add the text up to the next tag
159  $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
160  $offset = $pos + strlen($text);
161 
162  // opening tag?
163  if ($open = '/' != $text[1]) {
164  $tag = $matches[1][$i][0];
165  } else {
166  $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : '';
167  }
168 
169  if (!$open && !$tag) {
170  // </>
171  $this->styleStack->pop();
172  } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
173  $output .= $this->applyCurrentStyle($text);
174  } elseif ($open) {
175  $this->styleStack->push($style);
176  } else {
177  $this->styleStack->pop($style);
178  }
179  }
180 
181  $output .= $this->applyCurrentStyle(substr($message, $offset));
182 
183  return str_replace('\\<', '<', $output);
184  }
185 
189  public function getStyleStack()
190  {
191  return $this->styleStack;
192  }
193 
201  private function createStyleFromString($string)
202  {
203  if (isset($this->styles[$string])) {
204  return $this->styles[$string];
205  }
206 
207  if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
208  return false;
209  }
210 
211  $style = new OutputFormatterStyle();
212  foreach ($matches as $match) {
213  array_shift($match);
214 
215  if ('fg' == $match[0]) {
216  $style->setForeground($match[1]);
217  } elseif ('bg' == $match[0]) {
218  $style->setBackground($match[1]);
219  } else {
220  try {
221  $style->setOption($match[1]);
222  } catch (\InvalidArgumentException $e) {
223  return false;
224  }
225  }
226  }
227 
228  return $style;
229  }
230 
238  private function applyCurrentStyle($text)
239  {
240  return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;
241  }
242 }