File Coverage

blib/lib/Text/UberText/Tree.pm
Criterion Covered Total %
statement 15 194 7.7
branch 0 72 0.0
condition 0 18 0.0
subroutine 5 25 20.0
pod 8 15 53.3
total 28 324 8.6


line stmt bran cond sub pod time code
1             #
2             # Package Definition
3             #
4              
5             package Text::UberText::Tree;
6              
7             #
8             # Compiler Directives
9             #
10              
11 1     1   7 use strict;
  1         3  
  1         41  
12 1     1   6 use warnings;
  1         1  
  1         84  
13              
14             #
15             # Includes
16             #
17              
18 1     1   1425 use Text::UberText::Node::Command;
  1         2  
  1         29  
19 1     1   779 use Text::UberText::Node::Text;
  1         3  
  1         29  
20              
21             #
22             # Global Variables
23             #
24              
25 1     1   6 use vars qw/$VERSION /;
  1         2  
  1         1858  
26              
27             $VERSION=0.95;
28              
29             #
30             # Methods
31             #
32              
33             sub new
34             {
35 0     0 1   my ($class)=shift;
36 0           my ($object);
37 0           $object={};
38 0           bless ($object,$class);
39 0           $object->_init(@_);
40 0           return $object;
41             }
42              
43             sub addNode
44             {
45 0     0 1   my ($self)=shift;
46 0           my ($x,$line,$class,$string,$obj);
47 0           while (@_)
48             {
49 0           ($x)=shift;
50 0 0         if ($x eq "-text")
    0          
    0          
51             {
52 0           ($string)=shift;
53             } elsif ($x eq "-line")
54             {
55 0           ($line)=shift;
56             } elsif ($x eq "-class")
57             {
58 0           $class=shift;
59             }
60             }
61 0 0 0       if ($string && $line && $class)
      0        
62             {
63 0           $obj=$class->new(-text => $string, -line => $line, -tree => $self);
64 0           $self->_addObject($obj);
65             }
66 0           return;
67             }
68              
69             sub insertNode
70             {
71 0     0 0   my ($self)=shift;
72 0           my ($x,$string,$line,$class,$after,$before,$obj);
73 0           while (@_)
74             {
75 0           ($x)=shift;
76 0 0         if ($x eq "-text")
    0          
    0          
    0          
    0          
77             {
78 0           ($string)=shift;
79             } elsif ($x eq "-line")
80             {
81 0           ($line)=shift;
82             } elsif ($x eq "-class")
83             {
84 0           $class=shift;
85             } elsif ($x eq "-after")
86             {
87 0           ($after)=shift;
88             } elsif ($x eq "-before")
89             {
90 0           ($before)=shift;
91             }
92             }
93 0 0 0       if ($string && $line && $class)
      0        
94             {
95 0           $obj=$class->new(-text => $string, -line => $line, -tree => $self );
96 0 0         if ($after)
    0          
97             {
98 0           $self->_insertObj($obj, -after => $after);
99             } elsif ($before)
100             {
101 0           $self->_insertObj($obj, -before => $before);
102             }
103             }
104 0           return;
105             }
106              
107             sub flush
108             {
109 0     0 0   my ($self)=shift;
110 0           $self->{output}="";
111 0           return;
112             }
113              
114             sub output
115             {
116 0     0 1   my ($self)=shift;
117 0           my ($n,$x,@list);
118 0           $self->{output}="";
119 0 0         if (@_)
120             {
121 0           $n=shift;
122             } else {
123 0           $n=0;
124             }
125 0           (@list)=$self->children($n);
126 0           while(@list)
127             {
128 0           $x=shift(@list);
129 0           $self->{output}.=$self->{tree}->[$x]->{obj}->output();
130             }
131 0           return $self->{output};
132             }
133              
134             sub debugOutput
135             {
136 0     0 1   my ($self)=shift;
137 0           my ($n,$x,@list);
138 0 0         if (@_)
139             {
140 0           $n=shift;
141             } else {
142 0           $n=0;
143             }
144 0           $self->{debugOutput}="";
145 0           (@list)=$self->children($n);
146 0           while(@list)
147             {
148 0           $x=shift(@list);
149             #$self->{debugOutput}.=$self->{tree}->[$x]->{obj}->output();
150 0           $self->{debugOutput}.="($x)".$self->{tree}->[$x]->{obj}->output();
151             }
152 0           return $self->{debugOutput};
153             }
154              
155             sub treeOutput
156             {
157 0     0 0   my ($self)=shift;
158 0           my ($n,$x,$text,$ind,@remaining,@list);
159 0 0         if (@_)
160             {
161 0           $n=shift;
162             } else {
163 0           $n=0;
164             }
165 0           (@remaining)=();
166 0           (@list)=$self->children($n);
167 0           while (@list)
168             {
169 0           $x=shift(@list);
170 0           $text=$self->{tree}->[$x]->{obj}->output();
171 0           $text=~s/\n//g;
172 0           $ind=scalar(@remaining)*6;
173 0 0         if (length($text) > (62-$ind))
174             {
175 0           $text=substr($text,0,(67-$ind))."...";
176             }
177 0           printf("%*s [%3d] %s\n",$ind,"",$x,$text);
178 0 0         if ($self->children($x))
179             {
180 0           push(@remaining,[ @list ]);
181 0           (@list)=$self->children($x);
182             }
183 0 0 0       if (!@list && @remaining)
184             {
185 0           (@list)=@{ pop (@remaining) };
  0            
186             }
187             }
188 0           return;
189             }
190              
191             sub children
192             {
193 0     0 1   my ($self)=shift;
194 0           my ($id);
195 0 0         if (@_)
196             {
197 0           $id=shift;
198             } else {
199 0           $id=0;
200             }
201 0 0         if ($self->{tree}->[$id]->{children})
202             {
203 0           return @{$self->{tree}->[$id]->{children}};
  0            
204             } else {
205 0           return undef;
206             }
207             }
208              
209             sub showTree
210             {
211 0     0 1   my ($self)=shift;
212 0           my ($n,$x,$text,$ind,@remaining,@list);
213 0 0         if (@_)
214             {
215 0           $n=shift;
216             } else {
217 0           $n=0;
218             }
219 0           (@remaining)=();
220 0           (@list)=$self->children($n);
221 0           while (@list)
222             {
223 0           $x=shift(@list);
224 0           $text=$self->{tree}->[$x]->{obj}->input();
225 0           $text=~s/\n//g;
226 0           $ind=scalar(@remaining)*6;
227 0           $text=" (".$self->{tree}->[$x]->{obj}->parent().") ".$text;
228 0           printf("%*s [%3d] %s\n",$ind,"",$x,$text);
229 0 0         if ($self->children($x))
230             {
231 0           push(@remaining,[ @list ]);
232 0           (@list)=$self->children($x);
233             }
234 0 0 0       if (!@list && @remaining)
235             {
236 0           (@list)=@{ pop(@remaining) };
  0            
237             }
238             }
239 0           return;
240             }
241              
242             sub run
243             {
244 0     0 1   my ($self)=shift;
245 0           my ($n,$x,@list);
246 0 0         if (@_)
247             {
248 0           $n=shift;
249             } else {
250 0           $n=0;
251             }
252 0           (@list)=$self->children($n);
253 0           while (@list)
254             {
255 0           $x=shift(@list);
256 0           $self->{tree}->[$x]->{obj}->run();
257             #$self->{output}.=$self->{tree}->[$x]->{obj}->output();
258             }
259 0           return;
260             }
261              
262             sub node
263             {
264 0     0 1   my ($self,$id)=@_;
265 0           return $self->{tree}->[$id]->{obj};
266             }
267              
268             sub parentId
269             {
270 0     0 0   my ($self,$id)=@_;
271 0 0         if ($self->{tree}->[$id])
272             {
273 0           return $self->{tree}->[$id]->{parent};
274             }
275             }
276              
277             sub dispatch
278             {
279 0     0 0   my ($self)=shift;
280 0 0         if (@_)
281             {
282 0           $self->{dispatch}=shift;
283             }
284 0           return $self->{dispatch};
285             }
286              
287             sub log
288             {
289 0     0 0   my ($self)=shift;
290 0 0         if (@_)
291             {
292 0           $self->{log}=shift;
293             }
294 0           return $self->{log};
295             }
296              
297             sub parser
298             {
299 0     0 0   my ($self)=shift;
300 0 0         if (@_)
301             {
302 0           $self->{parser}=shift;
303             }
304 0           return $self->{parser};
305             }
306              
307             #
308             # Hidden Methods
309             #
310              
311             sub _init
312             {
313 0     0     my ($self)=shift;
314 0           my ($a);
315 0           while (@_)
316             {
317 0           ($a)=shift;
318 0 0         if ($a eq "-noBlocks")
    0          
319             {
320 0           $self->{opts}->{noblocks}=1;
321             } elsif ($a eq "-parser")
322             {
323 0           $self->{parser}=shift;
324             }
325             }
326             # At this point, we should get the log and the dispatch table!
327 0 0         if ($self->{parser})
328             {
329 0           my ($uber)=$self->{parser}->main();
330 0           $self->{log}=$uber->log();
331 0           $self->{dispatch}=$uber->dispatch();
332             }
333 0           $self->{tree}=[];
334 0           $self->{tree}->[0]={};
335 0           $self->{curParent}=0;
336 0           return;
337             }
338              
339             sub _addObject
340             {
341 0     0     my ($self,$obj)=@_;
342 0           $obj->tree($self);
343 0           $self->_determineIndex($obj);
344 0           $self->_determineParent($obj);
345 0           $self->{tree}->[$self->{index}]->{obj}=$obj;
346 0           $self->{tree}->[$self->{index}]->{parent}=$obj->parent();
347 0           push(@{$self->{tree}->[$obj->parent()]->{children}},$self->{index});
  0            
348 0           $self->{index}++;
349 0           $obj->inserted();
350 0           return;
351             }
352              
353             sub _insertObj
354             {
355              
356 0     0     return;
357             }
358              
359             sub _determineIndex
360             {
361 0     0     my ($self,$obj)=@_;
362 0 0         unless (defined($self->{index}))
363             {
364 0           $self->{index}=1;
365             }
366 0           $obj->index($self->{index});
367 0           return;
368             }
369              
370             sub _determineParent
371             {
372 0     0     my ($self,$obj)=@_;
373 0 0         unless (defined($self->{nextParent}))
374             {
375 0           $self->{nextParent}=0;
376             }
377 0           $obj->parent($self->{nextParent});
378 0 0         if ($obj->class() eq "Command")
379             {
380 0 0         if ($obj->startBlock())
    0          
381             {
382 0           $self->{nextParent}=$self->{index};
383             } elsif ($obj->endBlock())
384             {
385 0           $self->{nextParent}=
386             $self->{tree}->[$self->{nextParent}]->{parent};
387             } else {
388             }
389             }
390 0           return;
391             }
392              
393             #
394             # Exit Block
395             #
396             1;
397              
398             #
399             # POD Documentation
400             #
401              
402             =head1 NAME
403              
404             Text::UberText::Tree - Tree Representation Of UberText Document
405              
406             =head1 DESCRIPTION
407              
408             An UberText document can have command blocks that enclose other commands
409             or text within the document. Because of this, the document needs to be
410             structured like a tree to keep track of the relationships of the commands and
411             text. Some parts of the document are siblings in relation, others have
412             children, and all parts have a parent.
413              
414             Each broken down portion of the document is refered to as a node, and each
415             node can represent either a command, or a piece of text. If the command
416             acts as a container block, it will have an understanding of several child
417             nodes that must also be processed when the command is run by the
418             L object.
419              
420             =head1 METHODS
421              
422             =over 4
423              
424             =item $tree=Text::UberTree->new();
425              
426             Creates a new tree object.
427              
428             =item $tree->addNode(-text => $string, -line $line, -class => $class);
429              
430             Adds a hunk of text to the tree. The $string variable refers to the raw
431             text, and $line refers to the line number in the source document. The
432             $class variable points to which Node class this data should be
433             assigned to (either Text::UberText::Node::Text, or Text::UberText::Node::Command).
434              
435             =item $tree->showTree();
436              
437             Shows the breakdown of the document tree, which may be useful for
438             debugging purposes.
439              
440             =item $tree->run();
441              
442             Processes each top level node in the tree. If nodes at this level have
443             children, they are expected to handle processing the child nodes themselves.
444              
445             =item $tree->children($node_id);
446              
447             Returns a list of children for a particular node id. Zero (0) is used by
448             default, and is considered the topmost node in the document.
449              
450             =item $tree->output($node_id);
451              
452             Returns the output of the tree for all child nodes of $node_id. Zero (0)
453             is used by default since it is the highest node in the tree.
454              
455             =item $tree->debugOutput($node_id);
456              
457             Returns the document output like the output() method, but prefixes the
458             actual node output with the id number of the node.
459              
460             =item $tree->node($node_id);
461              
462             Returns a single Node object, based on the ID passed to it.
463              
464             =back
465              
466             =head1 AUTHOR
467              
468             Chris Josephes Ecpj1@visi.comE
469              
470             =head1 SEE ALSO
471              
472             L,
473             L
474              
475             =head1 COPYRIGHT
476              
477             Copyright 2002, Chris Josephes. All rights reserved.
478             This module is free software. It may be used, redistributed,
479             and/or modified under the same terms as Perl itself.
480             ~