From a19cb746c0a21cfd00dcac29f4b98c62b3d2956d Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 9 Mar 2010 13:15:25 -0800 Subject: [PATCH] Initial commit. Just slamming the 1.0.0 in with a single commit, like doing carpentry with Mr. Miagi. --- README.md | 23 +++++++++++ lib/abbrev.js | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 6 +++ 3 files changed, 140 insertions(+) create mode 100644 README.md create mode 100644 lib/abbrev.js create mode 100644 package.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..99746fe --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# abbrev-js + +Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev). + +Usage: + + var abbrev = require("abbrev"); + abbrev("foo", "fool", "folding", "flop"); + + // returns: + { fl: 'flop' + , flo: 'flop' + , flop: 'flop' + , fol: 'folding' + , fold: 'folding' + , foldi: 'folding' + , foldin: 'folding' + , folding: 'folding' + , foo: 'foo' + , fool: 'fool' + } + +This is handy for command-line scripts, or other cases where you want to be able to accept shorthands. diff --git a/lib/abbrev.js b/lib/abbrev.js new file mode 100644 index 0000000..5530042 --- /dev/null +++ b/lib/abbrev.js @@ -0,0 +1,111 @@ + +// wrapped in a closure for the benefit of browser implementations. +// tests get run when included by node as the main module. +(function (exports, doTest) { + +if ( typeof module === "object" && module.exports === exports ) { + module.exports = exports = abbrev; +} +exports.abbrev = abbrev; + +var sys = require("sys"); + +function abbrev () { + if (Array.isArray(arguments[0]) && arguments.length === 1) { + return abbrev.apply(this, arguments[0]); + } + for (var i = 0, l = arguments.length, args = []; i < l; i ++) { + args[i] = typeof arguments[i] === "string" ? arguments[i] : String(arguments[i]); + } + + // sort them lexicographically, so that they're next to their nearest kin + args = args.sort(lexSort); + + // walk through each, seeing how much it has in common with the next and previous + var abbrevs = {}, prev = ""; + for (var i = 0, l = args.length; i < l; i ++) { + var current = args[i], + next = args[i + 1] || "", + nextMatches = true, + prevMatches = true; + if (current === next) continue; + for (var j = 0, cl = current.length; j < cl; j ++) { + var curChar = current.charAt(j); + nextMatches = nextMatches && curChar === next.charAt(j); + prevMatches = prevMatches && curChar === prev.charAt(j); + if (nextMatches || prevMatches) continue; + else { + j ++; + break; + } + } + prev = current; + if (j === cl) { + abbrevs[current] = current; + continue; + } + var a = current.substr(0, j); + for (; j <= cl; j ++) { + abbrevs[a] = current; + a += current.charAt(j); + } + } + return abbrevs; +} + +function lexSort (a, b) { + return a === b ? 0 : a > b ? 1 : -1; +} + +if (!doTest) return; + +var assert = require("assert"), sys = require("sys"); + +sys.puts("running tests"); +var test = function (list, expect) { + var actual = abbrev(list); + assert.deepEqual(actual, expect, + "abbrev("+sys.inspect(list)+") === " + sys.inspect(expect) + "\n"+ + "actual: "+sys.inspect(actual)); + actual = abbrev.apply(exports, list); + assert.deepEqual(abbrev.apply(exports, list), expect, + "abbrev("+list.map(JSON.stringify).join(",")+") === " + sys.inspect(expect) + "\n"+ + "actual: "+sys.inspect(actual)); +}; + +test([ "ruby", "ruby", "rules", "rules", "rules" ], +{ rub: 'ruby' +, ruby: 'ruby' +, rul: 'rules' +, rule: 'rules' +, rules: 'rules' +}); +test(["fool", "foom", "pool", "pope"], +{ fool: 'fool' +, foom: 'foom' +, poo: 'pool' +, pool: 'pool' +, pop: 'pope' +, pope: 'pope' +}); +test(["a", "ab", "abc", "abcd", "abcde", "acde"], +{ a: 'a' +, ab: 'ab' +, abc: 'abc' +, abcd: 'abcd' +, abcde: 'abcde' +, ac: 'acde' +, acd: 'acde' +, acde: 'acde' +}); + +sys.puts("pass"); + +})( + typeof exports === "undefined" + ? (function () { return this })() + : exports, + typeof module === "object" + && typeof process === "object" + && process.mainModule === module +); diff --git a/package.json b/package.json new file mode 100644 index 0000000..65131e2 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ "name" : "abbrev-js" +, "version" : "1.0.0" +, "author" : "Isaac Z. Schlueter " +, "main" : "./lib/abbrev.js" +, "scripts" : { "test" : "node lib/abbrev.js" } +}