ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/staticperl/perl/lib/Pod/Select.pm
Revision: 1.1
Committed: Thu Jun 30 14:27:15 2005 UTC (21 years, 3 months ago) by root
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #############################################################################
2     # Pod/Select.pm -- function to select portions of POD docs
3     #
4     # Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved.
5     # This file is part of "PodParser". PodParser is free software;
6     # you can redistribute it and/or modify it under the same terms
7     # as Perl itself.
8     #############################################################################
9    
10     package Pod::Select;
11    
12     use vars qw($VERSION);
13     $VERSION = 1.30; ## Current version of this package
14     require 5.005; ## requires this Perl version or later
15    
16     #############################################################################
17    
18     =head1 NAME
19    
20     Pod::Select, podselect() - extract selected sections of POD from input
21    
22     =head1 SYNOPSIS
23    
24     use Pod::Select;
25    
26     ## Select all the POD sections for each file in @filelist
27     ## and print the result on standard output.
28     podselect(@filelist);
29    
30     ## Same as above, but write to tmp.out
31     podselect({-output => "tmp.out"}, @filelist):
32    
33     ## Select from the given filelist, only those POD sections that are
34     ## within a 1st level section named any of: NAME, SYNOPSIS, OPTIONS.
35     podselect({-sections => ["NAME|SYNOPSIS", "OPTIONS"]}, @filelist):
36    
37     ## Select the "DESCRIPTION" section of the PODs from STDIN and write
38     ## the result to STDERR.
39     podselect({-output => ">&STDERR", -sections => ["DESCRIPTION"]}, \*STDIN);
40    
41     or
42    
43     use Pod::Select;
44    
45     ## Create a parser object for selecting POD sections from the input
46     $parser = new Pod::Select();
47    
48     ## Select all the POD sections for each file in @filelist
49     ## and print the result to tmp.out.
50     $parser->parse_from_file("<&STDIN", "tmp.out");
51    
52     ## Select from the given filelist, only those POD sections that are
53     ## within a 1st level section named any of: NAME, SYNOPSIS, OPTIONS.
54     $parser->select("NAME|SYNOPSIS", "OPTIONS");
55     for (@filelist) { $parser->parse_from_file($_); }
56    
57     ## Select the "DESCRIPTION" and "SEE ALSO" sections of the PODs from
58     ## STDIN and write the result to STDERR.
59     $parser->select("DESCRIPTION");
60     $parser->add_selection("SEE ALSO");
61     $parser->parse_from_filehandle(\*STDIN, \*STDERR);
62    
63     =head1 REQUIRES
64    
65     perl5.005, Pod::Parser, Exporter, Carp
66    
67     =head1 EXPORTS
68    
69     podselect()
70    
71     =head1 DESCRIPTION
72    
73     B<podselect()> is a function which will extract specified sections of
74     pod documentation from an input stream. This ability is provided by the
75     B<Pod::Select> module which is a subclass of B<Pod::Parser>.
76     B<Pod::Select> provides a method named B<select()> to specify the set of
77     POD sections to select for processing/printing. B<podselect()> merely
78     creates a B<Pod::Select> object and then invokes the B<podselect()>
79     followed by B<parse_from_file()>.
80    
81     =head1 SECTION SPECIFICATIONS
82    
83     B<podselect()> and B<Pod::Select::select()> may be given one or more
84     "section specifications" to restrict the text processed to only the
85     desired set of sections and their corresponding subsections. A section
86     specification is a string containing one or more Perl-style regular
87     expressions separated by forward slashes ("/"). If you need to use a
88     forward slash literally within a section title you can escape it with a
89     backslash ("\/").
90    
91     The formal syntax of a section specification is:
92    
93     =over 4
94    
95     =item *
96    
97     I<head1-title-regex>/I<head2-title-regex>/...
98    
99     =back
100    
101     Any omitted or empty regular expressions will default to ".*".
102     Please note that each regular expression given is implicitly
103     anchored by adding "^" and "$" to the beginning and end. Also, if a
104     given regular expression starts with a "!" character, then the
105     expression is I<negated> (so C<!foo> would match anything I<except>
106     C<foo>).
107    
108     Some example section specifications follow.
109    
110     =over 4
111    
112     =item *
113    
114     Match the C<NAME> and C<SYNOPSIS> sections and all of their subsections:
115    
116     C<NAME|SYNOPSIS>
117    
118     =item *
119    
120     Match only the C<Question> and C<Answer> subsections of the C<DESCRIPTION>
121     section:
122    
123     C<DESCRIPTION/Question|Answer>
124    
125     =item *
126    
127     Match the C<Comments> subsection of I<all> sections:
128    
129     C</Comments>
130    
131     =item *
132    
133     Match all subsections of C<DESCRIPTION> I<except> for C<Comments>:
134    
135     C<DESCRIPTION/!Comments>
136    
137     =item *
138    
139     Match the C<DESCRIPTION> section but do I<not> match any of its subsections:
140    
141     C<DESCRIPTION/!.+>
142    
143     =item *
144    
145     Match all top level sections but none of their subsections:
146    
147     C</!.+>
148    
149     =back
150    
151     =begin _NOT_IMPLEMENTED_
152    
153     =head1 RANGE SPECIFICATIONS
154    
155     B<podselect()> and B<Pod::Select::select()> may be given one or more
156     "range specifications" to restrict the text processed to only the
157     desired ranges of paragraphs in the desired set of sections. A range
158     specification is a string containing a single Perl-style regular
159     expression (a regex), or else two Perl-style regular expressions
160     (regexs) separated by a ".." (Perl's "range" operator is "..").
161     The regexs in a range specification are delimited by forward slashes
162     ("/"). If you need to use a forward slash literally within a regex you
163     can escape it with a backslash ("\/").
164    
165     The formal syntax of a range specification is:
166    
167     =over 4
168    
169     =item *
170    
171     /I<start-range-regex>/[../I<end-range-regex>/]
172    
173     =back
174    
175     Where each the item inside square brackets (the ".." followed by the
176     end-range-regex) is optional. Each "range-regex" is of the form:
177    
178     =cmd-expr text-expr
179    
180     Where I<cmd-expr> is intended to match the name of one or more POD
181     commands, and I<text-expr> is intended to match the paragraph text for
182     the command. If a range-regex is supposed to match a POD command, then
183     the first character of the regex (the one after the initial '/')
184     absolutely I<must> be a single '=' character; it may not be anything
185     else (not even a regex meta-character) if it is supposed to match
186     against the name of a POD command.
187    
188     If no I<=cmd-expr> is given then the text-expr will be matched against
189     plain textblocks unless it is preceded by a space, in which case it is
190     matched against verbatim text-blocks. If no I<text-expr> is given then
191     only the command-portion of the paragraph is matched against.
192    
193     Note that these two expressions are each implicitly anchored. This
194     means that when matching against the command-name, there will be an
195     implicit '^' and '$' around the given I<=cmd-expr>; and when matching
196     against the paragraph text there will be an implicit '\A' and '\Z'
197     around the given I<text-expr>.
198    
199     Unlike with section-specs, the '!' character does I<not> have any special
200     meaning (negation or otherwise) at the beginning of a range-spec!
201    
202     Some example range specifications follow.
203    
204     =over 4
205    
206     =item
207     Match all C<=for html> paragraphs:
208    
209     C</=for html/>
210    
211     =item
212     Match all paragraphs between C<=begin html> and C<=end html>
213     (note that this will I<not> work correctly if such sections
214     are nested):
215    
216     C</=begin html/../=end html/>
217    
218     =item
219     Match all paragraphs between the given C<=item> name until the end of the
220     current section:
221    
222     C</=item mine/../=head\d/>
223    
224     =item
225     Match all paragraphs between the given C<=item> until the next item, or
226     until the end of the itemized list (note that this will I<not> work as
227     desired if the item contains an itemized list nested within it):
228    
229     C</=item mine/../=(item|back)/>
230    
231     =back
232    
233     =end _NOT_IMPLEMENTED_
234    
235     =cut
236    
237     #############################################################################
238    
239     use strict;
240     #use diagnostics;
241     use Carp;
242     use Pod::Parser 1.04;
243     use vars qw(@ISA @EXPORT $MAX_HEADING_LEVEL);
244    
245     @ISA = qw(Pod::Parser);
246     @EXPORT = qw(&podselect);
247    
248     ## Maximum number of heading levels supported for '=headN' directives
249     *MAX_HEADING_LEVEL = \3;
250    
251     #############################################################################
252    
253     =head1 OBJECT METHODS
254    
255     The following methods are provided in this module. Each one takes a
256     reference to the object itself as an implicit first parameter.
257    
258     =cut
259    
260     ##---------------------------------------------------------------------------
261    
262     ## =begin _PRIVATE_
263     ##
264     ## =head1 B<_init_headings()>
265     ##
266     ## Initialize the current set of active section headings.
267     ##
268     ## =cut
269     ##
270     ## =end _PRIVATE_
271    
272     use vars qw(%myData @section_headings);
273    
274     sub _init_headings {
275     my $self = shift;
276     local *myData = $self;
277    
278     ## Initialize current section heading titles if necessary
279     unless (defined $myData{_SECTION_HEADINGS}) {
280     local *section_headings = $myData{_SECTION_HEADINGS} = [];
281     for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) {
282     $section_headings[$i] = '';
283     }
284     }
285     }
286    
287     ##---------------------------------------------------------------------------
288    
289     =head1 B<curr_headings()>
290    
291     ($head1, $head2, $head3, ...) = $parser->curr_headings();
292     $head1 = $parser->curr_headings(1);
293    
294     This method returns a list of the currently active section headings and
295     subheadings in the document being parsed. The list of headings returned
296     corresponds to the most recently parsed paragraph of the input.
297    
298     If an argument is given, it must correspond to the desired section
299     heading number, in which case only the specified section heading is
300     returned. If there is no current section heading at the specified
301     level, then C<undef> is returned.
302    
303     =cut
304    
305     sub curr_headings {
306     my $self = shift;
307     $self->_init_headings() unless (defined $self->{_SECTION_HEADINGS});
308     my @headings = @{ $self->{_SECTION_HEADINGS} };
309     return (@_ > 0 and $_[0] =~ /^\d+$/) ? $headings[$_[0] - 1] : @headings;
310     }
311    
312     ##---------------------------------------------------------------------------
313    
314     =head1 B<select()>
315    
316     $parser->select($section_spec1,$section_spec2,...);
317    
318     This method is used to select the particular sections and subsections of
319     POD documentation that are to be printed and/or processed. The existing
320     set of selected sections is I<replaced> with the given set of sections.
321     See B<add_selection()> for adding to the current set of selected
322     sections.
323    
324     Each of the C<$section_spec> arguments should be a section specification
325     as described in L<"SECTION SPECIFICATIONS">. The section specifications
326     are parsed by this method and the resulting regular expressions are
327     stored in the invoking object.
328    
329     If no C<$section_spec> arguments are given, then the existing set of
330     selected sections is cleared out (which means C<all> sections will be
331     processed).
332    
333     This method should I<not> normally be overridden by subclasses.
334    
335     =cut
336    
337     use vars qw(@selected_sections);
338    
339     sub select {
340     my $self = shift;
341     my @sections = @_;
342     local *myData = $self;
343     local $_;
344    
345     ### NEED TO DISCERN A SECTION-SPEC FROM A RANGE-SPEC (look for m{^/.+/$}?)
346    
347     ##---------------------------------------------------------------------
348     ## The following is a blatant hack for backward compatibility, and for
349     ## implementing add_selection(). If the *first* *argument* is the
350     ## string "+", then the remaining section specifications are *added*
351     ## to the current set of selections; otherwise the given section
352     ## specifications will *replace* the current set of selections.
353     ##
354     ## This should probably be fixed someday, but for the present time,
355     ## it seems incredibly unlikely that "+" would ever correspond to
356     ## a legitimate section heading
357     ##---------------------------------------------------------------------
358     my $add = ($sections[0] eq "+") ? shift(@sections) : "";
359    
360     ## Reset the set of sections to use
361     unless (@sections > 0) {
362     delete $myData{_SELECTED_SECTIONS} unless ($add);
363     return;
364     }
365     $myData{_SELECTED_SECTIONS} = []
366     unless ($add && exists $myData{_SELECTED_SECTIONS});
367     local *selected_sections = $myData{_SELECTED_SECTIONS};
368    
369     ## Compile each spec
370     my $spec;
371     for $spec (@sections) {
372     if ( defined($_ = &_compile_section_spec($spec)) ) {
373     ## Store them in our sections array
374     push(@selected_sections, $_);
375     }
376     else {
377     carp "Ignoring section spec \"$spec\"!\n";
378     }
379     }
380     }
381    
382     ##---------------------------------------------------------------------------
383    
384     =head1 B<add_selection()>
385    
386     $parser->add_selection($section_spec1,$section_spec2,...);
387    
388     This method is used to add to the currently selected sections and
389     subsections of POD documentation that are to be printed and/or
390     processed. See <select()> for replacing the currently selected sections.
391    
392     Each of the C<$section_spec> arguments should be a section specification
393     as described in L<"SECTION SPECIFICATIONS">. The section specifications
394     are parsed by this method and the resulting regular expressions are
395     stored in the invoking object.
396    
397     This method should I<not> normally be overridden by subclasses.
398    
399     =cut
400    
401     sub add_selection {
402     my $self = shift;
403     $self->select("+", @_);
404     }
405    
406     ##---------------------------------------------------------------------------
407    
408     =head1 B<clear_selections()>
409    
410     $parser->clear_selections();
411    
412     This method takes no arguments, it has the exact same effect as invoking
413     <select()> with no arguments.
414    
415     =cut
416    
417     sub clear_selections {
418     my $self = shift;
419     $self->select();
420     }
421    
422     ##---------------------------------------------------------------------------
423    
424     =head1 B<match_section()>
425    
426     $boolean = $parser->match_section($heading1,$heading2,...);
427    
428     Returns a value of true if the given section and subsection heading
429     titles match any of the currently selected section specifications in
430     effect from prior calls to B<select()> and B<add_selection()> (or if
431     there are no explictly selected/deselected sections).
432    
433     The arguments C<$heading1>, C<$heading2>, etc. are the heading titles of
434     the corresponding sections, subsections, etc. to try and match. If
435     C<$headingN> is omitted then it defaults to the current corresponding
436     section heading title in the input.
437    
438     This method should I<not> normally be overridden by subclasses.
439    
440     =cut
441    
442     sub match_section {
443     my $self = shift;
444     my (@headings) = @_;
445     local *myData = $self;
446    
447     ## Return true if no restrictions were explicitly specified
448     my $selections = (exists $myData{_SELECTED_SECTIONS})
449     ? $myData{_SELECTED_SECTIONS} : undef;
450     return 1 unless ((defined $selections) && (@{$selections} > 0));
451    
452     ## Default any unspecified sections to the current one
453     my @current_headings = $self->curr_headings();
454     for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) {
455     (defined $headings[$i]) or $headings[$i] = $current_headings[$i];
456     }
457    
458     ## Look for a match against the specified section expressions
459     my ($section_spec, $regex, $negated, $match);
460     for $section_spec ( @{$selections} ) {
461     ##------------------------------------------------------
462     ## Each portion of this spec must match in order for
463     ## the spec to be matched. So we will start with a
464     ## match-value of 'true' and logically 'and' it with
465     ## the results of matching a given element of the spec.
466     ##------------------------------------------------------
467     $match = 1;
468     for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) {
469     $regex = $section_spec->[$i];
470     $negated = ($regex =~ s/^\!//);
471     $match &= ($negated ? ($headings[$i] !~ /${regex}/)
472     : ($headings[$i] =~ /${regex}/));
473     last unless ($match);
474     }
475     return 1 if ($match);
476     }
477     return 0; ## no match
478     }
479    
480     ##---------------------------------------------------------------------------
481    
482     =head1 B<is_selected()>
483    
484     $boolean = $parser->is_selected($paragraph);
485    
486     This method is used to determine if the block of text given in
487     C<$paragraph> falls within the currently selected set of POD sections
488     and subsections to be printed or processed. This method is also
489     responsible for keeping track of the current input section and
490     subsections. It is assumed that C<$paragraph> is the most recently read
491     (but not yet processed) input paragraph.
492    
493     The value returned will be true if the C<$paragraph> and the rest of the
494     text in the same section as C<$paragraph> should be selected (included)
495     for processing; otherwise a false value is returned.
496    
497     =cut
498    
499     sub is_selected {
500     my ($self, $paragraph) = @_;
501     local $_;
502     local *myData = $self;
503    
504     $self->_init_headings() unless (defined $myData{_SECTION_HEADINGS});
505    
506     ## Keep track of current sections levels and headings
507     $_ = $paragraph;
508     if (/^=((?:sub)*)(?:head(?:ing)?|sec(?:tion)?)(\d*)\s+(.*)\s*$/)
509     {
510     ## This is a section heading command
511     my ($level, $heading) = ($2, $3);
512     $level = 1 + (length($1) / 3) if ((! length $level) || (length $1));
513     ## Reset the current section heading at this level
514     $myData{_SECTION_HEADINGS}->[$level - 1] = $heading;
515     ## Reset subsection headings of this one to empty
516     for (my $i = $level; $i < $MAX_HEADING_LEVEL; ++$i) {
517     $myData{_SECTION_HEADINGS}->[$i] = '';
518     }
519     }
520    
521     return $self->match_section();
522     }
523    
524     #############################################################################
525    
526     =head1 EXPORTED FUNCTIONS
527    
528     The following functions are exported by this module. Please note that
529     these are functions (not methods) and therefore C<do not> take an
530     implicit first argument.
531    
532     =cut
533    
534     ##---------------------------------------------------------------------------
535    
536     =head1 B<podselect()>
537    
538     podselect(\%options,@filelist);
539    
540     B<podselect> will print the raw (untranslated) POD paragraphs of all
541     POD sections in the given input files specified by C<@filelist>
542     according to the given options.
543    
544     If any argument to B<podselect> is a reference to a hash
545     (associative array) then the values with the following keys are
546     processed as follows:
547    
548     =over 4
549    
550     =item B<-output>
551    
552     A string corresponding to the desired output file (or ">&STDOUT"
553     or ">&STDERR"). The default is to use standard output.
554    
555     =item B<-sections>
556    
557     A reference to an array of sections specifications (as described in
558     L<"SECTION SPECIFICATIONS">) which indicate the desired set of POD
559     sections and subsections to be selected from input. If no section
560     specifications are given, then all sections of the PODs are used.
561    
562     =begin _NOT_IMPLEMENTED_
563    
564     =item B<-ranges>
565    
566     A reference to an array of range specifications (as described in
567     L<"RANGE SPECIFICATIONS">) which indicate the desired range of POD
568     paragraphs to be selected from the desired input sections. If no range
569     specifications are given, then all paragraphs of the desired sections
570     are used.
571    
572     =end _NOT_IMPLEMENTED_
573    
574     =back
575    
576     All other arguments should correspond to the names of input files
577     containing POD sections. A file name of "-" or "<&STDIN" will
578     be interpeted to mean standard input (which is the default if no
579     filenames are given).
580    
581     =cut
582    
583     sub podselect {
584     my(@argv) = @_;
585     my %defaults = ();
586     my $pod_parser = new Pod::Select(%defaults);
587     my $num_inputs = 0;
588     my $output = ">&STDOUT";
589     my %opts;
590     local $_;
591     for (@argv) {
592     if (ref($_)) {
593     next unless (ref($_) eq 'HASH');
594     %opts = (%defaults, %{$_});
595    
596     ##-------------------------------------------------------------
597     ## Need this for backward compatibility since we formerly used
598     ## options that were all uppercase words rather than ones that
599     ## looked like Unix command-line options.
600     ## to be uppercase keywords)
601     ##-------------------------------------------------------------
602     %opts = map {
603     my ($key, $val) = (lc $_, $opts{$_});
604     $key =~ s/^(?=\w)/-/;
605     $key =~ /^-se[cl]/ and $key = '-sections';
606     #! $key eq '-range' and $key .= 's';
607     ($key => $val);
608     } (keys %opts);
609    
610     ## Process the options
611     (exists $opts{'-output'}) and $output = $opts{'-output'};
612    
613     ## Select the desired sections
614     $pod_parser->select(@{ $opts{'-sections'} })
615     if ( (defined $opts{'-sections'})
616     && ((ref $opts{'-sections'}) eq 'ARRAY') );
617    
618     #! ## Select the desired paragraph ranges
619     #! $pod_parser->select(@{ $opts{'-ranges'} })
620     #! if ( (defined $opts{'-ranges'})
621     #! && ((ref $opts{'-ranges'}) eq 'ARRAY') );
622     }
623     else {
624     $pod_parser->parse_from_file($_, $output);
625     ++$num_inputs;
626     }
627     }
628     $pod_parser->parse_from_file("-") unless ($num_inputs > 0);
629     }
630    
631     #############################################################################
632    
633     =head1 PRIVATE METHODS AND DATA
634    
635     B<Pod::Select> makes uses a number of internal methods and data fields
636     which clients should not need to see or use. For the sake of avoiding
637     name collisions with client data and methods, these methods and fields
638     are briefly discussed here. Determined hackers may obtain further
639     information about them by reading the B<Pod::Select> source code.
640    
641     Private data fields are stored in the hash-object whose reference is
642     returned by the B<new()> constructor for this class. The names of all
643     private methods and data-fields used by B<Pod::Select> begin with a
644     prefix of "_" and match the regular expression C</^_\w+$/>.
645    
646     =cut
647    
648     ##---------------------------------------------------------------------------
649    
650     =begin _PRIVATE_
651    
652     =head1 B<_compile_section_spec()>
653    
654     $listref = $parser->_compile_section_spec($section_spec);
655    
656     This function (note it is a function and I<not> a method) takes a
657     section specification (as described in L<"SECTION SPECIFICATIONS">)
658     given in C<$section_sepc>, and compiles it into a list of regular
659     expressions. If C<$section_spec> has no syntax errors, then a reference
660     to the list (array) of corresponding regular expressions is returned;
661     otherwise C<undef> is returned and an error message is printed (using
662     B<carp>) for each invalid regex.
663    
664     =end _PRIVATE_
665    
666     =cut
667    
668     sub _compile_section_spec {
669     my ($section_spec) = @_;
670     my (@regexs, $negated);
671    
672     ## Compile the spec into a list of regexs
673     local $_ = $section_spec;
674     s|\\\\|\001|g; ## handle escaped backward slashes
675     s|\\/|\002|g; ## handle escaped forward slashes
676    
677     ## Parse the regexs for the heading titles
678     @regexs = split('/', $_, $MAX_HEADING_LEVEL);
679    
680     ## Set default regex for ommitted levels
681     for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) {
682     $regexs[$i] = '.*' unless ((defined $regexs[$i])
683     && (length $regexs[$i]));
684     }
685     ## Modify the regexs as needed and validate their syntax
686     my $bad_regexs = 0;
687     for (@regexs) {
688     $_ .= '.+' if ($_ eq '!');
689     s|\001|\\\\|g; ## restore escaped backward slashes
690     s|\002|\\/|g; ## restore escaped forward slashes
691     $negated = s/^\!//; ## check for negation
692     eval "/$_/"; ## check regex syntax
693     if ($@) {
694     ++$bad_regexs;
695     carp "Bad regular expression /$_/ in \"$section_spec\": $@\n";
696     }
697     else {
698     ## Add the forward and rear anchors (and put the negator back)
699     $_ = '^' . $_ unless (/^\^/);
700     $_ = $_ . '$' unless (/\$$/);
701     $_ = '!' . $_ if ($negated);
702     }
703     }
704     return (! $bad_regexs) ? [ @regexs ] : undef;
705     }
706    
707     ##---------------------------------------------------------------------------
708    
709     =begin _PRIVATE_
710    
711     =head2 $self->{_SECTION_HEADINGS}
712    
713     A reference to an array of the current section heading titles for each
714     heading level (note that the first heading level title is at index 0).
715    
716     =end _PRIVATE_
717    
718     =cut
719    
720     ##---------------------------------------------------------------------------
721    
722     =begin _PRIVATE_
723    
724     =head2 $self->{_SELECTED_SECTIONS}
725    
726     A reference to an array of references to arrays. Each subarray is a list
727     of anchored regular expressions (preceded by a "!" if the expression is to
728     be negated). The index of the expression in the subarray should correspond
729     to the index of the heading title in C<$self-E<gt>{_SECTION_HEADINGS}>
730     that it is to be matched against.
731    
732     =end _PRIVATE_
733    
734     =cut
735    
736     #############################################################################
737    
738     =head1 SEE ALSO
739    
740     L<Pod::Parser>
741    
742     =head1 AUTHOR
743    
744     Please report bugs using L<http://rt.cpan.org>.
745    
746     Brad Appleton E<lt>bradapp@enteract.comE<gt>
747    
748     Based on code for B<pod2text> written by
749     Tom Christiansen E<lt>tchrist@mox.perl.comE<gt>
750    
751     =cut
752    
753     1;
754     # vim: ts=4 sw=4 et