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:
14: /**
15: * @author Jean-François Simon <contact@jfsimon.fr>
16: */
17: class OutputFormatterStyleStack
18: {
19: /**
20: * @var OutputFormatterStyleInterface[]
21: */
22: private $styles;
23:
24: /**
25: * @var OutputFormatterStyleInterface
26: */
27: private $emptyStyle;
28:
29: /**
30: * Constructor.
31: *
32: * @param OutputFormatterStyleInterface $emptyStyle
33: */
34: public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
35: {
36: $this->emptyStyle = $emptyStyle ?: new OutputFormatterStyle();
37: $this->reset();
38: }
39:
40: /**
41: * Resets stack (ie. empty internal arrays).
42: */
43: public function reset()
44: {
45: $this->styles = array();
46: }
47:
48: /**
49: * Pushes a style in the stack.
50: *
51: * @param OutputFormatterStyleInterface $style
52: */
53: public function push(OutputFormatterStyleInterface $style)
54: {
55: $this->styles[] = $style;
56: }
57:
58: /**
59: * Pops a style from the stack.
60: *
61: * @param OutputFormatterStyleInterface $style
62: *
63: * @return OutputFormatterStyleInterface
64: *
65: * @throws \InvalidArgumentException When style tags incorrectly nested
66: */
67: public function pop(OutputFormatterStyleInterface $style = null)
68: {
69: if (empty($this->styles)) {
70: return $this->emptyStyle;
71: }
72:
73: if (null === $style) {
74: return array_pop($this->styles);
75: }
76:
77: foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {
78: if ($style->apply('') === $stackedStyle->apply('')) {
79: $this->styles = array_slice($this->styles, 0, $index);
80:
81: return $stackedStyle;
82: }
83: }
84:
85: throw new \InvalidArgumentException('Incorrectly nested style tag found.');
86: }
87:
88: /**
89: * Computes current style with stacks top codes.
90: *
91: * @return OutputFormatterStyle
92: */
93: public function getCurrent()
94: {
95: if (empty($this->styles)) {
96: return $this->emptyStyle;
97: }
98:
99: return $this->styles[count($this->styles)-1];
100: }
101:
102: /**
103: * @param OutputFormatterStyleInterface $emptyStyle
104: *
105: * @return OutputFormatterStyleStack
106: */
107: public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
108: {
109: $this->emptyStyle = $emptyStyle;
110:
111: return $this;
112: }
113:
114: /**
115: * @return OutputFormatterStyleInterface
116: */
117: public function getEmptyStyle()
118: {
119: return $this->emptyStyle;
120: }
121: }
122: