From 0a212bab1d647b99f3fa8ce47eaf4ef7690a6407 Mon Sep 17 00:00:00 2001 From: reality Date: Mon, 12 Aug 2013 23:14:44 +0000 Subject: [PATCH] some command correction shiz --- modules/command/command.js | 22 ++++- modules/spelling/spelling.js | 154 ++++++++++++++++++----------------- 2 files changed, 100 insertions(+), 76 deletions(-) diff --git a/modules/command/command.js b/modules/command/command.js index 0c37cab..073017c 100644 --- a/modules/command/command.js +++ b/modules/command/command.js @@ -13,7 +13,27 @@ var command = function(dbot) { this.listener = function(event) { var commandName = event.params[0]; if(!_.has(dbot.commands, commandName)) { - if(_.has(dbot.modules, 'quotes')) { + if(_.has(dbot.modules, 'spelling')) { + var commands = _.keys(dbot.commands) + winner = false, + closestMatch = Infinity; + + _.each(commands, function(command) { + var distance = dbot.api.spelling.distance(commandName, command); + if(distance < closestMatch) { + closestMatch = distance; + winner = command; + } + }); + + if(closestMatch < 3) { + event.reply(commandName + ' not found. Did you mean ' + winner + '?'); + } else if(_.has(dbot.modules, 'quotes')) { + commandName = '~'; + } else { + return; + } + } else if(_.has(dbot.modules, 'quotes')) { commandName = '~'; } else { return; diff --git a/modules/spelling/spelling.js b/modules/spelling/spelling.js index cf574c9..0c50bd7 100644 --- a/modules/spelling/spelling.js +++ b/modules/spelling/spelling.js @@ -1,83 +1,87 @@ var _ = require('underscore')._; -var allGroupings = function(arr) { - if (arr.length == 0) { - return []; /* short-circuit the empty-array case */ - } - var groupings = []; - for(var n=1;n<=arr.length;n++) { - for(var i=0;i<(arr.length-(n-1));i++) { - groupings.push(arr.slice(i, i+n)); - } - } - return groupings; -} -var distance = function(s1, s2) { - // Calculate Levenshtein distance between two strings - // - // version: 1109.2015 - // discuss at: http://phpjs.org/functions/levenshtein - // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) - // + bugfixed by: Onno Marsman - // + revised by: Andrea Giammarchi (http://webreflection.blogspot.com) - // + reimplemented by: Brett Zamir (http://brett-zamir.me) - // + reimplemented by: Alexander M Beedie - if (s1 == s2) { - return 0; - } - var s1_len = s1.length; - var s2_len = s2.length; - if (s1_len === 0) { - return s2_len; } - if (s2_len === 0) { - return s1_len; - } - // BEGIN STATIC - var split = false; - try { - split = !('0')[0]; - } catch (e) { - split = true; // Earlier IE may not support access by string index - } - // END STATIC - if (split) { - s1 = s1.split(''); s2 = s2.split(''); - } - - var v0 = new Array(s1_len + 1); - var v1 = new Array(s1_len + 1); - var s1_idx = 0, - s2_idx = 0, - cost = 0; - for (s1_idx = 0; s1_idx < s1_len + 1; s1_idx++) { v0[s1_idx] = s1_idx; - } - var char_s1 = '', - char_s2 = ''; - for (s2_idx = 1; s2_idx <= s2_len; s2_idx++) { v1[0] = s2_idx; - char_s2 = s2[s2_idx - 1]; - - for (s1_idx = 0; s1_idx < s1_len; s1_idx++) { - char_s1 = s1[s1_idx]; cost = (char_s1 == char_s2) ? 0 : 1; - var m_min = v0[s1_idx + 1] + 1; - var b = v1[s1_idx] + 1; - var c = v0[s1_idx] + cost; - if (b < m_min) { m_min = b; - } - if (c < m_min) { - m_min = c; - } v1[s1_idx + 1] = m_min; - } - var v_tmp = v0; - v0 = v1; - v1 = v_tmp; } - return v0[s1_len]; -}; - var spelling = function(dbot) { this.last = {}; + + this.api = { + 'allGroupings': function(arr) { + if (arr.length == 0) { + return []; /* short-circuit the empty-array case */ + } + var groupings = []; + for(var n=1;n<=arr.length;n++) { + for(var i=0;i<(arr.length-(n-1));i++) { + groupings.push(arr.slice(i, i+n)); + } + } + return groupings; + }, + + 'distance': function(s1, s2) { + // Calculate Levenshtein distance between two strings + // + // version: 1109.2015 + // discuss at: http://phpjs.org/functions/levenshtein + // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com) + // + bugfixed by: Onno Marsman + // + revised by: Andrea Giammarchi (http://webreflection.blogspot.com) + // + reimplemented by: Brett Zamir (http://brett-zamir.me) + // + reimplemented by: Alexander M Beedie + if (s1 == s2) { + return 0; + } + var s1_len = s1.length; + var s2_len = s2.length; + if (s1_len === 0) { + return s2_len; } + if (s2_len === 0) { + return s1_len; + } + // BEGIN STATIC + var split = false; + try { + split = !('0')[0]; + } catch (e) { + split = true; // Earlier IE may not support access by string index + } + // END STATIC + if (split) { + s1 = s1.split(''); s2 = s2.split(''); + } + + var v0 = new Array(s1_len + 1); + var v1 = new Array(s1_len + 1); + var s1_idx = 0, + s2_idx = 0, + cost = 0; + for (s1_idx = 0; s1_idx < s1_len + 1; s1_idx++) { v0[s1_idx] = s1_idx; + } + var char_s1 = '', + char_s2 = ''; + for (s2_idx = 1; s2_idx <= s2_len; s2_idx++) { v1[0] = s2_idx; + char_s2 = s2[s2_idx - 1]; + + for (s1_idx = 0; s1_idx < s1_len; s1_idx++) { + char_s1 = s1[s1_idx]; cost = (char_s1 == char_s2) ? 0 : 1; + var m_min = v0[s1_idx + 1] + 1; + var b = v1[s1_idx] + 1; + var c = v0[s1_idx] + cost; + if (b < m_min) { m_min = b; + } + if (c < m_min) { + m_min = c; + } v1[s1_idx + 1] = m_min; + } + var v_tmp = v0; + v0 = v1; + v1 = v_tmp; } + return v0[s1_len]; + } + }; + this.internalAPI = {}; this.internalAPI.correct = function (event, correction, candidate, output_callback) { - var rawCandidates = allGroupings(this.last[event.channel.name][candidate].split(' ')); + var rawCandidates = this.api.allGroupings(this.last[event.channel.name][candidate].split(' ')); var candidates = []; for(var i=0;i 0)) { winner = candidates[i]; winnerDistance = d;