Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

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