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