#!/usr/bin/perl
#
# by Szymon Sokol
# ideas taken from BabelIRC by Stefan Tomanek
#
use strict;
use locale;
use utf8;
use Irssi 20020324;
use Irssi::TextUI;
use POSIX;
use Data::Dumper;
use vars qw($VERSION %IRSSI %HELP %channels %translations);
$VERSION = '2019071201';
%IRSSI = (
authors => 'Szymon Sokol',
contact => '[email protected]',
name => 'mangle',
description => 'translates your messages into Morse code, rot13 and other sillinesses.',
sbitems => 'mangle_sb',
license => 'GPLv2',
url => 'http://irssi.org/scripts/',
changed => $VERSION,
modules => 'Data::Dumper'
);
# To work, this help requires scripthelp.pl by Maciek 'fahren' Freudenheim
$HELP{"mangle add"} = "/mangle add []
Add a new translation entry for (default is current channel)";
$HELP{"mangle del"} = "/mangle del []
Removes the translation for (default is current channel)";
$HELP{"mangle say"} = "/mangle say
Says something to the current channel using given translation";
$HELP{"mangle load"} = "/mangle load
Loads translations from file";
$HELP{"mangle save"} = "/mangle save
Saves active translations to file";
$HELP{"mangle show"} = "/mangle show
Shows active translations";
$HELP{"mangle list"} = "/mangle list
Lists available translations";
# the endless possibilities for extensions here
%translations = (
# CChheecckk yyoouurr dduupplleexx sswwiittcchh
"duplex" => sub {
my ($text) = @_;
$text =~ s/./$&$&/g;
return $text;
},
# TaLk LiKe ThIs - EvErY OtHeR LeTtEr Is UpPeRcAse
"funky" => sub {
my ($text) = @_;
$text =~ s/(\w.)/\u$1/g;
return $text;
},
# TalkLikeThis-NoSpaces,WordBeginsWithUppercase
"gnome" => sub {
my ($text) = @_;
$text =~ s/\b(\w)/\u$1/g;
$text =~ s/\s+//g;
return $text;
},
# ds mangle by blap - double strike mathematical symbols
"ds" => sub {
my %ds = (
"A" => "ð¸",
"B" => "ð¹",
"C" => "â",
"D" => "ð»",
"E" => "ð¼",
"F" => "ð½",
"G" => "ð¾",
"H" => "â",
"I" => "ð",
"J" => "ð",
"K" => "ð",
"L" => "ð",
"M" => "ð",
"N" => "â",
"O" => "ð",
"P" => "â",
"Q" => "â",
"R" => "â",
"S" => "ð",
"T" => "ð",
"U" => "ð",
"V" => "ð",
"W" => "ð",
"X" => "ð",
"Y" => "ð",
"Z" => "â¤",
"a" => "ð",
"b" => "ð",
"c" => "ð",
"d" => "ð",
"e" => "ð",
"f" => "ð",
"g" => "ð",
"h" => "ð",
"i" => "ð",
"j" => "ð",
"k" => "ð",
"l" => "ð",
"m" => "ð",
"n" => "ð",
"o" => "ð ",
"p" => "ð¡",
"q" => "ð¢",
"r" => "ð£",
"s" => "ð¤",
"t" => "ð¥",
"u" => "ð¦",
"v" => "ð§",
"w" => "ð¨",
"x" => "ð©",
"y" => "ðª",
"z" => "ð«",
"0" => "ð",
"1" => "ð",
"2" => "ð",
"3" => "ð",
"4" => "ð",
"5" => "ð",
"6" => "ð",
"7" => "ð",
"8" => "ð ",
"9" => "ð¡"
);
my ($text) = @_;
$text =~ s/./defined $ds{$&} ? $ds{$&} : "$&"/eg;
return $text;
},
# curs cursive by blap - cursive (bold) script
"curs" => sub {
my %curs = (
"A" => "ð",
"B" => "ð",
"C" => "ð",
"D" => "ð",
"E" => "ð",
"F" => "ð",
"G" => "ð",
"H" => "ð",
"I" => "ð",
"J" => "ð",
"K" => "ð",
"L" => "ð",
"M" => "ð",
"N" => "ð",
"O" => "ð",
"P" => "ð",
"Q" => "ð ",
"R" => "ð¡",
"S" => "ð¢",
"T" => "ð£",
"U" => "ð¤",
"V" => "ð¥",
"W" => "ð¦",
"X" => "ð§",
"Y" => "ð¨",
"Z" => "ð©",
"a" => "ðª",
"b" => "ð«",
"c" => "ð¬",
"d" => "ð",
"e" => "ð®",
"f" => "ð¯",
"g" => "ð°",
"h" => "ð±",
"i" => "ð²",
"j" => "ð³",
"k" => "ð´",
"l" => "ðµ",
"m" => "ð¶",
"n" => "ð·",
"o" => "ð¸",
"p" => "ð¹",
"q" => "ðº",
"r" => "ð»",
"s" => "ð¼",
"t" => "ð½",
"u" => "ð¾",
"v" => "ð¿",
"w" => "ð",
"x" => "ð",
"y" => "ð",
"z" => "ð"
);
my ($text) = @_;
$text =~ s/./defined $curs{$&} ? $curs{$&} : "$&"/eg;
return $text;
},
# vapor double-width by blap - 'vaporwave' script
"vapor" => sub {
my %vapor = (
" " => " ",
"A" => "A",
"B" => "ï¼¢",
"C" => "ï¼£",
"D" => "D",
"E" => "ï¼¥",
"F" => "F",
"G" => "G",
"H" => "H",
"I" => "I",
"J" => "J",
"K" => "K",
"L" => "L",
"M" => "ï¼",
"N" => "ï¼®",
"O" => "O",
"P" => "ï¼°",
"Q" => "ï¼±",
"R" => "ï¼²",
"S" => "ï¼³",
"T" => "ï¼´",
"U" => "ï¼µ",
"V" => "V",
"W" => "ï¼·",
"X" => "X",
"Y" => "ï¼¹",
"Z" => "Z",
"a" => "ï½",
"b" => "ï½",
"c" => "ï½",
"d" => "ï½",
"e" => "ï½
",
"f" => "ï½",
"g" => "ï½",
"h" => "ï½",
"i" => "ï½",
"j" => "ï½",
"k" => "ï½",
"l" => "ï½",
"m" => "ï½",
"n" => "ï½",
"o" => "ï½",
"p" => "ï½",
"q" => "ï½",
"r" => "ï½",
"s" => "ï½",
"t" => "ï½",
"u" => "ï½",
"v" => "ï½",
"w" => "ï½",
"x" => "ï½",
"y" => "ï½",
"z" => "ï½",
"0" => "ï¼",
"1" => "ï¼",
"2" => "ï¼",
"3" => "ï¼",
"4" => "ï¼",
"5" => "ï¼",
"6" => "ï¼",
"7" => "ï¼",
"8" => "ï¼",
"9" => "ï¼",
'[' => 'ï¼»',
']' => 'ï¼½',
'{' => 'ï½',
'}' => 'ï½',
'(' => 'ï¼',
')' => 'ï¼',
'.' => 'ï¼',
',' => 'ï¼',
'?' => 'ï¼',
'!' => 'ï¼',
'"' => chr(65282),
'\'' => 'ï¼',
'#' => 'ï¼',
'$' => 'ï¼',
'%' => 'ï¼
',
'^' => 'ï¼¾',
'&' => 'ï¼',
'=' => 'ï¼',
'\\' => 'ï¼¼',
'/' => 'ï¼',
'`' => 'ï½'
);
my ($text) = @_;
$text =~ s/./defined $vapor{$&} ? $vapor{$&} : "$&"/eg;
return $text;
},
# blox cypher by blap
"blox" => sub {
my %blox = (
"a" => "â",
"b" => "â",
"c" => "â",
"d" => "â
",
"e" => "â",
"f" => "â",
"g" => "â¼",
"h" => "â",
"i" => "â",
"j" => "â",
"k" => "â«",
"l" => "â",
"m" => "â",
"n" => "â",
"o" => "â",
"p" => "â",
"q" => "â",
"r" => "â",
"s" => "â",
"t" => "â",
"u" => "â",
"v" => "â",
"w" => "â",
"x" => "â",
"y" => "â",
"z" => "â",
"0" => "â",
"1" => "â",
"2" => "â",
"3" => "â",
"4" => "â",
"5" => "â",
"6" => "â²",
"7" => "â£",
"8" => "â",
"9" => "â¼"
);
my ($text) = @_;
$text = lc($text);
$text =~ s/./defined $blox{$&} ? $blox{$&} : "$&"/eg;
return "â³".$text;
},
"morse" => sub {
my %morse = (
" " => "",
"a" => ".-",
"b" => "-...",
"c" => "-.-.",
"d" => "-..",
"e" => ".",
"f" => "..-.",
"g" => "--.",
"h" => "....",
"i" => "..",
"j" => ".---",
"k" => "-.-",
"l" => ".-..",
"m" => "--",
"n" => "-.",
"o" => "---",
"p" => ".--.",
"q" => "--.-",
"r" => ".-.",
"s" => "...",
"t" => "-",
"u" => "..-",
"v" => "...-",
"w" => ".--",
"x" => "-..-",
"y" => "-.--",
"z" => "--..",
# notice: Polish and German diacritical characters have their own
# Morse codes; the same probably stands true for other languages
# using ISO-8859-2 - if you happen to know them, please send me e-mail
"±" => ".-.-",
"æ" => "-.-..",
"ê" => "..-..",
"³" => ".-..-",
"ñ" => "--.-",
"ó" => "---.".
"¶" => "...-...",
"¼" => "--..",
"¿" => "--..-",
'ä'=>'.-.-',
'ö'=>'---.',
'ü'=>'..--',
"0" => "-----",
"1" => ".----",
"2" => "..---",
"3" => "...--",
"4" => "....-",
"5" => ".....",
"6" => "-....",
"7" => "--...",
"8" => "---..",
"9" => "----.",
"'" => ".----.",
'"' => ".-..-.",
'.' => ".-.-.-",
',' => "--..--",
'?' => "..--..",
':' => "---...",
';' => "-.-.-.",
'-' => "-....-",
'_' => "..--.-",
'/' => "-..-.",
'(' => "-.--.",
')' => "-.--.-",
'@' => ".--.-.", # byFlorian Ernst
'=' => "-...-"
);
my ($text) = @_;
$text = lc($text);
$text =~ s/./defined $morse{$&} ? $morse{$&}." " : ""/eg;
return $text.'[morse]';
},
# Fraktur font by blap
"frakt" => sub {
my %HoA = (
'a' => ["ð"],
'b' => ["ð"],
'c' => ["ð"],
'd' => ["ð"],
'e' => ["ð"],
'f' => ["ð"],
'g' => ["ð"],
'h' => ["ð"],
'i' => ["ð"],
'j' => ["ð"],
'k' => ["ð"],
'l' => ["ð"],
'm' => ["ð"],
'n' => ["ð"],
'o' => ["ð"],
'p' => ["ð"],
'q' => ["ð"],
'r' => ["ð"],
's' => ["ð"],
't' => ["ð"],
'u' => ["ð"],
'v' => ["ð"],
'w' => ["ð"],
'x' => ["ð"],
'y' => ["ð"],
'z' => ["ð"],
'A' => ["ð¬"],
'B' => ["ð"],
'C' => ["ð®"],
'D' => ["ð¯"],
'E' => ["ð°"],
'F' => ["ð±"],
'G' => ["ð²"],
'H' => ["ð³"],
'I' => ["ð´"],
'J' => ["ðµ"],
'K' => ["ð¶"],
'L' => ["ð·"],
'M' => ["ð¸"],
'N' => ["ð¹"],
'O' => ["ðº"],
'P' => ["ð»"],
'Q' => ["ð¼"],
'R' => ["ð½"],
'S' => ["ð¾"],
'T' => ["ð¿"],
'U' => ["ð"],
'V' => ["ð"],
'W' => ["ð"],
'X' => ["ð"],
'Y' => ["ð"],
'Z' => ["ð
"]
);
my ($text) = @_;
$text =~ s/./defined $HoA{$&} ? $HoA{$&}[rand(@{$HoA{$&}})] : "$&"/eg;
return $text;
},
# Unicode Obfusticator by blap
"obfus" => sub {
my %HoA = (
'0' => ["Ó¨","á½","á»","á»","Î","Ç","È","Ï´","Ã","Ã","Ã","Ǿ"],
'1' => ["Ĭ","Ἰ","Ī","Ó","Î","Î","Ð","Ð","á¿","á¿","á¿"],
'2' => ["ƻ","ƨ"],
'3' => ["Æ·","Ó ","Ò","Ò","Ó","з","Õ
","Ð","É"],
'4' => ["Ч"],
'5' => ["Ƽ"],
'6' => ["Ç","É"],
'7' => ["7"],
'8' => ["Õ"],
'9' => ["9"],
'a' => ["á¼
","á¼","áº","Ó","á½±","á¾·","ᾶ","á¾±","Ç","Ç","ά","É"],
'b' => ["Æ","Æ
","þ","á¸","á¸
","á¸","ϸ","É"],
'c' => ["Ä","Ä","Æ","â
½","Ï","ç","Ï","ϲ"],
'd' => ["Æ","á¸","â
¾","á¸","á¸","á¸","Õª","É","É"],
'e' => ["Ñ","Ä","á»","ѳ","á¸","á¸","è","ê","ϱ","È©","ε"],
'f' => ["Ò","Æ","Å¿","áº","Ï","á¸"],
'g' => ["Ä","Ä£","É¡","Ç¥","ǧ","Ö","Õ£","ǵ","ḡ","É"],
'h' => ["Ä¥","Ò»","áº","ɧ","ɦ","Õ«","ḩ","ḫ","Õ°"],
'i' => ["Ä©","Ä«","á¼²","É©","¡","Ã","ì","Î","ί","ι","á¸"],
'j' => ["Ñ","ĵ","Ê","È·","Ç°","Õµ"],
'k' => ["Ò","Æ","ĸ","Ä·","к","ḱ","ḳ","κ"],
'l' => ["Å","Å","Æ","ľ","ĺ","É«","Ç","É","ɬ","ḻ","ḽ"],
'm' => ["â¥","á¹","á¹","ɱ","ḿ"],
'n' => ["Æ","ἤ","á¹
","á½µ","ñ","É´","á¾","á¾","á¾","á¿","Õ¼","Õ²"],
'o' => ["á»","á»","á½","Å","Å","Æ¡","ὸ","á½¹","ó","ò","Ê","È«"],
'p' => ["Ñ","Ò","á¹","á¹","ῤ","á¿¥","þ","Õ©"],
'q' => ["Ô","Ê ","Õ¦","Õ£"],
'r' => ["Å","Å","Ñ","Ó·","г","È","ɽ","ɼ"],
's' => ["Å","Å","ṧ","á¹£","Ô","Å¡","Ê"],
't' => ["â ","ṫ","Å¥","È","Õ","ȶ","Ê"],
'u' => ["Æ°","á¹»","á¹³","ů","Å«","ụ","ủ","ù","µ","Ç","Ç"],
'v' => ["ṿ","á½","á½","á½","á½»","ѵ","Ò¯","á¿ ","á¿¢","â
´","ΰ"],
'w' => ["Ô","áº","áº","áº","ŵ","áº","áº
"],
'x' => ["áº","Ò³","áº","Ï°"],
'y' => ["Ñ","Æ´","Ó¯","Ñ","ỹ","ỵ","á»·","áº","ÿ"],
'z' => ["ƶ","ž","ż","ź","áº","áº","Ê"],
'A' => ["Ẩ","Ậ","Ä","á¼","Ó","á¾»","á¾¹","Î","Ⱥ","Ã","á¾","á¾"],
'B' => ["Æ","á¸","á¸","Î","Ð"],
'C' => ["Ä","Ä","Ä","âµ","Òª","Ͼ","Ã"],
'D' => ["Ä","Æ","Æ","á¸","á¸","á¸","á¸","Ã"],
'E' => ["Ẹ","Ä","Ẽ","Ä","á»","Æ","Ô","á¸","á¸","á¿","Ȩ"],
'F' => ["Ò","Æ","â£","Ï","Ï"],
'G' => ["Ä","Ä","Ä ","Ä¢","Ǥ","Ḡ","Ç´"],
'H' => ["Ĥ","Ó","Ò¤","Ò¢","È","Ð","Ḥ","Ḫ"],
'I' => ["á»","á¼¹","Ī","Ä°","È","È","Î","Ã","Ḭ","á¿","Ḯ"],
'J' => ["Ä´","Ê","Ð"],
'K' => ["â","Æ","Ķ","Î","Ḱ","Ḳ","Ḵ","Ð","Ð"],
'L' => ["Å","Ľ","â
¬","Ḷ","Ḹ","Ḻ","â"],
'M' => ["Ó","á¹","á¹","Î","Ð","Ḿ"],
'N' => ["Å","Å
","Å","â¦","á¹","á¹","Ã","Ǹ"],
'O' => ["Óª","á»","á»","á»","Î","Ã","Ã","Ã","Ȭ","È®"],
'P' => ["Ƥ","Ò","á¹","á¹","â±","Ῥ","Ρ"],
'Q' => ["Ô"],
'R' => ["Å","Å","Å","á¹","á¹","È"],
'S' => ["Ï","Å","Å","á¹ ","Å ","È","Õ"],
'T' => ["á¹°","á¹®","Ṫ","Æ®","Ŧ","Å¢","Т","Τ","á¿"],
'U' => ["á»°","Ų","Ứ","Ử","Ũ","È","È","Ç","Ç","Ç","Ã","Ã"],
'V' => ["á¹¾","á¹¼","Ѷ","â","â
¤"],
'W' => ["Ô","áº","áº","áº","Å´","áº","áº"],
'X' => ["áº","Ò²","áº","Ð¥","Χ"],
'Y' => ["Ỹ","áº","Ò°","Ÿ","Ỳ","á»´","Â¥","Ï","Ȳ","Î¥"],
'Z' => ["Ž","Å»","Ź","áº","Î","Ȥ"],
);
my ($text) = @_;
$text =~ s/./defined $HoA{$&} ? $HoA{$&}[rand(@{$HoA{$&}})] : "$&"/eg;
return $text;
},
# convert text in Polish from ISO-8859-2 to 7-bit approximation
# if you know how to do it for other languages using 8859-2,
# please let me know
"polskawe" => sub {
my ($text) = @_;
$text =~ y/¡ÃãÃ毬±æê³ñ󶿼/ACELNOSZZacelnoszz/;
return $text;
},
# Ouch, my eyes!
"rainbow" => sub {
my ($text) = @_;
# colors list
# 0 == white
# 4 == light red
# 8 == yellow
# 9 == light green
# 11 == light cyan
# 12 == light blue
# 13 == light magenta
my @colors = ('00','04','08','09','11','12','13');
my $color;
$text = join '', map { push @colors, $color = shift @colors;
"\003" . $color . ($_ eq "," ? ",," : $_) } split(//,$text);
return $text;
},
# .drawkcab klaT
"reverse" => sub {
my ($text) = @_;
$text = scalar reverse $text;
return $text;
},
# Gnyx va ebg13 rapbqvat.
"rot13" => sub {
my ($text) = @_;
$text =~ y/N-ZA-Mn-za-m/A-Za-z/;
return $text.' [rot13]';
},
# T-T-Talk l-l-like y-y-you h-h-have a s-s-stutter.
"stutter" => sub {
my ($text) = @_;
$text =~ s/(\w)(\w+)/$1-$1-$1$2/g;
return $text;
},
# rmv vwls
"vowels" => sub {
my ($text) = @_;
$text =~ y/aeiouy±ê//d;
return $text;
}
);
sub add_channel ($$) {
my ($channel,$code) = @_;
$channels{$channel} = $code;
}
sub save_channels {
my $filename = Irssi::settings_get_str('mangle_filename');
my $fo;
open $fo, '>',$filename;
my $data = Dumper(\%channels);
print $fo $data;
close $fo;
print CLIENTCRAP "%R>>%n Mangle channels saved";
}
sub load_channels {
my $filename = Irssi::settings_get_str('mangle_filename');
return unless (-e $filename);
my $fi;
open $fi, '<',$filename;
my $text;
$text .= $_ foreach <$fi>;
#no strict "vars";
my $VAR1;
eval "$text";
%channels = %$VAR1;
}
sub mangle_show ($$) {
my ($item, $get_size_only) = @_;
my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
if (ref $win && ($win->{type} eq "CHANNEL" || $win->{type} eq "QUERY") && $channels{$win->{name}}) {
my $code = $channels{$win->{name}};
$item->{min_size} = $item->{max_size} = length($code);
$code = '%U%g'.$code.'%U%n';
my $format = "{sb ".$code."}";
$item->default_handler($get_size_only, $format, 0, 1);
} else {
$item->{min_size} = $item->{max_size} = 0;
}
}
sub cmd_mangle ($$$) {
my ($args, $server, $witem) = @_;
my @arg = split(/ +/, $args);
if ($arg[0] eq 'add' && defined $arg[1]) {
my $code = $arg[1];
if(exists $translations{$code}) {
if (defined $arg[2]) {
add_channel($arg[2], $code);
}
elsif($witem) {
add_channel($witem->{name}, $code);
}
} else {
Irssi::print("There is no such translation as $code !");
}
} elsif ($arg[0] eq 'del') {
if(defined $arg[1]) {
delete $channels{$arg[1]} if defined $channels{$arg[1]};
} elsif($witem) {
delete $channels{$witem->{name}} if defined $channels{$witem->{name}};
}
} elsif ($arg[0] eq 'say' && defined $arg[1]) {
my $code = $arg[1];
if(exists $translations{$code}) {
if($witem) {
say($code, join(' ',@arg[2..$#arg]), $server, $witem);
}
} else {
Irssi::print("There is no such translation as $code !");
}
} elsif ($arg[0] eq 'save') {
save_channels();
} elsif ($arg[0] eq 'load') {
load_channels();
} elsif ($arg[0] eq 'list') {
Irssi::print("mangle: available translations are: ".
join(" ", sort keys %translations));
} elsif ($arg[0] eq 'show') {
for (sort keys %channels) {
Irssi::print("mangle: ".$_." set to ".$channels{$_});
}
} else {
Irssi::print("mangle v. $VERSION; use /help mangle for help (ensure you have scripthelp.pl loaded!)");
}
Irssi::statusbar_items_redraw('mangle_sb');
}
sub say ($$$$) {
my ($code, $line, $server, $witem) = @_;
my $target = "";
if ($line =~ s/^(\w+?: )//) {
$target = $1;
}
$line = $translations{$code}->($line);
$server->command('MSG '.$witem->{name}.' '.$target.$line);
}
sub event_send_text ($$$) {
my ($line, $server, $witem) = @_;
return unless ($witem &&
($witem->{type} eq "CHANNEL" || $witem->{type} eq "QUERY") &&
$channels{$witem->{name}});
say($channels{$witem->{name}}, $line, $server, $witem);
Irssi::signal_stop();
Irssi::statusbar_items_redraw('mangle_sb');
}
# main
Irssi::command_bind('mangle', \&cmd_mangle);
foreach my $cmd ('add', 'del', 'save', 'load', 'say', 'list', 'show') {
Irssi::command_bind('mangle '.$cmd => sub {
cmd_mangle($cmd." ".$_[0], $_[1], $_[2]); });
}
Irssi::statusbar_item_register('mangle_sb', 0, "mangle_show");
Irssi::signal_add('setup saved', 'save_channels');
Irssi::signal_add('send text', \&event_send_text);
Irssi::signal_add('window changed', sub {Irssi::statusbar_items_redraw('mangle_sb');});
Irssi::settings_add_str($IRSSI{name}, 'mangle_filename', Irssi::get_irssi_dir()."/mangle_channels");
load_channels();
print CLIENTCRAP '%B>>%n '.$IRSSI{name}.' '.$VERSION.' loaded: /help mangle for help';
# ;-)