During my playing in World of Warcraft, many times I have to communicate with Russian speaking players (especially now, when I in Russian guild). For me, typing Russian is a challenge: as for one who was grown in Israel, typing speed in Russian is about a word per minute. This is when I got an idea: translit addon. First of all, what translit is about: translit is solution for people like me, with have no ability to type Russian (sometimes the reason could be no Russian keyboard installed on the computer). Translit is a mapping of English letters to Russian – people typing Russian words using English letters. For example, “Zdravstvuy Mir” – “Здравствуй Мир” means in Russian “Hello World”. The idea is when a user pressing English “Z”, Russian “З” is actually being typed.
How to use it: after installing addin, you will have new added dialog with two buttons: “eng” and “rus”. First means translit off, second means translit on. Also in key bindings menu, under “Russian Translit” header you can bind some key to activate / deactivate translit. As a mapping rules, I used well known combinations with are used in online Russian translit – www.translit.ru
Implementation: the basic idea – somehow I have to intercept “OnKeyDown” event from chat edit box, and replace it by Russian letter, according to mapping rules. I accomplish this by hooking my script to the chat edit box:
local frame = getglobal(”ChatFrameEditBox”); //get pointer to chat edit box
frame:SetScript(”OnChar”, onTextChanged); //hook my script
Now, for some reason the “OnKeyDown” event is not being fired, and Blizzard still have me an answer for that. So I used “OnChar” event, which means “OnKeyUp”. Obviously, my algorithm have to take in account this when performing string calculations: when the event is fired, the pressed character already located inside the string. This means first I have to delete it, and then add on it place mapped Russian character. And this means, I have to track letter position inside of the message string.
In addition, sometimes combination of English letters means one single Russian letter. For example, “sh” means Russian “ш”. As a result, on each receiving letter I have to check previous one for possible combinations. So my algorithm going to be as the following:
1. Create new string
2. Copy all chars until current one (or until one before current one).
3. Add Russian letter with is representing pressed English key.
4. Copy all chars after current char (user could edit text in the middle of the exist string).
So far all sounds easy. Now this starts to be more complicated: as I discovered, Russian letters advancing cursor position by 2 (!!!), while English letters and numbers by 1. This is bad (and unexpected as well), because this way I have no idea how many chars I have to copy before current one (step 2). It seems this is how WoW encoding its strings: every non English letter combined from two letters (one of them is invisible) - the code of the letter and some kind of marker, which has code 209 or 208. The workaround I doing: I checking letter before current. If it has code 208 or 209 (greater than 200) – then it means I have Russian letter there, and I have to step one more position left to take it (again, Russian letter combined from two characters):
if(strbyte(charBefore) > 200) then
charBefore = strsub(currentText, cursorPosition-2, cursorPosition-1); //take 2 chars
else
charBefore = strsub(currentText, cursorPosition-1, cursorPosition-1); //take 1 char
end
That was the trickiest part of the addon, which took me a while to understand, due to lack of documentation.
One more interesting point: when I creating letter from combination (something like “sh”) – I have to delete two English chars, and replace it by single Russian. I achieving this by storing position offset: if single English char, then the offset is 1 (copy all characters until one position before current) or else offset is 3 (additional 2 characters representing single Russian letter).
result = strsub(currentText, 0, cursorPosition - offset); //copy all but 1 or 2 characters before current
result = result .. newChar; //add mapped russian character
if (cursorPosition < textLength) then //if we are not in the end of string, copy all rest of the letters.
result = result .. strsub(currentText, cursorPosition + 1);
end
Key Bindings: probably I would like to activate / deactivate translit by pressing some key from keyboard, not only by clicking on the proper button using mouse. For this purpose I created Bindings.xml file. It contains pretty straightforward xml:
<Binding name=”TRANSONOFF” header = “RUSTRANS”>
SwitchLang();
</Binding>
Inside frame.lua, I defined meanings for name and header:
BINDING_HEADER_RUSTRANS = “Russian Translit”;
BINDING_NAME_TRANSONOFF = “Translit On/Off”;
Now, if you will go to key bindings menu inside the game, you will find under “Russian Translit” section key bindings for “Translit On/Off” option. Each time this key will be pressed, ‘SwitchLang’ method will be called.
That’s all. You welcome to send me your feedback/suggestions/bugs.
Download addon from here.