1: <?php
2: /*
3: * Copyright (c) 2014 @trashtoy
4: * https://github.com/trashtoy/
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy of
7: * this software and associated documentation files (the "Software"), to deal in
8: * the Software without restriction, including without limitation the rights to use,
9: * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10: * Software, and to permit persons to whom the Software is furnished to do so,
11: * subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in all
14: * copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18: * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19: * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20: * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21: * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22: */
23: /**
24: * PHP class file.
25: * @auhtor trashtoy
26: * @since 2.0.0
27: */
28: namespace Peach\Markup;
29:
30: /**
31: * デバッグのために使用される Context です.
32: * この Context は, handle メソッドを実行した時に自動で echo を行います.
33: * 出力内容は, ノードツリーの構造を可視化した文字列となります.
34: */
35: class DebugContext extends Context
36: {
37: /**
38: * 出力を整形するために使用される Indent です.
39: * @var Indent
40: */
41: private $indent;
42:
43: /**
44: * 出力結果です.
45: * @var string
46: */
47: private $result;
48:
49: /**
50: * true の場合, handle() を実行すると同時に echo を実行します.
51: * @var bool
52: */
53: private $echoMode;
54:
55: /**
56: * 新しい DebugContext を構築します.
57: * @param bool $echoMode 自動で出力を行うかどうかの設定 (デフォルトで true)
58: */
59: public function __construct($echoMode = true)
60: {
61: $this->indent = new Indent();
62: $this->result = "";
63: $this->echoMode = (bool) $echoMode;
64: }
65:
66: /**
67: * ノードの開始を書式化します.
68: *
69: * @param string $name
70: */
71: private function startNode($name)
72: {
73: $result = $this->indent->indent() . $name . " {" . $this->indent->stepUp();
74: if ($this->echoMode) {
75: echo $result;
76: }
77: $this->result .= $result;
78: }
79:
80: /**
81: * インデントレベルを下げて "}" を出力します.
82: */
83: private function endNode()
84: {
85: $result = $this->indent->stepDown() . "}" . $this->indent->breakCode();
86: if ($this->echoMode) {
87: echo $result;
88: }
89: $this->result .= $result;
90: }
91:
92: /**
93: * 指定された文字列をインデントして追記します.
94: * @param string $contents
95: */
96: private function append($contents)
97: {
98: $result = $this->indent->indent() . $contents . $this->indent->breakCode();
99: if ($this->echoMode) {
100: echo $result;
101: }
102: $this->result .= $result;
103: }
104:
105: /**
106: * 指定された Container の子ノードを再帰的に処理します.
107: *
108: * @param Container $container
109: */
110: private function handleContainer(Container $container)
111: {
112: foreach ($container->getChildNodes() as $node) {
113: $this->handle($node);
114: }
115: }
116:
117: /**
118: * デバッグ用の出力データを返します.
119: * @return string
120: */
121: public function getResult()
122: {
123: return $this->result;
124: }
125:
126: /**
127: * Comment ノードのデバッグ文字列を出力します.
128: * 出力内容は以下の通りです.
129: *
130: * <code>
131: * Comment {
132: * # 子ノードの出力内容
133: * }
134: * </code>
135: *
136: * @param Comment $node
137: */
138: public function handleComment(Comment $node)
139: {
140: $this->startNode("Comment");
141: $this->handleContainer($node);
142: $this->endNode();
143: }
144:
145: /**
146: * ContainerElement ノードのデバッグ文字列を出力します.
147: * 出力内容は以下の通りです.
148: *
149: * <code>
150: * ContainerElement(tagName) {
151: * # 子ノードの出力内容
152: * }
153: * </code>
154: *
155: * @param ContainerElement $node
156: */
157: public function handleContainerElement(ContainerElement $node)
158: {
159: $name = $node->getName();
160: $this->startNode("ContainerElement({$name})");
161: $this->handleContainer($node);
162: $this->endNode();
163: }
164:
165: /**
166: * EmptyElement ノードのデバッグ文字列を出力します.
167: * 出力内容は以下の通りです.
168: *
169: * <code>
170: * EmptyElement(tagName)
171: * </code>
172: *
173: * @param EmptyElement $node
174: */
175: public function handleEmptyElement(EmptyElement $node)
176: {
177: $name = $node->getName();
178: $this->append("EmptyElement({$name})");
179: }
180:
181: /**
182: * NodeList のデバッグ文字列を出力します.
183: * 出力内容は以下の通りです.
184: *
185: * <code>
186: * NodeList {
187: * # 子ノードの出力内容
188: * }
189: * </code>
190: *
191: * @param NodeList $node
192: */
193: public function handleNodeList(NodeList $node)
194: {
195: $this->startNode("NodeList");
196: $this->handleContainer($node);
197: $this->endNode();
198: }
199:
200: /**
201: * Text ノードのデバッグ文字列を出力します.
202: * 出力内容は文字列 "Text" です.
203: * @param Text $node
204: */
205: public function handleText(Text $node)
206: {
207: $this->append("Text");
208: }
209:
210: /**
211: * Code ノードのデバッグ文字列を出力します.
212: * 出力内容は文字列 "Code" です.
213: * @param Code $node
214: */
215: public function handleCode(Code $node)
216: {
217: $this->append("Code");
218: }
219:
220: /**
221: * None のデバッグ文字列を出力します.
222: * 出力内容は文字列 "None" です.
223: * @param None $none
224: */
225: public function handleNone(None $none)
226: {
227: $this->append("None");
228: }
229: }
230: