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) { 'load': function(data, params) {
dbot.moduleNames.push(params[1]); dbot.moduleNames.push(params[1]);
dbot.reloadModules(); 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) { 'unload': function(data, params) {
@ -72,9 +72,9 @@ var adminCommands = function(dbot) {
dbot.moduleNames.splice(moduleIndex, 1); dbot.moduleNames.splice(moduleIndex, 1);
dbot.reloadModules(); 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 { } 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 { } else {
dbot.db.bans[params[2]] = [ params[1] ]; 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) { 'unban': function(data, params) {
if(dbot.db.bans.hasOwnProperty(params[2]) && dbot.db.bans[params[2]].include(params[1])) { 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.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 { } 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) { 'modehate': function(data, params) {
dbot.db.modehate.push(params[1]); 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) { 'unmodehate': function(data, params) {
dbot.db.modehate.splice(dbot.db.modehate.indexOf(params[1]), 1); 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) { 'lock': function(data, params) {
dbot.db.locks.push(params[1]); 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)) { if(quotes.hasOwnProperty(key)) {
dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key)); dbot.say(data.channel, q[1] + ': ' + interpolatedQuote(key));
} else { } 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.say(data.channel, '\'' + quote + '\'' +
dbot.strings[dbot.language].removed_from + q[1]); dbot.strings[dbot.language].removed_from + q[1]);
} else { } 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 { } 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 { } else {
var last = addStack.pop(); var last = addStack.pop();
@ -132,9 +132,9 @@ var quotes = function(dbot) {
if(!dbot.db.locks.include(last)) { if(!dbot.db.locks.include(last)) {
quotes[last].pop(); quotes[last].pop();
rmAllowed = false; 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 { } 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 { } else {
dbot.say(data.channel, dbot.strings[dbot.language].no_recent_adds); dbot.say(data.channel, dbot.strings[dbot.language].no_recent_adds);
@ -158,17 +158,15 @@ var quotes = function(dbot) {
delete quotes[q[1]]; delete quotes[q[1]];
} }
rmAllowed = false; rmAllowed = false;
dbot.say(data.channel, '\'' + q[2] + '\'' + dbot.say(data.channel, dbot.strings[dbot.language].removed_from.format({'category': q[1], 'quote': q[2]}));
dbot.strings[dbot.language].removed_from + q[1]);
} else { } else {
dbot.say(data.channel, '\'' + q[2] + '\'' + dbot.say(data.channel, dbot.strings[dbot.language].q_not_exist_under.format({'category': q[1], 'quote': q[2]}));
dbot.strings[dbot.language].q_not_exist_under + '\'' + q[1] + '\'.');
} }
} else { } 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 { } 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 { } else {
dbot.say(data.channel, dbot.strings[dbot.language].syntax_error); dbot.say(data.channel, dbot.strings[dbot.language].syntax_error);
@ -193,7 +191,7 @@ var quotes = function(dbot) {
for(var category in quotes) { for(var category in quotes) {
totalQuoteCount += category.length; 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]); quotes[key].push(q[2]);
addStack.push(q[1]); addStack.push(q[1]);
rmAllowed = true; rmAllowed = true;
dbot.say(data.channel, dbot.strings[dbot.language].quote_saved + dbot.say(data.channel, dbot.strings[dbot.language].quote_saved.format({'category': q[1], 'count': quotes[key].length}));
'\'' + q[1] + '\' (' + quotes[key].length + ')');
} else { } else {
dbot.say(data.channel, dbot.strings[dbot.language].syntax_error); 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) && if(!quotes.hasOwnProperty(key) || (quotes.hasOwnProperty(key) &&
quotes[key].length == 1)) { quotes[key].length == 1)) {
quotes[key] = [q[2]]; 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 { } else {
dbot.say(data.channel, dbot.strings[dbot.language].quote_replace); dbot.say(data.channel, dbot.strings[dbot.language].quote_replace);
} }
@ -262,7 +259,7 @@ var quotes = function(dbot) {
} }
} }
if(pruned.length > 0) { 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 { } else {
dbot.say(data.channel, dbot.strings[dbot.language].no_prune); 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); var otherQ = data.message.valMatch(/^([\d\w\s]*): (?:\*\*?([\d\w\s']*)|([\d\w\s']*)\*\*?)$/, 4);
if(q) { if(q) {
correct(data, q[1] || q[2], data.user, function (e) { 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) { } else if(otherQ) {
correct(data, otherQ[2] || otherQ[3], otherQ[1], function (e) { correct(data, otherQ[2] || otherQ[3], otherQ[1], function (e) {
dbot.say(data.channel, e.correcter + dbot.strings[dbot.language].spelling_other + dbot.say(data.channel, dbot.strings[dbot.language].spelling_other.format(e));
e.candidate + dbot.strings[dbot.language].spelling_self + e.fix);
}); });
} else { } else {
if(last.hasOwnProperty(data.channel)) { if(last.hasOwnProperty(data.channel)) {

2
run.js
View File

@ -117,7 +117,7 @@ DBot.prototype.reloadModules = function() {
try { try {
this.rawModules.push(require('./modules/' + name)); this.rawModules.push(require('./modules/' + name));
} catch(err) { } 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)); }.bind(this));

View File

@ -127,6 +127,21 @@ String.prototype.distance = function(s1, s2) {
return v0[s1_len]; 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 ***/
Object.prototype.isFunction = function(obj) { Object.prototype.isFunction = function(obj) {

View File

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