Enhance the link plugin to handle external links.

The following ways to create a link are supported now:
[[url]]
[[text|url]]
url can be one of the following:
- an internal wikilink: will be handled as before
- any other kind of URL, including mailto: proper links will be created:
  <a href="url">url</a>
  <a href="url">text</a>
- an email address:
  <a href="mailto:url">url</a>
  <a href="mailto:url">text</a>
master
Bernd Zeimetz 2010-06-14 01:18:33 +02:00
parent 99a4096397
commit dd3274ce73
2 changed files with 68 additions and 23 deletions

View File

@ -7,6 +7,9 @@ use IkiWiki 3.00;
my $link_regexp; my $link_regexp;
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;
my $url_regexp = qr/^(?:[^:]+:\/\/|mailto:).*/i;
sub import { sub import {
hook(type => "getsetup", id => "link", call => \&getsetup); hook(type => "getsetup", id => "link", call => \&getsetup);
hook(type => "checkconfig", id => "link", call => \&checkconfig); hook(type => "checkconfig", id => "link", call => \&checkconfig);
@ -57,10 +60,44 @@ sub checkconfig () {
)? # optional )? # optional
\]\] # end of link \]\] # end of link
}x, }x;
} }
} }
sub is_externallink ($$) {
my $page = shift;
my $url = shift;
if ($url =~ /$email_regexp/) {
# url looks like an email address, so we assume it
# is supposed to be an external link if there is no
# page with that name.
$url =~ s/#.*//;
return (! (bestlink($page, linkpage($url))))
}
return ($url =~ /$url_regexp/)
}
sub externallink ($;@) {
my $url = shift;
my $pagetitle = shift;
# build pagetitle
if (!($pagetitle)) {
$pagetitle = $url;
# use only the email address as title for mailto: urls
if ($pagetitle =~ /^mailto:.*/) {
$pagetitle =~ s/^mailto:([^?]+).*/$1/;
}
}
# handle email-addresses (without mailto:):
if ($url =~ /$email_regexp/) {
$url = "mailto:" . $url;
}
return "<a href=\"$url\">$pagetitle</a>";
}
sub linkify (@) { sub linkify (@) {
my %params=@_; my %params=@_;
my $page=$params{page}; my $page=$params{page};
@ -70,12 +107,16 @@ sub linkify (@) {
defined $2 defined $2
? ( $1 ? ( $1
? "[[$2|$3".($4 ? "#$4" : "")."]]" ? "[[$2|$3".($4 ? "#$4" : "")."]]"
: htmllink($page, $destpage, linkpage($3), : is_externallink($page, $3 . ($4 ? "#$4" : ""))
anchor => $4, linktext => pagetitle($2))) ? externallink("$3" . ($4 ? "#$4" : ""), $2)
: htmllink($page, $destpage, linkpage($3),
anchor => $4, linktext => pagetitle($2)))
: ( $1 : ( $1
? "[[$3".($4 ? "#$4" : "")."]]" ? "[[$3".($4 ? "#$4" : "")."]]"
: htmllink($page, $destpage, linkpage($3), : is_externallink($page, $3 . ($4 ? "#$4" : ""))
anchor => $4)) ? externallink("$3" . ($4 ? "#$4" : ""))
: htmllink($page, $destpage, linkpage($3),
anchor => $4))
}eg; }eg;
return $params{content}; return $params{content};
@ -87,7 +128,9 @@ sub scan (@) {
my $content=$params{content}; my $content=$params{content};
while ($content =~ /(?<!\\)$link_regexp/g) { while ($content =~ /(?<!\\)$link_regexp/g) {
add_link($page, linkpage($2)); if (! is_externallink($page, $2 . ($3 ? "#$3" : ""))) {
add_link($page, linkpage($2));
}
} }
} }
@ -98,24 +141,26 @@ sub renamepage (@) {
my $new=$params{newpage}; my $new=$params{newpage};
$params{content} =~ s{(?<!\\)$link_regexp}{ $params{content} =~ s{(?<!\\)$link_regexp}{
my $linktext=$2; if (! is_externallink($page, $2 . ($3 ? "#$3" : ""))) {
my $link=$linktext; my $linktext=$2;
if (bestlink($page, linkpage($linktext)) eq $old) { my $link=$linktext;
$link=pagetitle($new, 1); if (bestlink($page, linkpage($linktext)) eq $old) {
$link=~s/ /_/g; $link=pagetitle($new, 1);
if ($linktext =~ m/.*\/*?[A-Z]/) { $link=~s/ /_/g;
# preserve leading cap of last component if ($linktext =~ m/.*\/*?[A-Z]/) {
my @bits=split("/", $link); # preserve leading cap of last component
$link=join("/", @bits[0..$#bits-1], ucfirst($bits[$#bits])); my @bits=split("/", $link);
} $link=join("/", @bits[0..$#bits-1], ucfirst($bits[$#bits]));
if (index($linktext, "/") == 0) { }
# absolute link if (index($linktext, "/") == 0) {
$link="/$link"; # absolute link
$link="/$link";
}
} }
defined $1
? ( "[[$1|$link".($3 ? "#$3" : "")."]]" )
: ( "[[$link". ($3 ? "#$3" : "")."]]" )
} }
defined $1
? ( "[[$1|$link".($3 ? "#$3" : "")."]]" )
: ( "[[$link". ($3 ? "#$3" : "")."]]" )
}eg; }eg;
return $params{content}; return $params{content};

View File

@ -1,4 +1,4 @@
[[!template id=plugin name=link core=1 author="[[Joey]]"]] [[!template id=plugin name=link core=1 author="[[Joey]]"]]
[[!tag type/link]] [[!tag type/link]]
This plugin implements standard [[WikiLinks|ikiwiki/wikilink]]. This plugin implements standard [[WikiLinks|ikiwiki/wikilink]] and links to [[external pages|http://www.debian.org]].