2 package IkiWiki::Plugin::link;
10 my $email_regexp = qr/^(?:[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i;
11 my $url_regexp = qr/^(?:[^:]+:\/\/|mailto:).*/i;
14 hook(type => "getsetup", id => "link", call => \&getsetup);
15 hook(type => "checkconfig", id => "link", call => \&checkconfig);
16 hook(type => "linkify", id => "link", call => \&linkify);
17 hook(type => "scan", id => "link", call => \&scan);
18 hook(type => "renamepage", id => "link", call => \&renamepage);
31 if ($config{prefix_directives}) {
33 \[\[(?=[^!]) # beginning of link
35 ([^\]\|]+) # 1: link text
39 ([^\n\r\]#]+) # 2: page to link to
41 \# # '#', beginning of anchor
42 ([^\s\]]+) # 3: anchor text
50 \[\[ # beginning of link
52 ([^\]\|\n\s]+) # 1: link text
56 ([^\s\]#]+) # 2: page to link to
58 \# # '#', beginning of anchor
59 ([^\s\]]+) # 3: anchor text
67 sub is_externallink ($$) {
70 if ($url =~ /$email_regexp/) {
71 # url looks like an email address, so we assume it
72 # is supposed to be an external link if there is no
73 # page with that name.
75 return (! (bestlink($page, linkpage($url))))
77 return ($url =~ /$url_regexp/)
80 sub externallink ($;@) {
82 my $pagetitle = shift;
87 # use only the email address as title for mailto: urls
88 if ($pagetitle =~ /^mailto:.*/) {
89 $pagetitle =~ s/^mailto:([^?]+).*/$1/;
93 # handle email-addresses (without mailto:):
94 if ($url =~ /$email_regexp/) {
95 $url = "mailto:" . $url;
98 return "<a href=\"$url\">$pagetitle</a>";
103 my $page=$params{page};
104 my $destpage=$params{destpage};
106 $params{content} =~ s{(\\?)$link_regexp}{
109 ? "[[$2|$3".($4 ? "#$4" : "")."]]"
110 : is_externallink($page, $3 . ($4 ? "#$4" : ""))
111 ? externallink("$3" . ($4 ? "#$4" : ""), $2)
112 : htmllink($page, $destpage, linkpage($3),
113 anchor => $4, linktext => pagetitle($2)))
115 ? "[[$3".($4 ? "#$4" : "")."]]"
116 : is_externallink($page, $3 . ($4 ? "#$4" : ""))
117 ? externallink("$3" . ($4 ? "#$4" : ""))
118 : htmllink($page, $destpage, linkpage($3),
122 return $params{content};
127 my $page=$params{page};
128 my $content=$params{content};
130 while ($content =~ /(?<!\\)$link_regexp/g) {
131 if (! is_externallink($page, $2 . ($3 ? "#$3" : ""))) {
132 add_link($page, linkpage($2));
139 my $page=$params{page};
140 my $old=$params{oldpage};
141 my $new=$params{newpage};
143 $params{content} =~ s{(?<!\\)$link_regexp}{
144 if (! is_externallink($page, $2 . ($3 ? "#$3" : ""))) {
147 if (bestlink($page, linkpage($linktext)) eq $old) {
148 $link=pagetitle($new, 1);
150 if ($linktext =~ m/.*\/*?[A-Z]/) {
151 # preserve leading cap of last component
152 my @bits=split("/", $link);
153 $link=join("/", @bits[0..$#bits-1], ucfirst($bits[$#bits]));
155 if (index($linktext, "/") == 0) {
161 ? ( "[[$1|$link".($3 ? "#$3" : "")."]]" )
162 : ( "[[$link". ($3 ? "#$3" : "")."]]" )
166 return $params{content};