-
- while ($paragraph =~ m{ \b See \s+ ( ( [^L] ) <
- ( [^<]*? ) # The not-< excludes nested C<L<...
- > ) }ixg) {
- my $construct = $1;
- my $type = $2;
- my $interior = $3;
- if ($interior !~ /$non_pods/
- && $construct !~ /$C_path_re/g) {
- $self->poderror({ -line => $line, -file => $file,
- -msg => $see_not_linked,
- parameter => $construct
- });
+ while ($paragraph =~ m{
+ ( (?: \w+ \s+ )* ) # The phrase before, if any
+ \b [Ss]ee \s+
+ ( ( [^L] )
+ <
+ ( [^<]*? ) # The not < excludes nested C<L<...
+ >
+ )
+ ( \s+ (?: under | in ) \s+ L< )?
+ }xg) {
+ my $prefix = $1 // "";
+ my $construct = $2; # The whole thing, like C<...>
+ my $type = $3;
+ my $interior = $4;
+ my $trailing = $5; # After the whole thing ending in "L<"
+
+ # If the full phrase is something like, "you might see C<", or
+ # similar, it really isn't a reference to a link. The ones I saw
+ # all had the word "you" in them; and the "you" wasn't the
+ # beginning of a sentence.
+ if ($prefix !~ / \b you \b /x) {
+
+ # Now, find what the module or man page name within the
+ # construct would be if it actually has L<> syntax. If it
+ # doesn't have that syntax, will set the module to the entire
+ # interior.
+ $interior =~ m/ ^
+ (?: [^|]+ \| )? # Optional arbitrary text ending
+ # in "|"
+ ( .+? ) # module, etc. name
+ (?: \/ .+ )? # target within module
+ $
+ /xs;
+ my $module = $1;
+ if (! defined $trailing # not referring to something in another
+ # section
+ && $interior !~ /$non_pods/
+
+ # C<> that look like files have their own message below, so
+ # exclude them
+ && $construct !~ /$C_path_re/g
+
+ # There can't be spaces (I think) in module names or man
+ # pages
+ && $module !~ / \s /x
+
+ # F<> that end in eg \.pl are almost certainly ok, as are
+ # those that look like a path with multiple "/" chars
+ && ($type ne "F"
+ || (! -e $interior
+ && $interior !~ /\.\w+$/
+ && $interior !~ /\/.+\//)
+ )
+ ) {
+ $self->poderror({ -line => $line, -file => $file,
+ -msg => $see_not_linked,
+ parameter => $construct
+ });
+ }