fix encoding issues with link conversion
[ikiwiki] / IkiWiki / Plugin / link.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::link;
3
4 use warnings;
5 use strict;
6 use IkiWiki 2.00;
7
8 my $link_regexp;
9
10 sub import { #{{{
11         hook(type => "checkconfig", id => "link", call => \&checkconfig);
12         hook(type => "linkify", id => "link", call => \&linkify);
13         hook(type => "scan", id => "link", call => \&scan);
14         hook(type => "renamepage", id => "link", call => \&renamepage);
15 } # }}}
16
17 sub checkconfig () { #{{{
18         if ($config{prefix_directives}) {
19                 $link_regexp = qr{
20                         \[\[(?=[^!])            # beginning of link
21                         (?:
22                                 ([^\]\|]+)      # 1: link text
23                                 \|              # followed by '|'
24                         )?                      # optional
25                         
26                         ([^\n\r\]#]+)           # 2: page to link to
27                         (?:
28                                 \#              # '#', beginning of anchor
29                                 ([^\s\]]+)      # 3: anchor text
30                         )?                      # optional
31                         
32                         \]\]                    # end of link
33                 }x;
34         }
35         else {
36                 $link_regexp = qr{
37                         \[\[                    # beginning of link
38                         (?:
39                                 ([^\]\|\n\s]+)  # 1: link text
40                                 \|              # followed by '|'
41                         )?                      # optional
42
43                         ([^\s\]#]+)             # 2: page to link to
44                         (?:
45                                 \#              # '#', beginning of anchor
46                                 ([^\s\]]+)      # 3: anchor text
47                         )?                      # optional
48
49                         \]\]                    # end of link
50                 }x,
51         }
52 } #}}}
53
54 sub linkify (@) { #{{{
55         my %params=@_;
56         my $page=$params{page};
57         my $destpage=$params{destpage};
58
59         $params{content} =~ s{(\\?)$link_regexp}{
60                 defined $2
61                         ? ( $1 
62                                 ? "[[$2|$3".($4 ? "#$4" : "")."]]" 
63                                 : htmllink($page, $destpage, IkiWiki::linkpage($3),
64                                         anchor => $4, linktext => IkiWiki::pagetitle($2)))
65                         : ( $1 
66                                 ? "[[$3".($4 ? "#$4" : "")."]]"
67                                 : htmllink($page, $destpage, IkiWiki::linkpage($3),
68                                         anchor => $4))
69         }eg;
70         
71         return $params{content};
72 } #}}}
73
74 sub scan (@) { #{{{
75         my %params=@_;
76         my $page=$params{page};
77         my $content=$params{content};
78
79         while ($content =~ /(?<!\\)$link_regexp/g) {
80                 push @{$links{$page}}, IkiWiki::linkpage($2);
81         }
82 } # }}}
83
84 sub renamepage (@) { #{{{
85         my %params=@_;
86         my $page=$params{page};
87         my $old=$params{oldpage};
88         my $new=$params{newpage};
89
90         $params{content} =~ s{(?<!\\)$link_regexp}{
91                 my $linktext=$2;
92                 my $link=$linktext;
93                 if (bestlink($page, IkiWiki::linkpage($linktext)) eq $old) {
94                         $link=IkiWiki::pagetitle($new, 1);
95                         $link=~s/ /_/g;
96                         if ($linktext =~ m/.*\/*?[A-Z]/) {
97                                 # preserve leading cap of last component
98                                 my @bits=split("/", $link);
99                                 $link=join("/", @bits[0..$#bits-1], ucfirst($bits[$#bits]));
100                         }
101                         if (index($linktext, "/") == 0) {
102                                 # absolute link
103                                 $link="/$link";
104                         }
105                 }
106                 defined $1
107                         ? ( "[[$1|$link".($3 ? "#$3" : "")."]]" )
108                         : ( "[[$link".   ($3 ? "#$3" : "")."]]" )
109         }eg;
110
111         return $params{content};
112 } #}}}
113
114 1