15759b3d2Safresh1############################################################################# 25759b3d2Safresh1# Pod/Select.pm -- function to select portions of POD docs 35759b3d2Safresh1# 45759b3d2Safresh1# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved. 55759b3d2Safresh1# This file is part of "PodParser". PodParser is free software; 65759b3d2Safresh1# you can redistribute it and/or modify it under the same terms 75759b3d2Safresh1# as Perl itself. 85759b3d2Safresh1############################################################################# 95759b3d2Safresh1 105759b3d2Safresh1package Pod::Select; 115759b3d2Safresh1use strict; 12*256a93a4Safresh1use warnings; 135759b3d2Safresh1 145759b3d2Safresh1use vars qw($VERSION @ISA @EXPORT $MAX_HEADING_LEVEL %myData @section_headings @selected_sections); 155759b3d2Safresh1$VERSION = '1.60'; ## Current version of this package 165759b3d2Safresh1require 5.005; ## requires this Perl version or later 175759b3d2Safresh1 185759b3d2Safresh1############################################################################# 195759b3d2Safresh1 205759b3d2Safresh1=head1 NAME 215759b3d2Safresh1 225759b3d2Safresh1Pod::Select, podselect() - extract selected sections of POD from input 235759b3d2Safresh1 245759b3d2Safresh1=head1 SYNOPSIS 255759b3d2Safresh1 265759b3d2Safresh1 use Pod::Select; 275759b3d2Safresh1 285759b3d2Safresh1 ## Select all the POD sections for each file in @filelist 295759b3d2Safresh1 ## and print the result on standard output. 305759b3d2Safresh1 podselect(@filelist); 315759b3d2Safresh1 325759b3d2Safresh1 ## Same as above, but write to tmp.out 335759b3d2Safresh1 podselect({-output => "tmp.out"}, @filelist): 345759b3d2Safresh1 355759b3d2Safresh1 ## Select from the given filelist, only those POD sections that are 365759b3d2Safresh1 ## within a 1st level section named any of: NAME, SYNOPSIS, OPTIONS. 375759b3d2Safresh1 podselect({-sections => ["NAME|SYNOPSIS", "OPTIONS"]}, @filelist): 385759b3d2Safresh1 395759b3d2Safresh1 ## Select the "DESCRIPTION" section of the PODs from STDIN and write 405759b3d2Safresh1 ## the result to STDERR. 415759b3d2Safresh1 podselect({-output => ">&STDERR", -sections => ["DESCRIPTION"]}, \*STDIN); 425759b3d2Safresh1 435759b3d2Safresh1or 445759b3d2Safresh1 455759b3d2Safresh1 use Pod::Select; 465759b3d2Safresh1 475759b3d2Safresh1 ## Create a parser object for selecting POD sections from the input 48*256a93a4Safresh1 $parser = Pod::Select->new(); 495759b3d2Safresh1 505759b3d2Safresh1 ## Select all the POD sections for each file in @filelist 515759b3d2Safresh1 ## and print the result to tmp.out. 525759b3d2Safresh1 $parser->parse_from_file("<&STDIN", "tmp.out"); 535759b3d2Safresh1 545759b3d2Safresh1 ## Select from the given filelist, only those POD sections that are 555759b3d2Safresh1 ## within a 1st level section named any of: NAME, SYNOPSIS, OPTIONS. 565759b3d2Safresh1 $parser->select("NAME|SYNOPSIS", "OPTIONS"); 575759b3d2Safresh1 for (@filelist) { $parser->parse_from_file($_); } 585759b3d2Safresh1 595759b3d2Safresh1 ## Select the "DESCRIPTION" and "SEE ALSO" sections of the PODs from 605759b3d2Safresh1 ## STDIN and write the result to STDERR. 615759b3d2Safresh1 $parser->select("DESCRIPTION"); 625759b3d2Safresh1 $parser->add_selection("SEE ALSO"); 635759b3d2Safresh1 $parser->parse_from_filehandle(\*STDIN, \*STDERR); 645759b3d2Safresh1 655759b3d2Safresh1=head1 REQUIRES 665759b3d2Safresh1 675759b3d2Safresh1perl5.005, Pod::Parser, Exporter, Carp 685759b3d2Safresh1 695759b3d2Safresh1=head1 EXPORTS 705759b3d2Safresh1 715759b3d2Safresh1podselect() 725759b3d2Safresh1 735759b3d2Safresh1=head1 DESCRIPTION 745759b3d2Safresh1 755759b3d2Safresh1B<podselect()> is a function which will extract specified sections of 765759b3d2Safresh1pod documentation from an input stream. This ability is provided by the 775759b3d2Safresh1B<Pod::Select> module which is a subclass of B<Pod::Parser>. 785759b3d2Safresh1B<Pod::Select> provides a method named B<select()> to specify the set of 795759b3d2Safresh1POD sections to select for processing/printing. B<podselect()> merely 805759b3d2Safresh1creates a B<Pod::Select> object and then invokes the B<podselect()> 815759b3d2Safresh1followed by B<parse_from_file()>. 825759b3d2Safresh1 835759b3d2Safresh1=head1 SECTION SPECIFICATIONS 845759b3d2Safresh1 855759b3d2Safresh1B<podselect()> and B<Pod::Select::select()> may be given one or more 865759b3d2Safresh1"section specifications" to restrict the text processed to only the 875759b3d2Safresh1desired set of sections and their corresponding subsections. A section 885759b3d2Safresh1specification is a string containing one or more Perl-style regular 895759b3d2Safresh1expressions separated by forward slashes ("/"). If you need to use a 905759b3d2Safresh1forward slash literally within a section title you can escape it with a 915759b3d2Safresh1backslash ("\/"). 925759b3d2Safresh1 935759b3d2Safresh1The formal syntax of a section specification is: 945759b3d2Safresh1 955759b3d2Safresh1=over 4 965759b3d2Safresh1 975759b3d2Safresh1=item * 985759b3d2Safresh1 995759b3d2Safresh1I<head1-title-regex>/I<head2-title-regex>/... 1005759b3d2Safresh1 1015759b3d2Safresh1=back 1025759b3d2Safresh1 1035759b3d2Safresh1Any omitted or empty regular expressions will default to ".*". 1045759b3d2Safresh1Please note that each regular expression given is implicitly 1055759b3d2Safresh1anchored by adding "^" and "$" to the beginning and end. Also, if a 1065759b3d2Safresh1given regular expression starts with a "!" character, then the 1075759b3d2Safresh1expression is I<negated> (so C<!foo> would match anything I<except> 1085759b3d2Safresh1C<foo>). 1095759b3d2Safresh1 1105759b3d2Safresh1Some example section specifications follow. 1115759b3d2Safresh1 1125759b3d2Safresh1=over 4 1135759b3d2Safresh1 1145759b3d2Safresh1=item * 1155759b3d2Safresh1 1165759b3d2Safresh1Match the C<NAME> and C<SYNOPSIS> sections and all of their subsections: 1175759b3d2Safresh1 1185759b3d2Safresh1C<NAME|SYNOPSIS> 1195759b3d2Safresh1 1205759b3d2Safresh1=item * 1215759b3d2Safresh1 1225759b3d2Safresh1Match only the C<Question> and C<Answer> subsections of the C<DESCRIPTION> 1235759b3d2Safresh1section: 1245759b3d2Safresh1 1255759b3d2Safresh1C<DESCRIPTION/Question|Answer> 1265759b3d2Safresh1 1275759b3d2Safresh1=item * 1285759b3d2Safresh1 1295759b3d2Safresh1Match the C<Comments> subsection of I<all> sections: 1305759b3d2Safresh1 1315759b3d2Safresh1C</Comments> 1325759b3d2Safresh1 1335759b3d2Safresh1=item * 1345759b3d2Safresh1 1355759b3d2Safresh1Match all subsections of C<DESCRIPTION> I<except> for C<Comments>: 1365759b3d2Safresh1 1375759b3d2Safresh1C<DESCRIPTION/!Comments> 1385759b3d2Safresh1 1395759b3d2Safresh1=item * 1405759b3d2Safresh1 1415759b3d2Safresh1Match the C<DESCRIPTION> section but do I<not> match any of its subsections: 1425759b3d2Safresh1 1435759b3d2Safresh1C<DESCRIPTION/!.+> 1445759b3d2Safresh1 1455759b3d2Safresh1=item * 1465759b3d2Safresh1 1475759b3d2Safresh1Match all top level sections but none of their subsections: 1485759b3d2Safresh1 1495759b3d2Safresh1C</!.+> 1505759b3d2Safresh1 1515759b3d2Safresh1=back 1525759b3d2Safresh1 1535759b3d2Safresh1=begin _NOT_IMPLEMENTED_ 1545759b3d2Safresh1 1555759b3d2Safresh1=head1 RANGE SPECIFICATIONS 1565759b3d2Safresh1 1575759b3d2Safresh1B<podselect()> and B<Pod::Select::select()> may be given one or more 1585759b3d2Safresh1"range specifications" to restrict the text processed to only the 1595759b3d2Safresh1desired ranges of paragraphs in the desired set of sections. A range 1605759b3d2Safresh1specification is a string containing a single Perl-style regular 1615759b3d2Safresh1expression (a regex), or else two Perl-style regular expressions 1625759b3d2Safresh1(regexs) separated by a ".." (Perl's "range" operator is ".."). 1635759b3d2Safresh1The regexs in a range specification are delimited by forward slashes 1645759b3d2Safresh1("/"). If you need to use a forward slash literally within a regex you 1655759b3d2Safresh1can escape it with a backslash ("\/"). 1665759b3d2Safresh1 1675759b3d2Safresh1The formal syntax of a range specification is: 1685759b3d2Safresh1 1695759b3d2Safresh1=over 4 1705759b3d2Safresh1 1715759b3d2Safresh1=item * 1725759b3d2Safresh1 1735759b3d2Safresh1/I<start-range-regex>/[../I<end-range-regex>/] 1745759b3d2Safresh1 1755759b3d2Safresh1=back 1765759b3d2Safresh1 1775759b3d2Safresh1Where each the item inside square brackets (the ".." followed by the 1785759b3d2Safresh1end-range-regex) is optional. Each "range-regex" is of the form: 1795759b3d2Safresh1 1805759b3d2Safresh1 =cmd-expr text-expr 1815759b3d2Safresh1 1825759b3d2Safresh1Where I<cmd-expr> is intended to match the name of one or more POD 1835759b3d2Safresh1commands, and I<text-expr> is intended to match the paragraph text for 1845759b3d2Safresh1the command. If a range-regex is supposed to match a POD command, then 1855759b3d2Safresh1the first character of the regex (the one after the initial '/') 1865759b3d2Safresh1absolutely I<must> be a single '=' character; it may not be anything 1875759b3d2Safresh1else (not even a regex meta-character) if it is supposed to match 1885759b3d2Safresh1against the name of a POD command. 1895759b3d2Safresh1 1905759b3d2Safresh1If no I<=cmd-expr> is given then the text-expr will be matched against 1915759b3d2Safresh1plain textblocks unless it is preceded by a space, in which case it is 1925759b3d2Safresh1matched against verbatim text-blocks. If no I<text-expr> is given then 1935759b3d2Safresh1only the command-portion of the paragraph is matched against. 1945759b3d2Safresh1 1955759b3d2Safresh1Note that these two expressions are each implicitly anchored. This 1965759b3d2Safresh1means that when matching against the command-name, there will be an 1975759b3d2Safresh1implicit '^' and '$' around the given I<=cmd-expr>; and when matching 1985759b3d2Safresh1against the paragraph text there will be an implicit '\A' and '\Z' 1995759b3d2Safresh1around the given I<text-expr>. 2005759b3d2Safresh1 2015759b3d2Safresh1Unlike with section-specs, the '!' character does I<not> have any special 2025759b3d2Safresh1meaning (negation or otherwise) at the beginning of a range-spec! 2035759b3d2Safresh1 2045759b3d2Safresh1Some example range specifications follow. 2055759b3d2Safresh1 2065759b3d2Safresh1=over 4 2075759b3d2Safresh1 2085759b3d2Safresh1=item 2095759b3d2Safresh1Match all C<=for html> paragraphs: 2105759b3d2Safresh1 2115759b3d2Safresh1C</=for html/> 2125759b3d2Safresh1 2135759b3d2Safresh1=item 2145759b3d2Safresh1Match all paragraphs between C<=begin html> and C<=end html> 2155759b3d2Safresh1(note that this will I<not> work correctly if such sections 2165759b3d2Safresh1are nested): 2175759b3d2Safresh1 2185759b3d2Safresh1C</=begin html/../=end html/> 2195759b3d2Safresh1 2205759b3d2Safresh1=item 2215759b3d2Safresh1Match all paragraphs between the given C<=item> name until the end of the 2225759b3d2Safresh1current section: 2235759b3d2Safresh1 2245759b3d2Safresh1C</=item mine/../=head\d/> 2255759b3d2Safresh1 2265759b3d2Safresh1=item 2275759b3d2Safresh1Match all paragraphs between the given C<=item> until the next item, or 2285759b3d2Safresh1until the end of the itemized list (note that this will I<not> work as 2295759b3d2Safresh1desired if the item contains an itemized list nested within it): 2305759b3d2Safresh1 2315759b3d2Safresh1C</=item mine/../=(item|back)/> 2325759b3d2Safresh1 2335759b3d2Safresh1=back 2345759b3d2Safresh1 2355759b3d2Safresh1=end _NOT_IMPLEMENTED_ 2365759b3d2Safresh1 2375759b3d2Safresh1=cut 2385759b3d2Safresh1 2395759b3d2Safresh1############################################################################# 2405759b3d2Safresh1 2415759b3d2Safresh1#use diagnostics; 2425759b3d2Safresh1use Carp; 2435759b3d2Safresh1use Pod::Parser 1.04; 2445759b3d2Safresh1 2455759b3d2Safresh1@ISA = qw(Pod::Parser); 2465759b3d2Safresh1@EXPORT = qw(&podselect); 2475759b3d2Safresh1 2485759b3d2Safresh1## Maximum number of heading levels supported for '=headN' directives 2495759b3d2Safresh1*MAX_HEADING_LEVEL = \3; 2505759b3d2Safresh1 2515759b3d2Safresh1############################################################################# 2525759b3d2Safresh1 2535759b3d2Safresh1=head1 OBJECT METHODS 2545759b3d2Safresh1 2555759b3d2Safresh1The following methods are provided in this module. Each one takes a 2565759b3d2Safresh1reference to the object itself as an implicit first parameter. 2575759b3d2Safresh1 2585759b3d2Safresh1=cut 2595759b3d2Safresh1 2605759b3d2Safresh1##--------------------------------------------------------------------------- 2615759b3d2Safresh1 2625759b3d2Safresh1## =begin _PRIVATE_ 2635759b3d2Safresh1## 2645759b3d2Safresh1## =head1 B<_init_headings()> 2655759b3d2Safresh1## 2665759b3d2Safresh1## Initialize the current set of active section headings. 2675759b3d2Safresh1## 2685759b3d2Safresh1## =cut 2695759b3d2Safresh1## 2705759b3d2Safresh1## =end _PRIVATE_ 2715759b3d2Safresh1 2725759b3d2Safresh1sub _init_headings { 2735759b3d2Safresh1 my $self = shift; 2745759b3d2Safresh1 local *myData = $self; 2755759b3d2Safresh1 2765759b3d2Safresh1 ## Initialize current section heading titles if necessary 2775759b3d2Safresh1 unless (defined $myData{_SECTION_HEADINGS}) { 2785759b3d2Safresh1 local *section_headings = $myData{_SECTION_HEADINGS} = []; 2795759b3d2Safresh1 for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) { 2805759b3d2Safresh1 $section_headings[$i] = ''; 2815759b3d2Safresh1 } 2825759b3d2Safresh1 } 2835759b3d2Safresh1} 2845759b3d2Safresh1 2855759b3d2Safresh1##--------------------------------------------------------------------------- 2865759b3d2Safresh1 2875759b3d2Safresh1=head1 B<curr_headings()> 2885759b3d2Safresh1 2895759b3d2Safresh1 ($head1, $head2, $head3, ...) = $parser->curr_headings(); 2905759b3d2Safresh1 $head1 = $parser->curr_headings(1); 2915759b3d2Safresh1 2925759b3d2Safresh1This method returns a list of the currently active section headings and 2935759b3d2Safresh1subheadings in the document being parsed. The list of headings returned 2945759b3d2Safresh1corresponds to the most recently parsed paragraph of the input. 2955759b3d2Safresh1 2965759b3d2Safresh1If an argument is given, it must correspond to the desired section 2975759b3d2Safresh1heading number, in which case only the specified section heading is 2985759b3d2Safresh1returned. If there is no current section heading at the specified 2995759b3d2Safresh1level, then C<undef> is returned. 3005759b3d2Safresh1 3015759b3d2Safresh1=cut 3025759b3d2Safresh1 3035759b3d2Safresh1sub curr_headings { 3045759b3d2Safresh1 my $self = shift; 3055759b3d2Safresh1 $self->_init_headings() unless (defined $self->{_SECTION_HEADINGS}); 3065759b3d2Safresh1 my @headings = @{ $self->{_SECTION_HEADINGS} }; 3075759b3d2Safresh1 return (@_ > 0 and $_[0] =~ /^\d+$/) ? $headings[$_[0] - 1] : @headings; 3085759b3d2Safresh1} 3095759b3d2Safresh1 3105759b3d2Safresh1##--------------------------------------------------------------------------- 3115759b3d2Safresh1 3125759b3d2Safresh1=head1 B<select()> 3135759b3d2Safresh1 3145759b3d2Safresh1 $parser->select($section_spec1,$section_spec2,...); 3155759b3d2Safresh1 3165759b3d2Safresh1This method is used to select the particular sections and subsections of 3175759b3d2Safresh1POD documentation that are to be printed and/or processed. The existing 3185759b3d2Safresh1set of selected sections is I<replaced> with the given set of sections. 3195759b3d2Safresh1See B<add_selection()> for adding to the current set of selected 3205759b3d2Safresh1sections. 3215759b3d2Safresh1 3225759b3d2Safresh1Each of the C<$section_spec> arguments should be a section specification 3235759b3d2Safresh1as described in L<"SECTION SPECIFICATIONS">. The section specifications 3245759b3d2Safresh1are parsed by this method and the resulting regular expressions are 3255759b3d2Safresh1stored in the invoking object. 3265759b3d2Safresh1 3275759b3d2Safresh1If no C<$section_spec> arguments are given, then the existing set of 3285759b3d2Safresh1selected sections is cleared out (which means C<all> sections will be 3295759b3d2Safresh1processed). 3305759b3d2Safresh1 3315759b3d2Safresh1This method should I<not> normally be overridden by subclasses. 3325759b3d2Safresh1 3335759b3d2Safresh1=cut 3345759b3d2Safresh1 3355759b3d2Safresh1sub select { 3365759b3d2Safresh1 my ($self, @sections) = @_; 3375759b3d2Safresh1 local *myData = $self; 3385759b3d2Safresh1 local $_; 3395759b3d2Safresh1 3405759b3d2Safresh1### NEED TO DISCERN A SECTION-SPEC FROM A RANGE-SPEC (look for m{^/.+/$}?) 3415759b3d2Safresh1 3425759b3d2Safresh1 ##--------------------------------------------------------------------- 3435759b3d2Safresh1 ## The following is a blatant hack for backward compatibility, and for 3445759b3d2Safresh1 ## implementing add_selection(). If the *first* *argument* is the 3455759b3d2Safresh1 ## string "+", then the remaining section specifications are *added* 3465759b3d2Safresh1 ## to the current set of selections; otherwise the given section 3475759b3d2Safresh1 ## specifications will *replace* the current set of selections. 3485759b3d2Safresh1 ## 3495759b3d2Safresh1 ## This should probably be fixed someday, but for the present time, 3505759b3d2Safresh1 ## it seems incredibly unlikely that "+" would ever correspond to 3515759b3d2Safresh1 ## a legitimate section heading 3525759b3d2Safresh1 ##--------------------------------------------------------------------- 3535759b3d2Safresh1 my $add = ($sections[0] eq '+') ? shift(@sections) : ''; 3545759b3d2Safresh1 3555759b3d2Safresh1 ## Reset the set of sections to use 3565759b3d2Safresh1 unless (@sections) { 3575759b3d2Safresh1 delete $myData{_SELECTED_SECTIONS} unless ($add); 3585759b3d2Safresh1 return; 3595759b3d2Safresh1 } 3605759b3d2Safresh1 $myData{_SELECTED_SECTIONS} = [] 3615759b3d2Safresh1 unless ($add && exists $myData{_SELECTED_SECTIONS}); 3625759b3d2Safresh1 local *selected_sections = $myData{_SELECTED_SECTIONS}; 3635759b3d2Safresh1 3645759b3d2Safresh1 ## Compile each spec 3655759b3d2Safresh1 for my $spec (@sections) { 3665759b3d2Safresh1 if ( defined($_ = _compile_section_spec($spec)) ) { 3675759b3d2Safresh1 ## Store them in our sections array 3685759b3d2Safresh1 push(@selected_sections, $_); 3695759b3d2Safresh1 } 3705759b3d2Safresh1 else { 3715759b3d2Safresh1 carp qq{Ignoring section spec "$spec"!\n}; 3725759b3d2Safresh1 } 3735759b3d2Safresh1 } 3745759b3d2Safresh1} 3755759b3d2Safresh1 3765759b3d2Safresh1##--------------------------------------------------------------------------- 3775759b3d2Safresh1 3785759b3d2Safresh1=head1 B<add_selection()> 3795759b3d2Safresh1 3805759b3d2Safresh1 $parser->add_selection($section_spec1,$section_spec2,...); 3815759b3d2Safresh1 3825759b3d2Safresh1This method is used to add to the currently selected sections and 3835759b3d2Safresh1subsections of POD documentation that are to be printed and/or 3845759b3d2Safresh1processed. See <select()> for replacing the currently selected sections. 3855759b3d2Safresh1 3865759b3d2Safresh1Each of the C<$section_spec> arguments should be a section specification 3875759b3d2Safresh1as described in L<"SECTION SPECIFICATIONS">. The section specifications 3885759b3d2Safresh1are parsed by this method and the resulting regular expressions are 3895759b3d2Safresh1stored in the invoking object. 3905759b3d2Safresh1 3915759b3d2Safresh1This method should I<not> normally be overridden by subclasses. 3925759b3d2Safresh1 3935759b3d2Safresh1=cut 3945759b3d2Safresh1 3955759b3d2Safresh1sub add_selection { 3965759b3d2Safresh1 my $self = shift; 3975759b3d2Safresh1 return $self->select('+', @_); 3985759b3d2Safresh1} 3995759b3d2Safresh1 4005759b3d2Safresh1##--------------------------------------------------------------------------- 4015759b3d2Safresh1 4025759b3d2Safresh1=head1 B<clear_selections()> 4035759b3d2Safresh1 4045759b3d2Safresh1 $parser->clear_selections(); 4055759b3d2Safresh1 4065759b3d2Safresh1This method takes no arguments, it has the exact same effect as invoking 4075759b3d2Safresh1<select()> with no arguments. 4085759b3d2Safresh1 4095759b3d2Safresh1=cut 4105759b3d2Safresh1 4115759b3d2Safresh1sub clear_selections { 4125759b3d2Safresh1 my $self = shift; 4135759b3d2Safresh1 return $self->select(); 4145759b3d2Safresh1} 4155759b3d2Safresh1 4165759b3d2Safresh1##--------------------------------------------------------------------------- 4175759b3d2Safresh1 4185759b3d2Safresh1=head1 B<match_section()> 4195759b3d2Safresh1 4205759b3d2Safresh1 $boolean = $parser->match_section($heading1,$heading2,...); 4215759b3d2Safresh1 4225759b3d2Safresh1Returns a value of true if the given section and subsection heading 4235759b3d2Safresh1titles match any of the currently selected section specifications in 4245759b3d2Safresh1effect from prior calls to B<select()> and B<add_selection()> (or if 4255759b3d2Safresh1there are no explicitly selected/deselected sections). 4265759b3d2Safresh1 4275759b3d2Safresh1The arguments C<$heading1>, C<$heading2>, etc. are the heading titles of 4285759b3d2Safresh1the corresponding sections, subsections, etc. to try and match. If 4295759b3d2Safresh1C<$headingN> is omitted then it defaults to the current corresponding 4305759b3d2Safresh1section heading title in the input. 4315759b3d2Safresh1 4325759b3d2Safresh1This method should I<not> normally be overridden by subclasses. 4335759b3d2Safresh1 4345759b3d2Safresh1=cut 4355759b3d2Safresh1 4365759b3d2Safresh1sub match_section { 4375759b3d2Safresh1 my $self = shift; 4385759b3d2Safresh1 my (@headings) = @_; 4395759b3d2Safresh1 local *myData = $self; 4405759b3d2Safresh1 4415759b3d2Safresh1 ## Return true if no restrictions were explicitly specified 4425759b3d2Safresh1 my $selections = (exists $myData{_SELECTED_SECTIONS}) 4435759b3d2Safresh1 ? $myData{_SELECTED_SECTIONS} : undef; 4445759b3d2Safresh1 return 1 unless ((defined $selections) && @{$selections}); 4455759b3d2Safresh1 4465759b3d2Safresh1 ## Default any unspecified sections to the current one 4475759b3d2Safresh1 my @current_headings = $self->curr_headings(); 4485759b3d2Safresh1 for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) { 4495759b3d2Safresh1 (defined $headings[$i]) or $headings[$i] = $current_headings[$i]; 4505759b3d2Safresh1 } 4515759b3d2Safresh1 4525759b3d2Safresh1 ## Look for a match against the specified section expressions 4535759b3d2Safresh1 for my $section_spec ( @{$selections} ) { 4545759b3d2Safresh1 ##------------------------------------------------------ 4555759b3d2Safresh1 ## Each portion of this spec must match in order for 4565759b3d2Safresh1 ## the spec to be matched. So we will start with a 4575759b3d2Safresh1 ## match-value of 'true' and logically 'and' it with 4585759b3d2Safresh1 ## the results of matching a given element of the spec. 4595759b3d2Safresh1 ##------------------------------------------------------ 4605759b3d2Safresh1 my $match = 1; 4615759b3d2Safresh1 for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) { 4625759b3d2Safresh1 my $regex = $section_spec->[$i]; 4635759b3d2Safresh1 my $negated = ($regex =~ s/^\!//); 4645759b3d2Safresh1 $match &= ($negated ? ($headings[$i] !~ /${regex}/) 4655759b3d2Safresh1 : ($headings[$i] =~ /${regex}/)); 4665759b3d2Safresh1 last unless ($match); 4675759b3d2Safresh1 } 4685759b3d2Safresh1 return 1 if ($match); 4695759b3d2Safresh1 } 4705759b3d2Safresh1 return 0; ## no match 4715759b3d2Safresh1} 4725759b3d2Safresh1 4735759b3d2Safresh1##--------------------------------------------------------------------------- 4745759b3d2Safresh1 4755759b3d2Safresh1=head1 B<is_selected()> 4765759b3d2Safresh1 4775759b3d2Safresh1 $boolean = $parser->is_selected($paragraph); 4785759b3d2Safresh1 4795759b3d2Safresh1This method is used to determine if the block of text given in 4805759b3d2Safresh1C<$paragraph> falls within the currently selected set of POD sections 4815759b3d2Safresh1and subsections to be printed or processed. This method is also 4825759b3d2Safresh1responsible for keeping track of the current input section and 4835759b3d2Safresh1subsections. It is assumed that C<$paragraph> is the most recently read 4845759b3d2Safresh1(but not yet processed) input paragraph. 4855759b3d2Safresh1 4865759b3d2Safresh1The value returned will be true if the C<$paragraph> and the rest of the 4875759b3d2Safresh1text in the same section as C<$paragraph> should be selected (included) 4885759b3d2Safresh1for processing; otherwise a false value is returned. 4895759b3d2Safresh1 4905759b3d2Safresh1=cut 4915759b3d2Safresh1 4925759b3d2Safresh1sub is_selected { 4935759b3d2Safresh1 my ($self, $paragraph) = @_; 4945759b3d2Safresh1 local $_; 4955759b3d2Safresh1 local *myData = $self; 4965759b3d2Safresh1 4975759b3d2Safresh1 $self->_init_headings() unless (defined $myData{_SECTION_HEADINGS}); 4985759b3d2Safresh1 4995759b3d2Safresh1 ## Keep track of current sections levels and headings 5005759b3d2Safresh1 $_ = $paragraph; 5015759b3d2Safresh1 if (/^=((?:sub)*)(?:head(?:ing)?|sec(?:tion)?)(\d*)\s+(.*?)\s*$/) 5025759b3d2Safresh1 { 5035759b3d2Safresh1 ## This is a section heading command 5045759b3d2Safresh1 my ($level, $heading) = ($2, $3); 5055759b3d2Safresh1 $level = 1 + (length($1) / 3) if ((! length $level) || (length $1)); 5065759b3d2Safresh1 ## Reset the current section heading at this level 5075759b3d2Safresh1 $myData{_SECTION_HEADINGS}->[$level - 1] = $heading; 5085759b3d2Safresh1 ## Reset subsection headings of this one to empty 5095759b3d2Safresh1 for (my $i = $level; $i < $MAX_HEADING_LEVEL; ++$i) { 5105759b3d2Safresh1 $myData{_SECTION_HEADINGS}->[$i] = ''; 5115759b3d2Safresh1 } 5125759b3d2Safresh1 } 5135759b3d2Safresh1 5145759b3d2Safresh1 return $self->match_section(); 5155759b3d2Safresh1} 5165759b3d2Safresh1 5175759b3d2Safresh1############################################################################# 5185759b3d2Safresh1 5195759b3d2Safresh1=head1 EXPORTED FUNCTIONS 5205759b3d2Safresh1 5215759b3d2Safresh1The following functions are exported by this module. Please note that 5225759b3d2Safresh1these are functions (not methods) and therefore C<do not> take an 5235759b3d2Safresh1implicit first argument. 5245759b3d2Safresh1 5255759b3d2Safresh1=cut 5265759b3d2Safresh1 5275759b3d2Safresh1##--------------------------------------------------------------------------- 5285759b3d2Safresh1 5295759b3d2Safresh1=head1 B<podselect()> 5305759b3d2Safresh1 5315759b3d2Safresh1 podselect(\%options,@filelist); 5325759b3d2Safresh1 5335759b3d2Safresh1B<podselect> will print the raw (untranslated) POD paragraphs of all 5345759b3d2Safresh1POD sections in the given input files specified by C<@filelist> 5355759b3d2Safresh1according to the given options. 5365759b3d2Safresh1 5375759b3d2Safresh1If any argument to B<podselect> is a reference to a hash 5385759b3d2Safresh1(associative array) then the values with the following keys are 5395759b3d2Safresh1processed as follows: 5405759b3d2Safresh1 5415759b3d2Safresh1=over 4 5425759b3d2Safresh1 5435759b3d2Safresh1=item B<-output> 5445759b3d2Safresh1 5455759b3d2Safresh1A string corresponding to the desired output file (or ">&STDOUT" 5465759b3d2Safresh1or ">&STDERR"). The default is to use standard output. 5475759b3d2Safresh1 5485759b3d2Safresh1=item B<-sections> 5495759b3d2Safresh1 5505759b3d2Safresh1A reference to an array of sections specifications (as described in 5515759b3d2Safresh1L<"SECTION SPECIFICATIONS">) which indicate the desired set of POD 5525759b3d2Safresh1sections and subsections to be selected from input. If no section 5535759b3d2Safresh1specifications are given, then all sections of the PODs are used. 5545759b3d2Safresh1 5555759b3d2Safresh1=begin _NOT_IMPLEMENTED_ 5565759b3d2Safresh1 5575759b3d2Safresh1=item B<-ranges> 5585759b3d2Safresh1 5595759b3d2Safresh1A reference to an array of range specifications (as described in 5605759b3d2Safresh1L<"RANGE SPECIFICATIONS">) which indicate the desired range of POD 5615759b3d2Safresh1paragraphs to be selected from the desired input sections. If no range 5625759b3d2Safresh1specifications are given, then all paragraphs of the desired sections 5635759b3d2Safresh1are used. 5645759b3d2Safresh1 5655759b3d2Safresh1=end _NOT_IMPLEMENTED_ 5665759b3d2Safresh1 5675759b3d2Safresh1=back 5685759b3d2Safresh1 5695759b3d2Safresh1All other arguments should correspond to the names of input files 5705759b3d2Safresh1containing POD sections. A file name of "-" or "<&STDIN" will 5715759b3d2Safresh1be interpreted to mean standard input (which is the default if no 5725759b3d2Safresh1filenames are given). 5735759b3d2Safresh1 5745759b3d2Safresh1=cut 5755759b3d2Safresh1 5765759b3d2Safresh1sub podselect { 5775759b3d2Safresh1 my(@argv) = @_; 5785759b3d2Safresh1 my %defaults = (); 579*256a93a4Safresh1 my $pod_parser = Pod::Select->new(%defaults); 5805759b3d2Safresh1 my $num_inputs = 0; 5815759b3d2Safresh1 my $output = '>&STDOUT'; 5825759b3d2Safresh1 my %opts; 5835759b3d2Safresh1 local $_; 5845759b3d2Safresh1 for (@argv) { 5855759b3d2Safresh1 if (ref($_)) { 5865759b3d2Safresh1 next unless (ref($_) eq 'HASH'); 5875759b3d2Safresh1 %opts = (%defaults, %{$_}); 5885759b3d2Safresh1 5895759b3d2Safresh1 ##------------------------------------------------------------- 5905759b3d2Safresh1 ## Need this for backward compatibility since we formerly used 5915759b3d2Safresh1 ## options that were all uppercase words rather than ones that 5925759b3d2Safresh1 ## looked like Unix command-line options. 5935759b3d2Safresh1 ## to be uppercase keywords) 5945759b3d2Safresh1 ##------------------------------------------------------------- 5955759b3d2Safresh1 %opts = map { 5965759b3d2Safresh1 my ($key, $val) = (lc $_, $opts{$_}); 5975759b3d2Safresh1 $key =~ s/^(?=\w)/-/; 5985759b3d2Safresh1 $key =~ /^-se[cl]/ and $key = '-sections'; 5995759b3d2Safresh1 #! $key eq '-range' and $key .= 's'; 6005759b3d2Safresh1 ($key => $val); 6015759b3d2Safresh1 } (keys %opts); 6025759b3d2Safresh1 6035759b3d2Safresh1 ## Process the options 6045759b3d2Safresh1 (exists $opts{'-output'}) and $output = $opts{'-output'}; 6055759b3d2Safresh1 6065759b3d2Safresh1 ## Select the desired sections 6075759b3d2Safresh1 $pod_parser->select(@{ $opts{'-sections'} }) 6085759b3d2Safresh1 if ( (defined $opts{'-sections'}) 6095759b3d2Safresh1 && ((ref $opts{'-sections'}) eq 'ARRAY') ); 6105759b3d2Safresh1 6115759b3d2Safresh1 #! ## Select the desired paragraph ranges 6125759b3d2Safresh1 #! $pod_parser->select(@{ $opts{'-ranges'} }) 6135759b3d2Safresh1 #! if ( (defined $opts{'-ranges'}) 6145759b3d2Safresh1 #! && ((ref $opts{'-ranges'}) eq 'ARRAY') ); 6155759b3d2Safresh1 } 6165759b3d2Safresh1 else { 6175759b3d2Safresh1 $pod_parser->parse_from_file($_, $output); 6185759b3d2Safresh1 ++$num_inputs; 6195759b3d2Safresh1 } 6205759b3d2Safresh1 } 6215759b3d2Safresh1 $pod_parser->parse_from_file('-') unless ($num_inputs > 0); 6225759b3d2Safresh1} 6235759b3d2Safresh1 6245759b3d2Safresh1############################################################################# 6255759b3d2Safresh1 6265759b3d2Safresh1=head1 PRIVATE METHODS AND DATA 6275759b3d2Safresh1 6285759b3d2Safresh1B<Pod::Select> makes uses a number of internal methods and data fields 6295759b3d2Safresh1which clients should not need to see or use. For the sake of avoiding 6305759b3d2Safresh1name collisions with client data and methods, these methods and fields 6315759b3d2Safresh1are briefly discussed here. Determined hackers may obtain further 6325759b3d2Safresh1information about them by reading the B<Pod::Select> source code. 6335759b3d2Safresh1 6345759b3d2Safresh1Private data fields are stored in the hash-object whose reference is 6355759b3d2Safresh1returned by the B<new()> constructor for this class. The names of all 6365759b3d2Safresh1private methods and data-fields used by B<Pod::Select> begin with a 6375759b3d2Safresh1prefix of "_" and match the regular expression C</^_\w+$/>. 6385759b3d2Safresh1 6395759b3d2Safresh1=cut 6405759b3d2Safresh1 6415759b3d2Safresh1##--------------------------------------------------------------------------- 6425759b3d2Safresh1 6435759b3d2Safresh1=begin _PRIVATE_ 6445759b3d2Safresh1 6455759b3d2Safresh1=head1 B<_compile_section_spec()> 6465759b3d2Safresh1 6475759b3d2Safresh1 $listref = $parser->_compile_section_spec($section_spec); 6485759b3d2Safresh1 6495759b3d2Safresh1This function (note it is a function and I<not> a method) takes a 6505759b3d2Safresh1section specification (as described in L<"SECTION SPECIFICATIONS">) 6515759b3d2Safresh1given in C<$section_sepc>, and compiles it into a list of regular 6525759b3d2Safresh1expressions. If C<$section_spec> has no syntax errors, then a reference 6535759b3d2Safresh1to the list (array) of corresponding regular expressions is returned; 6545759b3d2Safresh1otherwise C<undef> is returned and an error message is printed (using 6555759b3d2Safresh1B<carp>) for each invalid regex. 6565759b3d2Safresh1 6575759b3d2Safresh1=end _PRIVATE_ 6585759b3d2Safresh1 6595759b3d2Safresh1=cut 6605759b3d2Safresh1 6615759b3d2Safresh1sub _compile_section_spec { 6625759b3d2Safresh1 my ($section_spec) = @_; 6635759b3d2Safresh1 my (@regexs, $negated); 6645759b3d2Safresh1 6655759b3d2Safresh1 ## Compile the spec into a list of regexs 6665759b3d2Safresh1 local $_ = $section_spec; 6675759b3d2Safresh1 s{\\\\}{\001}g; ## handle escaped backward slashes 6685759b3d2Safresh1 s{\\/}{\002}g; ## handle escaped forward slashes 6695759b3d2Safresh1 6705759b3d2Safresh1 ## Parse the regexs for the heading titles 6715759b3d2Safresh1 @regexs = split(/\//, $_, $MAX_HEADING_LEVEL); 6725759b3d2Safresh1 6735759b3d2Safresh1 ## Set default regex for ommitted levels 6745759b3d2Safresh1 for (my $i = 0; $i < $MAX_HEADING_LEVEL; ++$i) { 6755759b3d2Safresh1 $regexs[$i] = '.*' unless ((defined $regexs[$i]) 6765759b3d2Safresh1 && (length $regexs[$i])); 6775759b3d2Safresh1 } 6785759b3d2Safresh1 ## Modify the regexs as needed and validate their syntax 6795759b3d2Safresh1 my $bad_regexs = 0; 6805759b3d2Safresh1 for (@regexs) { 6815759b3d2Safresh1 $_ .= '.+' if ($_ eq '!'); 6825759b3d2Safresh1 s{\001}{\\\\}g; ## restore escaped backward slashes 6835759b3d2Safresh1 s{\002}{\\/}g; ## restore escaped forward slashes 6845759b3d2Safresh1 $negated = s/^\!//; ## check for negation 6855759b3d2Safresh1 eval "m{$_}"; ## check regex syntax 6865759b3d2Safresh1 if ($@) { 6875759b3d2Safresh1 ++$bad_regexs; 6885759b3d2Safresh1 carp qq{Bad regular expression /$_/ in "$section_spec": $@\n}; 6895759b3d2Safresh1 } 6905759b3d2Safresh1 else { 6915759b3d2Safresh1 ## Add the forward and rear anchors (and put the negator back) 6925759b3d2Safresh1 $_ = '^' . $_ unless (/^\^/); 6935759b3d2Safresh1 $_ = $_ . '$' unless (/\$$/); 6945759b3d2Safresh1 $_ = '!' . $_ if ($negated); 6955759b3d2Safresh1 } 6965759b3d2Safresh1 } 6975759b3d2Safresh1 return (! $bad_regexs) ? [ @regexs ] : undef; 6985759b3d2Safresh1} 6995759b3d2Safresh1 7005759b3d2Safresh1##--------------------------------------------------------------------------- 7015759b3d2Safresh1 7025759b3d2Safresh1=begin _PRIVATE_ 7035759b3d2Safresh1 7045759b3d2Safresh1=head2 $self->{_SECTION_HEADINGS} 7055759b3d2Safresh1 7065759b3d2Safresh1A reference to an array of the current section heading titles for each 7075759b3d2Safresh1heading level (note that the first heading level title is at index 0). 7085759b3d2Safresh1 7095759b3d2Safresh1=end _PRIVATE_ 7105759b3d2Safresh1 7115759b3d2Safresh1=cut 7125759b3d2Safresh1 7135759b3d2Safresh1##--------------------------------------------------------------------------- 7145759b3d2Safresh1 7155759b3d2Safresh1=begin _PRIVATE_ 7165759b3d2Safresh1 7175759b3d2Safresh1=head2 $self->{_SELECTED_SECTIONS} 7185759b3d2Safresh1 7195759b3d2Safresh1A reference to an array of references to arrays. Each subarray is a list 7205759b3d2Safresh1of anchored regular expressions (preceded by a "!" if the expression is to 7215759b3d2Safresh1be negated). The index of the expression in the subarray should correspond 7225759b3d2Safresh1to the index of the heading title in C<$self-E<gt>{_SECTION_HEADINGS}> 7235759b3d2Safresh1that it is to be matched against. 7245759b3d2Safresh1 7255759b3d2Safresh1=end _PRIVATE_ 7265759b3d2Safresh1 7275759b3d2Safresh1=cut 7285759b3d2Safresh1 7295759b3d2Safresh1############################################################################# 7305759b3d2Safresh1 7315759b3d2Safresh1=head1 SEE ALSO 7325759b3d2Safresh1 7335759b3d2Safresh1L<Pod::Parser> 7345759b3d2Safresh1 7355759b3d2Safresh1=head1 AUTHOR 7365759b3d2Safresh1 7375759b3d2Safresh1Please report bugs using L<http://rt.cpan.org>. 7385759b3d2Safresh1 7395759b3d2Safresh1Brad Appleton E<lt>bradapp@enteract.comE<gt> 7405759b3d2Safresh1 7415759b3d2Safresh1Based on code for B<pod2text> written by 7425759b3d2Safresh1Tom Christiansen E<lt>tchrist@mox.perl.comE<gt> 7435759b3d2Safresh1 7445759b3d2Safresh1B<Pod::Select> is part of the L<Pod::Parser> distribution. 7455759b3d2Safresh1 7465759b3d2Safresh1=cut 7475759b3d2Safresh1 7485759b3d2Safresh11; 7495759b3d2Safresh1# vim: ts=4 sw=4 et 750