Merge pull request #38 from psquid/flexible-translate-strings

Use String.prototype.format() <https://gist.github.com/1153608> to make the translation strings more amenable to variations in word order.
This commit is contained in:
Luke Slater 2012-03-26 06:36:38 -07:00
commit e9b6b2d0f6
6 changed files with 82 additions and 71 deletions

View File

@ -60,7 +60,7 @@ var adminCommands = function(dbot) {
'load': function(data, params) {
dbot.moduleNames.push(params[1]);
dbot.reloadModules();
dbot.say(data.channel, dbot.strings[dbot.language].load_module + params[1]);
dbot.say(data.channel, dbot.strings[dbot.language].load_module.format({'moduleName': params[1]}));
},
'unload': function(data, params) {
@ -72,9 +72,9 @@ var adminCommands = function(dbot) {
dbot.moduleNames.splice(moduleIndex, 1);
dbot.reloadModules();
dbot.say(data.channel, dbot.strings[dbot.language].unload_module + params[1]);
dbot.say(data.channel, dbot.strings[dbot.language].unload_module.format({'moduleName': params[1]}));
} else {
dbot.say(data.channel, params[1] + dbot.strings[dbot.language].unload_error);
dbot.say(data.channel, dbot.strings[dbot.language].unload_error.format({'moduleName': params[1]}));
}
},
@ -84,31 +84,31 @@ var adminCommands = function(dbot) {
} else {
dbot.db.bans[params[2]] = [ params[1] ];
}
dbot.say(data.channel, params[1] + dbot.strings[dbot.language].banned + params[2]);
dbot.say(data.channel, dbot.strings[dbot.language].banned.format({'user': params[1], 'command': params[2]}));
},
'unban': function(data, params) {
if(dbot.db.bans.hasOwnProperty(params[2]) && dbot.db.bans[params[2]].include(params[1])) {
dbot.db.bans[params[2]].splice(dbot.db.bans[params[2]].indexOf(params[1]), 1);
dbot.say(data.channel, params[1] + dbot.strings[dbot.language].unbanned + params[2]);
dbot.say(data.channel, dbot.strings[dbot.language].unbanned.format({'user': params[1], 'command': params[2]}));
} else {
dbot.say(data.channel, params[1] + dbot.strings[dbot.language].unban_error);
dbot.say(data.channel, dbot.strings[dbot.language].unban_error.format({'user': params[1]}));
}
},
'modehate': function(data, params) {
dbot.db.modehate.push(params[1]);
dbot.say(data.channel, dbot.strings[dbot.language].modehate + params[1]);
dbot.say(data.channel, dbot.strings[dbot.language].modehate.format({'user': params[1]}));
},
'unmodehate': function(data, params) {
dbot.db.modehate.splice(dbot.db.modehate.indexOf(params[1]), 1);
dbot.say(data.channel, dbot.strings[dbot.language].unmodehate + params[1]);
dbot.say(data.channel, dbot.strings[dbot.language].unmodehate.format({'user': params[1]}));
},
'lock': function(data, params) {
dbot.db.locks.push(params[1]);
dbot.say(data.channel, dbot.strings[dbot.language].qlock + params[1]);
dbot.say(data.channel, dbot.strings[dbot.language].qlock.format({'category': params[1]}));
}
};

View File

@ -53,7 +53,7 @@ var quotes = function(dbot) {
if(quotes.hasOwnProperty(key)) {
dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key));
} else {
dbot.say(data.channel, dbot.strings[dbot.language].category_not_found + q[1]);
dbot.say(data.channel, dbot.strings[dbot.language].category_not_found.format({'category': q[1]}));
}
}
},
@ -121,10 +121,10 @@ var quotes = function(dbot) {
dbot.say(data.channel, '\'' + quote + '\'' +
dbot.strings[dbot.language].removed_from + q[1]);
} else {
dbot.say(data.channel, q[1] + dbot.strings[dbot.language].locked_category);
dbot.say(data.channel, dbot.strings[dbot.language].locked_category.format({'category': q[1]}));
}
} else {
dbot.say(data.channel, dbot.strings[dbot.language].no_quotes + q[1]);
dbot.say(data.channel, dbot.strings[dbot.language].no_quotes.format({'category': q[1]}));
}
} else {
var last = addStack.pop();
@ -132,9 +132,9 @@ var quotes = function(dbot) {
if(!dbot.db.locks.include(last)) {
quotes[last].pop();
rmAllowed = false;
dbot.say(data.channel, dbot.strings[dbot.language].last_removed + last + '.');
dbot.say(data.channel, dbot.strings[dbot.language].last_removed.format({'category': last}));
} else {
dbot.say(data.channel, last + dbot.strings[dbot.language].locked_category);
dbot.say(data.channel, dbot.strings[dbot.language].locked_category.format({'category': last}));
}
} else {
dbot.say(data.channel, dbot.strings[dbot.language].no_recent_adds);
@ -158,17 +158,15 @@ var quotes = function(dbot) {
delete quotes[q[1]];
}
rmAllowed = false;
dbot.say(data.channel, '\'' + q[2] + '\'' +
dbot.strings[dbot.language].removed_from + q[1]);
dbot.say(data.channel, dbot.strings[dbot.language].removed_from.format({'category': q[1], 'quote': q[2]}));
} else {
dbot.say(data.channel, '\'' + q[2] + '\'' +
dbot.strings[dbot.language].q_not_exist_under + '\'' + q[1] + '\'.');
dbot.say(data.channel, dbot.strings[dbot.language].q_not_exist_under.format({'category': q[1], 'quote': q[2]}));
}
} else {
dbot.say(data.channel, q[1] + dbot.strings[dbot.language].locked_category);
dbot.say(data.channel, dbot.strings[dbot.language].locked_category.format({'category': q[1]}));
}
} else {
dbot.say(data.channel, dbot.strings[dbot.language].no_quotes + q[1]);
dbot.say(data.channel, dbot.strings[dbot.language].no_quotes.format({'category': q[1]}));
}
} else {
dbot.say(data.channel, dbot.strings[dbot.language].syntax_error);
@ -193,7 +191,7 @@ var quotes = function(dbot) {
for(var category in quotes) {
totalQuoteCount += category.length;
}
dbot.say(data.channel, dbot.strings[dbot.language].total_quotes + totalQuoteCount + '.');
dbot.say(data.channel, dbot.strings[dbot.language].total_quotes.format({'count': totalQuoteCount}));
}
},
@ -212,8 +210,7 @@ var quotes = function(dbot) {
quotes[key].push(q[2]);
addStack.push(q[1]);
rmAllowed = true;
dbot.say(data.channel, dbot.strings[dbot.language].quote_saved +
'\'' + q[1] + '\' (' + quotes[key].length + ')');
dbot.say(data.channel, dbot.strings[dbot.language].quote_saved.format({'category': q[1], 'count': quotes[key].length}));
} else {
dbot.say(data.channel, dbot.strings[dbot.language].syntax_error);
}
@ -227,7 +224,7 @@ var quotes = function(dbot) {
if(!quotes.hasOwnProperty(key) || (quotes.hasOwnProperty(key) &&
quotes[key].length == 1)) {
quotes[key] = [q[2]];
dbot.say(data.channel, dbot.strings[dbot.language].quote_saved + q[1]);
dbot.say(data.channel, dbot.strings[dbot.language].quote_saved.format({'category': q[1], 'count': 1}));
} else {
dbot.say(data.channel, dbot.strings[dbot.language].quote_replace);
}
@ -262,7 +259,7 @@ var quotes = function(dbot) {
}
}
if(pruned.length > 0) {
dbot.say(data.channel, dbot.strings[dbot.language].prune + pruned.join(", "));
dbot.say(data.channel, dbot.strings[dbot.language].prune.format({'categories': pruned.join(", ")}));
} else {
dbot.say(data.channel, dbot.strings[dbot.language].no_prune);
}

View File

@ -42,12 +42,11 @@ var spelling = function(dbot) {
var otherQ = data.message.valMatch(/^([\d\w\s]*): (?:\*\*?([\d\w\s']*)|([\d\w\s']*)\*\*?)$/, 4);
if(q) {
correct(data, q[1] || q[2], data.user, function (e) {
dbot.say(data.channel, e.correcter + dbot.strings[dbot.language].spelling_self + e.fix);
dbot.say(data.channel, dbot.strings[dbot.language].spelling_self.format(e));
});
} else if(otherQ) {
correct(data, otherQ[2] || otherQ[3], otherQ[1], function (e) {
dbot.say(data.channel, e.correcter + dbot.strings[dbot.language].spelling_other +
e.candidate + dbot.strings[dbot.language].spelling_self + e.fix);
dbot.say(data.channel, dbot.strings[dbot.language].spelling_other.format(e));
});
} else {
if(last.hasOwnProperty(data.channel)) {

2
run.js
View File

@ -117,7 +117,7 @@ DBot.prototype.reloadModules = function() {
try {
this.rawModules.push(require('./modules/' + name));
} catch(err) {
console.log(this.strings[this.language].module_load_error + name);
console.log(this.strings[this.language].module_load_error.format({'moduleName': name}));
}
}.bind(this));

View File

@ -127,6 +127,21 @@ String.prototype.distance = function(s1, s2) {
return v0[s1_len];
}
String.prototype.format = function() { // format takes either multiple indexed arguments, or a single object, whose keys/values will be used
var targetStr = this;
var replacements = [].splice.call(arguments, 0);
if ((replacements.length === 1) && (typeof(replacements[0]) === 'object')) { // if we were passed a single object rather than multiple args
replacements = replacements[0]; // use the object as source of replacements
};
for (key in replacements) {
if (replacements.hasOwnProperty(key)) {
var replacePattern = new RegExp("\\{"+key+"\\}", "g");
targetStr = targetStr.replace(replacePattern, replacements[key]);
};
};
return targetStr;
};
/*** Object ***/
Object.prototype.isFunction = function(obj) {

View File

@ -1,74 +1,74 @@
{
"english": {
"syntax_error": "Invalid syntax. Initiate incineration.",
"module_load_error": "Failed to load module: ",
"category_not_found": "Nobody loves ",
"module_load_error": "Failed to load module: {moduleName}",
"category_not_found": "Nobody loves {category}",
"large_categories": "Largest categories: ",
"empty_category": "That category has no quotes in. Commence incineration.",
"no_results": "No results found.",
"locked_category": " is locked. Commence incineration.",
"no_quotes": "No quotes exist under ",
"last_removed": "Last quote removed from ",
"locked_category": "{category} is locked. Commence incineration.",
"no_quotes": "No quotes exist under {category}",
"last_removed": "Last quote removed from {category}.",
"no_recent_adds": "No quotes were added recently.",
"rmlast_spam": "No spamming that shit. Try again in a few minutes...",
"removed_from": " removed from ",
"q_not_exist_under": " doesn't exist under user ",
"total_quotes": "Total quote count: ",
"removed_from": "'{quote}' removed from {category}",
"q_not_exist_under": "'{quote}' doesn't exist under '{category}'.",
"total_quotes": "Total quote count: {count}.",
"quote_exists": "Quote already in DB. Initiate incineration.",
"quote_saved": "Quote saved in ",
"quote_saved": "Quote saved in '{category}' ({count}).",
"quote_replace": "No replacing arrays, you whore.",
"prune": "Pruning empty quote categories: ",
"prune": "Pruning empty quote categories: {categories}",
"no_prune": "No empty quote categories. Commence incineration.",
"command_ban": " is banned from using this command. Commence incineration.",
"correction": "Did you mean: ",
"gpull": "Git pulled that shit.",
"reload": "Reloaded that shit.",
"load_module": "Loaded new module: ",
"unload_module": "Turned off module: ",
"unload_error": " isn't loaded. Idiot.",
"banned": " banned from ",
"unbanned": " unbanned from ",
"unban_error": " wasn't banned from that command, fool.",
"modehate": "Hating on ",
"unmodehate": "No longer hating on ",
"qlock": "Locked quote category: ",
"spelling_self": " meant: ",
"spelling_other": " thinks "
"load_module": "Loaded new module: {moduleName}",
"unload_module": "Turned off module: {moduleName}",
"unload_error": "{moduleName} isn't loaded. Idiot.",
"banned": "{user} banned from {command}",
"unbanned": "{user} unbanned from {command}",
"unban_error": "{user} wasn't banned from that command, fool.",
"modehate": "Hating on {user}",
"unmodehate": "No longer hating on {user}",
"qlock": "Locked quote category: {category}",
"spelling_self": "{correcter} meant: {fix}",
"spelling_other": "{correcter} thinks {candidate} meant: {fix}"
},
"spanish": {
"syntax_error": "Sintaxis no válida. Iniciar incineración.",
"module_load_error": "No se pudó cargar el módulo: ",
"category_not_found": "Nadie ama a ",
"module_load_error": "No se pudó cargar el módulo: {moduleName}",
"category_not_found": "Nadie ama a {category}",
"large_categories": "Los categorías más grandes: ",
"empty_category": "Categoría vacía. Iniciar incineración.",
"no_results": "No hubo ningún resultado.",
"locked_category": " está cerrada. Comenzar incineración.",
"no_quotes": "Ninguna cita existe en ",
"last_removed": "Última cita quitado de ",
"locked_category": "{category} está cerrada. Comenzar incineración.",
"no_quotes": "Ninguna cita existe en {category}",
"last_removed": "Última cita quitado de {category}.",
"no_recent_adds": "Ninguna cita fue añadido recientamente.",
"rmlast_spam": "No me inundes de mierda. Intenta otra vez en unos minutos.",
"removed_from": " quitado de ",
"q_not_exist_under": " no existe en ",
"total_quotes": "Total de citas: ",
"removed_from": "'{quote}' quitado de {category}",
"q_not_exist_under": "'{quote}' no existe en '{category}'.",
"total_quotes": "Total de citas: {count}.",
"quote_exists": "Cita ya existe. Iniciar incineración.",
"quote_saved": "Cita guardada en ",
"quote_saved": "Cita guardada en '{category}' ({count})",
"quote_replace": "No sustituites arrays, hijo de puta.",
"prune": "Reduciendo categorías vacías",
"prune": "Reduciendo categorías vacías {categories}",
"no_prune": "Ninguna categoría vacía. Comenzar incineracíon",
"command_ban": " está prohibido de usar esta instrucción. Comenzar incineración.",
"correction": "¿Querías decir: ",
"gpull": "Hecho git pull en esta mierda.",
"reload": "Recargado esta mierda.",
"load_module": "Cargado módulo nuevo: ",
"unload_module": "Descargado modulo: ",
"unload_error": " no está cargado. Idiota.",
"banned": "",
"unbanned": " prohibido de ",
"unban_error": " no fue prohibido de esta instrucción, tont@..",
"modehate": "Odiando a ",
"unmodehate": "Ni siquera odiando a ",
"qlock": "Cerrado la categoría: ",
"spelling_self": " quería decir: ",
"spelling_other": " piensa que "
"load_module": "Cargado módulo nuevo: {moduleName}",
"unload_module": "Descargado modulo: {moduleName}",
"unload_error": "{moduleName} no está cargado. Idiota.",
"banned": "{user} está prohibido de usar {command}",
"unbanned": "{user} no está prohibido de user {command}",
"unban_error": "{user} no fue prohibido de esta instrucción, tont@..",
"modehate": "Odiando a {user}",
"unmodehate": "Ni siquera odiando a {user}",
"qlock": "Cerrado la categoría: {category}",
"spelling_self": "{correcter} quería decir: {fix}",
"spelling_other": "{correcter} piensa que {candidate} queria decir: {fix}"
}
}