~kosova/+junk/tuxfamily-twiki

« back to all changes in this revision

Viewing changes to foswiki/lib/Foswiki/Plugins/RenderListPlugin.pm

  • Committer: James Michael DuPont
  • Date: 2009-07-18 19:58:49 UTC
  • Revision ID: jamesmikedupont@gmail.com-20090718195849-vgbmaht2ys791uo2
added foswiki

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Plugin for Foswiki - The Free and Open Source Wiki, http://foswiki.org/
 
2
#
 
3
# Copyright (C) 2001-2007 Peter Thoeny, peter@thoeny.org
 
4
# Copyright (C) 2008 Foswiki Contributors
 
5
#
 
6
# This program is free software; you can redistribute it and/or
 
7
# modify it under the terms of the GNU General Public License
 
8
# as published by the Free Software Foundation; either version 2
 
9
# of the License, or (at your option) any later version. For
 
10
# more details read LICENSE in the root of this distribution.
 
11
#
 
12
# This program is distributed in the hope that it will be useful,
 
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 
15
#
 
16
# As per the GPL, removal of this notice is prohibited.
 
17
# =========================
 
18
 
 
19
 
 
20
# =========================
 
21
package Foswiki::Plugins::RenderListPlugin;    # change the package name and $pluginName!!!
 
22
 
 
23
# =========================
 
24
use vars qw(
 
25
        $web $topic $user $installWeb $VERSION $RELEASE $pluginName
 
26
        $debug $pubUrl $attachUrl
 
27
    );
 
28
 
 
29
$VERSION = '$Rev: 3048 (2009-03-12) $';
 
30
$RELEASE = '2.1';
 
31
$pluginName = 'RenderListPlugin';  # Name of this Plugin
 
32
 
 
33
# =========================
 
34
sub initPlugin
 
35
{
 
36
    ( $topic, $web, $user, $installWeb ) = @_;
 
37
 
 
38
    # check for Plugins.pm versions
 
39
    if( $Foswiki::Plugins::VERSION < 1 ) {
 
40
        Foswiki::Func::writeWarning( "Version mismatch between $pluginName and Plugins.pm" );
 
41
        return 0;
 
42
    }
 
43
 
 
44
    # Get plugin debug flag
 
45
    $debug = Foswiki::Func::getPreferencesFlag( "\U$pluginName\E_DEBUG" );
 
46
 
 
47
    # one time initialization
 
48
    $pubUrl = Foswiki::Func::getUrlHost() . Foswiki::Func::getPubUrlPath();
 
49
    $attachUrl = "$pubUrl/$installWeb/$pluginName";
 
50
 
 
51
    # Plugin correctly initialized
 
52
    Foswiki::Func::writeDebug( "- Foswiki::Plugins::${pluginName}::initPlugin( $web.$topic ) is OK" ) if $debug;
 
53
    return 1;
 
54
}
 
55
 
 
56
# =========================
 
57
sub startRenderingHandler
 
58
{
 
59
### my ( $text, $web ) = @_;   # do not uncomment, use $_[0], $_[1] instead
 
60
 
 
61
    Foswiki::Func::writeDebug( "- ${pluginName}::startRenderingHandler( $_[1] )" ) if $debug;
 
62
 
 
63
    # This handler is called by getRenderedVersion just before the line loop
 
64
 
 
65
    # Render here, not in commonTagsHandler so that lists produced by
 
66
    # Plugins, TOC and SEARCH can be rendered
 
67
    if ($_[0] =~/%RENDERLIST/o ) {
 
68
        unless ($_[0] =~ s/%RENDERLIST{(.*?)}%(([\n\r]+[^ ]{3}[^\n\r]*)*?)(([\n\r]+ {3}[^\n\r]*)+)/&handleRenderList($1, $2, $4)/ges ) {
 
69
            # Cairo compatibility fallback
 
70
            $_[0] =~ s/%RENDERLIST{(.*?)}%(([\n\r]+[^\t]{1}[^\n\r]*)*?)(([\n\r]+\t[^\n\r]*)+)/&handleRenderList($1, $2, $4)/ges;
 
71
        }
 
72
    }
 
73
}
 
74
 
 
75
# =========================
 
76
sub handleRenderList
 
77
{
 
78
    my ( $theAttr, $thePre, $theList ) = @_;
 
79
 
 
80
    $theAttr =~ s/ {3}/\t/gs;
 
81
    $thePre =~ s/ {3}/\t/gs;
 
82
    $theList =~ s/ {3}/\t/gs;
 
83
 
 
84
    my $focus = &Foswiki::Func::extractNameValuePair( $theAttr, "focus" );
 
85
    my $depth = &Foswiki::Func::extractNameValuePair( $theAttr, "depth" );
 
86
    my $theme = &Foswiki::Func::extractNameValuePair( $theAttr, "theme" ) ||
 
87
                &Foswiki::Func::extractNameValuePair( $theAttr );
 
88
    $theme = "RENDERLISTPLUGIN_" . uc( $theme ) . "_THEME";
 
89
    $theme = &Foswiki::Func::getPreferencesValue( $theme ) || "unrecognized theme type";
 
90
    my ( $type, $params ) = split( /, */, $theme, 2 );
 
91
    $type = lc( $type );
 
92
 
 
93
    if( $type eq "tree" || $type eq "icon" ) {
 
94
        return $thePre . renderIconList( $type, $params, $focus, $depth, $theList );
 
95
    } else {
 
96
        return "$thePre$theList";
 
97
    }
 
98
}
 
99
 
 
100
# =========================
 
101
sub renderIconList
 
102
{
 
103
    my ( $theType, $theParams, $theFocus, $theDepth, $theText ) = @_;
 
104
 
 
105
    $theText =~ s/^[\n\r]*//os;
 
106
    my @tree = ();
 
107
    my $level = 0;
 
108
    my $type = "";
 
109
    my $text = "";
 
110
    my $focusIndex = -1;
 
111
    foreach( split ( /[\n\r]+/, $theText ) ) {
 
112
        m/^(\t+)(.) *(.*)/;
 
113
        $level = length( $1 );
 
114
        $type = $2;
 
115
        $text = $3;
 
116
        if( ( $theFocus ) && ( $focusIndex < 0 ) && ( $text =~ /$theFocus/ ) ) {
 
117
            $focusIndex = scalar( @tree );
 
118
        }
 
119
        push( @tree, { level => $level, type => $type, text => $text } );
 
120
    }
 
121
 
 
122
    # reduce tree to relatives around focus
 
123
    if( $focusIndex >= 0 ) {
 
124
        # splice tree into before, current node and after parts
 
125
        my @after = splice( @tree, $focusIndex + 1 );
 
126
        my $nref = pop( @tree );
 
127
 
 
128
        # highlight node with focus and remove links
 
129
        $text = $nref->{'text'};
 
130
        $text =~ s/^([^\-]*)\[\[.*?\]\[(.*?)\]\]/$1$2/o;  # remove [[...][...]] link
 
131
        $text =~ s/^([^\-]*)\[\[(.*?)\]\]/$1$2/o;         # remove [[...]] link
 
132
        $text = "<b> $text </b>"; # bold focus text
 
133
        $nref->{'text'} = $text;
 
134
 
 
135
        # remove uncles and siblings below current node
 
136
        $level = $nref->{'level'};
 
137
        for( my $i = 0; $i < scalar( @after ); $i++ ) {
 
138
            if( ( $after[$i]->{'level'} < $level )
 
139
             || ( $after[$i]->{'level'} <= $level &&  $after[$i]->{'type'} ne " " ) ) {
 
140
                splice( @after, $i );
 
141
                last;
 
142
            }
 
143
        }
 
144
 
 
145
        # remove uncles and siblings above current node
 
146
        my @before = ();
 
147
        for( my $i = scalar( @tree ) - 1; $i >= 0; $i-- ) {
 
148
            if( $tree[$i]->{'level'} < $level ) {
 
149
                push( @before, $tree[$i] );
 
150
                $level = $tree[$i]->{'level'};
 
151
            }
 
152
        }
 
153
        @tree = reverse( @before );
 
154
        $focusIndex = scalar( @tree );
 
155
        push( @tree, $nref );
 
156
        push( @tree, @after );
 
157
    }
 
158
 
 
159
    # limit depth of tree
 
160
    my $depth = $theDepth;
 
161
    unless( $depth =~ s/.*?([0-9]+).*/$1/o ) {
 
162
        $depth = 0;
 
163
    }
 
164
    if( $theFocus ) {
 
165
        if( $theDepth eq "" ) {
 
166
            $depth = $focusIndex + 3;
 
167
        } else {
 
168
            $depth += $focusIndex + 1;
 
169
        }
 
170
    }
 
171
    if( $depth > 0 ) {
 
172
        my @tmp = ();
 
173
        foreach my $ref ( @tree ) {
 
174
            push( @tmp, $ref ) if( $ref->{'level'} <= $depth );
 
175
        }
 
176
        @tree = @tmp;
 
177
    }
 
178
 
 
179
    $theParams =~ s/%PUBURL%/$pubUrl/go;
 
180
    $theParams =~ s/%ATTACHURL%/$attachUrl/go;
 
181
    $theParams =~ s/%WEB%/$installWeb/go;
 
182
    $theParams =~ s/%MAINWEB%/Foswiki::Func::getMainWebname()/geo;
 
183
    $theParams =~ s/%TWIKIWEB%/$Foswiki::cfg{SystemWebName}/geo;
 
184
    $theParams =~ s/%SYSTEMWEB%/$Foswiki::cfg{SystemWebName}/geo;
 
185
    my ( $showLead, $width, $height, $iconSp, $iconT, $iconI, $iconL, $iconImg )
 
186
       = split( /, */, $theParams );
 
187
    $width   = 16 unless( $width );
 
188
    $height  = 16 unless( $height );
 
189
    $iconSp  = "empty.gif"   unless( $iconSp );
 
190
    $iconSp  = fixImageTag( $iconSp, $width, $height );
 
191
    $iconT   = "dot_udr.gif" unless( $iconT );
 
192
    $iconT   = fixImageTag( $iconT, $width, $height );
 
193
    $iconI   = "dot_ud.gif"  unless( $iconI );
 
194
    $iconI   = fixImageTag( $iconI, $width, $height );
 
195
    $iconL   = "dot_ur.gif"  unless( $iconL );
 
196
    $iconL   = fixImageTag( $iconL, $width, $height );
 
197
    $iconImg = "home.gif"    unless( $iconImg );
 
198
    $iconImg = fixImageTag( $iconImg, $width, $height );
 
199
 
 
200
    $text = "";
 
201
    my $start = 0;
 
202
    $start = 1 unless( $showLead );
 
203
    my @listIcon = ();
 
204
    for( my $i = 0; $i < scalar( @tree ); $i++ ) {
 
205
        $text .= '<table border="0" cellspacing="0" cellpadding="0"><tr>' . "\n";
 
206
        $level = $tree[$i]->{'level'};
 
207
        for( my $l = $start; $l < $level; $l++ ) {
 
208
            if( $l == $level - 1 ) {
 
209
                $listIcon[$l] = $iconSp;
 
210
                for( my $x = $i + 1; $x < scalar( @tree ); $x++ ) {
 
211
                   last if( $tree[$x]->{'level'} < $level );
 
212
                   if( $tree[$x]->{'level'} <= $level && $tree[$x]->{'type'} ne " " ) {
 
213
                       $listIcon[$l] = $iconI;
 
214
                       last;
 
215
                   }
 
216
                }
 
217
                if( $tree[$i]->{'type'} eq " " ) {
 
218
                   $text .= "<td valign=\"top\">$listIcon[$l]</td>\n";
 
219
                } elsif( $listIcon[$l] eq $iconSp ) {
 
220
                   $text .= "<td valign=\"top\">$iconL</td>\n";
 
221
                } else {
 
222
                   $text .= "<td valign=\"top\">$iconT</td>\n";
 
223
                }
 
224
            } else {
 
225
                $text .= "<td valign=\"top\">" . ($listIcon[$l] || '') . "</td>\n";
 
226
            }
 
227
        }
 
228
        if( $theType eq "icon" ) {
 
229
            # icon theme type
 
230
            if( $tree[$i]->{'type'} eq " " ) {
 
231
                # continuation line
 
232
                $text .= "<td valign=\"top\">$iconSp</td>\n";
 
233
            } elsif( $tree[$i]->{'text'} =~ /^\s*(<b>)?\s*((icon\:)?<img[^>]+>|icon\:[^\s]+)\s*(.*)/ ) {
 
234
                # specific icon
 
235
                $tree[$i]->{'text'} = $4;
 
236
                $tree[$i]->{'text'} = "$1 $4" if( $1 );
 
237
                my $icon = $2;
 
238
                $icon =~ s/^icon\://o;
 
239
                $icon = fixImageTag( $icon, $width, $height );
 
240
                $text .= "<td valign=\"top\">$icon</td>\n";
 
241
            } else {
 
242
                # default icon
 
243
                $text .= "<td valign=\"top\">$iconImg</td>\n";
 
244
            }
 
245
            $text .= "<td valign=\"top\"><nobr>&nbsp; $tree[$i]->{'text'} </nobr></td>\n";
 
246
 
 
247
        } else {
 
248
            # tree theme type
 
249
            if( $tree[$i]->{'text'} =~ /^\s*(<b>)?\s*((icon\:)?<img[^>]+>|icon\:[^\s]+)\s*(.*)/ ) {
 
250
                # specific icon
 
251
                $tree[$i]->{'text'} = $4;
 
252
                $tree[$i]->{'text'} = "$1 $4" if( $1 );
 
253
                my $icon = $2;
 
254
                $icon =~ s/^icon\://o;
 
255
                $icon = fixImageTag( $icon, $width, $height );
 
256
                $text .= "<td valign=\"top\">$icon</td>\n";
 
257
                $text .= "<td valign=\"top\"><nobr>&nbsp; $tree[$i]->{'text'} </nobr></td>\n";
 
258
            } else {
 
259
                $text .= "<td valign=\"top\"><nobr> $tree[$i]->{'text'} </nobr></td>\n";
 
260
            }
 
261
        }
 
262
        $text .= '</tr></table>' . "\n";
 
263
    }
 
264
    return $text;
 
265
}
 
266
 
 
267
# =========================
 
268
sub fixImageTag
 
269
{
 
270
    my ( $theIcon, $theWidth, $theHeight ) = @_;
 
271
 
 
272
    if( $theIcon !~ /^<img/i ) {
 
273
        $theIcon .= '.gif' if( $theIcon !~ /\.(png|gif|jpeg|jpg)$/i );
 
274
        $theIcon = "$attachUrl/$theIcon" if( $theIcon !~ /^(\/|https?\:)/ );
 
275
        $theIcon = "<img src=\"$theIcon\" width=\"$theWidth\" height=\"$theHeight\""
 
276
                 . " alt=\"\" border=\"0\" />";
 
277
    }
 
278
    return $theIcon;
 
279
}
 
280
 
 
281
# =========================
 
282
 
 
283
1;