>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,perlfaq9 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}

Reply via email to