6 use File::Spec::Functions qw(rel2abs abs2rel splitdir);
8 # external stuff we refer to
10 qw(perl Affix::Infix2Postfix Parse::RecDescent GD Image::Magick Graphics::Magick CGI Image::ExifTool XSLoader DynaLoader Prima::Image IPA PDL);
12 my @pod; # files with pod
14 my $base = rel2abs("blib/lib");
19 and push @files, $File::Find::name;
22 my %targets = map { $_ => {} } @known;
25 for my $file (@files) {
26 my $parser = PodPreparse->new;
28 my $link = abs2rel($file, $base);
29 $link =~ s/\.(pod|pm|pl|PL)$//;
30 $link = join("::", splitdir($link));
32 $parser->{'targets'} = \%targets;
33 $parser->{'link'} = $link;
34 $parser->{'file'} = $file;
35 $parser->{item_in} = \%item_in;
36 $parser->parse_from_file($file);
37 if ($targets{$link}) {
42 plan tests => scalar(@pod);
45 my $parser = PodLinkCheck->new;
46 $parser->{"targets"} = \%targets;
47 my $relfile = abs2rel($file, $base);
48 (my $link = $relfile) =~ s/\.(pod|pm|pl|PL)$//;
49 $link = join("::", splitdir($link));
50 $parser->{"file"} = $relfile;
51 $parser->{"link"} = $link;
53 $parser->{"errors"} = \@errors;
54 $parser->{item_in} = \%item_in;
55 $parser->parse_from_file($file);
57 unless (ok(!@errors, "check links in $relfile")) {
58 print STDERR "# $_\n" for @errors;
63 BEGIN { our @ISA = qw(Pod::Parser); }
66 my ($self, $cmd, $para) = @_;
68 my $targets = $self->{"targets"};
69 my $link = $self->{"link"};
70 $targets->{$link} ||= {};
72 if ($cmd =~ /^(head[1-5]|item)/) {
75 $targets->{$link}{$para} = 1;
76 push @{$self->{item_in}{$para}}, $link;
85 BEGIN { our @ISA = qw(Pod::Parser); }
92 my ($self, $para, $line_num) = @_;
96 { -expand_seq => "sequence" },
102 my ($self, $seq) = @_;
104 if ($seq->cmd_name eq "L") {
105 my $raw = $seq->raw_text;
106 my $base_link = $seq->parse_tree->raw_text;
107 $base_link =~ /^(https?|ftp|mailto):/
109 (my $link = $base_link) =~ s/.*\|//;
110 my ($pod, $part) = split m(/), $link, 2;
111 $pod ||= $self->{link};
116 my $targets = $self->{targets};
117 my $errors = $self->{errors};
118 (undef, my $line) = $seq->file_line;
120 if (!$targets->{$pod}) {
121 push @$errors, "$line: No $pod found ($raw)";
123 elsif ($part && !$targets{$pod}{$part}) {
124 push @$errors, "$line: No item/section '$part' found in $pod ($raw)";
125 if ($self->{item_in}{$part}) {
126 push @$errors, " $part can be found in:";
127 push @$errors, map " $_", @{$self->{item_in}{$part}};
132 return $seq->raw_text;