1# Parse an L<> formatting code in POD text. 2# 3# This module implements parsing of the text of an L<> formatting code as 4# defined in perlpodspec. It should be suitable for any POD formatter. It 5# exports only one function, parselink(), which returns the five-item parse 6# defined in perlpodspec. 7# 8# SPDX-License-Identifier: GPL-1.0-or-later OR Artistic-1.0-Perl 9 10############################################################################## 11# Modules and declarations 12############################################################################## 13 14package Pod::ParseLink; 15 16use 5.006; 17use strict; 18use warnings; 19 20use vars qw(@EXPORT @ISA $VERSION); 21 22use Exporter; 23@ISA = qw(Exporter); 24@EXPORT = qw(parselink); 25 26$VERSION = '4.11'; 27 28############################################################################## 29# Implementation 30############################################################################## 31 32# Parse the name and section portion of a link into a name and section. 33sub _parse_section { 34 my ($link) = @_; 35 $link =~ s/^\s+//; 36 $link =~ s/\s+$//; 37 38 # If the whole link is enclosed in quotes, interpret it all as a section 39 # even if it contains a slash. 40 return (undef, $1) if ($link =~ /^"\s*(.*?)\s*"$/); 41 42 # Split into page and section on slash, and then clean up quoting in the 43 # section. If there is no section and the name contains spaces, also 44 # guess that it's an old section link. 45 my ($page, $section) = split (/\s*\/\s*/, $link, 2); 46 $section =~ s/^"\s*(.*?)\s*"$/$1/ if $section; 47 if ($page && $page =~ / / && !defined ($section)) { 48 $section = $page; 49 $page = undef; 50 } else { 51 $page = undef unless $page; 52 $section = undef unless $section; 53 } 54 return ($page, $section); 55} 56 57# Infer link text from the page and section. 58sub _infer_text { 59 my ($page, $section) = @_; 60 my $inferred; 61 if ($page && !$section) { 62 $inferred = $page; 63 } elsif (!$page && $section) { 64 $inferred = '"' . $section . '"'; 65 } elsif ($page && $section) { 66 $inferred = '"' . $section . '" in ' . $page; 67 } 68 return $inferred; 69} 70 71# Given the contents of an L<> formatting code, parse it into the link text, 72# the possibly inferred link text, the name or URL, the section, and the type 73# of link (pod, man, or url). 74sub parselink { 75 my ($link) = @_; 76 $link =~ s/\s+/ /g; 77 my $text; 78 if ($link =~ /\|/) { 79 ($text, $link) = split (/\|/, $link, 2); 80 } 81 if ($link =~ /\A\w+:[^:\s]\S*\Z/) { 82 my $inferred; 83 if (defined ($text) && length ($text) > 0) { 84 return ($text, $text, $link, undef, 'url'); 85 } else { 86 return ($text, $link, $link, undef, 'url'); 87 } 88 } else { 89 my ($name, $section) = _parse_section ($link); 90 my $inferred; 91 if (defined ($text) && length ($text) > 0) { 92 $inferred = $text; 93 } else { 94 $inferred = _infer_text ($name, $section); 95 } 96 my $type = ($name && $name =~ /\(\S*\)/) ? 'man' : 'pod'; 97 return ($text, $inferred, $name, $section, $type); 98 } 99} 100 101############################################################################## 102# Module return value and documentation 103############################################################################## 104 105# Ensure we evaluate to true. 1061; 107__END__ 108 109=for stopwords 110markup Allbery URL 111 112=head1 NAME 113 114Pod::ParseLink - Parse an LE<lt>E<gt> formatting code in POD text 115 116=head1 SYNOPSIS 117 118 use Pod::ParseLink; 119 my $link = get_link(); 120 my ($text, $inferred, $name, $section, $type) = parselink($link); 121 122=head1 DESCRIPTION 123 124This module only provides a single function, parselink(), which takes the 125text of an LE<lt>E<gt> formatting code and parses it. It returns the 126anchor text for the link (if any was given), the anchor text possibly 127inferred from the name and section, the name or URL, the section if any, 128and the type of link. The type will be one of C<url>, C<pod>, or C<man>, 129indicating a URL, a link to a POD page, or a link to a Unix manual page. 130 131Parsing is implemented per L<perlpodspec>. For backward compatibility, 132links where there is no section and name contains spaces, or links where the 133entirety of the link (except for the anchor text if given) is enclosed in 134double-quotes are interpreted as links to a section (LE<lt>/sectionE<gt>). 135 136The inferred anchor text is implemented per L<perlpodspec>: 137 138 L<name> => L<name|name> 139 L</section> => L<"section"|/section> 140 L<name/section> => L<"section" in name|name/section> 141 142The name may contain embedded EE<lt>E<gt> and ZE<lt>E<gt> formatting codes, 143and the section, anchor text, and inferred anchor text may contain any 144formatting codes. Any double quotes around the section are removed as part 145of the parsing, as is any leading or trailing whitespace. 146 147If the text of the LE<lt>E<gt> escape is entirely enclosed in double 148quotes, it's interpreted as a link to a section for backward 149compatibility. 150 151No attempt is made to resolve formatting codes. This must be done after 152calling parselink() (since EE<lt>E<gt> formatting codes can be used to 153escape characters that would otherwise be significant to the parser and 154resolving them before parsing would result in an incorrect parse of a 155formatting code like: 156 157 L<verticalE<verbar>barE<sol>slash> 158 159which should be interpreted as a link to the C<vertical|bar/slash> POD page 160and not as a link to the C<slash> section of the C<bar> POD page with an 161anchor text of C<vertical>. Note that not only the anchor text will need to 162have formatting codes expanded, but so will the target of the link (to deal 163with EE<lt>E<gt> and ZE<lt>E<gt> formatting codes), and special handling of 164the section may be necessary depending on whether the translator wants to 165consider markup in sections to be significant when resolving links. See 166L<perlpodspec> for more information. 167 168=head1 AUTHOR 169 170Russ Allbery <rra@cpan.org>. 171 172=head1 COPYRIGHT AND LICENSE 173 174Copyright 2001, 2008, 2009, 2014, 2018 Russ Allbery <rra@cpan.org> 175 176This program is free software; you may redistribute it and/or modify it 177under the same terms as Perl itself. 178 179=head1 SEE ALSO 180 181L<Pod::Parser> 182 183The current version of this module is always available from its web site at 184L<https://www.eyrie.org/~eagle/software/podlators/>. 185 186=cut 187 188# Local Variables: 189# copyright-at-end-flag: t 190# End: 191