File Coverage

blib/lib/Text/UberText/Node/Command.pm
Criterion Covered Total %
statement 15 223 6.7
branch 0 62 0.0
condition 0 6 0.0
subroutine 5 28 17.8
pod 12 14 85.7
total 32 333 9.6


line stmt bran cond sub pod time code
1             #
2             # Package Definition
3             #
4              
5             package Text::UberText::Node::Command;
6              
7             #
8             # Compiler Directives
9             #
10              
11 1     1   7 use strict;
  1         3  
  1         44  
12 1     1   6 use warnings;
  1         2  
  1         30  
13              
14             #
15             # Includes
16             #
17              
18 1     1   626 use Text::UberText::Node;
  1         11  
  1         30  
19 1     1   7 use Text::UberText::Parser;
  1         2  
  1         26  
20              
21             #
22             # Global Variables
23             #
24              
25 1     1   5 use vars qw/@ISA $VERSION/;
  1         1  
  1         3838  
26              
27             $VERSION=0.95;
28              
29             #
30             # Inheritance
31             #
32              
33             @ISA=("Text::UberText::Node");
34              
35             #
36             # Methods
37             #
38              
39             sub new
40             {
41 0     0 1   my ($class)=shift;
42 0           my ($object);
43 0           $object={};
44 0           bless ($object,$class);
45 0           $object->_init(@_);
46 0           return $object;
47             }
48              
49             sub process
50             {
51 0     0 1   my ($self)=shift;
52 0           my ($arg,$value,$argCount);
53 0           $argCount=0;
54 0           $self->{dispatch}=$self->{tree}->{dispatch};
55 0           $self->_prep();
56 0           $self->_determineBlockStatus();
57 0           $self->{warray}=[ split(//,$self->{working}) ];
58 0           $self->_setNameSpace();
59 0           while (@{$self->{warray}})
  0            
60             {
61 0           ($arg,$value)=_getOpt($self->{warray});
62 0 0         if ($argCount==0)
63             {
64 0           $self->command($arg,$value);
65             } else {
66 0           $self->setOpt($arg,$value);
67             }
68 0           $argCount++;
69             }
70 0           return;
71             }
72              
73             sub inserted
74             {
75 0     0 0   my ($self)=@_;
76 0 0         if ($self->{endBlock})
77             {
78 0           $self->_sendArgsToParent();
79             }
80 0           return;
81             }
82              
83             sub startBlock
84             {
85 0     0 1   my ($self)=shift;
86              
87 0           return $self->{startBlock};
88             }
89              
90             sub endBlock
91             {
92 0     0 1   my ($self)=shift;
93              
94 0           return $self->{endBlock};
95             }
96              
97             sub command
98             {
99 0     0 1   my ($self)=shift;
100 0 0         if (@_)
101             {
102 0           my ($cmd,$arg)=@_;
103 0           my ($parser);
104 0           $parser=$self->{tree}->parser();
105 0           $self->{command}=$cmd;
106 0           $arg=_trimArg($arg);
107 0 0         if ($arg)
108             {
109 0           $self->{commandArg}=$parser->quickie($arg);
110             }
111             }
112 0           return ($self->{command},$self->{commandArg});
113             }
114              
115             sub commandValue
116             {
117 0     0 1   my ($self)=@_;
118 0           return $self->{commandArg};
119             }
120              
121             sub namespace
122             {
123 0     0 1   my ($self)=shift;
124 0           return $self->{namespace};
125             }
126              
127             sub setOpt
128             {
129 0     0 1   my ($self,$optName,$value)=@_;
130 0 0         if ($value)
131             {
132             # Identify the option as being set
133 0           $self->{opt}->{$optName}->{set}=1;
134             # Trim the surrounding parenthesis or double-quotes
135 0 0         if ($value=~/^(.*)$/)
136             {
137 0           $self->{opt}->{$optName}->{enclosure}="parenthesis";
138             } else {
139 0           $self->{opt}->{$optName}->{enclosure}="double-quotes";
140             }
141 0           $value=_trimArg($value);
142             # Create a new parser, and go through the value to parse it
143 0           my ($parser);
144 0           $parser=$self->{tree}->parser();
145 0           $self->{opt}->{$optName}->{value}=$parser->quickie($value);
146             } else {
147             # Only identify the option as being set
148 0           $self->{opt}->{$optName}->{set}=1;
149             }
150 0           return;
151             }
152              
153             sub getOpt
154             {
155 0     0 1   my ($self,$optName)=@_;
156 0           my ($set,$value);
157 0 0         if ($self->{opt}->{$optName}->{set})
158             {
159 0           $set=1;
160 0           $value=$self->{opt}->{$optName}->{value};
161             } else {
162 0           $set=0;
163             }
164 0           return ($set,$value);
165             }
166              
167             sub getOptValue
168             {
169 0     0 1   my ($self,$optName)=@_;
170 0 0         if ($self->{opt}->{$optName})
171             {
172 0           return $self->{opt}->{$optName}->{value};
173             }
174             }
175              
176             sub opts
177             {
178 0     0 0   my ($self)=shift;
179 0           return keys(%{$self->{opt}});
  0            
180             }
181              
182             sub info
183             {
184 0     0 1   my ($self)=shift;
185 0           my ($cm,$ca,$a);
186 0           ($cm,$ca)=$self->command();
187 0           $ca=_trimArg($ca);
188 0           print("NAMESPACE: ",$self->namespace(),"\n");
189 0           print("COMMAND: $cm\n");
190 0           print("COMMAND ARG: $ca\n");
191 0           print("OPTS:\n");
192 0           foreach $a (keys(%{$self->{opt}}))
  0            
193             {
194 0           print("\t$a: ",_trimArg($self->{opt}->{$a}->{value}),"\n");
195             }
196 0           return;
197             }
198              
199             # run notes
200             # need access to tree and dispatch table
201              
202             sub run
203             {
204 0     0 1   my ($self)=shift;
205 0           my ($module);
206 0 0         unless ($self->endBlock())
207             {
208 0           $self->{output}=$self->{dispatch}->involke($self);
209             } else {
210 0           $self->{output}="";
211             }
212 0           return;
213             }
214              
215             #
216             # Hidden Methods
217             #
218              
219             # Make a copy of the input, remove the surrounding brackets ( [] )
220             sub _prep
221             {
222 0     0     my ($self)=shift;
223 0           $self->{working}=$self->{input};
224 0           $self->{working}=~s/(^\[\s*|\s*\]$)//g;
225 0           return;
226             }
227              
228             sub _truncSpace
229             {
230 0     0     my ($input)=@_;
231 0           my ($c);
232 0           while (@{$input})
  0            
233             {
234 0           ($c)=shift(@{$input});
  0            
235 0 0         if ($c !~ /\s/)
236             {
237 0           unshift(@{$input},$c);
  0            
238 0           return;
239             }
240             }
241 0           return;
242             }
243              
244             sub _trimArg
245             {
246 0     0     my ($string)=@_;
247 0 0         if ($string)
248             {
249 0           $string=~s/(^"|^\(|\)$|"$)//g;
250             }
251 0           return $string;
252             }
253              
254             # See if it is an opening or closing block, remove the arrows, but set the
255             # appropriate flags
256             sub _determineBlockStatus
257             {
258 0     0     my ($self)=shift;
259 0 0         if ($self->{working}=~/->$/s)
    0          
260             {
261 0           $self->{working}=~s/\s*->//;
262 0           $self->{startBlock}=1;
263             } elsif ($self->{working}=~/^<-/s)
264             {
265 0           $self->{working}=~s/^<-\s*//;
266 0           $self->{endBlock}=1;
267             }
268 0           return;
269             }
270              
271             sub _setNameSpace
272             {
273 0     0     my ($self)=shift;
274 0           my ($ns,$x);
275 0           while (@{$self->{warray}})
  0            
276             {
277 0           ($x)=shift(@{$self->{warray}});
  0            
278 0 0         last if ($x =~/\s/);
279 0           $ns.=$x;
280             }
281 0 0         if ($ns=~/^\w[\w.]*$/)
282             {
283 0           $self->{namespace}=$ns;
284             }
285 0           return;
286             }
287              
288             sub _getOpt
289             {
290 0     0     my ($chars)=@_;
291 0           my ($c,$arg,$value);
292 0           while (@{$chars})
  0            
293             {
294 0           ($c)=shift(@{$chars});
  0            
295 0 0         if ($c=~/\s/)
    0          
296             {
297 0           _truncSpace($chars);
298 0           ($c)=shift(@{$chars});
  0            
299 0 0         if ($c eq ":" )
300             {
301 0           _truncSpace($chars);
302 0           $value=_getValue($chars);
303             } else {
304 0           unshift(@{$chars},$c);
  0            
305             }
306 0           last;
307             } elsif ($c eq ":")
308             {
309 0           _truncSpace($chars);
310 0           $value=_getValue($chars);
311             } else {
312 0           $arg.=$c;
313             }
314             }
315 0           return ($arg,$value);
316             }
317              
318             sub _getValue
319             {
320 0     0     my ($chars)=@_;
321 0           my ($c,$value);
322 0           while (@{$chars})
  0            
323             {
324 0           ($c)=shift(@{$chars});
  0            
325 0 0         if ($c eq "(")
    0          
326             {
327 0           $value.=$c;
328 0           my ($level)=1;
329 0           while (@{$chars})
  0            
330             {
331 0           ($c)=shift(@{$chars});
  0            
332 0 0         if ($c eq "[")
    0          
333             {
334 0           $level++;
335             } elsif ($c eq "]")
336             {
337 0           $level--;
338             }
339 0           $value.=$c;
340 0 0 0       if ($c eq ")" && $level==1)
341             {
342 0           return $value;
343             }
344             }
345            
346             }
347             elsif ($c eq "\"")
348             {
349 0           $value.=$c;
350 0           my ($level)=1;
351 0           while (@{$chars})
  0            
352             {
353 0           ($c)=shift(@{$chars});
  0            
354 0 0         if ($c eq "[")
    0          
355             {
356 0           $level++;
357             } elsif ($c eq "]")
358             {
359 0           $level--;
360             }
361 0           $value.=$c;
362 0 0 0       if ($c eq "\"" && $level==1)
363             {
364 0           return $value;
365             }
366             }
367             }
368             }
369 0           return ($value);
370             }
371              
372             sub _extractCommand
373             {
374 0     0     my ($self)=shift;
375 0           my ($cmd,$carg,$x,@chars);
376 0           $self->{working}=~s/^\s*//;
377 0           (@chars)=split(//,$self->{working});
378 0           while (@chars)
379             {
380 0           ($x)=shift(@chars);
381 0 0         last if ($x !~ /\w/);
382 0           $cmd.=$x;
383             }
384 0 0         if ($x =~/\s/)
385             {
386 0           while (@chars)
387             {
388 0           ($x)=shift(@chars);
389 0 0         last if ($x !~ /\s/);
390             }
391             }
392 0           return;
393             }
394              
395             sub _sendArgsToParent
396             {
397 0     0     my ($self)=shift;
398 0           my ($sid,$pid,$parent,$cmd,$value,$opt);
399 0           $sid=$self->index();
400 0           $pid=$self->{tree}->parentId($sid);
401 0           $parent=$self->{tree}->node($pid);
402             # Do the command first
403 0           $cmd=$self->{command};
404 0           $value=$self->{commandArg};
405 0 0         if ($cmd)
406             {
407 0 0         if ($value)
408             {
409 0           $parent->{opt}->{$cmd}->{value}=$value;
410             }
411 0           $parent->{opt}->{$cmd}->{set}=1;
412 0           $parent->{opt}->{$cmd}->{closing}=1;
413             }
414             # Now the args
415 0           foreach $opt ($self->opts())
416             {
417 0           $parent->{opt}->{$opt}->{value}=$self->{opt}->{$opt}->{value};
418 0           $parent->{opt}->{$opt}->{set}=$self->{opt}->{$opt}->{set};
419 0           $parent->{opt}->{$opt}->{enclosure}=$self->{opt}->{$opt}->{enclosure};
420 0           $parent->{opt}->{$opt}->{closing}=1;
421             }
422             # And the namespace
423 0           $parent->{closingNamespace}=$self->namespace();
424 0           return;
425             }
426              
427             #
428             # Exit Block
429             #
430             1;
431              
432             #
433             # POD Documentation
434             #
435              
436             =head1 NAME
437              
438             Text::UberText::Node::Command - UberText Command Node
439              
440             =head1 DESCRIPTION
441              
442             The Node::Command module handles processing an UberText command statement
443             embedded within an UberText file. It is a subclass of the Text::UberText::Node
444             class.
445              
446             =head1 METHODS
447              
448             The following methods are unique to the Node::Command module. For a full
449             listing of the methods available, also check the Text::UberText::Node
450             documentation.
451              
452             =over 4
453              
454             =item $node->namespace();
455              
456             Returns the namespace portion of the UberText command. Namespaces are
457             an alphanumeric sequence, with the first character being a letter and are segmented
458             with periods to create a hierarchial namespace.
459              
460             Namespaces are case-insensitive and internally represented by transforming all
461             characters to lowerspace.
462              
463             The "uber.*" namespace is reserved and should not be used for private modules.
464              
465             =item ($command,$value)=$node->command();
466              
467             Returns the command portion of the UberText command, and the value that
468             was passed to the command (if any).
469              
470             =item ($value)=$node->commandValue();
471              
472             Returns the value that was assigned to the command.
473              
474             =item ($bool,$value)=$node->getOpt($opt);
475              
476             Returns whether or not a particular option was set, and the value
477             passed along with the option (if any).
478              
479             Options and values to options are, well, optional. Implementors need to make
480             sure they test whether or not an option was set, and what value was passed
481             to the option.
482              
483             =item $node->setOpt($opt,$value);
484              
485             Identifies an option as set, and specifies a value to go along with
486             it.
487              
488             =item ($value)=$node->getOptValue($opt);
489              
490             Returns only the value of an option. This routine may be easier to use
491             when it comes to handling conditional evaluation.
492              
493             =item $node->startBlock();
494              
495             Identifies whether or not this Command node contains child elements.
496              
497             =item $node->endBlock();
498              
499             Identifies whether or not this Command node is the last element in a string
500             of child elements.
501              
502             =item $node->process();
503              
504             Runs through the command string to break apart the namespace, the command,
505             command value, and options.
506              
507             =item $node->info();
508              
509             Reports on the namespace, command, command value, and options.
510              
511             =head1 AUTHOR
512              
513             Chris Josephes Ecpj1@visi.comE
514              
515             =head1 SEE ALSO
516              
517             L,
518             L
519              
520             =head1 COPYRIGHT
521              
522             Copyright 2002, Chris Josephes. All rights reserved.
523             This module is free software. It may be used, redistributed,
524             and/or modified under the same terms as Perl itself.
525             ~