html/romajibind.pl
1 #!/usr/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
28 use strict;
29 use 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 license => 'BSD 2-clause',
37 url => 'http://irssi.org/scripts/'
38 );
39
40 # Some help...
41 # First, this is UTF-8 script.
42 # Press ctrl-R to switch between Hiragana, Katakana and English input
43 #
44 # When the script is loading, it will install the huge amount of
45 # second-level binds. This takes some time.
46 #
47 # When you press ctrl-R it will install some binds, but not the whole
48 # bunch. Still, it takes noticeable amount of time. If you want
49 # something faster, try the simple romaji.pl :)
50 #
51 # The system is mostly Hepburn, but it could have some kunrei mappings also.
52 #
53 # Because of the irssi bind limits, the small tsu is not automatic as in
54 # the romaji.pl. You need to type it explicitly, using 'tt'.
55 # Same goes for ã and ã³, which are typed with nn or mm.
56 #
57 # There is a statusbar item which shows a glyph for the current mapping.
58 # [è±]èª -> [å¹³]ä»®å -> [ç]ä»®å
59 #
60 # If you want it, type
61 # /statusbar window add ro1_sb
62 # (just once, it will remember it)
63
64 use Irssi;
65 use Irssi::TextUI;
66
67 # Meow
68 # These are almost the same as in romaji.pl
69
70 my(%hira) = (
71 "a" => "ã", "i" => "ã", "u" => "ã", "e" => "ã", "o" => "ã",
72 "ka" => "ã", "ki" => "ã", "ku" => "ã", "ke" => "ã", "ko" => "ã",
73 "sa" => "ã", "shi" => "ã", "su" => "ã", "se" => "ã", "so" => "ã",
74 "ta" => "ã", "chi" => "ã¡", "tsu" => "ã¤", "te" => "ã¦", "to" => "ã¨",
75 "na" => "ãª", "ni" => "ã«", "nu" => "ã¬", "ne" => "ã", "no" => "ã®",
76 "ha" => "ã¯", "hi" => "ã²", "hu" => "ãµ", "he" => "ã¸", "ho" => "ã»", "fu" => "ãµ",
77 "ma" => "ã¾", "mi" => "ã¿", "mu" => "ã", "me" => "ã", "mo" => "ã",
78 "ya" => "ã", "yu" => "ã", "yo" => "ã",
79 "ra" => "ã", "ri" => "ã", "ru" => "ã", "re" => "ã", "ro" => "ã",
80 "wa" => "ã", "wi" => "ã", "we" => "ã", "wo" => "ã",
81 "nn" => "ã",
82 "mm" => "ã",
83
84 "ga" => "ã", "gi" => "ã", "gu" => "ã", "ge" => "ã", "go" => "ã",
85 "za" => "ã", "ji" => "ã", "zu" => "ã", "ze" => "ã", "zo" => "ã",
86 "da" => "ã ", "dzi" => "ã¢", "dzu" => "ã¥", "de" => "ã§", "do" => "ã©",
87 "ba" => "ã°", "bi" => "ã³", "bu" => "ã¶", "be" => "ã¹", "bo" => "ã¼",
88 "pa" => "ã±", "pi" => "ã´", "pu" => "ã·", "pe" => "ãº", "po" => "ã½",
89
90 "fa" => "ãµã", "fi" => "ãµã", "fe" => "ãµã", "fo" => "ãµã",
91 "di" => "ã§ã",
92
93 "kya" => "ãã", "kyu" => "ãã
", "kyo" => "ãã",
94 "sha" => "ãã", "shu" => "ãã
", "sho" => "ãã",
95 "cha" => "ã¡ã", "chu" => "ã¡ã
", "cho" => "ã¡ã",
96 "nya" => "ã«ã", "nyu" => "ã«ã
", "nyo" => "ã«ã",
97 "hya" => "ã²ã", "hyu" => "ã²ã
", "hyo" => "ã²ã",
98 "mya" => "ã¿ã", "myu" => "ã¿ã
", "myo" => "ã¿ã",
99 "rya" => "ãã", "ryu" => "ãã
", "ryo" => "ãã",
100 "gya" => "ãã", "gyu" => "ãã
", "gyo" => "ãã",
101 "ja" => "ãã", "ju" => "ãã
", "jo" => "ãã",
102 "jya" => "ãã", "jyu" => "ãã
", "jyo" => "ãã",
103 "dza" => "ã¢ã", "dju" => "ã¢ã
", "dzo" => "ã¢ã",
104 "dja" => "ã¢ã", "djo" => "ã¢ã",
105 "bya" => "ã³ã", "byu" => "ã³ã
", "byo" => "ã³ã",
106 "pya" => "ã´ã", "pyu" => "ã´ã
", "pyo" => "ã´ã",
107
108 "tt" => "ã£"
109 );
110
111 my(%kata) = (
112 "a" => "ã¢", "i" => "ã¤", "u" => "ã¦", "e" => "ã¨", "o" => "ãª",
113 "ka" => "ã«", "ki" => "ã", "ku" => "ã¯", "ke" => "ã±", "ko" => "ã³",
114 "sa" => "ãµ", "shi" => "ã·", "su" => "ã¹", "se" => "ã»", "so" => "ã½",
115 "ta" => "ã¿", "chi" => "ã", "tsu" => "ã", "te" => "ã", "to" => "ã",
116 "na" => "ã", "ni" => "ã", "nu" => "ã", "ne" => "ã", "no" => "ã",
117 "ha" => "ã", "hi" => "ã", "hu" => "ã", "he" => "ã", "ho" => "ã", "fu" => "ã",
118 "ma" => "ã", "mi" => "ã", "mu" => "ã ", "me" => "ã¡", "mo" => "ã¢",
119 "ya" => "ã¤", "yu" => "ã¦", "yo" => "ã¨", "ye" => "ã¨",
120 "ra" => "ã©", "ri" => "ãª", "ru" => "ã«", "re" => "ã¬", "ro" => "ã",
121 "wa" => "ã¯", "wi" => "ã°", "we" => "ã±", "wo" => "ã²",
122 "nn" => "ã³",
123 "mm" => "ã³",
124
125 "ga" => "ã¬", "gi" => "ã®", "gu" => "ã°", "ge" => "ã²", "go" => "ã´",
126 "za" => "ã¶", "ji" => "ã¸", "zu" => "ãº", "ze" => "ã¼", "zo" => "ã¾",
127 "da" => "ã", "dzi" => "ã", "dzu" => "ã
", "de" => "ã", "do" => "ã",
128 "ba" => "ã", "bi" => "ã", "bu" => "ã", "be" => "ã", "bo" => "ã",
129 "pa" => "ã", "pi" => "ã", "pu" => "ã", "pe" => "ã", "po" => "ã",
130
131 "va" => "ã´ã¡", "vi" => "ã´ã£", "vu" => "ã´", "ve" => "ã´ã§", "vo" => "ã´ã©",
132 "fa" => "ãã¡", "fi" => "ãã£", "fe" => "ãã§", "fo" => "ãã©",
133 "di" => "ãã£",
134
135 "dje" => "ãã§", "dze" => "ãã§",
136
137 "kya" => "ãã£", "kyu" => "ãã¥", "kyo" => "ãã§",
138 "sha" => "ã·ã£", "shu" => "ã·ã¥", "sho" => "ã·ã§",
139 "cha" => "ãã£", "chu" => "ãã¥", "cho" => "ãã§",
140 "nya" => "ãã£", "nyu" => "ãã¥", "nyo" => "ãã§",
141 "hya" => "ãã£", "hyu" => "ãã¥", "hyo" => "ãã§",
142 "mya" => "ãã£", "myu" => "ãã¥", "myo" => "ãã§",
143 "rya" => "ãªã£", "ryu" => "ãªã¥", "ryo" => "ãªã§",
144 "gya" => "ã®ã£", "gyu" => "ã®ã¥", "gyo" => "ã®ã§",
145 "ja" => "ã¸ã£", "ju" => "ã¸ã¥", "jo" => "ã¸ã§",
146 "jya" => "ã¸ã£", "jyu" => "ã¸ã¥", "jyo" => "ã¸ã§",
147 "dza" => "ãã£", "dju" => "ãã¥", "dzo" => "ãã§",
148 "dja" => "ãã£", "djo" => "ãã§",
149 "bya" => "ãã£", "byu" => "ãã¥", "byo" => "ãã§",
150 "pya" => "ãã£", "pyu" => "ãã¥", "pyo" => "ãã§",
151
152 "tt" => "ã"
153 );
154
155 my(%comm) = (
156 "-" => "ã¼",
157 "." => "ã",
158 "," => "ã",
159 "!" => "ï¼",
160 "?" => "ï¼",
161 "~" => "ã",
162 "[" => "ã", "]" => "ã",
163 "{" => "ã", "}" => "ã",
164 "(" => "ï¼", ")" => "ï¼",
165 "0" => "ï¼", "1" => "ï¼", "2" => "ï¼", "3" => "ï¼", "4" => "ï¼",
166 "5" => "ï¼", "6" => "ï¼", "7" => "ï¼", "8" => "ï¼", "9" => "ï¼",
167 "*" => "â
", # â is uglier :P
168 # where to put ⪠?
169 );
170
171 my(@squot) = ( "ã", "ã" );
172 my($squoti) = 0;
173 my(@dquot) = ( "ã", "ã" );
174 my($dquoti) = 0;
175
176 my(%hirab); # Contains DIRECT insert_texts and first-level metas for Hiragana
177 my(%katab); # Contains DIRECT insert_texts and first-level metas for Katakana
178 my(%commb); # Common binds
179 my(%persb); # Persistent binds (don't collide and are all second-level or more)
180
181 my($currs) = "è±"; # Current state eigo -> hiragana -> katakana
182
183 # Builds irssi binds from a hash containing romaji -> utf-8 pairs
184 # Arguments: sh, dh, pr
185 # sh: Source Hash (%hira, %kata, %comm)
186 # dh: Destination Hash (%hirab or %katab)
187 # pr: Prefix for meta keys (hira or kata)
188 # The function uses %persb for all non-direct binds
189 sub build_binds ($$$) {
190 my($sh) = $_[0]; # Source hash, %hira or %kata
191 my($dh) = $_[1]; # Destination hash, %hirab or %katab
192 my($pr) = $_[2]; # The prefix
193 my($k, $v); # for each from the source hash
194
195 while (($k, $v) = each %{$sh}) {
196 my($ll) = length($k); # get the length of the KEY
197 my($tk, $tv); # used to take apart the KEY into chars
198
199 if ($ll == 1) { # one-char KEYs are easy
200 ${$dh}{$k} = "insert_text $v";
201 } elsif ($ll >= 2) {
202 # take the first and the second chars
203 $tk = substr($k, 0, 1);
204 $tv = substr($k, 1, 1);
205 # if the meta-key is not defined yet, define it now
206 if (!${$dh}{$tk}) {
207 ${$dh}{$tk} = "key $pr$tk";
208 }
209 # if the KEY is 2-char, define it now
210 if ($ll == 2) {
211 $persb{"$pr$tk-$tv"} = "insert_text $v";
212 } else {
213 # otherwise register a new meta key, if not yet registered
214 if (!$persb{"$pr$tk-$tv"}) {
215 $persb{"$pr$tk-$tv"} = "key $pr$tk$tv";
216 }
217 # and now register the key...
218 $tk .= $tv;
219 $tv = substr($k, 2, 1);
220 $persb{"$pr$tk-$tv"} = "insert_text $v";
221 }
222 }
223 }
224 }
225
226 # Applies all binds in a given hash
227 sub do_binds ($) {
228 my($h) = $_[0];
229 my($k, $v);
230
231 while (($k, $v) = each %{$h}) {
232 Irssi::command("^bind $k $v");
233 }
234 }
235
236 # Deletes all binds existing in the given hash
237 sub del_binds ($) {
238 my($h) = $_[0];
239 my($k, $v);
240
241 while (($k, $v) = each %{$h}) {
242 Irssi::command("^bind -delete $k");
243 }
244 }
245
246 # Bindings for hiragana, next Ctrl-R will bind Katakana
247 sub cmd_rohira {
248 Irssi::command("^bind ^R /rokata");
249 do_binds \%hirab;
250 do_binds \%commb;
251 $currs = "å¹³";
252 Irssi::statusbar_items_redraw('ro1_sb');
253 }
254
255 # Bindings for Katakana, next Ctrl-R will restore
256 sub cmd_rokata {
257 Irssi::command("^bind ^R /rorest");
258 del_binds \%hirab;
259 do_binds \%katab;
260 # no need to rebind commons from %commb
261 $currs = "ç";
262 Irssi::statusbar_items_redraw('ro1_sb');
263 }
264
265 # Delete bindings (first-level), next Ctrl-R will bind Hiragana
266 sub cmd_rorest {
267 Irssi::command("^bind ^R /rohira");
268 del_binds \%katab;
269 del_binds \%commb;
270 $currs = "è±";
271 Irssi::statusbar_items_redraw('ro1_sb');
272 }
273
274 # Display the statusbar item
275 sub ro1_sb_show ($$) {
276 my ($item, $get_size_only) = @_;
277
278 $item->{min_size} = $item->{max_size} = 2;
279 $item->default_handler($get_size_only, "{sb " . $currs . "}", 0, 1);
280 }
281
282 # Register the /commands
283 Irssi::command_bind('rohira', 'cmd_rohira');
284 Irssi::command_bind('rokata', 'cmd_rokata');
285 Irssi::command_bind('rorest', 'cmd_rorest');
286
287 # Register the statusbar item
288 Irssi::statusbar_item_register('ro1_sb', 0, "ro1_sb_show");
289 Irssi::statusbar_items_redraw('ro1_sb');
290
291 # Bind Ctrl-R to Hiragana (initial position)
292 Irssi::command("^bind ^R /rohira");
293
294 # Build the bind hashes
295 build_binds \%hira, \%hirab, "hira";
296 build_binds \%kata, \%katab, "kata";
297 build_binds \%comm, \%commb, "comm";
298
299 # Register persistent binds... SLOWwwwwww :(((
300 do_binds \%persb;