If by "That version didn't get included as a replacement simply because I, not neither having a M$-LOSS system nor willing to acquire one, was personally unable to create an installation that I could test where linked $0 was unreliable." you mean you wanted it tested on a Windows box, I'd be happy to. If you meant more explain...(I'd probably still be happy to, but I hesitate to extend a blank check<g>)
--hsm -----Original Message----- From: Tom Christiansen [mailto:[EMAIL PROTECTED] Sent: Monday, March 10, 2003 4:23 PM To: [EMAIL PROTECTED] Cc: [EMAIL PROTECTED] Subject: Re: perldoc rethink >I think a general purpose query system is in order, -Q for query >Here's how I envisage it. Given an index (more on that later) -Q EXPR >checks the index to determine which page(s) has information about EXPR. >All perl man pages would be in the index, and so you need not know where >anything lives to display the relevant section. I already did all that rewrite work years ago--as well as considerably more convenience and functionality for than I have ever seen discussed on this list. That version didn't get included as a replacement simply because I, not neither having a M$-LOSS system nor willing to acquire one, was personally unable to create an installation that I could test where linked $0 was unreliable. Completed and fully functional code available upon request. --tom [Note: some of this is out of date, in that option names have changed.] Note that these are all the same perlman (normal mode) podgrep (same, but non Perl-installation aware mode) perldoc (for legacy operation; may have a few differing CLI flags, but these are deprecated.) But see below. Passing a full path to perlman is the same as calling podgrep, although with podgrep the pager is not autocalled. ===================== NORMAL USAGE ================= $ perlman Prints out a short usage message. $ perlsub $ perlman perlsub Shows you the perlsub manpage, formatted and paged. (The program will use its own name as the name of the manpage to display if that name is not from a set of expected installation names.) If the pre-converted version is available in Config's $man1dir, the system man program will be invoked upon it. If there is no converted version but if you appear to be on a manly system, the page will be manually sent through pod2man and nroff and your pager. If you are unmanly, you get it run through pod2text and thence to your pager once again. If you want to do things the slow way, you can ignore the nroff translations using the "-t" flag, which means "pod2text" only. These are all the same: $ perlsub -t $ perlman -t perlsub $ pod2text `podpath perlsub` | $PAGER $ pod2text /usr/local/lib/perl5/5.6.0/pod/perlsub.pod | $PAGER ==================== SEARCH MODES ======================= [ section, paragraph, line; should this be a --mode=line style option? ] Search modes are one of the following: no flag => section search -p flag => paragraph search -a flag => line search -C flag => code search (verbatim/indented podagraphs) -L flag => outline search (pod directives) These are all the same: $ perlsub local $ perlman perlsub local $ podgrep `podpath perlsub` local | $PAGER $ podgrep /usr/local/lib/perl5/5.6.0/pod/perlsub.pod local | $PAGER This runs section-search mode against the raw perlsub podpage, where we're looking for any pod sections whose *headers* match the pattern "local". By default, this text is sent through pod2text and, if stdout isatty, your pager. What's a section? A section is defined to be an =foo pod directive plus any undirected text following that up until another pod directive of the same or higher level. For example, a =head1 would include subordinate =head2s and =items, but be terminated by another =head1. An =item is lower than any =headN, and is terminated by any =headN, or any =item that did not occur immediately following the matched one without intervening text; this latter rule allows a paragraph with multiple, consecutive =item tags to be matched, such as you find in perlfunc and perlvar. That way you can say things like $ perlfunc split $ perlvar OFS $ perldiag 'assigned to typeglob' To get each of those =item entries. $ perldata -p typeglob This runs paragraph-search mode, displaying any paragraph that matches "typeglob". Pod directive paragraphs matching the pattern are not immediately catted out. The paragraphs are by default tagged with the paragraph number from the pod source, and, if multiple files are possible (see Metapages below), the manpage name itself. These paragraphs are sent through your pager (and pod2text?). Because paragraphs break across line boundaries, in paragraph mode, all whitespace chunks are converted into \s+ and the (?ms) flags are added to control ^, $, and . $ perlmod -a typeglob The -a flag runs in line-search mode, showing all lines matching the pattern "typeglob". Lines are tagged with the number from their source, and, with multiple files, the name of the file. Your pager will be used for output, but not pod2text, as this is line-based. $ perldata -C code $ perldata -Ca code The -C flag runs in code-search mode, either on paragraphs (by default, or with -p) or lines (with -a). Only verbatim pod paragraphs are listed, usually code. By default, -p is assumed if -C is used and -a is not. $ perlxs -L Keyword $ perlman -L perlxs Keyword The -L flag (same as the ol(1) program below) will search only in the outline. It's essentially the same as $ ol perlxs | grep Keyword ===================== CONJUNCTIVE SEARCHES ====================== If you ask for more than one search string, these are by default ANDed together. The -o flag makes them ORed together. For example: $ perldata -pi typeglob variable Prints only those paragraphs that case-insensitively contain both "typeglob" AND "variable". With the -o flag, you get those with either of them. $ perldata -opi typeglob variable GREP OPTIONS: Definitely: -i case-insensitive using (?i) -w whole words only using \bPAT\b, presuming P and T are word-chars. -l list filenames matching, but not matches Maybe: (but these tend to conflict) -e EXPR for patterns beginning with -? -c just show count of matches -o always show filename (conflicts with -o above) -h hide filenames -n show recnos (but this is the default!) -x exact matches only, so nothing else on line; eg, perlsub -x BUGS to find just the BUGS section, not any section with "BUGS" in the name. For example $ perldata -ai typeglob This searches perldata for any lines (the -a flag) that match "typeglob" case-insensitively (the -i flag). =============== MULTIPLE PAGES AND METAPAGES ============ You can search multiple pages at once explicitly using a comma separated pagelist: $ perlman -i perlsub,perldata variables That does a case-insensitive section-search against those two manpages. or by a "metapage" specification. For example, the "perlfaq" metapage is really all the stanard perlfaq? manpages. $ perlfaq -w round is the same as $ perlman -w perlfaq1,perlfaq2,perlfaq3,perlfaq4,perlfaq5,perlfaq6,perlfaq7,perlfaq8,perl faq9 round But much easier to type. Some metapages also set or clear specific flags, usually change the default search mode (which is section search) into something else. Metapage Meaning perlhelp All standard Perl manpages, with -a (line mode). perlfaq All perlfaq? manpages. perltoc All standard manpages, with -L (outline mode). stdmods All CORE module manpages, with -a flag. modpods All module manpages, with -a flag. sitemods All non-CORE (site) module manpages, with -a flag. These can be used with non-searches also. If no search is provided with a metabase, the -l is assumed to list out what files they are consulting, as in: $ sitepods (Lists all the modules in your sitelib directories) The module-related metapages all have to run a find (well, its perl equivalent) on the relevant directories. There is no central database, nor is it all in one place. +--------------------------------------------------------------------------+ | =============== HOOKS FROM perlman INTO OTHER PROGRAMS ================= | +--------------------------------------------------------------------------+ +-------------------------+ | podgrep - grep the pods | +-------------------------+ This is a regular search (pod-section search as described below be default, but with the other search modes enabled by flags.) $ podgrep `podpath manpage` pattern $ podgrep /full/path pattern $ perlman manpage pattern $ manpage pattern +----------------------------------+ | docpath - show paths to docpages | +----------------------------------+ The "docpath" program can be invoked as "perlman -l" if no search is given. The "podpath" program, which doesn't include manpages, is the same as "perlman -lt", where the -t flag makes it only think about pod2textual bits. On manpages: $ docpath perlfunc $ perlfunc -l $ perlman -l perlfunc /usr/local/man/man1/perlfunc.1 /usr/local/lib/perl5/5.6.0/pod/perlfunc.pod $ podpath perlfunc $ perlfunc -lt $ perlman -lt perlfunc /usr/local/lib/perl5/5.6.0/pod/perlfunc.pod On modules: $ docpath LWP $ perlman -l LWP /usr/local/man/man3/LWP.3 /usr/local/lib/perl5/site_perl/5.6.0/LWP.pm /usr/local/lib/perl5/site_perl/5.00554/LWP.pm On programs: $ docpath perlbug $ perlman -l perlbug /usr/local/man/man1/perlbug.1 /usr/local/bin/perlbug /usr/bin/perlbug Alternative invocations work as follows (this is really all the same program). These are also all available as functions from the PM::Tools::podpath module. If called as functions, then all paths are returned in list context, but just the first found in scalar context, which short-circuits the first. The program versions show all paths; see pmpath(1) below for more details. The docpath program means pod2manpath + podpath (that is, paths to the manpages plus the podpages) The podpath program means stdpodpath + pmpodpath + progpodpath (that is, just podpages) use PM::Tools qw/podpath/; # imports podpath only use PM::Tools::podpath; # imports podpath only use PM::Tools::podpath /:ALL/; # imports all podpath tools stdpodpath("perlfunc") => /usr/local/perl/lib/pod/perlfunc.pod pmpodpath("CGI") => /usr/local/perl/lib/CGI.pm pmpodpath("POSIX") => /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/POSIX.pod progpodpath("perlbug") => /usr/local/perl/bin/perlbug pod2manpath("perlfunc") => /usr/local/man/man1/perlfunc.1 pod2manpath("CGI") => /usr/local/perl/man/man3/CGI.3 +------------------------------------+ | pmpath - find path to perl modules | +------------------------------------+ If you just want the path to the module, not its documentation, use "pmpath". The podpath functions/programs will prefer a ".pod" over a ".pm", and they will open up programs to search for pods. This only cares about modules. As the pmpath(1) program $ pmpath POSIX /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/POSIX.pm $ pmpath IO::Socket /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/IO/Socket.pm $ pmpath LWP /usr/local/lib/perl5/site_perl/5.6.0/LWP.pm /usr/local/lib/perl5/site_perl/5.00554/LWP.pm $ pmpath CGI LWP CGI: /usr/local/lib/perl5/5.6.0/CGI.pm LWP: /usr/local/lib/perl5/site_perl/5.6.0/LWP.pm /usr/local/lib/perl5/site_perl/5.00554/LWP. pm $ pmpath -I/some/dir MyMod /some/Dir/MyMod.pm Or, as a module; first load module: use PM::Tools qw(pmpath); use PM::Tools::pmpath; # this form imports pmpath Then in scalar context: my $path = pmpath("CGI"); Or in list context: my @paths = pmpath("LWP"); +--------------------------------+ | catpod - cat out just the pods | +--------------------------------+ This program produces just the unformatted pods, but not the non-pod which will be filtered out, from a file. If an absolute path is given, that will be the literal filename. Otherwise, a podpath() search will be run to find the real path. Thus, $ catpod CGI is really $ catpod `podpath CGI` is really $ catpod /usr/local/lib/perl5/5.6.0/CGI.pm And, since this is the "perlman -u" unformatted flag, the same as: $ perlman -u CGI +--------------------------+ | ol - display pod outline | +--------------------------+ (Should this be called olpod or podol instead?) These are all (presumably) equivalent: $ ol /usr/local/lib/perl5/5.6.0/pod/perlsub.pod $ ol `podpath perlsub` $ ol perlsub $ perlsub -O $ perlman -O perlsub The "ol" program prints the pod outline for the given file. If the file is not absolute, podpath() will be used to find it, as shown above. $ ol -2 perlsub You may specify a max level to display, so -1 would be only =head1, -2 would be no lower than =head2, etc. =items are considered to be of the ninth level. The ol program can also be invoked as "perlman -L" or eg "perlman -L2": $ perlsub -L $ perlman -L perlsub $ perlsub -L2 $ perlman -L2 perlsub Note that if you provide a search in conjunction with -L, you are in "outline search" mode described above. +------------------------------------------+ | pmcat - cat out complete module contents | +------------------------------------------+ The pmcat locates the path to the named module and cats out the complete contents (through your pager, probably, though). This is different from catpod in that it doesn't select only pod, or in fact, prefer pod if both .pod and .pm versions are available, as with POSIX. The -U flag (for *really* unformatted) to perlman does the same thing. $ pmcat CGI $ pmcat `pmpath CGI` $ $PAGER /usr/local/lib/perl5/5.6.0/CGI.pm $ perlman -U /usr/local/lib/perl5/5.6.0/CGI.pm +-------------------------+ | other podpath funcprogs | +-------------------------+ The PM::Tools::podpath module also supports the following simple functions, which may be called as programs, too. $ podlibdir /usr/local/lib/perl5/5.6.0/pod $ mandirs /usr/local/man/man1 /usr/local/man/man3 $ pmanpath /usr/local/man ======================================================== What about apropos and whatis (that is, perlman -k or perlman -f)? Those are either easy or hard. If there's a whatis database in the perl mandirs, then you just call native man. If not, it's rough, and you really would need to run pretty slowly to do a manual apropos on the pods. I suppose that "perlman -k foo" could be "perlhelp -x NAME foo" or some such if you don't have a podful makewhatis to build and install a podtree-specific database. But if you did, then you should think hard about what else the database should hold. ---------------------------- Call sequences; all lines within each grouping are (essentially) equivalent perlman perlman --help perlman $PAGENAME $PAGENAME man -M `pmanpath` $PAGENAME || (pod2text `podpath $PAGENAME` | $PAGER) perlman -t $PAGENAME $PAGENAME -t pod2text `podpath $PAGENAME` perlman $PAGENAME $SEARCH $PAGENAME $SEARCH podgrep $SEARCH `podpath $PAGENAME` | pod2text | $PAGER perlman -l $PAGENAME $PAGENAME -l podpath $PAGENAME perlman -l $PAGENAME $SEARCH $PAGENAME -l $SEARCH podgrep -l $SEARCH `podpath $PAGENAME` perlman -O $PAGENAME $PAGENAME -O olpod `podpath $PAGENAME` perlman -O2 $PAGENAME $PAGENAME -O2 olpod -2 `podpath $PAGENAME` perlman --cat $PAGENAME $PAGENAME --cat cat `podpath $PAGENAME` perlman --catpod $PAGENAME $PAGENAME --catpod catpod `pmpath $PAGENAME || podpath $PAGENAME` perlman perlhelp $SEARCH perlhelp $SEARCH podgrep $SEARCH `podlibdir`/*.pod | pod2text | $PAGER perlman perlhelp $SEARCH perlhelp $SEARCH perlman --mode=$HOW $SEARCH eg: perlman -L $SEARCH perlman -P $SEARCH perlman -C $SEARCH ##### QUESTION: can we distinguish perlman $PAGENAME from perlman $SEARCH to mean perlhelp $SEARCH by looking for \W in argument? $METAPAGE $METAPAGE -l perlman -l $METAPAGE modman $SEARCH perlman -r $SEARCH `allpods` perlman --modules=all $SEARCH Don't forget $ENV{PERLDOC}
