Skip to content
Snippets Groups Projects
Commit 24692562 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Start of localization support for JS modules/shells/etc.

Similar to GNU gettext(), by loading gettext.js and enclosing all user-visible
strings in gettext(), a script can get easy/easier support for non-default
(i.e. US-English) locales by loading translated strings from the [JS] section
of ctrl/text.<locale>.ini (if it exists), or customized strings from the [JS]
section of ctrl/text.ini (if it exists).

Results are cached for fast subsequent uses of the same string.

What's *not* supported is different translations (e.g. colorization or
whatever) for the same string used in a different scripts. That could be
added (e.g. use a different section name for script-specific translations),
pretty easily, if desired.
parent 309fe94c
No related branches found
No related tags found
1 merge request!455Update branch with changes from master
......@@ -9,6 +9,7 @@ require("sbbsdefs.js", "K_UPPER");
require("userdefs.js", "UFLAG_T");
require("nodedefs.js", "NODE_MAIN");
require("key_defs.js", "KEY_UP");
require("gettext.js", "gettext");
require("text.js", "Pause");
bbs.revert_text(Pause);
load("termsetup.js");
......@@ -22,7 +23,7 @@ const main_menu = {
file: "main",
eval: 'bbs.main_cmds++',
node_action: NODE_MAIN,
prompt: "\x01-\x01c\xfe \x01b\x01hMain \x01n\x01c\xfe \x01h" + time_code +
prompt: "\x01-\x01c\xfe \x01b\x01h" + gettext("Main") + " \x01n\x01c\xfe \x01h" + time_code +
" \x01n\x01c[\x01h@GN@\x01n\x01c] @GRP@\x01\\ [\x01h@SN@\x01n\x01c] @SUB@: \x01n",
num_input: shell.get_sub_num,
slash_num_input: shell.get_grp_num,
......@@ -30,14 +31,14 @@ const main_menu = {
'A': { eval: 'bbs.auto_msg()' },
'/A': { exec: 'avatar_chooser.js'
,ars: 'ANSI and not GUEST'
,err: '\r\nSorry, only regular users with ANSI terminals can do that.\r\n' },
,err: '\r\n' + gettext("Sorry, only regular users with ANSI terminals can do that.") + '\r\n' },
'B': { eval: 'bbs.scan_subs(SCAN_BACK)'
,msg: '\r\n\x01c\x01hBrowse/New Message Scan\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Browse/New Message Scan") + '\r\n' },
'C': { eval: 'bbs.chat_sec()' },
'D': { eval: 'bbs.user_config(); exit()' },
'E': { exec: 'email_sec.js' },
'F': { eval: 'bbs.scan_subs(SCAN_FIND)'
,msg: '\r\n\x01c\x01hFind Text in Messages\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Find Text in Messages") + '\r\n' },
'/F': { eval: 'bbs.scan_subs(SCAN_FIND, /* all */true)' },
'G': { eval: 'bbs.text_sec()' },
'I': { eval: 'shell.main_info()' },
......@@ -46,7 +47,7 @@ const main_menu = {
'/L': { eval: 'bbs.list_nodes()' },
'M': { eval: 'bbs.time_bank()' },
'N': { eval: 'bbs.scan_subs(SCAN_NEW)'
,msg: '\r\n\x01c\x01hNew Message Scan\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("New Message Scan") + '\r\n' },
'/N': { eval: 'bbs.scan_subs(SCAN_NEW, /* all */true)' },
'O': { eval: 'shell.logoff(/* fast: */false)' },
'/O': { eval: 'shell.logoff(/* fast: */true)' },
......@@ -55,7 +56,7 @@ const main_menu = {
'Q': { eval: 'bbs.qwk_sec()' },
'R': { eval: 'bbs.scan_msgs()' },
'S': { eval: 'bbs.scan_subs(SCAN_TOYOU)'
,msg: '\r\n\x01c\x01hScan for Messages Posted to You\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Scan for Messages Posted to You") + '\r\n' },
'/S': { eval: 'bbs.scan_subs(SCAN_TOYOU, /* all */true)' },
'U': { eval: 'shell.list_users()' },
'/U': { eval: 'bbs.list_users(UL_ALL)' },
......@@ -64,15 +65,15 @@ const main_menu = {
'W': { eval: 'bbs.whos_online()' },
'X': { eval: 'bbs.xtrn_sec()' },
'Z': { eval: 'bbs.scan_subs(SCAN_NEW | SCAN_CONT)'
,msg: '\r\n\x01c\x01hContinuous New Message Scan\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Continuous New Message Scan") + '\r\n' },
'/Z': { eval: 'bbs.scan_subs(SCAN_NEW | SCAN_CONT, /* all */true)' },
'*': { eval: 'shell.show_subs(bbs.curgrp)' },
'/*': { eval: 'shell.show_grps()' },
'&': { exec: 'msgscancfg.js' },
'!': { eval: 'bbs.menu("sysmain")'
,ars: 'SYSOP or EXEMPT Q or I or N' },
'#': { msg: '\r\n\x01c\x01hType the actual number, not the symbol.\r\n' },
'/#': { msg: '\r\n\x01c\x01hType the actual number, not the symbol.\r\n' },
'#': { msg: '\r\n\x01c\x01h' + gettext("Type the actual number, not the symbol.") + '\r\n' },
'/#': { msg: '\r\n\x01c\x01h' + gettext("Type the actual number, not the symbol.") + '\r\n' },
},
nav: {
'\r': { },
......@@ -101,7 +102,7 @@ const file_menu = {
file: "transfer",
eval: 'bbs.file_cmds++',
node_action: NODE_XFER,
prompt: "\x01-\x01c\xfe \x01b\x01hFile \x01n\x01c\xfe \x01h" + time_code +
prompt: "\x01-\x01c\xfe \x01b\x01h" + gettext("File") + " \x01n\x01c\xfe \x01h" + time_code +
" \x01n\x01c(\x01h@LN@\x01n\x01c) @LIB@\x01\\ (\x01h@DN@\x01n\x01c) @DIR@: \x01n",
num_input: shell.get_dir_num,
slash_num_input: shell.get_lib_num,
......@@ -109,46 +110,46 @@ const file_menu = {
'B': { eval: 'bbs.batch_menu()' },
'C': { eval: 'bbs.chat_sec()' },
'D': { eval: 'shell.download_files()'
,msg: '\r\n\x01c\x01hDownload File(s)\r\n'
,msg: '\r\n\x01c\x01h' + gettext("Download File(s)") + '\r\n'
,ars: 'REST NOT D' },
'/D': { eval: 'shell.download_user_files()'
,msg: '\r\n\x01c\x01hDownload File(s) from User(s)\r\n'
,msg: '\r\n\x01c\x01h' + gettext("Download File(s) from User(s)") + '\r\n'
,ars: 'REST NOT D' },
'E': { eval: 'shell.view_file_info(FI_INFO)'
,msg: '\r\n\x01c\x01hList Extended File Information\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("List Extended File Information") + '\r\n' },
'F': { eval: 'bbs.scan_dirs(FL_FINDDESC);'
,msg: '\r\n\x01c\x01hFind Text in File Descriptions (no wildcards)\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Find Text in File Descriptions (no wildcards)") + '\r\n' },
'/F': { eval: 'bbs.scan_dirs(FL_FINDDESC, /* all: */true);' },
'I': { eval: 'shell.file_info()' },
'J': { eval: 'shell.select_file_area()' },
'L': { eval: 'shell.list_files()' },
'/L': { eval: 'bbs.list_nodes()' },
'N': { eval: 'bbs.scan_dirs(FL_ULTIME)'
,msg: '\r\n\x01c\x01hNew File Scan\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("New File Scan") + '\r\n' },
'/N': { eval: 'bbs.scan_dirs(FL_ULTIME, /* all */true)' },
'O': { eval: 'shell.logoff(/* fast: */false)' },
'/O': { eval: 'shell.logoff(/* fast: */true)' },
'R': { eval: 'shell.view_file_info(FI_REMOVE)'
,msg: '\r\n\x01c\x01hRemove/Edit File(s)\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Remove/Edit File(s)") + '\r\n' },
'S': { eval: 'bbs.scan_dirs(FL_NO_HDR)'
,msg: '\r\n\x01c\x01hSearch for Filename(s)\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Search for Filename(s)") + '\r\n' },
'/S': { eval: 'bbs.scan_dirs(FL_NO_HDR, /* all */true) ' },
'T': { eval: 'bbs.temp_xfer()' },
'U': { eval: 'shell.upload_file()'
,msg: '\r\n\x01c\x01hUpload File\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Upload File") + '\r\n' },
'/U': { eval: 'shell.upload_user_file()'
,msg: '\r\n\x01c\x01hUpload File to User\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Upload File to User") + '\r\n' },
'V': { eval: 'shell.view_files()'
,msg: '\r\n\x01c\x01hView File(s)\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("View File(s)") + '\r\n' },
'W': { eval: 'bbs.whos_online()' },
'Z': { eval: 'shell.upload_sysop_file()'
,msg: '\r\n\x01c\x01hUpload File to Sysop\r\n' },
,msg: '\r\n\x01c\x01h' + gettext("Upload File to Sysop") + '\r\n' },
'*': { eval: 'shell.show_dirs(bbs.curlib)' },
'/*': { eval: 'shell.show_libs()' },
'&': { exec: 'filescancfg.js' },
'!': { eval: 'bbs.menu("sysxfer")' },
'#': { msg: '\r\n\x01c\x01hType the actual number, not the symbol.\r\n' },
'/#': { msg: '\r\n\x01c\x01hType the actual number, not the symbol.\r\n' },
'#': { msg: '\r\n\x01c\x01h' + gettext("Type the actual number, not the symbol.") + '\r\n' },
'/#': { msg: '\r\n\x01c\x01h' + gettext("Type the actual number, not the symbol.") + '\r\n' },
},
nav: {
'\r': { },
......@@ -232,9 +233,9 @@ while(bbs.online && !js.terminated) {
}
var menu_cmd = menu.command[cmd];
if(!menu_cmd) {
console.print("\r\n\x01c\x01hUnrecognized command.");
console.print("\r\n\x01c\x01h" + gettext("Unrecognized command."));
if(user.settings & USER_EXPERT)
console.print(" Hit '\x01i" + help_key + "\x01n\x01c\x01h' for a menu.");
console.print(" " + gettext("Hit") + " '\x01i" + help_key + "\x01n\x01c\x01h' " + gettext("for a menu."));
console.crlf();
continue;
}
......
// Localized/customized support for JavaScript user-visible text (i.e. strings not contained in text.dat)
// Customized text strings go in the [JS] section of ctrl/text.ini
// Localized (translated to non-default locale) text strings go in the [JS] section of ctrl/text.<lang>.ini
"use strict";
var gettext_cache = {};
function gettext(orig) {
function get_text_from_ini(ini_fname, orig) {
var f = new File(ini_fname);
if(!f.open("r"))
return undefined;
var text = f.iniGetValue("js", orig);
f.close();
return text;
}
if (gettext_cache[orig] !== undefined)
return gettext_cache[orig];
var text;
if (user.lang)
text = get_text_from_ini("text." + user.lang + ".ini", orig);
if (text === undefined)
text = get_text_from_ini("text.ini", orig);
if (text === undefined)
text = orig;
return gettext_cache[orig] = text;
}
this;
......@@ -7,6 +7,7 @@
require("text.js", "DownloadBatchQ");
require("sbbsdefs.js", "USER_EXPERT");
require("gettext.js", "gettext");
// Build list of current subs/dirs in each group/library
// This hack is required because the 'bbs' object doesn't expose the current
......@@ -244,7 +245,7 @@ function main_info()
if(!(user.settings & USER_EXPERT))
bbs.menu("maininfo");
bbs.nodesync();
console.print("\r\n\x01y\x01hInfo: \x01n");
console.print("\r\n\x01y\x01h"+ gettext("Info") + ": \x01n");
var key = console.getkeys("?QISVY\r");
bbs.log_key(key);
switch(key) {
......@@ -290,7 +291,7 @@ function file_info()
if(!(user.settings & USER_EXPERT))
bbs.menu("xferinfo");
bbs.nodesync();
console.print("\r\n\x01y\x01hInfo: \x01n");
console.print("\r\n\x01y\x01h" + gettext("Info") + ": \x01n");
key=console.getkeys("?TYDUQ\r");
bbs.log_key(key);
......@@ -325,9 +326,9 @@ function file_info()
function list_users()
{
console.print("\r\n\x01c\x01hList Users\r\n");
console.mnemonics("\r\n~Logons Today, ~Yesterday, ~Sub-board, or ~All: ");
switch(console.getkeys("LSAY\r")) {
console.print("\r\n\x01c\x01h" + "List Users" + "\r\n");
console.mnemonics("\r\n~" + gettext("Logons Today") + ", ~" + gettext("Yesterday") + ", ~" + gettext("Sub-board") + ", " + gettext("or") + " ~@All@: ");
switch(console.getkeys("LSY\r" + console.all_key)) {
case 'L':
bbs.list_logons();
break;
......@@ -337,7 +338,7 @@ function list_users()
case 'S':
bbs.list_users(UL_SUB);
break;
case 'A':
case console.all_key:
bbs.list_users(UL_ALL);
break;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment