1*0Sstevel@tonic-gate############################################################################# 2*0Sstevel@tonic-gate# Pod/Usage.pm -- print usage messages for the running script. 3*0Sstevel@tonic-gate# 4*0Sstevel@tonic-gate# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved. 5*0Sstevel@tonic-gate# This file is part of "PodParser". PodParser is free software; 6*0Sstevel@tonic-gate# you can redistribute it and/or modify it under the same terms 7*0Sstevel@tonic-gate# as Perl itself. 8*0Sstevel@tonic-gate############################################################################# 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gatepackage Pod::Usage; 11*0Sstevel@tonic-gate 12*0Sstevel@tonic-gateuse vars qw($VERSION); 13*0Sstevel@tonic-gate$VERSION = 1.16; ## Current version of this package 14*0Sstevel@tonic-gaterequire 5.005; ## requires this Perl version or later 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gate=head1 NAME 17*0Sstevel@tonic-gate 18*0Sstevel@tonic-gatePod::Usage, pod2usage() - print a usage message from embedded pod documentation 19*0Sstevel@tonic-gate 20*0Sstevel@tonic-gate=head1 SYNOPSIS 21*0Sstevel@tonic-gate 22*0Sstevel@tonic-gate use Pod::Usage 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate my $message_text = "This text precedes the usage message."; 25*0Sstevel@tonic-gate my $exit_status = 2; ## The exit status to use 26*0Sstevel@tonic-gate my $verbose_level = 0; ## The verbose level to use 27*0Sstevel@tonic-gate my $filehandle = \*STDERR; ## The filehandle to write to 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate pod2usage($message_text); 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate pod2usage($exit_status); 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate pod2usage( { -message => $message_text , 34*0Sstevel@tonic-gate -exitval => $exit_status , 35*0Sstevel@tonic-gate -verbose => $verbose_level, 36*0Sstevel@tonic-gate -output => $filehandle } ); 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate pod2usage( -msg => $message_text , 39*0Sstevel@tonic-gate -exitval => $exit_status , 40*0Sstevel@tonic-gate -verbose => $verbose_level, 41*0Sstevel@tonic-gate -output => $filehandle ); 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate=head1 ARGUMENTS 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gateB<pod2usage> should be given either a single argument, or a list of 46*0Sstevel@tonic-gatearguments corresponding to an associative array (a "hash"). When a single 47*0Sstevel@tonic-gateargument is given, it should correspond to exactly one of the following: 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate=over 4 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate=item * 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gateA string containing the text of a message to print I<before> printing 54*0Sstevel@tonic-gatethe usage message 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate=item * 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gateA numeric value corresponding to the desired exit status 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate=item * 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gateA reference to a hash 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate=back 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gateIf more than one argument is given then the entire argument list is 67*0Sstevel@tonic-gateassumed to be a hash. If a hash is supplied (either as a reference or 68*0Sstevel@tonic-gateas a list) it should contain one or more elements with the following 69*0Sstevel@tonic-gatekeys: 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate=over 4 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate=item C<-message> 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate=item C<-msg> 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gateThe text of a message to print immediately prior to printing the 78*0Sstevel@tonic-gateprogram's usage message. 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate=item C<-exitval> 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gateThe desired exit status to pass to the B<exit()> function. 83*0Sstevel@tonic-gateThis should be an integer, or else the string "NOEXIT" to 84*0Sstevel@tonic-gateindicate that control should simply be returned without 85*0Sstevel@tonic-gateterminating the invoking process. 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate=item C<-verbose> 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gateThe desired level of "verboseness" to use when printing the usage 90*0Sstevel@tonic-gatemessage. If the corresponding value is 0, then only the "SYNOPSIS" 91*0Sstevel@tonic-gatesection of the pod documentation is printed. If the corresponding value 92*0Sstevel@tonic-gateis 1, then the "SYNOPSIS" section, along with any section entitled 93*0Sstevel@tonic-gate"OPTIONS", "ARGUMENTS", or "OPTIONS AND ARGUMENTS" is printed. If the 94*0Sstevel@tonic-gatecorresponding value is 2 or more then the entire manpage is printed. 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate=item C<-output> 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gateA reference to a filehandle, or the pathname of a file to which the 99*0Sstevel@tonic-gateusage message should be written. The default is C<\*STDERR> unless the 100*0Sstevel@tonic-gateexit value is less than 2 (in which case the default is C<\*STDOUT>). 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate=item C<-input> 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gateA reference to a filehandle, or the pathname of a file from which the 105*0Sstevel@tonic-gateinvoking script's pod documentation should be read. It defaults to the 106*0Sstevel@tonic-gatefile indicated by C<$0> (C<$PROGRAM_NAME> for users of F<English.pm>). 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate=item C<-pathlist> 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gateA list of directory paths. If the input file does not exist, then it 111*0Sstevel@tonic-gatewill be searched for in the given directory list (in the order the 112*0Sstevel@tonic-gatedirectories appear in the list). It defaults to the list of directories 113*0Sstevel@tonic-gateimplied by C<$ENV{PATH}>. The list may be specified either by a reference 114*0Sstevel@tonic-gateto an array, or by a string of directory paths which use the same path 115*0Sstevel@tonic-gateseparator as C<$ENV{PATH}> on your system (e.g., C<:> for Unix, C<;> for 116*0Sstevel@tonic-gateMSWin32 and DOS). 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate=back 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate=head1 DESCRIPTION 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gateB<pod2usage> will print a usage message for the invoking script (using 123*0Sstevel@tonic-gateits embedded pod documentation) and then exit the script with the 124*0Sstevel@tonic-gatedesired exit status. The usage message printed may have any one of three 125*0Sstevel@tonic-gatelevels of "verboseness": If the verbose level is 0, then only a synopsis 126*0Sstevel@tonic-gateis printed. If the verbose level is 1, then the synopsis is printed 127*0Sstevel@tonic-gatealong with a description (if present) of the command line options and 128*0Sstevel@tonic-gatearguments. If the verbose level is 2, then the entire manual page is 129*0Sstevel@tonic-gateprinted. 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gateUnless they are explicitly specified, the default values for the exit 132*0Sstevel@tonic-gatestatus, verbose level, and output stream to use are determined as 133*0Sstevel@tonic-gatefollows: 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate=over 4 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate=item * 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gateIf neither the exit status nor the verbose level is specified, then the 140*0Sstevel@tonic-gatedefault is to use an exit status of 2 with a verbose level of 0. 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate=item * 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gateIf an exit status I<is> specified but the verbose level is I<not>, then the 145*0Sstevel@tonic-gateverbose level will default to 1 if the exit status is less than 2 and 146*0Sstevel@tonic-gatewill default to 0 otherwise. 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate=item * 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gateIf an exit status is I<not> specified but verbose level I<is> given, then 151*0Sstevel@tonic-gatethe exit status will default to 2 if the verbose level is 0 and will 152*0Sstevel@tonic-gatedefault to 1 otherwise. 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate=item * 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gateIf the exit status used is less than 2, then output is printed on 157*0Sstevel@tonic-gateC<STDOUT>. Otherwise output is printed on C<STDERR>. 158*0Sstevel@tonic-gate 159*0Sstevel@tonic-gate=back 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gateAlthough the above may seem a bit confusing at first, it generally does 162*0Sstevel@tonic-gate"the right thing" in most situations. This determination of the default 163*0Sstevel@tonic-gatevalues to use is based upon the following typical Unix conventions: 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate=over 4 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate=item * 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gateAn exit status of 0 implies "success". For example, B<diff(1)> exits 170*0Sstevel@tonic-gatewith a status of 0 if the two files have the same contents. 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate=item * 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gateAn exit status of 1 implies possibly abnormal, but non-defective, program 175*0Sstevel@tonic-gatetermination. For example, B<grep(1)> exits with a status of 1 if 176*0Sstevel@tonic-gateit did I<not> find a matching line for the given regular expression. 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate=item * 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gateAn exit status of 2 or more implies a fatal error. For example, B<ls(1)> 181*0Sstevel@tonic-gateexits with a status of 2 if you specify an illegal (unknown) option on 182*0Sstevel@tonic-gatethe command line. 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate=item * 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gateUsage messages issued as a result of bad command-line syntax should go 187*0Sstevel@tonic-gateto C<STDERR>. However, usage messages issued due to an explicit request 188*0Sstevel@tonic-gateto print usage (like specifying B<-help> on the command line) should go 189*0Sstevel@tonic-gateto C<STDOUT>, just in case the user wants to pipe the output to a pager 190*0Sstevel@tonic-gate(such as B<more(1)>). 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate=item * 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gateIf program usage has been explicitly requested by the user, it is often 195*0Sstevel@tonic-gatedesireable to exit with a status of 1 (as opposed to 0) after issuing 196*0Sstevel@tonic-gatethe user-requested usage message. It is also desireable to give a 197*0Sstevel@tonic-gatemore verbose description of program usage in this case. 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gate=back 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gateB<pod2usage> doesn't force the above conventions upon you, but it will 202*0Sstevel@tonic-gateuse them by default if you don't expressly tell it to do otherwise. The 203*0Sstevel@tonic-gateability of B<pod2usage()> to accept a single number or a string makes it 204*0Sstevel@tonic-gateconvenient to use as an innocent looking error message handling function: 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate use Pod::Usage; 207*0Sstevel@tonic-gate use Getopt::Long; 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate ## Parse options 210*0Sstevel@tonic-gate GetOptions("help", "man", "flag1") || pod2usage(2); 211*0Sstevel@tonic-gate pod2usage(1) if ($opt_help); 212*0Sstevel@tonic-gate pod2usage(-verbose => 2) if ($opt_man); 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate ## Check for too many filenames 215*0Sstevel@tonic-gate pod2usage("$0: Too many files given.\n") if (@ARGV > 1); 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gateSome user's however may feel that the above "economy of expression" is 218*0Sstevel@tonic-gatenot particularly readable nor consistent and may instead choose to do 219*0Sstevel@tonic-gatesomething more like the following: 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate use Pod::Usage; 222*0Sstevel@tonic-gate use Getopt::Long; 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate ## Parse options 225*0Sstevel@tonic-gate GetOptions("help", "man", "flag1") || pod2usage(-verbose => 0); 226*0Sstevel@tonic-gate pod2usage(-verbose => 1) if ($opt_help); 227*0Sstevel@tonic-gate pod2usage(-verbose => 2) if ($opt_man); 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate ## Check for too many filenames 230*0Sstevel@tonic-gate pod2usage(-verbose => 2, -message => "$0: Too many files given.\n") 231*0Sstevel@tonic-gate if (@ARGV > 1); 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gateAs with all things in Perl, I<there's more than one way to do it>, and 234*0Sstevel@tonic-gateB<pod2usage()> adheres to this philosophy. If you are interested in 235*0Sstevel@tonic-gateseeing a number of different ways to invoke B<pod2usage> (although by no 236*0Sstevel@tonic-gatemeans exhaustive), please refer to L<"EXAMPLES">. 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate=head1 EXAMPLES 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gateEach of the following invocations of C<pod2usage()> will print just the 241*0Sstevel@tonic-gate"SYNOPSIS" section to C<STDERR> and will exit with a status of 2: 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gate pod2usage(); 244*0Sstevel@tonic-gate 245*0Sstevel@tonic-gate pod2usage(2); 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate pod2usage(-verbose => 0); 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate pod2usage(-exitval => 2); 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate pod2usage({-exitval => 2, -output => \*STDERR}); 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate pod2usage({-verbose => 0, -output => \*STDERR}); 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate pod2usage(-exitval => 2, -verbose => 0); 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate pod2usage(-exitval => 2, -verbose => 0, -output => \*STDERR); 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gateEach of the following invocations of C<pod2usage()> will print a message 260*0Sstevel@tonic-gateof "Syntax error." (followed by a newline) to C<STDERR>, immediately 261*0Sstevel@tonic-gatefollowed by just the "SYNOPSIS" section (also printed to C<STDERR>) and 262*0Sstevel@tonic-gatewill exit with a status of 2: 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate pod2usage("Syntax error."); 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate pod2usage(-message => "Syntax error.", -verbose => 0); 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate pod2usage(-msg => "Syntax error.", -exitval => 2); 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate pod2usage({-msg => "Syntax error.", -exitval => 2, -output => \*STDERR}); 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate pod2usage({-msg => "Syntax error.", -verbose => 0, -output => \*STDERR}); 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate pod2usage(-msg => "Syntax error.", -exitval => 2, -verbose => 0); 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate pod2usage(-message => "Syntax error.", 277*0Sstevel@tonic-gate -exitval => 2, 278*0Sstevel@tonic-gate -verbose => 0, 279*0Sstevel@tonic-gate -output => \*STDERR); 280*0Sstevel@tonic-gate 281*0Sstevel@tonic-gateEach of the following invocations of C<pod2usage()> will print the 282*0Sstevel@tonic-gate"SYNOPSIS" section and any "OPTIONS" and/or "ARGUMENTS" sections to 283*0Sstevel@tonic-gateC<STDOUT> and will exit with a status of 1: 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate pod2usage(1); 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate pod2usage(-verbose => 1); 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate pod2usage(-exitval => 1); 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate pod2usage({-exitval => 1, -output => \*STDOUT}); 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gate pod2usage({-verbose => 1, -output => \*STDOUT}); 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate pod2usage(-exitval => 1, -verbose => 1); 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate pod2usage(-exitval => 1, -verbose => 1, -output => \*STDOUT}); 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gateEach of the following invocations of C<pod2usage()> will print the 300*0Sstevel@tonic-gateentire manual page to C<STDOUT> and will exit with a status of 1: 301*0Sstevel@tonic-gate 302*0Sstevel@tonic-gate pod2usage(-verbose => 2); 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate pod2usage({-verbose => 2, -output => \*STDOUT}); 305*0Sstevel@tonic-gate 306*0Sstevel@tonic-gate pod2usage(-exitval => 1, -verbose => 2); 307*0Sstevel@tonic-gate 308*0Sstevel@tonic-gate pod2usage({-exitval => 1, -verbose => 2, -output => \*STDOUT}); 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate=head2 Recommended Use 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gateMost scripts should print some type of usage message to C<STDERR> when a 313*0Sstevel@tonic-gatecommand line syntax error is detected. They should also provide an 314*0Sstevel@tonic-gateoption (usually C<-H> or C<-help>) to print a (possibly more verbose) 315*0Sstevel@tonic-gateusage message to C<STDOUT>. Some scripts may even wish to go so far as to 316*0Sstevel@tonic-gateprovide a means of printing their complete documentation to C<STDOUT> 317*0Sstevel@tonic-gate(perhaps by allowing a C<-man> option). The following complete example 318*0Sstevel@tonic-gateuses B<Pod::Usage> in combination with B<Getopt::Long> to do all of these 319*0Sstevel@tonic-gatethings: 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate use Getopt::Long; 322*0Sstevel@tonic-gate use Pod::Usage; 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate my $man = 0; 325*0Sstevel@tonic-gate my $help = 0; 326*0Sstevel@tonic-gate ## Parse options and print usage if there is a syntax error, 327*0Sstevel@tonic-gate ## or if usage was explicitly requested. 328*0Sstevel@tonic-gate GetOptions('help|?' => \$help, man => \$man) or pod2usage(2); 329*0Sstevel@tonic-gate pod2usage(1) if $help; 330*0Sstevel@tonic-gate pod2usage(-verbose => 2) if $man; 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate ## If no arguments were given, then allow STDIN to be used only 333*0Sstevel@tonic-gate ## if it's not connected to a terminal (otherwise print usage) 334*0Sstevel@tonic-gate pod2usage("$0: No files given.") if ((@ARGV == 0) && (-t STDIN)); 335*0Sstevel@tonic-gate __END__ 336*0Sstevel@tonic-gate 337*0Sstevel@tonic-gate =head1 NAME 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate sample - Using GetOpt::Long and Pod::Usage 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate =head1 SYNOPSIS 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate sample [options] [file ...] 344*0Sstevel@tonic-gate 345*0Sstevel@tonic-gate Options: 346*0Sstevel@tonic-gate -help brief help message 347*0Sstevel@tonic-gate -man full documentation 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate =head1 OPTIONS 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gate =over 8 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate =item B<-help> 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate Print a brief help message and exits. 356*0Sstevel@tonic-gate 357*0Sstevel@tonic-gate =item B<-man> 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate Prints the manual page and exits. 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate =back 362*0Sstevel@tonic-gate 363*0Sstevel@tonic-gate =head1 DESCRIPTION 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate B<This program> will read the given input file(s) and do something 366*0Sstevel@tonic-gate useful with the contents thereof. 367*0Sstevel@tonic-gate 368*0Sstevel@tonic-gate =cut 369*0Sstevel@tonic-gate 370*0Sstevel@tonic-gate=head1 CAVEATS 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gateBy default, B<pod2usage()> will use C<$0> as the path to the pod input 373*0Sstevel@tonic-gatefile. Unfortunately, not all systems on which Perl runs will set C<$0> 374*0Sstevel@tonic-gateproperly (although if C<$0> isn't found, B<pod2usage()> will search 375*0Sstevel@tonic-gateC<$ENV{PATH}> or else the list specified by the C<-pathlist> option). 376*0Sstevel@tonic-gateIf this is the case for your system, you may need to explicitly specify 377*0Sstevel@tonic-gatethe path to the pod docs for the invoking script using something 378*0Sstevel@tonic-gatesimilar to the following: 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate pod2usage(-exitval => 2, -input => "/path/to/your/pod/docs"); 381*0Sstevel@tonic-gate 382*0Sstevel@tonic-gate=head1 AUTHOR 383*0Sstevel@tonic-gate 384*0Sstevel@tonic-gatePlease report bugs using L<http://rt.cpan.org>. 385*0Sstevel@tonic-gate 386*0Sstevel@tonic-gateBrad Appleton E<lt>bradapp@enteract.comE<gt> 387*0Sstevel@tonic-gate 388*0Sstevel@tonic-gateBased on code for B<Pod::Text::pod2text()> written by 389*0Sstevel@tonic-gateTom Christiansen E<lt>tchrist@mox.perl.comE<gt> 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate=head1 ACKNOWLEDGEMENTS 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gateSteven McDougall E<lt>swmcd@world.std.comE<gt> for his help and patience 394*0Sstevel@tonic-gatewith re-writing this manpage. 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate=cut 397*0Sstevel@tonic-gate 398*0Sstevel@tonic-gate############################################################################# 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gateuse strict; 401*0Sstevel@tonic-gate#use diagnostics; 402*0Sstevel@tonic-gateuse Carp; 403*0Sstevel@tonic-gateuse Config; 404*0Sstevel@tonic-gateuse Exporter; 405*0Sstevel@tonic-gateuse File::Spec; 406*0Sstevel@tonic-gate 407*0Sstevel@tonic-gateuse vars qw(@ISA @EXPORT); 408*0Sstevel@tonic-gate@EXPORT = qw(&pod2usage); 409*0Sstevel@tonic-gateBEGIN { 410*0Sstevel@tonic-gate if ( $] >= 5.005_58 ) { 411*0Sstevel@tonic-gate require Pod::Text; 412*0Sstevel@tonic-gate @ISA = qw( Pod::Text ); 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate else { 415*0Sstevel@tonic-gate require Pod::PlainText; 416*0Sstevel@tonic-gate @ISA = qw( Pod::PlainText ); 417*0Sstevel@tonic-gate } 418*0Sstevel@tonic-gate} 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gate 421*0Sstevel@tonic-gate##--------------------------------------------------------------------------- 422*0Sstevel@tonic-gate 423*0Sstevel@tonic-gate##--------------------------------- 424*0Sstevel@tonic-gate## Function definitions begin here 425*0Sstevel@tonic-gate##--------------------------------- 426*0Sstevel@tonic-gate 427*0Sstevel@tonic-gatesub pod2usage { 428*0Sstevel@tonic-gate local($_) = shift || ""; 429*0Sstevel@tonic-gate my %opts; 430*0Sstevel@tonic-gate ## Collect arguments 431*0Sstevel@tonic-gate if (@_ > 0) { 432*0Sstevel@tonic-gate ## Too many arguments - assume that this is a hash and 433*0Sstevel@tonic-gate ## the user forgot to pass a reference to it. 434*0Sstevel@tonic-gate %opts = ($_, @_); 435*0Sstevel@tonic-gate } 436*0Sstevel@tonic-gate elsif (ref $_) { 437*0Sstevel@tonic-gate ## User passed a ref to a hash 438*0Sstevel@tonic-gate %opts = %{$_} if (ref($_) eq 'HASH'); 439*0Sstevel@tonic-gate } 440*0Sstevel@tonic-gate elsif (/^[-+]?\d+$/) { 441*0Sstevel@tonic-gate ## User passed in the exit value to use 442*0Sstevel@tonic-gate $opts{"-exitval"} = $_; 443*0Sstevel@tonic-gate } 444*0Sstevel@tonic-gate else { 445*0Sstevel@tonic-gate ## User passed in a message to print before issuing usage. 446*0Sstevel@tonic-gate $_ and $opts{"-message"} = $_; 447*0Sstevel@tonic-gate } 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate ## Need this for backward compatibility since we formerly used 450*0Sstevel@tonic-gate ## options that were all uppercase words rather than ones that 451*0Sstevel@tonic-gate ## looked like Unix command-line options. 452*0Sstevel@tonic-gate ## to be uppercase keywords) 453*0Sstevel@tonic-gate %opts = map { 454*0Sstevel@tonic-gate my $val = $opts{$_}; 455*0Sstevel@tonic-gate s/^(?=\w)/-/; 456*0Sstevel@tonic-gate /^-msg/i and $_ = '-message'; 457*0Sstevel@tonic-gate /^-exit/i and $_ = '-exitval'; 458*0Sstevel@tonic-gate lc($_) => $val; 459*0Sstevel@tonic-gate } (keys %opts); 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate ## Now determine default -exitval and -verbose values to use 462*0Sstevel@tonic-gate if ((! defined $opts{"-exitval"}) && (! defined $opts{"-verbose"})) { 463*0Sstevel@tonic-gate $opts{"-exitval"} = 2; 464*0Sstevel@tonic-gate $opts{"-verbose"} = 0; 465*0Sstevel@tonic-gate } 466*0Sstevel@tonic-gate elsif (! defined $opts{"-exitval"}) { 467*0Sstevel@tonic-gate $opts{"-exitval"} = ($opts{"-verbose"} > 0) ? 1 : 2; 468*0Sstevel@tonic-gate } 469*0Sstevel@tonic-gate elsif (! defined $opts{"-verbose"}) { 470*0Sstevel@tonic-gate $opts{"-verbose"} = ($opts{"-exitval"} < 2); 471*0Sstevel@tonic-gate } 472*0Sstevel@tonic-gate 473*0Sstevel@tonic-gate ## Default the output file 474*0Sstevel@tonic-gate $opts{"-output"} = (lc($opts{"-exitval"}) eq "noexit" || 475*0Sstevel@tonic-gate $opts{"-exitval"} < 2) ? \*STDOUT : \*STDERR 476*0Sstevel@tonic-gate unless (defined $opts{"-output"}); 477*0Sstevel@tonic-gate ## Default the input file 478*0Sstevel@tonic-gate $opts{"-input"} = $0 unless (defined $opts{"-input"}); 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gate ## Look up input file in path if it doesnt exist. 481*0Sstevel@tonic-gate unless ((ref $opts{"-input"}) || (-e $opts{"-input"})) { 482*0Sstevel@tonic-gate my ($dirname, $basename) = ('', $opts{"-input"}); 483*0Sstevel@tonic-gate my $pathsep = ($^O =~ /^(?:dos|os2|MSWin32)$/) ? ";" 484*0Sstevel@tonic-gate : (($^O eq 'MacOS' || $^O eq 'VMS') ? ',' : ":"); 485*0Sstevel@tonic-gate my $pathspec = $opts{"-pathlist"} || $ENV{PATH} || $ENV{PERL5LIB}; 486*0Sstevel@tonic-gate 487*0Sstevel@tonic-gate my @paths = (ref $pathspec) ? @$pathspec : split($pathsep, $pathspec); 488*0Sstevel@tonic-gate for $dirname (@paths) { 489*0Sstevel@tonic-gate $_ = File::Spec->catfile($dirname, $basename) if length; 490*0Sstevel@tonic-gate last if (-e $_) && ($opts{"-input"} = $_); 491*0Sstevel@tonic-gate } 492*0Sstevel@tonic-gate } 493*0Sstevel@tonic-gate 494*0Sstevel@tonic-gate ## Now create a pod reader and constrain it to the desired sections. 495*0Sstevel@tonic-gate my $parser = new Pod::Usage(USAGE_OPTIONS => \%opts); 496*0Sstevel@tonic-gate if ($opts{"-verbose"} == 0) { 497*0Sstevel@tonic-gate $parser->select("SYNOPSIS"); 498*0Sstevel@tonic-gate } 499*0Sstevel@tonic-gate elsif ($opts{"-verbose"} == 1) { 500*0Sstevel@tonic-gate my $opt_re = '(?i)' . 501*0Sstevel@tonic-gate '(?:OPTIONS|ARGUMENTS)' . 502*0Sstevel@tonic-gate '(?:\s*(?:AND|\/)\s*(?:OPTIONS|ARGUMENTS))?'; 503*0Sstevel@tonic-gate $parser->select( 'SYNOPSIS', $opt_re, "DESCRIPTION/$opt_re" ); 504*0Sstevel@tonic-gate } 505*0Sstevel@tonic-gate 506*0Sstevel@tonic-gate ## Now translate the pod document and then exit with the desired status 507*0Sstevel@tonic-gate if ( $opts{"-verbose"} >= 2 508*0Sstevel@tonic-gate and !ref($opts{"-input"}) 509*0Sstevel@tonic-gate and $opts{"-output"} == \*STDOUT ) 510*0Sstevel@tonic-gate { 511*0Sstevel@tonic-gate ## spit out the entire PODs. Might as well invoke perldoc 512*0Sstevel@tonic-gate my $progpath = File::Spec->catfile($Config{scriptdir}, "perldoc"); 513*0Sstevel@tonic-gate system($progpath, $opts{"-input"}); 514*0Sstevel@tonic-gate } 515*0Sstevel@tonic-gate else { 516*0Sstevel@tonic-gate $parser->parse_from_file($opts{"-input"}, $opts{"-output"}); 517*0Sstevel@tonic-gate } 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate exit($opts{"-exitval"}) unless (lc($opts{"-exitval"}) eq 'noexit'); 520*0Sstevel@tonic-gate} 521*0Sstevel@tonic-gate 522*0Sstevel@tonic-gate##--------------------------------------------------------------------------- 523*0Sstevel@tonic-gate 524*0Sstevel@tonic-gate##------------------------------- 525*0Sstevel@tonic-gate## Method definitions begin here 526*0Sstevel@tonic-gate##------------------------------- 527*0Sstevel@tonic-gate 528*0Sstevel@tonic-gatesub new { 529*0Sstevel@tonic-gate my $this = shift; 530*0Sstevel@tonic-gate my $class = ref($this) || $this; 531*0Sstevel@tonic-gate my %params = @_; 532*0Sstevel@tonic-gate my $self = {%params}; 533*0Sstevel@tonic-gate bless $self, $class; 534*0Sstevel@tonic-gate $self->initialize(); 535*0Sstevel@tonic-gate return $self; 536*0Sstevel@tonic-gate} 537*0Sstevel@tonic-gate 538*0Sstevel@tonic-gatesub begin_pod { 539*0Sstevel@tonic-gate my $self = shift; 540*0Sstevel@tonic-gate $self->SUPER::begin_pod(); ## Have to call superclass 541*0Sstevel@tonic-gate my $msg = $self->{USAGE_OPTIONS}->{-message} or return 1; 542*0Sstevel@tonic-gate my $out_fh = $self->output_handle(); 543*0Sstevel@tonic-gate print $out_fh "$msg\n"; 544*0Sstevel@tonic-gate} 545*0Sstevel@tonic-gate 546*0Sstevel@tonic-gatesub preprocess_paragraph { 547*0Sstevel@tonic-gate my $self = shift; 548*0Sstevel@tonic-gate local $_ = shift; 549*0Sstevel@tonic-gate my $line = shift; 550*0Sstevel@tonic-gate ## See if this is a heading and we arent printing the entire manpage. 551*0Sstevel@tonic-gate if (($self->{USAGE_OPTIONS}->{-verbose} < 2) && /^=head/) { 552*0Sstevel@tonic-gate ## Change the title of the SYNOPSIS section to USAGE 553*0Sstevel@tonic-gate s/^=head1\s+SYNOPSIS\s*$/=head1 USAGE/; 554*0Sstevel@tonic-gate ## Try to do some lowercasing instead of all-caps in headings 555*0Sstevel@tonic-gate s{([A-Z])([A-Z]+)}{((length($2) > 2) ? $1 : lc($1)) . lc($2)}ge; 556*0Sstevel@tonic-gate ## Use a colon to end all headings 557*0Sstevel@tonic-gate s/\s*$/:/ unless (/:\s*$/); 558*0Sstevel@tonic-gate $_ .= "\n"; 559*0Sstevel@tonic-gate } 560*0Sstevel@tonic-gate return $self->SUPER::preprocess_paragraph($_); 561*0Sstevel@tonic-gate} 562*0Sstevel@tonic-gate 563*0Sstevel@tonic-gate1; # keep require happy 564