source: branches/Release01x01/InterwikiPlugin/lib/Foswiki/Plugins/InterwikiPlugin.pm @ 10301

Revision 10301, 5.3 KB checked in by AndrewJones, 2 years ago (diff)

Item10151: Fix inter-wiki's with paranthesis

  • Property svn:keywords set to Revision Date
Line 
1# See bottom of file for license and copyright information
2
3=begin TML
4
5---+ package Foswiki::Plugins::InterwikiPlugin
6
7Recognises and processes special links to other sites defined
8using "inter-site syntax".
9
10The recognized syntax is:
11<pre>
12       InterSiteName:TopicName
13</pre>
14
15Sites must start with upper case and must be preceded by white
16space, '-', '*' or '(', or be part of the link expression
17in a [[link]] or [[link][text]] expression.
18
19=cut
20
21package Foswiki::Plugins::InterwikiPlugin;
22
23use strict;
24use warnings;
25
26use Foswiki::Func    ();    # The plugins API
27use Foswiki::Plugins ();    # For the API version
28
29our $VERSION           = '$Rev$';
30our $RELEASE           = '13 Dec 2010';
31our $NO_PREFS_IN_TOPIC = 1;
32our $SHORTDESCRIPTION =
33'Link !ExternalSite:Page text to external sites based on aliases defined in a rules topic';
34
35my $interLinkFormat;
36my $sitePattern;
37my $pagePattern;
38my %interSiteTable;
39
40BEGIN {
41
42    # 'Use locale' for internationalisation of Perl sorting and searching -
43    if ( $Foswiki::cfg{UseLocale} ) {
44        require locale;
45        import locale();
46    }
47}
48
49# Read preferences and get all InterWiki Site->URL mappings
50sub initPlugin {
51    my ( $topic, $web, $user, $installWeb ) = @_;
52
53    # Regexes for the Site:page format InterWiki reference
54    my $man = $Foswiki::regex{mixedAlphaNum};
55    my $ua  = $Foswiki::regex{upperAlpha};
56    %interSiteTable = ();
57    $sitePattern    = "([$ua][$man]+)";
58    $pagePattern =
59      "([${man}_\/][$man" . '"\'\.\/\+\_\,\&\;\:\=\!\?\%\#\@\-\(\)]*?)';
60
61    # Get plugin preferences from InterwikiPlugin topic
62    $interLinkFormat =
63      Foswiki::Func::getPreferencesValue('INTERWIKIPLUGIN_INTERLINKFORMAT')
64      || '<a class="interwikiLink" href="$url" title="$tooltip"><noautolink>$label</noautolink></a>';
65
66    my $rulesTopicPref =
67      Foswiki::Func::getPreferencesValue('INTERWIKIPLUGIN_RULESTOPIC')
68      || 'InterWikis';
69    my @rulesTopics = split( ',', $rulesTopicPref );
70    foreach my $topic (@rulesTopics) {
71        $topic = _trimWhitespace($topic);
72
73        my ( $interWeb, $interTopic ) =
74          Foswiki::Func::normalizeWebTopicName( $installWeb, $topic );
75
76        if (
77            !Foswiki::Func::checkAccessPermission(
78                'VIEW', $user, undef, $interTopic, $interWeb
79            )
80          )
81        {
82            Foswiki::Func::writeWarning(
83"InterwikiPlugin: user '$user' did not have permission to read the rules topic at '$interWeb.$interTopic'"
84            );
85            return 1;
86        }
87        my $text =
88          Foswiki::Func::readTopicText( $interWeb, $interTopic, undef, 1 );
89
90        # '| alias | URL | ...' table and extract into 'alias', "URL" list
91        $text =~
92s/^\|\s*$sitePattern\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|.*$/_map($1,$2,$3)/meg;
93    }
94
95    $sitePattern = "(" . join( "|", keys %interSiteTable ) . ")";
96    return 1;
97}
98
99sub _map {
100    my ( $site, $url, $tooltip ) = @_;
101    if ($site) {
102        $interSiteTable{$site}{url}     = $url     || '';
103        $interSiteTable{$site}{tooltip} = $tooltip || '';
104    }
105    return '';
106}
107
108sub preRenderingHandler {
109
110    # ref in [[ref]] or [[ref][
111    $_[0] =~
112s/(\[\[)$sitePattern:$pagePattern(\]\]|\]\[[^\]]+\]\])/_link($1,$2,$3,$4)/ge;
113
114    # ref in text
115    $_[0] =~
116s/(^|[\s\-\*\(])$sitePattern:$pagePattern(?=[\s\.\,\;\:\!\?\|]*(\s|$))/_link($1,$2,$3)/ge;
117
118    return;
119}
120
121sub _link {
122    my ( $prefix, $site, $page, $postfix ) = @_;
123
124    $prefix  ||= '';
125    $site    ||= '';
126    $page    ||= '';
127    $postfix ||= '';
128
129    my $text = $prefix;
130    if ( defined( $interSiteTable{$site} ) ) {
131        my $tooltip = $interSiteTable{$site}{tooltip};
132        my $url     = $interSiteTable{$site}{url};
133        $url .= $page unless ( $url =~ /\$page/ );
134        my $label = '$site:$page';
135
136        if ($postfix) {
137
138            # [[...]] or [[...][...]] interwiki link
139            $text = '';
140            if ( $postfix =~ /^\]\[([^\]]+)/ ) {
141                $label = $1;
142            }
143        }
144
145        my $format = $interLinkFormat;
146        $format =~ s/\$url/$url/g;
147        $format =~ s/\$tooltip/$tooltip/g;
148        $format =~ s/\$label/$label/g;
149        $format =~ s/\$site/$site/g;
150        $format =~ s/\$page/$page/g;
151        $text .= $format;
152    }
153    else {
154        $text .= "$site\:$page$postfix";
155    }
156    return $text;
157}
158
159sub _trimWhitespace {
160    my $string = shift;
161    $string =~ s/^\s+//;
162    $string =~ s/\s+$//;
163    return $string;
164}
165
1661;
167__END__
168Foswiki - The Free and Open Source Wiki, http://foswiki.org/
169
170Copyright (C) 2008-2010 Foswiki Contributors. Foswiki Contributors
171are listed in the AUTHORS file in the root of this distribution.
172NOTE: Please extend that file, not this notice.
173
174Additional copyrights apply to some or all of the code in this
175file as follows:
176Copyright (C) 2000-2003 Andrea Sterbini, a.sterbini@flashnet.it
177Copyright (C) 2001-2007 Peter Thoeny, peter@thoeny.com
178
179This program is free software; you can redistribute it and/or
180modify it under the terms of the GNU General Public License
181as published by the Free Software Foundation; either version 2
182of the License, or (at your option) any later version. For
183more details read LICENSE in the root of this distribution.
184
185This program is distributed in the hope that it will be useful,
186but WITHOUT ANY WARRANTY; without even the implied warranty of
187MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
188
189As per the GPL, removal of this notice is prohibited.
Note: See TracBrowser for help on using the repository browser.