diff --git a/src/Symfony/Component/Console/Formatter/OutputFormatter.php b/src/Symfony/Component/Console/Formatter/OutputFormatter.php index 8d60c74f8d..8f696c06eb 100644 --- a/src/Symfony/Component/Console/Formatter/OutputFormatter.php +++ b/src/Symfony/Component/Console/Formatter/OutputFormatter.php @@ -23,10 +23,11 @@ class OutputFormatter implements OutputFormatterInterface /** * The pattern to phrase the format. */ - const FORMAT_PATTERN = '#<([a-z][a-z0-9_=;-]+)>(.*?)#is'; + const FORMAT_PATTERN = '#<(/?)([a-z][a-z0-9_=;-]+)?>([^<]*)#is'; private $decorated; private $styles = array(); + private $styleStack; /** * Initializes console output formatter. @@ -48,6 +49,8 @@ class OutputFormatter implements OutputFormatterInterface foreach ($styles as $name => $style) { $this->setStyle($name, $style); } + + $this->styleStack = new OutputFormatterStyleStack(); } /** @@ -144,21 +147,35 @@ class OutputFormatter implements OutputFormatterInterface */ private function replaceStyle($match) { - if (!$this->isDecorated()) { - return $match[2]; + if ('' === $match[2]) { + if ('/' === $match[1]) { + // we got "" tag + $this->styleStack->pop(); + + return $this->applyStyle($this->styleStack->getCurrent(), $match[3]); + } + + // we got "<>" tag + return '<>'.$match[3]; } - if (isset($this->styles[strtolower($match[1])])) { - $style = $this->styles[strtolower($match[1])]; + if (isset($this->styles[strtolower($match[2])])) { + $style = $this->styles[strtolower($match[2])]; } else { - $style = $this->createStyleFromString($match[1]); + $style = $this->createStyleFromString($match[2]); if (false === $style) { - return $match[0]; + return $match[3]; } } - return $style->apply($this->format($match[2])); + if ('/' === $match[1]) { + $this->styleStack->pop($style); + } else { + $this->styleStack->push($style); + } + + return $this->applyStyle($this->styleStack->getCurrent(), $match[3]); } /** @@ -166,7 +183,7 @@ class OutputFormatter implements OutputFormatterInterface * * @param string $string * - * @return Symfony\Component\Console\Format\FormatterStyle|Boolean false if string is not format string + * @return \Symfony\Component\Console\Formatter\OutputFormatterStyle|Boolean false if string is not format string */ private function createStyleFromString($string) { @@ -189,4 +206,17 @@ class OutputFormatter implements OutputFormatterInterface return $style; } + + /** + * Applies style to text if must be applied. + * + * @param OutputFormatterStyleInterface $style Style to apply + * @param string $text Input text + * + * @return string string Styled text + */ + private function applyStyle(OutputFormatterStyleInterface $style, $text) + { + return $this->isDecorated() && strlen($text) > 0 ? $style->apply($text) : $text; + } }