1#!/usr/local/bin/perl -w 2# 3# Copyright (c) 2002 Victor Ivanov <v0rbiz@yahoo.com> 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26# 27 28use strict; 29use vars qw($VERSION %IRSSI); 30$VERSION = "1.0b"; 31%IRSSI = ( 32 authors => 'Victor Ivanov', 33 contact => 'v0rbiz@yahoo.com', 34 name => 'romajibind', 35 description => 'Dynamic romaji binds', 36 sbitems => 'ro1_sb', 37 license => 'BSD 2-clause', 38 url => 'http://irssi.org/scripts/' 39); 40 41# Some help... 42# First, this is UTF-8 script. 43# Press ctrl-R to switch between Hiragana, Katakana and English input 44# 45# When the script is loading, it will install the huge amount of 46# second-level binds. This takes some time. 47# 48# When you press ctrl-R it will install some binds, but not the whole 49# bunch. Still, it takes noticeable amount of time. If you want 50# something faster, try the simple romaji.pl :) 51# 52# The system is mostly Hepburn, but it could have some kunrei mappings also. 53# 54# Because of the irssi bind limits, the small tsu is not automatic as in 55# the romaji.pl. You need to type it explicitly, using 'tt'. 56# Same goes for ん and ン, which are typed with nn or mm. 57# 58# There is a statusbar item which shows a glyph for the current mapping. 59# [英]語 -> [平]仮名 -> [片]仮名 60# 61# If you want it, type 62# /statusbar window add ro1_sb 63# (just once, it will remember it) 64 65use Irssi; 66use Irssi::TextUI; 67 68# Meow 69# These are almost the same as in romaji.pl 70 71my(%hira) = ( 72 "a" => "あ", "i" => "い", "u" => "う", "e" => "え", "o" => "お", 73 "ka" => "か", "ki" => "き", "ku" => "く", "ke" => "け", "ko" => "こ", 74 "sa" => "さ", "shi" => "し", "su" => "す", "se" => "せ", "so" => "そ", 75 "ta" => "た", "chi" => "ち", "tsu" => "つ", "te" => "て", "to" => "と", 76 "na" => "な", "ni" => "に", "nu" => "ぬ", "ne" => "ね", "no" => "の", 77 "ha" => "は", "hi" => "ひ", "hu" => "ふ", "he" => "へ", "ho" => "ほ", "fu" => "ふ", 78 "ma" => "ま", "mi" => "み", "mu" => "む", "me" => "め", "mo" => "も", 79 "ya" => "や", "yu" => "ゆ", "yo" => "よ", 80 "ra" => "ら", "ri" => "り", "ru" => "る", "re" => "れ", "ro" => "ろ", 81 "wa" => "わ", "wi" => "ゐ", "we" => "ゑ", "wo" => "を", 82 "nn" => "ん", 83 "mm" => "ん", 84 85 "ga" => "が", "gi" => "ぎ", "gu" => "ぐ", "ge" => "げ", "go" => "ご", 86 "za" => "ざ", "ji" => "じ", "zu" => "ず", "ze" => "ぜ", "zo" => "ぞ", 87 "da" => "だ", "dzi" => "ぢ", "dzu" => "づ", "de" => "で", "do" => "ど", 88 "ba" => "ば", "bi" => "び", "bu" => "ぶ", "be" => "べ", "bo" => "ぼ", 89 "pa" => "ぱ", "pi" => "ぴ", "pu" => "ぷ", "pe" => "ぺ", "po" => "ぽ", 90 91 "fa" => "ふぁ", "fi" => "ふぃ", "fe" => "ふぇ", "fo" => "ふぉ", 92 "di" => "でぃ", 93 94 "kya" => "きゃ", "kyu" => "きゅ", "kyo" => "きょ", 95 "sha" => "しゃ", "shu" => "しゅ", "sho" => "しょ", 96 "cha" => "ちゃ", "chu" => "ちゅ", "cho" => "ちょ", 97 "nya" => "にゃ", "nyu" => "にゅ", "nyo" => "にょ", 98 "hya" => "ひゃ", "hyu" => "ひゅ", "hyo" => "ひょ", 99 "mya" => "みゃ", "myu" => "みゅ", "myo" => "みょ", 100 "rya" => "りゃ", "ryu" => "りゅ", "ryo" => "りょ", 101 "gya" => "ぎゃ", "gyu" => "ぎゅ", "gyo" => "ぎょ", 102 "ja" => "じゃ", "ju" => "じゅ", "jo" => "じょ", 103 "jya" => "じゃ", "jyu" => "じゅ", "jyo" => "じょ", 104 "dza" => "ぢゃ", "dju" => "ぢゅ", "dzo" => "ぢょ", 105 "dja" => "ぢゃ", "djo" => "ぢょ", 106 "bya" => "びゃ", "byu" => "びゅ", "byo" => "びょ", 107 "pya" => "ぴゃ", "pyu" => "ぴゅ", "pyo" => "ぴょ", 108 109 "tt" => "っ" 110); 111 112my(%kata) = ( 113 "a" => "ア", "i" => "イ", "u" => "ウ", "e" => "エ", "o" => "オ", 114 "ka" => "カ", "ki" => "キ", "ku" => "ク", "ke" => "ケ", "ko" => "コ", 115 "sa" => "サ", "shi" => "シ", "su" => "ス", "se" => "セ", "so" => "ソ", 116 "ta" => "タ", "chi" => "チ", "tsu" => "ツ", "te" => "テ", "to" => "ト", 117 "na" => "ナ", "ni" => "ニ", "nu" => "ヌ", "ne" => "ネ", "no" => "ノ", 118 "ha" => "ハ", "hi" => "ヒ", "hu" => "フ", "he" => "ヘ", "ho" => "ホ", "fu" => "フ", 119 "ma" => "マ", "mi" => "ミ", "mu" => "ム", "me" => "メ", "mo" => "モ", 120 "ya" => "ヤ", "yu" => "ユ", "yo" => "ヨ", "ye" => "エ", 121 "ra" => "ラ", "ri" => "リ", "ru" => "ル", "re" => "レ", "ro" => "ロ", 122 "wa" => "ワ", "wi" => "ヰ", "we" => "ヱ", "wo" => "ヲ", 123 "nn" => "ン", 124 "mm" => "ン", 125 126 "ga" => "ガ", "gi" => "ギ", "gu" => "グ", "ge" => "ゲ", "go" => "ゴ", 127 "za" => "ザ", "ji" => "ジ", "zu" => "ズ", "ze" => "ゼ", "zo" => "ゾ", 128 "da" => "ダ", "dzi" => "ヂ", "dzu" => "ヅ", "de" => "デ", "do" => "ド", 129 "ba" => "バ", "bi" => "ビ", "bu" => "ブ", "be" => "ベ", "bo" => "ボ", 130 "pa" => "パ", "pi" => "ピ", "pu" => "プ", "pe" => "ペ", "po" => "ポ", 131 132 "va" => "ヴァ", "vi" => "ヴィ", "vu" => "ヴ", "ve" => "ヴェ", "vo" => "ヴォ", 133 "fa" => "ファ", "fi" => "フィ", "fe" => "フェ", "fo" => "フォ", 134 "di" => "ディ", 135 136 "dje" => "ヂェ", "dze" => "ヂェ", 137 138 "kya" => "キャ", "kyu" => "キュ", "kyo" => "キョ", 139 "sha" => "シャ", "shu" => "シュ", "sho" => "ショ", 140 "cha" => "チャ", "chu" => "チュ", "cho" => "チョ", 141 "nya" => "ニャ", "nyu" => "ニュ", "nyo" => "ニョ", 142 "hya" => "ヒャ", "hyu" => "ヒュ", "hyo" => "ヒョ", 143 "mya" => "ミャ", "myu" => "ミュ", "myo" => "ミョ", 144 "rya" => "リャ", "ryu" => "リュ", "ryo" => "リョ", 145 "gya" => "ギャ", "gyu" => "ギュ", "gyo" => "ギョ", 146 "ja" => "ジャ", "ju" => "ジュ", "jo" => "ジョ", 147 "jya" => "ジャ", "jyu" => "ジュ", "jyo" => "ジョ", 148 "dza" => "ヂャ", "dju" => "ヂュ", "dzo" => "ヂョ", 149 "dja" => "ヂャ", "djo" => "ヂョ", 150 "bya" => "ビャ", "byu" => "ビュ", "byo" => "ビョ", 151 "pya" => "ピャ", "pyu" => "ピュ", "pyo" => "ピョ", 152 153 "tt" => "ッ" 154); 155 156my(%comm) = ( 157 "-" => "ー", 158 "." => "。", 159 "," => "、", 160 "!" => "!", 161 "?" => "?", 162 "~" => "〜", 163 "[" => "〔", "]" => "〕", 164 "{" => "【", "}" => "】", 165 "(" => "(", ")" => ")", 166 "0" => "0", "1" => "1", "2" => "2", "3" => "3", "4" => "4", 167 "5" => "5", "6" => "6", "7" => "7", "8" => "8", "9" => "9", 168 "*" => "★", # ☆ is uglier :P 169 # where to put ♪ ? 170); 171 172my(@squot) = ( "「", "」" ); 173my($squoti) = 0; 174my(@dquot) = ( "『", "』" ); 175my($dquoti) = 0; 176 177my(%hirab); # Contains DIRECT insert_texts and first-level metas for Hiragana 178my(%katab); # Contains DIRECT insert_texts and first-level metas for Katakana 179my(%commb); # Common binds 180my(%persb); # Persistent binds (don't collide and are all second-level or more) 181 182my($currs) = "英"; # Current state eigo -> hiragana -> katakana 183 184# Builds irssi binds from a hash containing romaji -> utf-8 pairs 185# Arguments: sh, dh, pr 186# sh: Source Hash (%hira, %kata, %comm) 187# dh: Destination Hash (%hirab or %katab) 188# pr: Prefix for meta keys (hira or kata) 189# The function uses %persb for all non-direct binds 190sub build_binds ($$$) { 191 my($sh) = $_[0]; # Source hash, %hira or %kata 192 my($dh) = $_[1]; # Destination hash, %hirab or %katab 193 my($pr) = $_[2]; # The prefix 194 my($k, $v); # for each from the source hash 195 196 while (($k, $v) = each %{$sh}) { 197 my($ll) = length($k); # get the length of the KEY 198 my($tk, $tv); # used to take apart the KEY into chars 199 200 if ($ll == 1) { # one-char KEYs are easy 201 ${$dh}{$k} = "insert_text $v"; 202 } elsif ($ll >= 2) { 203 # take the first and the second chars 204 $tk = substr($k, 0, 1); 205 $tv = substr($k, 1, 1); 206 # if the meta-key is not defined yet, define it now 207 if (!${$dh}{$tk}) { 208 ${$dh}{$tk} = "key $pr$tk"; 209 } 210 # if the KEY is 2-char, define it now 211 if ($ll == 2) { 212 $persb{"$pr$tk-$tv"} = "insert_text $v"; 213 } else { 214 # otherwise register a new meta key, if not yet registered 215 if (!$persb{"$pr$tk-$tv"}) { 216 $persb{"$pr$tk-$tv"} = "key $pr$tk$tv"; 217 } 218 # and now register the key... 219 $tk .= $tv; 220 $tv = substr($k, 2, 1); 221 $persb{"$pr$tk-$tv"} = "insert_text $v"; 222 } 223 } 224 } 225} 226 227# Applies all binds in a given hash 228sub do_binds ($) { 229 my($h) = $_[0]; 230 my($k, $v); 231 232 while (($k, $v) = each %{$h}) { 233 Irssi::command("^bind $k $v"); 234 } 235} 236 237# Deletes all binds existing in the given hash 238sub del_binds ($) { 239 my($h) = $_[0]; 240 my($k, $v); 241 242 while (($k, $v) = each %{$h}) { 243 Irssi::command("^bind -delete $k"); 244 } 245} 246 247# Bindings for hiragana, next Ctrl-R will bind Katakana 248sub cmd_rohira { 249 Irssi::command("^bind ^R /rokata"); 250 do_binds \%hirab; 251 do_binds \%commb; 252 $currs = "平"; 253 Irssi::statusbar_items_redraw('ro1_sb'); 254} 255 256# Bindings for Katakana, next Ctrl-R will restore 257sub cmd_rokata { 258 Irssi::command("^bind ^R /rorest"); 259 del_binds \%hirab; 260 do_binds \%katab; 261 # no need to rebind commons from %commb 262 $currs = "片"; 263 Irssi::statusbar_items_redraw('ro1_sb'); 264} 265 266# Delete bindings (first-level), next Ctrl-R will bind Hiragana 267sub cmd_rorest { 268 Irssi::command("^bind ^R /rohira"); 269 del_binds \%katab; 270 del_binds \%commb; 271 $currs = "英"; 272 Irssi::statusbar_items_redraw('ro1_sb'); 273} 274 275# Display the statusbar item 276sub ro1_sb_show ($$) { 277 my ($item, $get_size_only) = @_; 278 279 $item->{min_size} = $item->{max_size} = 2; 280 $item->default_handler($get_size_only, "{sb " . $currs . "}", 0, 1); 281} 282 283# Register the /commands 284Irssi::command_bind('rohira', 'cmd_rohira'); 285Irssi::command_bind('rokata', 'cmd_rokata'); 286Irssi::command_bind('rorest', 'cmd_rorest'); 287 288# Register the statusbar item 289Irssi::statusbar_item_register('ro1_sb', 0, "ro1_sb_show"); 290Irssi::statusbar_items_redraw('ro1_sb'); 291 292# Bind Ctrl-R to Hiragana (initial position) 293Irssi::command("^bind ^R /rohira"); 294 295# Build the bind hashes 296build_binds \%hira, \%hirab, "hira"; 297build_binds \%kata, \%katab, "kata"; 298build_binds \%comm, \%commb, "comm"; 299 300# Register persistent binds... SLOWwwwwww :((( 301do_binds \%persb; 302