Commit | Line | Data |
360aca43 |
1 | ############################################################################# |
2 | # Pod/InputObjects.pm -- package which defines objects for input streams |
3 | # and paragraphs and commands when parsing POD docs. |
4 | # |
664bb207 |
5 | # Copyright (C) 1996-1999 by Bradford Appleton. All rights reserved. |
360aca43 |
6 | # This file is part of "PodParser". PodParser is free software; |
7 | # you can redistribute it and/or modify it under the same terms |
8 | # as Perl itself. |
9 | ############################################################################# |
10 | |
11 | package Pod::InputObjects; |
12 | |
13 | use vars qw($VERSION); |
e3237417 |
14 | $VERSION = 1.090; ## Current version of this package |
360aca43 |
15 | require 5.004; ## requires this Perl version or later |
16 | |
17 | ############################################################################# |
18 | |
19 | =head1 NAME |
20 | |
21 | Pod::InputObjects - objects representing POD input paragraphs, commands, etc. |
22 | |
23 | =head1 SYNOPSIS |
24 | |
25 | use Pod::InputObjects; |
26 | |
27 | =head1 REQUIRES |
28 | |
29 | perl5.004, Carp |
30 | |
31 | =head1 EXPORTS |
32 | |
33 | Nothing. |
34 | |
35 | =head1 DESCRIPTION |
36 | |
37 | This module defines some basic input objects used by B<Pod::Parser> when |
38 | reading and parsing POD text from an input source. The following objects |
39 | are defined: |
40 | |
41 | =over 4 |
42 | |
43 | =begin __PRIVATE__ |
44 | |
45 | =item B<Pod::InputSource> |
46 | |
47 | An object corresponding to a source of POD input text. It is mostly a |
48 | wrapper around a filehandle or C<IO::Handle>-type object (or anything |
49 | that implements the C<getline()> method) which keeps track of some |
50 | additional information relevant to the parsing of PODs. |
51 | |
52 | =end __PRIVATE__ |
53 | |
54 | =item B<Pod::Paragraph> |
55 | |
56 | An object corresponding to a paragraph of POD input text. It may be a |
57 | plain paragraph, a verbatim paragraph, or a command paragraph (see |
58 | L<perlpod>). |
59 | |
60 | =item B<Pod::InteriorSequence> |
61 | |
62 | An object corresponding to an interior sequence command from the POD |
63 | input text (see L<perlpod>). |
64 | |
65 | =item B<Pod::ParseTree> |
66 | |
67 | An object corresponding to a tree of parsed POD text. Each "node" in |
68 | a parse-tree (or I<ptree>) is either a text-string or a reference to |
69 | a B<Pod::InteriorSequence> object. The nodes appear in the parse-tree |
70 | in they order in which they were parsed from left-to-right. |
71 | |
72 | =back |
73 | |
74 | Each of these input objects are described in further detail in the |
75 | sections which follow. |
76 | |
77 | =cut |
78 | |
79 | ############################################################################# |
80 | |
81 | use strict; |
82 | #use diagnostics; |
83 | #use Carp; |
84 | |
85 | ############################################################################# |
86 | |
87 | package Pod::InputSource; |
88 | |
89 | ##--------------------------------------------------------------------------- |
90 | |
91 | =begin __PRIVATE__ |
92 | |
93 | =head1 B<Pod::InputSource> |
94 | |
95 | This object corresponds to an input source or stream of POD |
96 | documentation. When parsing PODs, it is necessary to associate and store |
97 | certain context information with each input source. All of this |
98 | information is kept together with the stream itself in one of these |
99 | C<Pod::InputSource> objects. Each such object is merely a wrapper around |
100 | an C<IO::Handle> object of some kind (or at least something that |
101 | implements the C<getline()> method). They have the following |
102 | methods/attributes: |
103 | |
104 | =end __PRIVATE__ |
105 | |
106 | =cut |
107 | |
108 | ##--------------------------------------------------------------------------- |
109 | |
110 | =begin __PRIVATE__ |
111 | |
112 | =head2 B<new()> |
113 | |
114 | my $pod_input1 = Pod::InputSource->new(-handle => $filehandle); |
115 | my $pod_input2 = new Pod::InputSource(-handle => $filehandle, |
116 | -name => $name); |
117 | my $pod_input3 = new Pod::InputSource(-handle => \*STDIN); |
118 | my $pod_input4 = Pod::InputSource->new(-handle => \*STDIN, |
119 | -name => "(STDIN)"); |
120 | |
121 | This is a class method that constructs a C<Pod::InputSource> object and |
122 | returns a reference to the new input source object. It takes one or more |
123 | keyword arguments in the form of a hash. The keyword C<-handle> is |
124 | required and designates the corresponding input handle. The keyword |
125 | C<-name> is optional and specifies the name associated with the input |
126 | handle (typically a file name). |
127 | |
128 | =end __PRIVATE__ |
129 | |
130 | =cut |
131 | |
132 | sub new { |
133 | ## Determine if we were called via an object-ref or a classname |
134 | my $this = shift; |
135 | my $class = ref($this) || $this; |
136 | |
137 | ## Any remaining arguments are treated as initial values for the |
138 | ## hash that is used to represent this object. Note that we default |
139 | ## certain values by specifying them *before* the arguments passed. |
140 | ## If they are in the argument list, they will override the defaults. |
141 | my $self = { -name => '(unknown)', |
142 | -handle => undef, |
143 | -was_cutting => 0, |
144 | @_ }; |
145 | |
146 | ## Bless ourselves into the desired class and perform any initialization |
147 | bless $self, $class; |
148 | return $self; |
149 | } |
150 | |
151 | ##--------------------------------------------------------------------------- |
152 | |
153 | =begin __PRIVATE__ |
154 | |
155 | =head2 B<name()> |
156 | |
157 | my $filename = $pod_input->name(); |
158 | $pod_input->name($new_filename_to_use); |
159 | |
160 | This method gets/sets the name of the input source (usually a filename). |
161 | If no argument is given, it returns a string containing the name of |
162 | the input source; otherwise it sets the name of the input source to the |
163 | contents of the given argument. |
164 | |
165 | =end __PRIVATE__ |
166 | |
167 | =cut |
168 | |
169 | sub name { |
170 | (@_ > 1) and $_[0]->{'-name'} = $_[1]; |
171 | return $_[0]->{'-name'}; |
172 | } |
173 | |
174 | ## allow 'filename' as an alias for 'name' |
175 | *filename = \&name; |
176 | |
177 | ##--------------------------------------------------------------------------- |
178 | |
179 | =begin __PRIVATE__ |
180 | |
181 | =head2 B<handle()> |
182 | |
183 | my $handle = $pod_input->handle(); |
184 | |
185 | Returns a reference to the handle object from which input is read (the |
186 | one used to contructed this input source object). |
187 | |
188 | =end __PRIVATE__ |
189 | |
190 | =cut |
191 | |
192 | sub handle { |
193 | return $_[0]->{'-handle'}; |
194 | } |
195 | |
196 | ##--------------------------------------------------------------------------- |
197 | |
198 | =begin __PRIVATE__ |
199 | |
200 | =head2 B<was_cutting()> |
201 | |
202 | print "Yes.\n" if ($pod_input->was_cutting()); |
203 | |
204 | The value of the C<cutting> state (that the B<cutting()> method would |
205 | have returned) immediately before any input was read from this input |
206 | stream. After all input from this stream has been read, the C<cutting> |
207 | state is restored to this value. |
208 | |
209 | =end __PRIVATE__ |
210 | |
211 | =cut |
212 | |
213 | sub was_cutting { |
214 | (@_ > 1) and $_[0]->{-was_cutting} = $_[1]; |
215 | return $_[0]->{-was_cutting}; |
216 | } |
217 | |
218 | ##--------------------------------------------------------------------------- |
219 | |
220 | ############################################################################# |
221 | |
222 | package Pod::Paragraph; |
223 | |
224 | ##--------------------------------------------------------------------------- |
225 | |
226 | =head1 B<Pod::Paragraph> |
227 | |
228 | An object representing a paragraph of POD input text. |
229 | It has the following methods/attributes: |
230 | |
231 | =cut |
232 | |
233 | ##--------------------------------------------------------------------------- |
234 | |
235 | =head2 B<new()> |
236 | |
237 | my $pod_para1 = Pod::Paragraph->new(-text => $text); |
238 | my $pod_para2 = Pod::Paragraph->new(-name => $cmd, |
239 | -text => $text); |
240 | my $pod_para3 = new Pod::Paragraph(-text => $text); |
241 | my $pod_para4 = new Pod::Paragraph(-name => $cmd, |
242 | -text => $text); |
243 | my $pod_para5 = Pod::Paragraph->new(-name => $cmd, |
244 | -text => $text, |
245 | -file => $filename, |
246 | -line => $line_number); |
247 | |
248 | This is a class method that constructs a C<Pod::Paragraph> object and |
249 | returns a reference to the new paragraph object. It may be given one or |
250 | two keyword arguments. The C<-text> keyword indicates the corresponding |
251 | text of the POD paragraph. The C<-name> keyword indicates the name of |
252 | the corresponding POD command, such as C<head1> or C<item> (it should |
253 | I<not> contain the C<=> prefix); this is needed only if the POD |
254 | paragraph corresponds to a command paragraph. The C<-file> and C<-line> |
255 | keywords indicate the filename and line number corresponding to the |
256 | beginning of the paragraph |
257 | |
258 | =cut |
259 | |
260 | sub new { |
261 | ## Determine if we were called via an object-ref or a classname |
262 | my $this = shift; |
263 | my $class = ref($this) || $this; |
264 | |
265 | ## Any remaining arguments are treated as initial values for the |
266 | ## hash that is used to represent this object. Note that we default |
267 | ## certain values by specifying them *before* the arguments passed. |
268 | ## If they are in the argument list, they will override the defaults. |
269 | my $self = { |
270 | -name => undef, |
271 | -text => (@_ == 1) ? $_[0] : undef, |
272 | -file => '<unknown-file>', |
273 | -line => 0, |
274 | -prefix => '=', |
275 | -separator => ' ', |
276 | -ptree => [], |
277 | @_ |
278 | }; |
279 | |
280 | ## Bless ourselves into the desired class and perform any initialization |
281 | bless $self, $class; |
282 | return $self; |
283 | } |
284 | |
285 | ##--------------------------------------------------------------------------- |
286 | |
287 | =head2 B<cmd_name()> |
288 | |
289 | my $para_cmd = $pod_para->cmd_name(); |
290 | |
291 | If this paragraph is a command paragraph, then this method will return |
292 | the name of the command (I<without> any leading C<=> prefix). |
293 | |
294 | =cut |
295 | |
296 | sub cmd_name { |
297 | (@_ > 1) and $_[0]->{'-name'} = $_[1]; |
298 | return $_[0]->{'-name'}; |
299 | } |
300 | |
301 | ## let name() be an alias for cmd_name() |
302 | *name = \&cmd_name; |
303 | |
304 | ##--------------------------------------------------------------------------- |
305 | |
306 | =head2 B<text()> |
307 | |
308 | my $para_text = $pod_para->text(); |
309 | |
310 | This method will return the corresponding text of the paragraph. |
311 | |
312 | =cut |
313 | |
314 | sub text { |
315 | (@_ > 1) and $_[0]->{'-text'} = $_[1]; |
316 | return $_[0]->{'-text'}; |
317 | } |
318 | |
319 | ##--------------------------------------------------------------------------- |
320 | |
321 | =head2 B<raw_text()> |
322 | |
323 | my $raw_pod_para = $pod_para->raw_text(); |
324 | |
325 | This method will return the I<raw> text of the POD paragraph, exactly |
326 | as it appeared in the input. |
327 | |
328 | =cut |
329 | |
330 | sub raw_text { |
331 | return $_[0]->{'-text'} unless (defined $_[0]->{'-name'}); |
332 | return $_[0]->{'-prefix'} . $_[0]->{'-name'} . |
333 | $_[0]->{'-separator'} . $_[0]->{'-text'}; |
334 | } |
335 | |
336 | ##--------------------------------------------------------------------------- |
337 | |
338 | =head2 B<cmd_prefix()> |
339 | |
340 | my $prefix = $pod_para->cmd_prefix(); |
341 | |
342 | If this paragraph is a command paragraph, then this method will return |
343 | the prefix used to denote the command (which should be the string "=" |
344 | or "=="). |
345 | |
346 | =cut |
347 | |
348 | sub cmd_prefix { |
349 | return $_[0]->{'-prefix'}; |
350 | } |
351 | |
352 | ##--------------------------------------------------------------------------- |
353 | |
354 | =head2 B<cmd_separator()> |
355 | |
356 | my $separator = $pod_para->cmd_separator(); |
357 | |
358 | If this paragraph is a command paragraph, then this method will return |
359 | the text used to separate the command name from the rest of the |
360 | paragraph (if any). |
361 | |
362 | =cut |
363 | |
364 | sub cmd_separator { |
365 | return $_[0]->{'-separator'}; |
366 | } |
367 | |
368 | ##--------------------------------------------------------------------------- |
369 | |
370 | =head2 B<parse_tree()> |
371 | |
372 | my $ptree = $pod_parser->parse_text( $pod_para->text() ); |
373 | $pod_para->parse_tree( $ptree ); |
374 | $ptree = $pod_para->parse_tree(); |
375 | |
376 | This method will get/set the corresponding parse-tree of the paragraph's text. |
377 | |
378 | =cut |
379 | |
380 | sub parse_tree { |
381 | (@_ > 1) and $_[0]->{'-ptree'} = $_[1]; |
382 | return $_[0]->{'-ptree'}; |
383 | } |
384 | |
385 | ## let ptree() be an alias for parse_tree() |
386 | *ptree = \&parse_tree; |
387 | |
388 | ##--------------------------------------------------------------------------- |
389 | |
390 | =head2 B<file_line()> |
391 | |
392 | my ($filename, $line_number) = $pod_para->file_line(); |
393 | my $position = $pod_para->file_line(); |
394 | |
395 | Returns the current filename and line number for the paragraph |
396 | object. If called in an array context, it returns a list of two |
397 | elements: first the filename, then the line number. If called in |
398 | a scalar context, it returns a string containing the filename, followed |
399 | by a colon (':'), followed by the line number. |
400 | |
401 | =cut |
402 | |
403 | sub file_line { |
404 | my @loc = ($_[0]->{'-file'} || '<unknown-file>', |
405 | $_[0]->{'-line'} || 0); |
406 | return (wantarray) ? @loc : join(':', @loc); |
407 | } |
408 | |
409 | ##--------------------------------------------------------------------------- |
410 | |
411 | ############################################################################# |
412 | |
413 | package Pod::InteriorSequence; |
414 | |
415 | ##--------------------------------------------------------------------------- |
416 | |
417 | =head1 B<Pod::InteriorSequence> |
418 | |
419 | An object representing a POD interior sequence command. |
420 | It has the following methods/attributes: |
421 | |
422 | =cut |
423 | |
424 | ##--------------------------------------------------------------------------- |
425 | |
426 | =head2 B<new()> |
427 | |
428 | my $pod_seq1 = Pod::InteriorSequence->new(-name => $cmd |
429 | -ldelim => $delimiter); |
430 | my $pod_seq2 = new Pod::InteriorSequence(-name => $cmd, |
431 | -ldelim => $delimiter); |
432 | my $pod_seq3 = new Pod::InteriorSequence(-name => $cmd, |
433 | -ldelim => $delimiter, |
434 | -file => $filename, |
435 | -line => $line_number); |
436 | |
664bb207 |
437 | my $pod_seq4 = new Pod::InteriorSequence(-name => $cmd, $ptree); |
438 | my $pod_seq5 = new Pod::InteriorSequence($cmd, $ptree); |
439 | |
360aca43 |
440 | This is a class method that constructs a C<Pod::InteriorSequence> object |
441 | and returns a reference to the new interior sequence object. It should |
442 | be given two keyword arguments. The C<-ldelim> keyword indicates the |
443 | corresponding left-delimiter of the interior sequence (e.g. 'E<lt>'). |
444 | The C<-name> keyword indicates the name of the corresponding interior |
445 | sequence command, such as C<I> or C<B> or C<C>. The C<-file> and |
446 | C<-line> keywords indicate the filename and line number corresponding |
664bb207 |
447 | to the beginning of the interior sequence. If the C<$ptree> argument is |
448 | given, it must be the last argument, and it must be either string, or |
449 | else an array-ref suitable for passing to B<Pod::ParseTree::new> (or |
450 | it may be a reference to an Pod::ParseTree object). |
360aca43 |
451 | |
452 | =cut |
453 | |
454 | sub new { |
455 | ## Determine if we were called via an object-ref or a classname |
456 | my $this = shift; |
457 | my $class = ref($this) || $this; |
458 | |
664bb207 |
459 | ## See if first argument has no keyword |
460 | if (((@_ <= 2) or (@_ % 2)) and $_[0] !~ /^-\w/) { |
461 | ## Yup - need an implicit '-name' before first parameter |
462 | unshift @_, '-name'; |
463 | } |
464 | |
465 | ## See if odd number of args |
466 | if ((@_ % 2) != 0) { |
467 | ## Yup - need an implicit '-ptree' before the last parameter |
468 | splice @_, $#_, 0, '-ptree'; |
469 | } |
470 | |
360aca43 |
471 | ## Any remaining arguments are treated as initial values for the |
472 | ## hash that is used to represent this object. Note that we default |
473 | ## certain values by specifying them *before* the arguments passed. |
474 | ## If they are in the argument list, they will override the defaults. |
475 | my $self = { |
476 | -name => (@_ == 1) ? $_[0] : undef, |
477 | -file => '<unknown-file>', |
478 | -line => 0, |
479 | -ldelim => '<', |
480 | -rdelim => '>', |
360aca43 |
481 | @_ |
482 | }; |
483 | |
664bb207 |
484 | ## Initialize contents if they havent been already |
485 | my $ptree = $self->{'-ptree'} || new Pod::ParseTree(); |
486 | if ( ref $ptree =~ /^(ARRAY)?$/ ) { |
487 | ## We have an array-ref, or a normal scalar. Pass it as an |
488 | ## an argument to the ptree-constructor |
489 | $ptree = new Pod::ParseTree($1 ? [$ptree] : $ptree); |
490 | } |
491 | $self->{'-ptree'} = $ptree; |
492 | |
360aca43 |
493 | ## Bless ourselves into the desired class and perform any initialization |
494 | bless $self, $class; |
495 | return $self; |
496 | } |
497 | |
498 | ##--------------------------------------------------------------------------- |
499 | |
500 | =head2 B<cmd_name()> |
501 | |
502 | my $seq_cmd = $pod_seq->cmd_name(); |
503 | |
504 | The name of the interior sequence command. |
505 | |
506 | =cut |
507 | |
508 | sub cmd_name { |
509 | (@_ > 1) and $_[0]->{'-name'} = $_[1]; |
510 | return $_[0]->{'-name'}; |
511 | } |
512 | |
513 | ## let name() be an alias for cmd_name() |
514 | *name = \&cmd_name; |
515 | |
516 | ##--------------------------------------------------------------------------- |
517 | |
518 | ## Private subroutine to set the parent pointer of all the given |
519 | ## children that are interior-sequences to be $self |
520 | |
521 | sub _set_child2parent_links { |
522 | my ($self, @children) = @_; |
523 | ## Make sure any sequences know who their parent is |
524 | for (@children) { |
664bb207 |
525 | next unless (ref || ref eq 'SCALAR'); |
360aca43 |
526 | if ($_->isa('Pod::InteriorSequence') or $_->can('nested')) { |
527 | $_->nested($self); |
528 | } |
529 | } |
530 | } |
531 | |
532 | ## Private subroutine to unset child->parent links |
533 | |
534 | sub _unset_child2parent_links { |
535 | my $self = shift; |
536 | $self->{'-parent_sequence'} = undef; |
537 | my $ptree = $self->{'-ptree'}; |
538 | for (@$ptree) { |
664bb207 |
539 | next unless (length and ref and ref ne 'SCALAR'); |
540 | $_->_unset_child2parent_links() if $_->isa('Pod::InteriorSequence'); |
360aca43 |
541 | } |
542 | } |
543 | |
544 | ##--------------------------------------------------------------------------- |
545 | |
546 | =head2 B<prepend()> |
547 | |
548 | $pod_seq->prepend($text); |
549 | $pod_seq1->prepend($pod_seq2); |
550 | |
551 | Prepends the given string or parse-tree or sequence object to the parse-tree |
552 | of this interior sequence. |
553 | |
554 | =cut |
555 | |
556 | sub prepend { |
557 | my $self = shift; |
558 | $self->{'-ptree'}->prepend(@_); |
559 | _set_child2parent_links($self, @_); |
560 | return $self; |
561 | } |
562 | |
563 | ##--------------------------------------------------------------------------- |
564 | |
565 | =head2 B<append()> |
566 | |
567 | $pod_seq->append($text); |
568 | $pod_seq1->append($pod_seq2); |
569 | |
570 | Appends the given string or parse-tree or sequence object to the parse-tree |
571 | of this interior sequence. |
572 | |
573 | =cut |
574 | |
575 | sub append { |
576 | my $self = shift; |
577 | $self->{'-ptree'}->append(@_); |
578 | _set_child2parent_links($self, @_); |
579 | return $self; |
580 | } |
581 | |
582 | ##--------------------------------------------------------------------------- |
583 | |
584 | =head2 B<nested()> |
585 | |
586 | $outer_seq = $pod_seq->nested || print "not nested"; |
587 | |
588 | If this interior sequence is nested inside of another interior |
589 | sequence, then the outer/parent sequence that contains it is |
590 | returned. Otherwise C<undef> is returned. |
591 | |
592 | =cut |
593 | |
594 | sub nested { |
595 | my $self = shift; |
596 | (@_ == 1) and $self->{'-parent_sequence'} = shift; |
597 | return $self->{'-parent_sequence'} || undef; |
598 | } |
599 | |
600 | ##--------------------------------------------------------------------------- |
601 | |
602 | =head2 B<raw_text()> |
603 | |
604 | my $seq_raw_text = $pod_seq->raw_text(); |
605 | |
606 | This method will return the I<raw> text of the POD interior sequence, |
607 | exactly as it appeared in the input. |
608 | |
609 | =cut |
610 | |
611 | sub raw_text { |
612 | my $self = shift; |
613 | my $text = $self->{'-name'} . $self->{'-ldelim'}; |
614 | for ( $self->{'-ptree'}->children ) { |
615 | $text .= (ref $_) ? $_->raw_text : $_; |
616 | } |
617 | $text .= $self->{'-rdelim'}; |
618 | return $text; |
619 | } |
620 | |
621 | ##--------------------------------------------------------------------------- |
622 | |
623 | =head2 B<left_delimiter()> |
624 | |
625 | my $ldelim = $pod_seq->left_delimiter(); |
626 | |
627 | The leftmost delimiter beginning the argument text to the interior |
628 | sequence (should be "<"). |
629 | |
630 | =cut |
631 | |
632 | sub left_delimiter { |
633 | (@_ > 1) and $_[0]->{'-ldelim'} = $_[1]; |
634 | return $_[0]->{'-ldelim'}; |
635 | } |
636 | |
637 | ## let ldelim() be an alias for left_delimiter() |
638 | *ldelim = \&left_delimiter; |
639 | |
640 | ##--------------------------------------------------------------------------- |
641 | |
642 | =head2 B<right_delimiter()> |
643 | |
644 | The rightmost delimiter beginning the argument text to the interior |
645 | sequence (should be ">"). |
646 | |
647 | =cut |
648 | |
649 | sub right_delimiter { |
650 | (@_ > 1) and $_[0]->{'-rdelim'} = $_[1]; |
651 | return $_[0]->{'-rdelim'}; |
652 | } |
653 | |
654 | ## let rdelim() be an alias for right_delimiter() |
655 | *rdelim = \&right_delimiter; |
656 | |
657 | ##--------------------------------------------------------------------------- |
658 | |
659 | =head2 B<parse_tree()> |
660 | |
661 | my $ptree = $pod_parser->parse_text($paragraph_text); |
662 | $pod_seq->parse_tree( $ptree ); |
663 | $ptree = $pod_seq->parse_tree(); |
664 | |
665 | This method will get/set the corresponding parse-tree of the interior |
666 | sequence's text. |
667 | |
668 | =cut |
669 | |
670 | sub parse_tree { |
671 | (@_ > 1) and $_[0]->{'-ptree'} = $_[1]; |
672 | return $_[0]->{'-ptree'}; |
673 | } |
674 | |
675 | ## let ptree() be an alias for parse_tree() |
676 | *ptree = \&parse_tree; |
677 | |
678 | ##--------------------------------------------------------------------------- |
679 | |
680 | =head2 B<file_line()> |
681 | |
682 | my ($filename, $line_number) = $pod_seq->file_line(); |
683 | my $position = $pod_seq->file_line(); |
684 | |
685 | Returns the current filename and line number for the interior sequence |
686 | object. If called in an array context, it returns a list of two |
687 | elements: first the filename, then the line number. If called in |
688 | a scalar context, it returns a string containing the filename, followed |
689 | by a colon (':'), followed by the line number. |
690 | |
691 | =cut |
692 | |
693 | sub file_line { |
694 | my @loc = ($_[0]->{'-file'} || '<unknown-file>', |
695 | $_[0]->{'-line'} || 0); |
696 | return (wantarray) ? @loc : join(':', @loc); |
697 | } |
698 | |
699 | ##--------------------------------------------------------------------------- |
700 | |
701 | =head2 B<DESTROY()> |
702 | |
703 | This method performs any necessary cleanup for the interior-sequence. |
704 | If you override this method then it is B<imperative> that you invoke |
705 | the parent method from within your own method, otherwise |
706 | I<interior-sequence storage will not be reclaimed upon destruction!> |
707 | |
708 | =cut |
709 | |
710 | sub DESTROY { |
711 | ## We need to get rid of all child->parent pointers throughout the |
712 | ## tree so their reference counts will go to zero and they can be |
713 | ## garbage-collected |
714 | _unset_child2parent_links(@_); |
715 | } |
716 | |
717 | ##--------------------------------------------------------------------------- |
718 | |
719 | ############################################################################# |
720 | |
721 | package Pod::ParseTree; |
722 | |
723 | ##--------------------------------------------------------------------------- |
724 | |
725 | =head1 B<Pod::ParseTree> |
726 | |
727 | This object corresponds to a tree of parsed POD text. As POD text is |
728 | scanned from left to right, it is parsed into an ordered list of |
729 | text-strings and B<Pod::InteriorSequence> objects (in order of |
730 | appearance). A B<Pod::ParseTree> object corresponds to this list of |
731 | strings and sequences. Each interior sequence in the parse-tree may |
732 | itself contain a parse-tree (since interior sequences may be nested). |
733 | |
734 | =cut |
735 | |
736 | ##--------------------------------------------------------------------------- |
737 | |
738 | =head2 B<new()> |
739 | |
740 | my $ptree1 = Pod::ParseTree->new; |
741 | my $ptree2 = new Pod::ParseTree; |
742 | my $ptree4 = Pod::ParseTree->new($array_ref); |
743 | my $ptree3 = new Pod::ParseTree($array_ref); |
744 | |
745 | This is a class method that constructs a C<Pod::Parse_tree> object and |
746 | returns a reference to the new parse-tree. If a single-argument is given, |
664bb207 |
747 | it must be a reference to an array, and is used to initialize the root |
360aca43 |
748 | (top) of the parse tree. |
749 | |
750 | =cut |
751 | |
752 | sub new { |
753 | ## Determine if we were called via an object-ref or a classname |
754 | my $this = shift; |
755 | my $class = ref($this) || $this; |
756 | |
757 | my $self = (@_ == 1 and ref $_[0]) ? $_[0] : []; |
758 | |
759 | ## Bless ourselves into the desired class and perform any initialization |
760 | bless $self, $class; |
761 | return $self; |
762 | } |
763 | |
764 | ##--------------------------------------------------------------------------- |
765 | |
766 | =head2 B<top()> |
767 | |
768 | my $top_node = $ptree->top(); |
769 | $ptree->top( $top_node ); |
770 | $ptree->top( @children ); |
771 | |
772 | This method gets/sets the top node of the parse-tree. If no arguments are |
773 | given, it returns the topmost node in the tree (the root), which is also |
774 | a B<Pod::ParseTree>. If it is given a single argument that is a reference, |
775 | then the reference is assumed to a parse-tree and becomes the new top node. |
776 | Otherwise, if arguments are given, they are treated as the new list of |
777 | children for the top node. |
778 | |
779 | =cut |
780 | |
781 | sub top { |
782 | my $self = shift; |
783 | if (@_ > 0) { |
784 | @{ $self } = (@_ == 1 and ref $_[0]) ? ${ @_ } : @_; |
785 | } |
786 | return $self; |
787 | } |
788 | |
789 | ## let parse_tree() & ptree() be aliases for the 'top' method |
790 | *parse_tree = *ptree = \⊤ |
791 | |
792 | ##--------------------------------------------------------------------------- |
793 | |
794 | =head2 B<children()> |
795 | |
796 | This method gets/sets the children of the top node in the parse-tree. |
797 | If no arguments are given, it returns the list (array) of children |
798 | (each of which should be either a string or a B<Pod::InteriorSequence>. |
799 | Otherwise, if arguments are given, they are treated as the new list of |
800 | children for the top node. |
801 | |
802 | =cut |
803 | |
804 | sub children { |
805 | my $self = shift; |
806 | if (@_ > 0) { |
807 | @{ $self } = (@_ == 1 and ref $_[0]) ? ${ @_ } : @_; |
808 | } |
809 | return @{ $self }; |
810 | } |
811 | |
812 | ##--------------------------------------------------------------------------- |
813 | |
814 | =head2 B<prepend()> |
815 | |
816 | This method prepends the given text or parse-tree to the current parse-tree. |
817 | If the first item on the parse-tree is text and the argument is also text, |
818 | then the text is prepended to the first item (not added as a separate string). |
819 | Otherwise the argument is added as a new string or parse-tree I<before> |
820 | the current one. |
821 | |
822 | =cut |
823 | |
824 | use vars qw(@ptree); ## an alias used for performance reasons |
825 | |
826 | sub prepend { |
827 | my $self = shift; |
828 | local *ptree = $self; |
829 | for (@_) { |
e9fdc7d2 |
830 | next unless length; |
360aca43 |
831 | if (@ptree and !(ref $ptree[0]) and !(ref $_)) { |
832 | $ptree[0] = $_ . $ptree[0]; |
833 | } |
834 | else { |
835 | unshift @ptree, $_; |
836 | } |
837 | } |
838 | } |
839 | |
840 | ##--------------------------------------------------------------------------- |
841 | |
842 | =head2 B<append()> |
843 | |
844 | This method appends the given text or parse-tree to the current parse-tree. |
845 | If the last item on the parse-tree is text and the argument is also text, |
846 | then the text is appended to the last item (not added as a separate string). |
847 | Otherwise the argument is added as a new string or parse-tree I<after> |
848 | the current one. |
849 | |
850 | =cut |
851 | |
852 | sub append { |
853 | my $self = shift; |
854 | local *ptree = $self; |
855 | for (@_) { |
e9fdc7d2 |
856 | next unless length; |
360aca43 |
857 | if (@ptree and !(ref $ptree[-1]) and !(ref $_)) { |
858 | $ptree[-1] .= $_; |
859 | } |
860 | else { |
861 | push @ptree, $_; |
862 | } |
863 | } |
864 | } |
865 | |
866 | =head2 B<raw_text()> |
867 | |
868 | my $ptree_raw_text = $ptree->raw_text(); |
869 | |
870 | This method will return the I<raw> text of the POD parse-tree |
871 | exactly as it appeared in the input. |
872 | |
873 | =cut |
874 | |
875 | sub raw_text { |
876 | my $self = shift; |
877 | my $text = ""; |
878 | for ( @$self ) { |
879 | $text .= (ref $_) ? $_->raw_text : $_; |
880 | } |
881 | return $text; |
882 | } |
883 | |
884 | ##--------------------------------------------------------------------------- |
885 | |
886 | ## Private routines to set/unset child->parent links |
887 | |
888 | sub _unset_child2parent_links { |
889 | my $self = shift; |
890 | local *ptree = $self; |
891 | for (@ptree) { |
664bb207 |
892 | next unless (length and ref and ref ne 'SCALAR'); |
893 | $_->_unset_child2parent_links() if $_->isa('Pod::InteriorSequence'); |
360aca43 |
894 | } |
895 | } |
896 | |
897 | sub _set_child2parent_links { |
898 | ## nothing to do, Pod::ParseTrees cant have parent pointers |
899 | } |
900 | |
901 | =head2 B<DESTROY()> |
902 | |
903 | This method performs any necessary cleanup for the parse-tree. |
904 | If you override this method then it is B<imperative> |
905 | that you invoke the parent method from within your own method, |
906 | otherwise I<parse-tree storage will not be reclaimed upon destruction!> |
907 | |
908 | =cut |
909 | |
910 | sub DESTROY { |
911 | ## We need to get rid of all child->parent pointers throughout the |
912 | ## tree so their reference counts will go to zero and they can be |
913 | ## garbage-collected |
914 | _unset_child2parent_links(@_); |
915 | } |
916 | |
917 | ############################################################################# |
918 | |
919 | =head1 SEE ALSO |
920 | |
921 | See L<Pod::Parser>, L<Pod::Select>, and L<Pod::Callbacks>. |
922 | |
923 | =head1 AUTHOR |
924 | |
925 | Brad Appleton E<lt>bradapp@enteract.comE<gt> |
926 | |
927 | =cut |
928 | |
929 | 1; |