LSL MultiLingual Library(en)
[ Japanese ]
This is the extention library to use multi languages. Including alternative functions for llSay(), llSetText(), llDialog(), and more. This library is distributed under GNU Lesser General Public License.
Features
About lsl-ml.lib
An extention library for LSL enables to build multilingual environments with using alternative functions. It corresponds to 8 languages; de, en-us, es, fr, ja, ko, pt and zh. It also enables to use other languages that can be shown by using UTF-8.
- German(de)
- English(en-us)
- Spanish(es)
- French(fr)
- Japanese(ja)
- Korean(ko)
- Portuguese(pt)
- Chinese(zh)
These language data are selectable from the main script outside the library, and it is possible to output it dynamically. Moreover, it is also possible to substitute a part in the language data for other character strings and to output it in that case.
About alternative functions
Kind of alternative function
The following 9 alternative functions that output the character string are collected.
- mlSay() … for llSay()
- mlWhisper() … for llWhisper()
- mlShout() … for llShout()
- mlRegionSay() … for llRegionSay()
- mlOwnerSay() … llOwnerSay()の代替関数
- mlInstantMessage() … for llInstantMessage()
- mlSetText() … for llSetText()
- mlDialog() … for llDialog()
- mlLoadURL() … for llLoadURL()
lsl-ml.lib can be controlled by using these alternative functions in the main script outside the library.
Enhanced arguments
All alternative functions need the same arguments as the functions of LSL standard. For instance, mlSay() should specify two arguments of “integer channel, string msg” as well as llSay(), and is necessary for mlSetText() three arguments of “string msg, vector color, float alpha” as well as llSetText().
You in addition to this call an alternative function with the following two enhanced common arguments affixed.
- string lang_code … Specification of language code[de, en-us, es, fr, ja, ko, pt, zh]
- list replacement … Specification of substitution character string(plural and acceptable)
“string lang_code” is an argument that specifies the language when outputting it by way of lsl-ml.lib. This specifies language code (de, en-us, es, fr, ja, ko, pt, zh) as it is. Because the llGetAgentLanguage(key id) function outputs this value, combining is convenient.
“list replacement” is an argument used when substituting and outputting it in lsl-ml.lib. For instance, language data in lsl-ml.lib is “Hello, %s” and list replacement is [“arz Nitely”], it is output, saying that “Hello, arz Nitely”. Two or more this substitutions can be specified in one language data. For instance, language data is “It is %s %s, %s today” and list replacement is [“November”, “29”, “2008”], it is sequentially substituted ahead and it is output , saying that “It is November 29, 2008 today”.
When it is not necessary to substitute it, specify an empty list such as “list replacement = []”.
Remarks
Division of the language data
When the very big language data is needed, the upper bound of the memory can be exceeded. For this case, you can evade this problem by setting up two or more lsl-ml.lib divided in one object.
Construction procedure of multilingual environment
1. Make the script as usual
Making to several languages need not be considered at all at the early stage. Please finish a series of work from the scripting to debugging in the single language that you are using usually. This library achieves making to several languages by calling outside lsl-ml.lib by using an alternative function that looks like the default function of LSL very well. Moreover, the communication between the main script and the library is done only to one direction from the main script to lsl-ml.lib. Therefore, easily constructing a multilingual environment back by correcting the minimum requirement degree becomes possible.
2. Introduce lsl-ml.lib
The source code is under this page. Create new script in the object includes your main script(s), rename to “lsl-ml.lib”, and copy & paste that code into the new script. However, lsl-ml.lib need not be edited at this stage yet. Close the window after you save it.
3. Replaces some with alternative functions
First of all, please put alternative functions under this page beforehand before starting this work. Putting position is befor “state default”.
After this work, the part that wants to be made multilingual is replaced with an alternative function. As for all alternative functions, the first step only in rewrite one character of the start from “l” in “m” ends.
Next, the enhancing argument is specified. To switch lang_code dynamically, it may be useful to put llGetAgentLangage(key id) function.
4. Edit the language data
Work to need the time might be an edit of the language data. Please input the words or sentences translated into each language by using the dictionary and the translation site, etc.If substitution is necessary in that case, ”%s” is input to the right place.
As for the language column where the translation is impossible, it is an empty column (or, fill it in by the other language), and I think the method of entrusting the translation to the user who obtains it to be good in all respects.
Postscript: about link message
lsl-ml.lib communicates by using the link message between the main script and the library. In that case, the value of the second argument “integer num” of the llMessageLinked() function is ”-125” in default. In the link message with other scripts, please rewrite the part of “integer ML_COMMAND =-125;” in an alternative function and in lsl-ml.lib having put it in the main script in other numerical values when you have already used this numerical value.
Source code
lsl-ml.lib
// ##################### LSL MultiLingual Library ##################### // ver.0.1.2-beta // // This program is free library: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation, either version 3 of the // License, or any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // For the person who gets this, you should keep the module modifyable // when you sell or distribute the object including this. That is, you // should keep this module FULL PERMISSION and keep object MODIFYABLE. // I think that it is very important to let the person who gets it edit // the language data for him/herself. // // You should have received a copy of the GNU Lesser General Public // License along with this program. If not, see following website. // http://www.gnu.org/licenses/ // // // Copyright 2008 arz Nitely // http://arznitely.com // // _______________________________________________a_r_z___N_i_t_e_l_y__ // Language Data ====================================================== // // modify as you like! // --> each data should be written as // "msg", "de", "en-us", "es", "fr", "ja", "ko", "po", "zh" // --> %s is replaced by this library and substitute functions list lang_data = [ "HELLO_AVATAR", "Guten Tag, %s.", "Hello, %s.", "Ciao, %s", "Bonjour, %s", "こんにちは、%sさん。", "안녕하세요, %s씨.", "Oi, %s.", "你好,%s先生.", "TOUCHED", "(%s): %s berührte sich.", "(%s): %s touched.", "(%s): %s tocó.", "(%s): %s a touché.", "(%s): %sがタッチしました。", "(%s): %s가 손대었습니다.", "(%s): %s tocou.", "(%s): %s觸摸了." ]; // Script ============================================================= // // CAUTION: The following part is concerned with other scripts in the // contents. When you change some, other related scripts want modifying // at the same time. // LSL Multilingual Library Command Num integer ML_COMMAND = -125; // Function: integer mlGetLangNum(string lang_code) list lang_code_list = ["de", "en-us", "es", "fr", "ja", "ko", "pt", "zh"]; integer mlGetLangNum(string lang_code){ integer result = llListFindList(lang_code_list, [lang_code]); return result; } // Flow default{ link_message(integer sender_num, integer num, string str, key id){ string command; string msg; string lang_code; string base_params; string extend_params; list expand_data; // = [command, msg, lang_code, base_params, extend_params] list temp_data; integer channel; vector color; float alpha; string url; list buttons; list replacement; integer replacement_num; integer cursor; string temp_result; string result; if (num == ML_COMMAND){ expand_data = llParseString2List(str, ["||"], []); command = llList2String(expand_data, 0); msg = llList2String(expand_data, 1); lang_code = llList2String(expand_data, 2); base_params = llList2String(expand_data, 3); extend_params = llList2String(expand_data, 4); if (llListFindList(lang_data, [msg]) != -1){ temp_data = llParseString2List(base_params, ["|"], []); replacement = llParseString2List(extend_params, ["|"], []); replacement_num = llGetListLength(replacement); cursor = llListFindList(lang_data, [msg]) + mlGetLangNum(lang_code) + 1; temp_result = llList2String(lang_data, cursor); if (replacement_num != 0){ list split = llParseStringKeepNulls(temp_result, ["%s"], []); integer i; for (i=0; i<replacement_num + 1; i++){ result += llList2String(split, i) + llList2String(replacement, i); } }else{ result = temp_result; } if (command == "ML_SAY"){ channel = (integer)llList2String(temp_data, 0); llSay(channel, result); }else if (command == "ML_WHISPER"){ channel = (integer)llList2String(temp_data, 0); llWhisper(channel, result); }else if (command == "ML_REGION_SAY"){ channel = (integer)llList2String(temp_data, 0); llRegionSay(channel, result); }else if (command == "ML_OWNER_SAY"){ llOwnerSay(result); }else if (command == "ML_INSTANT_MESSAGE"){ llInstantMessage(id, result); }else if (command == "ML_SET_TEXT"){ color = (vector)llList2String(temp_data, 0); alpha = (float)llList2String(temp_data, 1); llSetText(result, color, alpha); }else if (command == "ML_DIALOG"){ channel = (integer)llList2String(temp_data, 0); buttons = llList2List(temp_data, 1, -1); llDialog(id, result, buttons, channel); }else if (command == "ML_LOAD_URL"){ url = llList2String(temp_data, 0); llLoadURL(id, result, url); } } } } }
Alternative Functions
// ######## Alternative Functions for LSL MultiLingual Library ######## // // LSL Multilingual Library Command Num integer ML_COMMAND = -125; // Alternative Function: mlSay(integer channel, string msg, string lang_code, list replacement) mlSay(integer channel, string msg, string lang_code, list replacement){ string sending_msg = "ML_SAY||" + msg + "||" + lang_code + "||" + (string)channel + "||" + llDumpList2String(replacement, "|"); llMessageLinked(LINK_SET, ML_COMMAND, sending_msg, ""); } // Alternative Function: mlOwnerSay(string msg, string lang_code, list replacement) mlOwnerSay(string msg, string lang_code, list replacement){ string sending_msg = "ML_OWNER_SAY||" + msg + "||" + lang_code + "||NULL||" + llDumpList2String(replacement, "|"); llMessageLinked(LINK_SET, ML_COMMAND, sending_msg, ""); } // Alternative Function: mlWhisper(integer channel, string msg, string lang_code, list replacement) mlWhisper(integer channel, string msg, string lang_code, list replacement){ string sending_msg = "ML_WHISPER||" + msg + "||" + lang_code + "||" + (string)channel + "||" + llDumpList2String(replacement, "|"); llMessageLinked(LINK_SET, ML_COMMAND, sending_msg, ""); } // Alternative Function: mlRegionSay(integer channel, string msg, string lang_code, list replacement) mlRegionSay(integer channel, string msg, string lang_code, list replacement){ string sending_msg = "ML_REGION_SAY||" + msg + "||" + lang_code + "||" + (string)channel + "||" + llDumpList2String(replacement, "|"); llMessageLinked(LINK_SET, ML_COMMAND, sending_msg, ""); } // Alternative Function: mlInstantMessage(key id, string msg, string lang_code, list replacement) mlInstantMessage(key id, string msg, string lang_code, list replacement){ string sending_msg = "ML_INSTANT_MESSAGE||" + msg + "||" + lang_code + "||NULL||" + llDumpList2String(replacement, "|"); llMessageLinked(LINK_SET, ML_COMMAND, sending_msg, id); } // Alternative Function: mlSetText(string str, vector color, float alpha, string lang_code, list replacement) mlSetText(string str, vector color, float alpha, string lang_code, list replacement){ string sending_msg = "ML_SET_TEXT||" + str + "||" + lang_code + "||" + (string)color + "|" + (string)alpha + "||" + llDumpList2String(replacement, "|"); llMessageLinked(LINK_SET, ML_COMMAND, sending_msg, ""); } // Alternative Function: mlDialog(key id, string msg, list buttons, integer channel, string lang_code, list replacement) mlDialog(key id, string msg, list buttons, integer channel, string lang_code, list replacement){ string sending_msg = "ML_DIALOG||" + msg + "||" + lang_code + "||" + (string)channel + "|" + llDumpList2String(buttons, "|") + "||" + llDumpList2String(replacement, "|"); llMessageLinked(LINK_SET, ML_COMMAND, sending_msg, id); } // Alternative Function: mlLoadURL(key id, string msg, string url, string lang_code, list replacement) mlLoadURL(key id, string msg, string url, string lang_code, list replacement){ string sending_msg = "ML_LOAD_URL||" + msg + "||" + lang_code + "||" + url + "||" + llDumpList2String(replacement, "|"); llMessageLinked(LINK_SET, ML_COMMAND, sending_msg, id); } // [EOF] // Copyright 2008 arz Nitely <http://arznitely.com/> // // _______________________________________________a_r_z___N_i_t_e_l_y__ // Sample Script default{ state_entry(){ llSetText("", <1.0, 1.0, 1.0>, 1.0); key owner_key = llGetOwner(); string owner_name = llKey2Name(owner_key); string owner_lang = llGetAgentLanguage(owner_key); mlSay(0, "HELLO_AVATAR", owner_lang, [owner_name]); } touch_start(integer total_number){ key user_key = llDetectedKey(0); string user_name = llKey2Name(user_key); string user_lang = llGetAgentLanguage(user_key); mlInstantMessage(user_key, "TOUCHED", user_lang , [user_lang, user_name]); } }