diff --git a/lib/coffee_script/command_line.js b/lib/coffee_script/command_line.js index 70fabf0c..b093b55a 100644 --- a/lib/coffee_script/command_line.js +++ b/lib/coffee_script/command_line.js @@ -3,7 +3,7 @@ posix = require('posix'); path = require('path'); coffee = require('coffee-script'); - optparse = require('./../../vendor/optparse-js/src/optparse'); + optparse = require('optparse'); BANNER = "coffee compiles CoffeeScript source files into JavaScript.\n\nUsage:\n coffee path/to/script.coffee"; SWITCHES = [['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-r', '--run', 'compile and run a CoffeeScript'], ['-o', '--output [DIR]', 'set the directory for compiled JavaScript'], ['-w', '--watch', 'watch scripts for changes, and recompile'], ['-p', '--print', 'print the compiled JavaScript to stdout'], ['-l', '--lint', 'pipe the compiled JavaScript through JSLint'], ['-e', '--eval', 'compile a string from the command line'], ['-t', '--tokens', 'print the tokens that the lexer produces'], ['-tr', '--tree', 'print the parse tree that Jison produces'], ['-v', '--version', 'display CoffeeScript version'], ['-h', '--help', 'display this help message']]; WATCH_INTERVAL = 0.5; @@ -27,7 +27,7 @@ }; // The "--help" usage message. usage = function usage() { - puts('\n' + option_parser.toString() + '\n'); + puts('\n' + option_parser.help() + '\n'); return process.exit(0); }; // The "--version" message. @@ -125,14 +125,13 @@ opts = (options = {}); oparser = (option_parser = new optparse.OptionParser(SWITCHES)); oparser.banner = BANNER; - oparser.add = oparser['on']; oparser.add('interactive', function() { return opts.interactive = true; }); oparser.add('run', function() { return opts.run = true; }); - oparser.add('output', function(n, dir) { + oparser.add('output', function(dir) { return opts.output = dir; }); oparser.add('watch', function() { diff --git a/lib/coffee_script/optparse.js b/lib/coffee_script/optparse.js new file mode 100755 index 00000000..d30ec5e2 --- /dev/null +++ b/lib/coffee_script/optparse.js @@ -0,0 +1,116 @@ +(function(){ + var LONG_FLAG, OPTIONAL, SHORT_FLAG, build_rule, build_rules, op, spaces; + // Create an OptionParser with a list of valid options. + op = (exports.OptionParser = function OptionParser(rules) { + this.banner = 'Usage: [Options]'; + this.options_title = 'Available options:'; + this.rules = build_rules(rules); + this.actions = {}; + return this; + }); + // Add a callback to fire when a particular option is encountered. + op.prototype.add = function add(value, callback) { + return this.actions[value] = callback; + }; + // Parse the argument array, calling defined callbacks, returning the remaining non-option arguments. + op.prototype.parse = function parse(args) { + var __a, __b, arg, callback, is_option, results, rule, value; + results = []; + args = args.concat([]); + while (((arg = args.shift()))) { + is_option = false; + __a = this.rules; + for (__b = 0; __b < __a.length; __b++) { + rule = __a[__b]; + if (rule.letter === arg || rule.flag === arg) { + callback = this.actions[rule.name]; + value = rule.argument && args.shift(); + if (callback) { + callback(value); + } + is_option = true; + break; + } + } + if (!(is_option)) { + results.push(arg); + } + } + return results; + }; + // Return the help text for this OptionParser, for --help and such. + op.prototype.help = function help() { + var __a, __b, __c, __d, has_shorts, lines, longest, rule, text; + longest = 0; + has_shorts = false; + lines = [this.banner, '', this.options_title]; + __a = this.rules; + for (__b = 0; __b < __a.length; __b++) { + rule = __a[__b]; + if (rule.letter) { + has_shorts = true; + } + if (rule.flag.length > longest) { + longest = rule.flag.length; + } + } + __c = this.rules; + for (__d = 0; __d < __c.length; __d++) { + rule = __c[__d]; + has_shorts ? (text = rule.letter ? spaces(2) + rule.letter + ', ' : spaces(6)) : null; + text += spaces(longest, rule.flag) + spaces(3); + text += rule.description; + lines.push(text); + } + return lines.join('\n'); + }; + // Private: + // Regex matchers for option flags. + LONG_FLAG = /^(--\w+)/; + SHORT_FLAG = /^(-\w+)/; + OPTIONAL = /\[(.+)\]/; + // Build rules from a list of valid switch tuples in the form: + // [letter-flag, long-flag, help], or [long-flag, help]. + build_rules = function build_rules(rules) { + var __a, __b, __c, tuple; + __a = []; __b = rules; + for (__c = 0; __c < __b.length; __c++) { + tuple = __b[__c]; + __a.push((function() { + if (tuple.length < 3) { + tuple.unshift(null); + } + return build_rule.apply(this, tuple); + }).call(this)); + } + return __a; + }; + // Build a rule from a short-letter-flag, long-form-flag, and help text. + build_rule = function build_rule(letter, flag, description) { + var match; + match = flag.match(OPTIONAL); + return { + name: flag.match(LONG_FLAG)[1].substr(2), + letter: letter, + flag: flag, + description: description, + argument: !!(match && match[1]) + }; + }; + // Space-pad a string with the specified number of characters. + spaces = function spaces(num, text) { + var builder; + builder = []; + if (text) { + if (text.length >= num) { + return text; + } + num -= text.length; + builder.push(text); + } + while (num -= 1) { + builder.push(' '); + } + return builder.join(''); + }; +})(); \ No newline at end of file diff --git a/lib/coffee_script/underscore.js b/lib/coffee_script/underscore.js index fd1e292e..5527c963 100644 --- a/lib/coffee_script/underscore.js +++ b/lib/coffee_script/underscore.js @@ -706,7 +706,7 @@ }; // JavaScript templating a-la ERB, pilfered from John Resig's // "Secrets of the JavaScript Ninja", page 83. - // Single-quotea fix from Rick Strahl's version. + // Single-quote fix from Rick Strahl's version. _.template = function template(str, data) { var c, fn; c = _.templateSettings; diff --git a/src/command_line.coffee b/src/command_line.coffee index b0624bf6..237841be 100644 --- a/src/command_line.coffee +++ b/src/command_line.coffee @@ -1,7 +1,7 @@ posix: require 'posix' path: require 'path' coffee: require 'coffee-script' -optparse: require('./../../vendor/optparse-js/src/optparse') +optparse: require('optparse') BANNER: ''' coffee compiles CoffeeScript source files into JavaScript. @@ -41,7 +41,7 @@ exports.run: -> # The "--help" usage message. usage: -> - puts '\n' + option_parser.toString() + '\n' + puts '\n' + option_parser.help() + '\n' process.exit 0 # The "--version" message. @@ -107,11 +107,10 @@ parse_options: -> opts: options: {} oparser: option_parser: new optparse.OptionParser SWITCHES oparser.banner: BANNER - oparser.add: oparser['on'] oparser.add 'interactive', -> opts.interactive: true oparser.add 'run', -> opts.run: true - oparser.add 'output', (n, dir) -> opts.output: dir + oparser.add 'output', (dir) -> opts.output: dir oparser.add 'watch', -> opts.watch: true oparser.add 'print', -> opts.print: true oparser.add 'lint', -> opts.lint: true diff --git a/src/optparse.coffee b/src/optparse.coffee new file mode 100644 index 00000000..14b847a6 --- /dev/null +++ b/src/optparse.coffee @@ -0,0 +1,78 @@ +# Create an OptionParser with a list of valid options. +op: exports.OptionParser: (rules) -> + @banner: 'Usage: [Options]' + @options_title: 'Available options:' + @rules: build_rules(rules) + @actions: {} + this + +# Add a callback to fire when a particular option is encountered. +op::add: (value, callback) -> + @actions[value]: callback + +# Parse the argument array, calling defined callbacks, returning the remaining non-option arguments. +op::parse: (args) -> + results: [] + args: args.concat [] + while (arg: args.shift()) + is_option: false + for rule in @rules + if rule.letter is arg or rule.flag is arg + callback: @actions[rule.name] + value: rule.argument and args.shift() + callback(value) if callback + is_option: true + break + results.push arg unless is_option + results + +# Return the help text for this OptionParser, for --help and such. +op::help: -> + longest: 0 + has_shorts: false + lines: [@banner, '', @options_title] + for rule in @rules + has_shorts: true if rule.letter + longest: rule.flag.length if rule.flag.length > longest + for rule in @rules + if has_shorts + text: if rule.letter then spaces(2) + rule.letter + ', ' else spaces(6) + text += spaces(longest, rule.flag) + spaces(3) + text += rule.description + lines.push text + lines.join('\n') + +# Private: + +# Regex matchers for option flags. +LONG_FLAG: /^(--\w+)/ +SHORT_FLAG: /^(-\w+)/ +OPTIONAL: /\[(.+)\]/ + +# Build rules from a list of valid switch tuples in the form: +# [letter-flag, long-flag, help], or [long-flag, help]. +build_rules: (rules) -> + for tuple in rules + tuple.unshift(null) if tuple.length < 3 + build_rule(tuple...) + +# Build a rule from a short-letter-flag, long-form-flag, and help text. +build_rule: (letter, flag, description) -> + match: flag.match(OPTIONAL) + { + name: flag.match(LONG_FLAG)[1].substr(2) + letter: letter + flag: flag + description: description + argument: !!(match and match[1]) + } + +# Space-pad a string with the specified number of characters. +spaces: (num, text) -> + builder: [] + if text + return text if text.length >= num + num -= text.length + builder.push text + while num -= 1 then builder.push ' ' + builder.join '' diff --git a/src/underscore.coffee b/src/underscore.coffee index 8026ea7d..ac008e5f 100644 --- a/src/underscore.coffee +++ b/src/underscore.coffee @@ -533,7 +533,7 @@ # JavaScript templating a-la ERB, pilfered from John Resig's # "Secrets of the JavaScript Ninja", page 83. - # Single-quotea fix from Rick Strahl's version. + # Single-quote fix from Rick Strahl's version. _.template: (str, data) -> c: _.templateSettings fn: new Function 'obj', diff --git a/vendor/optparse-js/README.md b/vendor/optparse-js/README.md deleted file mode 100644 index d08ccf16..00000000 --- a/vendor/optparse-js/README.md +++ /dev/null @@ -1,161 +0,0 @@ -optparse-js -=========== - -Optparse-js is a command line option parser for Javascript. It's slightly based on Ruby's implementation optparse but with some differences (different languages has different needs) such as custom parsers. - -All examples in this readme is using [Node.js](http://nodejs.org/). How ever, the library works with all kinds of Javascript implementations. - - -QUICK START ------------ - -The library defines one class, the OptionParser class. The class constructor takes one single argument, a list with a set of rules. Here is a quick example: - - // Import the sys library - var sys = require('sys'); - - // Import the optparse library. - var optparse = require('optparse'); - - // Define an option called ´´help´´. We give it a quick alias named ´´-h´´ - // and a quick help text. - var switches = [ - ['-h', '--help', 'Shows help sections'] - ]; - - // Create a new OptionParser. - var parser = new optparse.OptionParser(switches); - - // Hook the help option. The callback will be executed when the OptionParser - // hits the switch ´´-h´´ or ´´--help´´. Each representatio - parser.on('help', function() { - sys.puts('Help'); - }); - - - -DEFINING RULES --------------- -The OptionParser constructor takes an Array with rules. Each rule is represented by an array (tuple) of two or three values. A typical rule definition may look like this: - - ['-h', '--help', 'Print this help'] - - -The first value is optional, and represents an alias for the long-named switch (the second value, in this case ´´--help´´). - -The second argument is the actual rule. The rule must start with a double dash followed by a switch name (in this case ´help´). The OptionParser also supports special option arguments. Define an option argument in the rule by adding a named argument after the leading double dash and switch name (E.G '--port-number PORT_NUMBER'). The argument is then parsed to the option handler. To define an optional option argument, just add a braces around argument in the rule (E.G '--port-number [PORT_NUMBER]). The OptionParser also supports filter. More on that in in the section called ´Option Filters´. - -The third argument is an optional rule description. - - -OPTION FILTERS --------------- -Filters is a neat feature that let you filter option arguments. The OptionParser itself as already a set of built-in common filter's. These are: - -- NUMBER, supports both decimal and hexadecimal numbers. -- DATE, filters arguments that matches YYYY-MM-DD. -- EMAIL, filters arguments that matches my@email.com. - -It's simple to use any of the filter above in your rule-set. Here is a quick example how to filter number: - - var rules = [ - ['--first-option NUMBER', 'Takes a number as argument'], - ['--second-option [NUMBER]', 'Takes an optional number as argument'] - ] - -You can add your own set of filter by calling the *parser_instance.filter* method: - - parser.filter('single_char', function(value) { - if(value.length != 1) throw "Filter mismatch."; - return value; - }); - - -OPTION PARSER -------------- -The OptionParser class has the following properties and methods: - -### string banner -An optional usage banner. This text is included when calling ´´toString´´. Default value is: "Usage: [Options]". - - -### string options_title -An optional title for the options list. This text is included when calling ´´toString´´. Default value is: "Available options:". - - -### function on(switch_or_arg_index, callback) -Add's a callback for a switch or an argument (defined by index). Switch hooks MUST be typed witout the leading ´´--´´. This example show how to hook a switch: - - parser.on('help', function(optional_argument) { - // Show help section - }); - -And this example show how to hook an argument (an option without the leading - or --): - - parser.on(0, function(opt) { - puts('The first non-switch option is:' + opt); - }); - -It's also possible to define a default handler. The default handler is called when no rule's are meet. Here is an example how to add a ´default handler´: - - parser.on(function(opt) { - puts('No handler was defined for option:' + opt); - }); - -Use the wildcard handler to build a custom ´´on´´ handler. - - parser.on('*', function(opt, value) { - puts('option=' + opt + ', value=' + value); - }); - -### function filter(name, callback) -Adds a new filter extension to the OptionParser instance. The first argument is the name of the filter (trigger). The second argument is the actual filter See the ´OPTION FILTERS´ section for more info. - -It's possible to override the default filters by passing the value "_DEFAULT" to the ´´name´´ argument. The name of the filter is automatically transformed into -upper case. - - -### function halt([callback]) -Interrupt's further parsing. This function should be called from an ´on´ -callbacks, to cancel the parsing. This can be useful when the program should ignore all other arguments (when displaying help or version information). - -The function also takes an optional callback argument. If the callback argument is specified, a ´halt´ callback will be added (instead of executing the ´halt´ command). - -Here is an example how to add an ´on_halt´ callback: - - parser.halt(function() { - puts('An option callback interupted the parser'); - }); - - -### function parse(arguments) -Start's parsing of arguments. This should be the last thing you do. - - -### function options() -Returns an Array with all defined option rules - - -### function toString() -Returns a string representation of this OptionParser instance (a formatted help section). - - -MORE EXAMPLES -------------- -See examples/nodejs-test.js and examples/browser-test-html for more info how to -use the script. - - -SUGGESTIONS ------------ -All comments in how to improve this library is very welcome. Feel free post suggestions to the [Issue tracker](http://github.com/jfd/optparse-js/issues), or even better, fork the repository to implement your own features. - - -LICENSE -------- -Released under a MIT-style license. - - -COPYRIGHT ---------- -Copyright (c) 2009 Johan Dahlberg - diff --git a/vendor/optparse-js/TODO b/vendor/optparse-js/TODO deleted file mode 100644 index a1b60506..00000000 --- a/vendor/optparse-js/TODO +++ /dev/null @@ -1 +0,0 @@ -- Support for Argument lists (for switches) \ No newline at end of file diff --git a/vendor/optparse-js/examples/browser-test.html b/vendor/optparse-js/examples/browser-test.html deleted file mode 100644 index 2d8f6d38..00000000 --- a/vendor/optparse-js/examples/browser-test.html +++ /dev/null @@ -1,75 +0,0 @@ - - -
- -