#!perl -w
# Copyright 2010, 2011, 2012, 2013 Kevin Ryde
# This file is part of PodLinkCheck.
# PodLinkCheck is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3, or (at your option) any later
# version.
#
# PodLinkCheck is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with PodLinkCheck. If not, see <http://www.gnu.org/licenses/>.
use 5.006;
use strict;
use warnings;
use App::PodLinkCheck;
use vars '$VERSION';
$VERSION = 12;
my $plc = App::PodLinkCheck->new;
exit $plc->command_line;
__END__
=for stopwords podlinkcheck Ryde subdirs cpan Manpage manpage whitespace eg mis-interpreted SQLite
=head1 NAME
podlinkcheck -- check Perl pod LE<lt>E<gt> link references
=head1 SYNOPSIS
podlinkcheck [--options] file-or-dir...
=head1 DESCRIPTION
PodLinkCheck parses Perl POD from a script, module or documentation and
checks that C<LE<lt>E<gt>> links within it refer to a known program, module,
or man page.
=for ProhibitVerbatimMarkup allow next
L<foo> check module, pod or program "foo"
L<foo/section> and check section within the pod
L<bar(1)> check man page "bar(1)"
The command line is either individual files or whole directories. For a
directory all the F<.pl>, F<.pm> and F<.pod> files under it are checked. So
for example to churn through all installed add-on modules,
podlinkcheck /usr/share/perl5
Bad links are usually typos in the target page name or section name, and
sometimes C<LE<lt>display|targetE<gt>> parts the wrong way around.
Occasionally there may be an C<LE<lt>fooE<gt>> used where just markup
C<CE<lt>E<gt>> or C<IE<lt>E<gt>> was intended.
=head2 Checks
External links are checked by seeking the target F<.pm> module or F<.pod>
documentation in the C<@INC> path (per L<Pod::Find>), or seeking a script
(no file extension) in the usual executable C<PATH>. A section name in a
link is checked by parsing the POD in the target file.
Module existence is also checked in the CPAN indexes with C<CPAN::SQLite>,
C<CPAN> or C<CPANPLUS>. Nothing is downloaded, just current data consulted.
This covers cross-references to things not currently installed. A warning
is given if a section name in a link goes unchecked because it's only on
CPAN, not available locally.
Manpage links are checked by asking the C<man> program if it recognises the
name, including any number part like C<chmod(2)>. A manpage can also
satisfy what otherwise appears to be a POD link with no sub-section, since
there's often some confusion between the two.
=head2 Internal Links
Internal links are sometimes written
L<SYNOPSIS> # may be ambiguous
but the Perl 5.10 C<perlpodspec> advice is to avoid ambiguity between an
external module and a one-word internal section by writing a section with /
or quotes,
=for ProhibitVerbatimMarkup allow next 2
See L</SYNOPSIS> above. # good
See L<"SYNOPSIS"> above. # good
C<podlinkcheck> warns about C<LE<lt>SYNOPSISE<gt>> section links. But not
if it's both an valid external module and internal section -- because it's
not uncommon to have a module name as a heading or item and an
C<LE<lt>E<gt>> link still meaning the external one.
=head2 Section Name Matching
An C<LE<lt>E<gt>> section name can use just the first word of an item or
heading. This is how C<Pod::Checker> behaves and it's particularly good for
C<perlfunc> cross references where just the function name can be given
without the full argument list of the C<=item>. Eg.
=for ProhibitVerbatimMarkup allow next
L<perlfunc/split>
The first word is everything up to the first whitespace. This doesn't come
out very well on a target like C<=item somefun( ARG )>, but it's how
C<Pod::Checker> 1.45 behaves. If the targets are your own then you might
make the first word or full item something sensible to appear in an
C<LE<lt>E<gt>>.
If a target section is not found then C<podlinkcheck> will try to suggest
something close, eg. differing only in punctuation or upper/lower case.
Some of the POD translators may ignore upper/lower case, but it's good to
write an C<LE<lt>E<gt>> the same as the actual target.
foo.pl:130:31: no section "constructor" in "CHI"
(file /usr/share/perl5/CHI.pm)
perhaps it should be "CONSTRUCTOR"
For reference, numbered C<=item> section names go in an C<LE<lt>E<gt>> without
the number. This is a good thing since the numbering might change. If
C<podlinkcheck> suggests a number in a target then it may be a mistake in
the target document. A numbered item should have the number alone on the
C<=item> and the section name as the following paragraph.
=item 1. # good
The First Thing # the section name
Paragraph about this thing.
=item 2. The Second Thing # bad
Paragraph about this next thing.
The second item "2. The Second Thing" is not a numbered item for POD
purposes, but rather text that happens to start with a number. Of course
sometimes that's what you want, eg.
=item 64 Bit Support
C<podlinkcheck> uses C<Pod::Simple> for parsing and so follows its
interpretation of the various hairy C<LE<lt>E<gt>> link forms. If an
C<LE<lt>E<gt>> appears to be mis-interpreted you might rewrite it, perhaps
with escapes like EE<lt>solE<gt>, for the benefit of all translators which
use C<Pod::Simple>, which in Perl 5.10 includes the basic C<pod2man>.
=head2 Other Ways to Do It
C<podchecker> (the C<Pod::Checker> module) checks internal links, but it
doesn't check external links.
=head1 BUGS
The line:column number reported for an offending C<LE<lt>E<gt>> is sometimes a
bit off due to limited information recorded by C<Pod::Simple> during its
parse.
C<CPAN::SQLite> is checked first because it's fast and compact, but if a
target is not found there then the C<CPAN> and C<CPANPLUS> caches are loaded
and checked. This may use a lot of memory for a non-existent target, but
it's also possible they're more up-to-date than the SQLite.
The code consulting C<CPAN.pm> may need a tolerably new version of that
module, maybe 1.61 circa Perl 5.8.0. On earlier versions the index is not
used.
=head1 ENVIRONMENT VARIABLES
=over 4
=item C<PATH>
The search path for installed scripts.
=item C<HOME>
Used by the various C<CPAN> modules for the C<~/.cpan> directory.
=item C<PERL5LIB>
The usual extra Perl module directories (see L<perlrun/ENVIRONMENT>), which
is also where link targets are sought.
=back
=head1 BUGS
C<Pod::Simple> prior to version 3.24 didn't allow "." dots in man-page
names, resulting in for example L<login.conf(5)> being treated as a Perl
module name not a man page name. If you have such links then C<Pod::Simple>
version 3.24 or up is recommended.
=head1 SEE ALSO
L<podchecker>, L<podlint>
L<Pod::Simple>, L<Pod::Find>, L<Pod::Checker>, L<CPAN>, L<CPAN::SQLite>,
L<CPANPLUS>
=head1 HOME PAGE
http://user42.tuxfamily.org/podlinkcheck/index.html
=head1 LICENSE
Copyright 2010, 2011, 2012, 2013 Kevin Ryde
PodLinkCheck is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
PodLinkCheck is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
PodLinkCheck. If not, see <http://www.gnu.org/licenses/>.
=cut