Permalink
Browse files

Allow quoting of arguments for commands.

Quotes only work at the beginning and end of tokens, so the input

    name "Mike Cooper"

works, but

    name M"ike Coop"er

will not. This isn't bash, go away.
  • Loading branch information...
1 parent c71fecb commit cb395138fb481b6e03cdfc62b1e6eac8e5630a3e @mythmon mythmon committed Aug 23, 2012
Showing with 88 additions and 1 deletion.
  1. +1 −0 standup-irc.js
  2. +51 −0 test.js
  3. +36 −1 utils.js
View
1 standup-irc.js
@@ -119,6 +119,7 @@ client.on('message', function(user, channel, message) {
// message = "!cmd arg1 arg2 arg3"
var cmd_name = message.split(' ')[0].slice(1);
var args = message.split(' ').slice(1);
+ args = utils.parseArgs(args);
var cmd = commands[cmd_name] || commands['default'];
cmd.func(user, channel, message, args);
} else {
View
51 test.js
@@ -0,0 +1,51 @@
+assert = require('assert');
+
+utils = require('./utils');
+
+function eq(a, b, name) {
+ var expected = JSON.stringify(a);
+ var actual = JSON.stringify(b);
+ assert.deepEqual(a, b, name + ": Expected " + expected + ", but got " + actual);
+}
+
+(function test_parseArgs() {
+ var args;
+ var actual;
+ var expected;
+
+ // No-op
+ args = ["hello", "world"];
+ expected = args;
+ actual = utils.parseArgs(args);
+ eq(expected, actual, "noop");
+
+ // Basic quotes - single
+ args = ["one", "'two", "which", "is", "quoted'", "three"];
+ expected = ["one", "two which is quoted", "three"];
+ actual = utils.parseArgs(args);
+ eq(expected, actual, "basic quotes single");
+
+ // Basic quotes - double
+ args = ["one", '"two', "which", "is", 'quoted"', "three"];
+ expected = ["one", "two which is quoted", "three"];
+ actual = utils.parseArgs(args);
+ eq(expected, actual, "basic quotes double");
+
+ // One word quoted
+ args = ["one", "'two'", "three"];
+ expected = ["one", "two", "three"];
+ actual = utils.parseArgs(args);
+ eq(expected, actual, "one word quoted");
+
+ // mixed quotes
+ args = ["one", "'two", '("2")', "tricky'", "three"];
+ expected = ["one", 'two ("2") tricky', "three"];
+ actual = utils.parseArgs(args);
+ eq(expected, actual, "nested quotes");
+
+ // Bare apostrophe
+ args = ["name", "O'Dell", "more"];
+ expected = ["name", "O'Dell", "more"];
+ actual = utils.parseArgs(args);
+ eq(expected, actual, "Bare apostrophe");
+})();
View
37 utils.js
@@ -68,5 +68,40 @@ exports.ifAuthorized = function(user, channel, callback) {
};
exports.escapeRegExp = function(str) {
- return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+ return str.replace(/[-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
+}
+
+/* Parse things like quotes strings from an argument list. */
+exports.parseArgs = function(argList) {
+ var args = [];
+ var argBuilder = "";
+ var quote = "";
+ _.each(argList, function(arg) {
+ if (argBuilder) {
+ argBuilder += ' ' + arg;
+ if (arg.slice(-1) === quote) {
+ argBuilder = argBuilder.slice(0, -1);
+ args.push(argBuilder);
+ argBuilder = "";
+ quote = "";
+ }
+ } else {
+ if (arg[0] === "'") {
+ quote = "'";
+ } else if (arg[0] === '"') {
+ quote = '"';
+ }
+ if (quote) {
+ if (arg.slice(-1) === quote) {
+ args.push(arg.slice(1,-1));
+ quote = '';
+ } else {
+ argBuilder = arg.slice(1);
+ }
+ } else {
+ args.push(arg);
+ }
+ }
+ });
+ return args;
}

0 comments on commit cb39513

Please sign in to comment.