1# See bottom of file for license and copyright information 2# 3# This plugin replaces smilies with small smilies bitmaps 4 5package Foswiki::Plugins::SmiliesPlugin; 6 7use strict; 8use warnings; 9 10use Foswiki::Func (); 11 12our %cache = (); 13our $current; 14 15our $VERSION = '2.03'; 16our $RELEASE = '17 Sep 2015'; 17our $NO_PREFS_IN_TOPIC = 1; 18our $SHORTDESCRIPTION = 'Render smilies like :-) as icons'; 19our $doneHeader = 0; 20 21sub initPlugin { 22 23 Foswiki::Func::registerTagHandler( 'SMILIES', \&_renderSmilies ); 24 25 my $web = $Foswiki::cfg{SystemWebName}; 26 my $topic = Foswiki::Func::getPreferencesValue('SMILIESPLUGIN_TOPIC') 27 || "SmiliesPlugin"; 28 29 $doneHeader = 0; 30 31 _loadSmilies( $web, $topic ); 32 33 return 1; 34} 35 36sub preRenderingHandler { 37 38 if ( $_[0] =~ 39 s/(\s|^)$cache{$current}{pattern}(?=\s|$)/_renderSmily($1,$2)/ge ) 40 { 41 _addToZone(); 42 } 43} 44 45sub _addToZone { 46 return if $doneHeader; 47 $doneHeader = 1; 48 Foswiki::Func::addToZone( "head", "SMILIESPLUGIN", 49"<link rel='stylesheet' href='%PUBURLPATH%/%SYSTEMWEB%/SmiliesPlugin/smilies.css' type='text/css' media='all' />" 50 ); 51} 52 53sub _loadSmilies { 54 my ( $web, $topic, $force ) = @_; 55 56 ( $web, $topic ) = Foswiki::Func::normalizeWebTopicName( $web, $topic ); 57 58 $current = "$web.$topic"; 59 return if !$force && defined $cache{$current}; 60 61 $cache{$current} = (); 62 63 $cache{$current}{format} = 64 Foswiki::Func::getPreferencesValue('SMILIESPLUGIN_FORMAT') 65 || '<img class=\'smily\' src=\'$url\' alt=\'$tooltip\' title=\'$tooltip\' />'; 66 67 $cache{$current}{pattern} = "("; 68 my $state = 0; 69 my ( $meta, $text ) = Foswiki::Func::readTopic( $web, $topic ); 70 foreach my $line ( split( /\n/, $text || '' ) ) { 71 72 # | smily | image | description | 73 if ( $line =~ m/^\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*$/ ) { 74 75 my $alternatives = $1; 76 my $image = $2; 77 my $desc = $3; 78 79 if ( $alternatives =~ m/^\*/ ) { 80 $state = 1; 81 next; 82 } 83 84 $image =~ s/%ATTACHURL(PATH)?%//g; 85 $desc =~ s/"//g; 86 87 next unless $alternatives && $image; 88 89 foreach my $key ( split( /\s+/, $alternatives ) ) { 90 $key =~ s/<nop>|\ //g; 91 $cache{$current}{pattern} .= "\Q$key\E|"; 92 $cache{$current}{image}{$key} = $image; 93 $cache{$current}{desc}{$key} = $desc; 94 $cache{$current}{alts}{$key} = $alternatives; 95 } 96 } 97 else { 98 last if $state == 1; 99 } 100 } 101 102 #$cache{$current}{pattern} =~ s/\|$//; 103 $cache{$current}{pattern} .= ")"; 104 $cache{$current}{pubUrl} = Foswiki::Func::getPubUrlPath() . "/$web/$topic"; 105 106} 107 108sub _renderSmily { 109 my ( $pre, $smily ) = @_; 110 111 return $pre unless $smily; 112 return $pre . _formatSmily( $cache{$current}{format}, $smily ); 113} 114 115sub _formatSmily { 116 my ( $format, $smily ) = @_; 117 118 my $text = $format; 119 120 $text =~ s/\$key/<nop>$smily/g; 121 $text =~ s/\$alternatives/$cache{$current}{alts}{$smily}/g; 122 $text =~ s/\$emoticon/$smily/g; 123 $text =~ s/\$tooltip/$cache{$current}{desc}{$smily}/g; 124 $text =~ 125 s/\$url/$cache{$current}{pubUrl}\/$cache{$current}{image}{$smily}/g; 126 127 return $text; 128} 129 130sub _renderSmilies { 131 my ( $session, $params ) = @_; 132 133 my $smily = $params->{_DEFAULT}; 134 my $header = $params->{header}; 135 my $format = $params->{format}; 136 my $footer = $params->{footer} || ''; 137 my $separator = $params->{separator} || '$n'; 138 139 $header = 140'| *%MAKETEXT{"Notation"}%* | *%MAKETEXT{"Image"}%* | *%MAKETEXT{"Description"}%* |$n' 141 unless defined $header; 142 143 $format = '| $alternatives | $emoticon | $tooltip |' unless defined $format; 144 145 my @smilies = (); 146 if ( defined $smily ) { 147 push @smilies, $smily; 148 } 149 else { 150 @smilies = 151 sort { 152 lc( $cache{$current}{image}{$a} ) cmp 153 lc( $cache{$current}{image}{$b} ) 154 } 155 keys %{ $cache{$current}{alts} }; 156 } 157 158 my @result = (); 159 my %seen = (); 160 foreach my $smily (@smilies) { 161 next if $seen{ $cache{$current}{alts}{$smily} }; 162 push @result, _formatSmily( $format, $smily ); 163 $seen{ $cache{$current}{alts}{$smily} } = 1; 164 } 165 166 return '' unless @result; 167 168 _addToZone(); 169 170 return Foswiki::Func::decodeFormatTokens( 171 $header . join( $separator, @result ) . $footer ); 172} 173 1741; 175__END__ 176Foswiki - The Free and Open Source Wiki, http://foswiki.org/ 177 178Copyright (C) 2008-2014 Foswiki Contributors. Foswiki Contributors 179are listed in the AUTHORS file in the root of this distribution. 180NOTE: Please extend that file, not this notice. 181 182Additional copyrights apply to some or all of the code in this 183file as follows: 184 185Copyright (C) 2000-2001 Andrea Sterbini, a.sterbini@flashnet.it 186Copyright (C) 2002-2006 Peter Thoeny, peter@thoeny.org 187 188This program is free software; you can redistribute it and/or 189modify it under the terms of the GNU General Public License 190as published by the Free Software Foundation; either version 2 191of the License, or (at your option) any later version. For 192more details read LICENSE in the root of this distribution. 193 194This program is distributed in the hope that it will be useful, 195but WITHOUT ANY WARRANTY; without even the implied warranty of 196MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 197 198As per the GPL, removal of this notice is prohibited. 199