Adium2Pidgin
This is a script which converts Adium smiley themes to Pidgin compatible smiley themes. I've tested this on all of three different themes, and it seemed to work for all of them.
You might be looking at this and thinking, blimey thats a lot of duplication with the whole $data->{'dict'}->... thing. Well, yes I agree and will be getting rid of it all soon (I simply used this method because I was getting crazy results before and wanted to make sure everything was as expected).
Anyway, this script can be downloaded from here and is used as follows.
$ adium2pidgin <Path to Emoticons.plist> <Theme name> <Theme Description> [Author]
#!/usr/bin/perl -w # # A script to create a pidgin emoticon theme file from # adium themes. # # Author: Harry Rose # use XML::Simple; use File::Copy; my $xml = new XML::Simple; if( $#ARGV < 2) { print STDERR "Requires 3 inputs. <Emoticons File> <Name> <Description> [Author]\n"; exit(); } if( ! $dir =~ /Emoticons\.plist$/i ) { print STDERR "Please pass the Emoticons.plist file as the first parameter to this command\n"; exit(); } #Open the given file into the parser. my $data = $xml->XMLin("$ARGV[0]"); my $dir = $ARGV[0]; #Get rid of the file to give us the relative path to its directory. $dir =~ s/Emoticons\.plist//i; my $name = $ARGV[1]; #Name of the theme my $desc = $ARGV[2]; #Description ... my $author = "Unknown"; #Author of the theme if( $#ARGV == 3 ) { #They've specified an author, set $author to it. $author = $ARGV[3]; } my $display = ""; #This is the display icon to use my $index = 0; #Just a counter my $content = ""; #An accumulator. Will use this to build up the content of the file. #Used define here as foreach didn't seem to work while(defined $data->{'dict'}->{'dict'}->{'key'}->[$index]) { #The filename my $file = $data->{'dict'}->{'dict'}->{'key'}->[$index]; if( $file=~ /\s/) { #Contains spaces :o, pidgin won't like this, replace with _ my $oFile = $file; $file =~ s/\s/_/g; copy($dir.$oFile, $dir.$file); } $content .= $file; #If only one string is given it won't be an array. if(!UNIVERSAL::isa($data->{'dict'}->{'dict'}->{'dict'}->[$index]->{'array'}->{'string'}, 'ARRAY')) { $content .= " ".$data->{'dict'}->{'dict'}->{'dict'}->[$index]->{'array'}->{'string'}; } else { my $stringPos = 0; while (defined $data->{'dict'}->{'dict'}->{'dict'}->[$index]->{'array'}->{'string'}->[$stringPos]) { #If someone puts an empty string, it will turn up as a hash, we can safely ignore empty strings. if(!UNIVERSAL::isa($data->{'dict'}->{'dict'}->{'dict'}->[$index]->{'array'}->{'string'}->[$stringPos], 'HASH')) { $content .= " ".$data->{'dict'}->{'dict'}->{'dict'}->[$index]->{'array'}->{'string'}->[$stringPos]; } $stringPos ++; } } $content .= "\n"; $index ++; #If we've still not set a display icon, set it to the current smiley. if($display eq "") { $display = $file; } } #build up the beginnings of the document. #Done here because we dont know what icon to use until now (also it keeps everything together). my $start = "Name=$name\n"; $start .= "Description=$desc\n"; $start .= "Author=$author\n"; $start .= "Icon=$display\n\n[default]\n"; $content = $start.$content; $outFile = $dir."theme"; #Overwrite any existing theme file open(THEME,">$outFile"); print THEME $content; close(THEME);