1
# Plugin for Foswiki - The Free and Open Source Wiki, http://foswiki.org/
3
# Copyright (C) 2001-2007 Peter Thoeny, peter@thoeny.org
4
# Copyright (C) 2008 Foswiki Contributors
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.
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.
16
# As per the GPL, removal of this notice is prohibited.
17
# =========================
20
# =========================
21
package Foswiki::Plugins::RenderListPlugin; # change the package name and $pluginName!!!
23
# =========================
25
$web $topic $user $installWeb $VERSION $RELEASE $pluginName
26
$debug $pubUrl $attachUrl
29
$VERSION = '$Rev: 3048 (2009-03-12) $';
31
$pluginName = 'RenderListPlugin'; # Name of this Plugin
33
# =========================
36
( $topic, $web, $user, $installWeb ) = @_;
38
# check for Plugins.pm versions
39
if( $Foswiki::Plugins::VERSION < 1 ) {
40
Foswiki::Func::writeWarning( "Version mismatch between $pluginName and Plugins.pm" );
44
# Get plugin debug flag
45
$debug = Foswiki::Func::getPreferencesFlag( "\U$pluginName\E_DEBUG" );
47
# one time initialization
48
$pubUrl = Foswiki::Func::getUrlHost() . Foswiki::Func::getPubUrlPath();
49
$attachUrl = "$pubUrl/$installWeb/$pluginName";
51
# Plugin correctly initialized
52
Foswiki::Func::writeDebug( "- Foswiki::Plugins::${pluginName}::initPlugin( $web.$topic ) is OK" ) if $debug;
56
# =========================
57
sub startRenderingHandler
59
### my ( $text, $web ) = @_; # do not uncomment, use $_[0], $_[1] instead
61
Foswiki::Func::writeDebug( "- ${pluginName}::startRenderingHandler( $_[1] )" ) if $debug;
63
# This handler is called by getRenderedVersion just before the line loop
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;
75
# =========================
78
my ( $theAttr, $thePre, $theList ) = @_;
80
$theAttr =~ s/ {3}/\t/gs;
81
$thePre =~ s/ {3}/\t/gs;
82
$theList =~ s/ {3}/\t/gs;
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 );
93
if( $type eq "tree" || $type eq "icon" ) {
94
return $thePre . renderIconList( $type, $params, $focus, $depth, $theList );
96
return "$thePre$theList";
100
# =========================
103
my ( $theType, $theParams, $theFocus, $theDepth, $theText ) = @_;
105
$theText =~ s/^[\n\r]*//os;
111
foreach( split ( /[\n\r]+/, $theText ) ) {
113
$level = length( $1 );
116
if( ( $theFocus ) && ( $focusIndex < 0 ) && ( $text =~ /$theFocus/ ) ) {
117
$focusIndex = scalar( @tree );
119
push( @tree, { level => $level, type => $type, text => $text } );
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 );
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;
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 );
145
# remove uncles and siblings above current node
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'};
153
@tree = reverse( @before );
154
$focusIndex = scalar( @tree );
155
push( @tree, $nref );
156
push( @tree, @after );
159
# limit depth of tree
160
my $depth = $theDepth;
161
unless( $depth =~ s/.*?([0-9]+).*/$1/o ) {
165
if( $theDepth eq "" ) {
166
$depth = $focusIndex + 3;
168
$depth += $focusIndex + 1;
173
foreach my $ref ( @tree ) {
174
push( @tmp, $ref ) if( $ref->{'level'} <= $depth );
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 );
202
$start = 1 unless( $showLead );
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;
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";
222
$text .= "<td valign=\"top\">$iconT</td>\n";
225
$text .= "<td valign=\"top\">" . ($listIcon[$l] || '') . "</td>\n";
228
if( $theType eq "icon" ) {
230
if( $tree[$i]->{'type'} eq " " ) {
232
$text .= "<td valign=\"top\">$iconSp</td>\n";
233
} elsif( $tree[$i]->{'text'} =~ /^\s*(<b>)?\s*((icon\:)?<img[^>]+>|icon\:[^\s]+)\s*(.*)/ ) {
235
$tree[$i]->{'text'} = $4;
236
$tree[$i]->{'text'} = "$1 $4" if( $1 );
238
$icon =~ s/^icon\://o;
239
$icon = fixImageTag( $icon, $width, $height );
240
$text .= "<td valign=\"top\">$icon</td>\n";
243
$text .= "<td valign=\"top\">$iconImg</td>\n";
245
$text .= "<td valign=\"top\"><nobr> $tree[$i]->{'text'} </nobr></td>\n";
249
if( $tree[$i]->{'text'} =~ /^\s*(<b>)?\s*((icon\:)?<img[^>]+>|icon\:[^\s]+)\s*(.*)/ ) {
251
$tree[$i]->{'text'} = $4;
252
$tree[$i]->{'text'} = "$1 $4" if( $1 );
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> $tree[$i]->{'text'} </nobr></td>\n";
259
$text .= "<td valign=\"top\"><nobr> $tree[$i]->{'text'} </nobr></td>\n";
262
$text .= '</tr></table>' . "\n";
267
# =========================
270
my ( $theIcon, $theWidth, $theHeight ) = @_;
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\" />";
281
# =========================