mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
346 lines
13 KiB
HTML
346 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html>
|
|
<head>
|
|
<title>optparse.coffee</title>
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
|
<link rel="stylesheet" media="all" href="docco.css" />
|
|
</head>
|
|
<body>
|
|
<div id="container">
|
|
<div id="background"></div>
|
|
|
|
<ul id="jump_to">
|
|
<li>
|
|
<a class="large" href="javascript:void(0);">Jump To …</a>
|
|
<a class="small" href="javascript:void(0);">+</a>
|
|
<div id="jump_wrapper">
|
|
<div id="jump_page">
|
|
|
|
|
|
<a class="source" href="browser.html">
|
|
browser.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="cake.html">
|
|
cake.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="coffee-script.html">
|
|
coffee-script.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="command.html">
|
|
command.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="grammar.html">
|
|
grammar.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="helpers.html">
|
|
helpers.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="index.html">
|
|
index.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="lexer.html">
|
|
lexer.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="nodes.html">
|
|
nodes.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="optparse.html">
|
|
optparse.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="repl.html">
|
|
repl.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="rewriter.html">
|
|
rewriter.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="scope.html">
|
|
scope.litcoffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="sourcemap.html">
|
|
sourcemap.coffee
|
|
</a>
|
|
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="sections">
|
|
|
|
<li id="title">
|
|
<div class="annotation">
|
|
<h1>optparse.coffee</h1>
|
|
</div>
|
|
</li>
|
|
|
|
|
|
|
|
<li id="section-1">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap ">
|
|
<a class="pilcrow" href="#section-1">¶</a>
|
|
</div>
|
|
<p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
|
|
Use it like so:
|
|
|
|
</p>
|
|
<pre><code>parser = new OptionParser switches, helpBanner
|
|
options = parser.parse process.argv</code></pre>
|
|
<p>The first non-option is considered to be the start of the file (and file
|
|
option) list, and all subsequent arguments are left unparsed.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre>exports.OptionParser = <span class="class"><span class="keyword">class</span> <span class="title">OptionParser</span></span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-2">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap ">
|
|
<a class="pilcrow" href="#section-2">¶</a>
|
|
</div>
|
|
<p>Initialize with a list of valid options, in the form:
|
|
|
|
</p>
|
|
<pre><code>[short-flag, long-flag, description]</code></pre>
|
|
<p>Along with an an optional banner for the usage help.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre> constructor: (rules, <span class="property">@banner</span>) ->
|
|
<span class="property">@rules</span> = buildRules rules</pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-3">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap ">
|
|
<a class="pilcrow" href="#section-3">¶</a>
|
|
</div>
|
|
<p>Parse the list of arguments, populating an <code>options</code> object with all of the
|
|
specified options, and return it. Options after the first non-option
|
|
argument are treated as arguments. <code>options.arguments</code> will be an array
|
|
containing the remaining arguments. This is a simpler API than many option
|
|
parsers that allow you to attach callback actions for every flag. Instead,
|
|
you're responsible for interpreting the options object.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre> parse: (args) ->
|
|
options = arguments: []
|
|
skippingArgument = <span class="literal">no</span>
|
|
originalArgs = args
|
|
args = normalizeArguments args
|
|
<span class="keyword">for</span> arg, i <span class="keyword">in</span> args
|
|
<span class="keyword">if</span> skippingArgument
|
|
skippingArgument = <span class="literal">no</span>
|
|
<span class="keyword">continue</span>
|
|
<span class="keyword">if</span> arg <span class="keyword">is</span> <span class="string">'--'</span>
|
|
pos = originalArgs.indexOf <span class="string">'--'</span>
|
|
options.arguments = options.arguments.concat originalArgs[(pos + <span class="number">1</span>)..]
|
|
<span class="keyword">break</span>
|
|
isOption = !!(arg.match(LONG_FLAG) <span class="keyword">or</span> arg.match(SHORT_FLAG))</pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-4">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap ">
|
|
<a class="pilcrow" href="#section-4">¶</a>
|
|
</div>
|
|
<p>the CS option parser is a little odd; options after the first
|
|
non-option argument are treated as non-option arguments themselves
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre> seenNonOptionArg = options.arguments.length > <span class="number">0</span>
|
|
<span class="keyword">unless</span> seenNonOptionArg
|
|
matchedRule = <span class="literal">no</span>
|
|
<span class="keyword">for</span> rule <span class="keyword">in</span> <span class="property">@rules</span>
|
|
<span class="keyword">if</span> rule.shortFlag <span class="keyword">is</span> arg <span class="keyword">or</span> rule.longFlag <span class="keyword">is</span> arg
|
|
value = <span class="literal">true</span>
|
|
<span class="keyword">if</span> rule.hasArgument
|
|
skippingArgument = <span class="literal">yes</span>
|
|
value = args[i + <span class="number">1</span>]
|
|
options[rule.name] = <span class="keyword">if</span> rule.isList <span class="keyword">then</span> (options[rule.name] <span class="keyword">or</span> []).concat value <span class="keyword">else</span> value
|
|
matchedRule = <span class="literal">yes</span>
|
|
<span class="keyword">break</span>
|
|
<span class="keyword">throw</span> <span class="keyword">new</span> Error <span class="string">"unrecognized option: <span class="subst">#{arg}</span>"</span> <span class="keyword">if</span> isOption <span class="keyword">and</span> <span class="keyword">not</span> matchedRule
|
|
<span class="keyword">if</span> seenNonOptionArg <span class="keyword">or</span> <span class="keyword">not</span> isOption
|
|
options.arguments.push arg
|
|
options</pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-5">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap ">
|
|
<a class="pilcrow" href="#section-5">¶</a>
|
|
</div>
|
|
<p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
|
|
of the valid options, for <code>--help</code> and such.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre> help: ->
|
|
lines = []
|
|
lines.unshift <span class="string">"<span class="subst">#{@banner}</span>\n"</span> <span class="keyword">if</span> <span class="property">@banner</span>
|
|
<span class="keyword">for</span> rule <span class="keyword">in</span> <span class="property">@rules</span>
|
|
spaces = <span class="number">15</span> - rule.longFlag.length
|
|
spaces = <span class="keyword">if</span> spaces > <span class="number">0</span> <span class="keyword">then</span> Array(spaces + <span class="number">1</span>).join(<span class="string">' '</span>) <span class="keyword">else</span> <span class="string">''</span>
|
|
letPart = <span class="keyword">if</span> rule.shortFlag <span class="keyword">then</span> rule.shortFlag + <span class="string">', '</span> <span class="keyword">else</span> <span class="string">' '</span>
|
|
lines.push <span class="string">' '</span> + letPart + rule.longFlag + spaces + rule.description
|
|
<span class="string">"\n<span class="subst">#{ lines.join('\n') }</span>\n"</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-6">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap for-h2">
|
|
<a class="pilcrow" href="#section-6">¶</a>
|
|
</div>
|
|
<h2>Helpers</h2>
|
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-7">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap ">
|
|
<a class="pilcrow" href="#section-7">¶</a>
|
|
</div>
|
|
<p>Regex matchers for option flags.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre>LONG_FLAG = <span class="regexp">/^(--\w[\w\-]*)/</span>
|
|
SHORT_FLAG = <span class="regexp">/^(-\w)$/</span>
|
|
MULTI_FLAG = <span class="regexp">/^-(\w{2,})/</span>
|
|
OPTIONAL = <span class="regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-8">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap ">
|
|
<a class="pilcrow" href="#section-8">¶</a>
|
|
</div>
|
|
<p>Build and return the list of option rules. If the optional <em>short-flag</em> is
|
|
unspecified, leave it out by padding with <code>null</code>.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">buildRules</span></span> = (rules) ->
|
|
<span class="keyword">for</span> tuple <span class="keyword">in</span> rules
|
|
tuple.unshift <span class="literal">null</span> <span class="keyword">if</span> tuple.length < <span class="number">3</span>
|
|
buildRule tuple...</pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-9">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap ">
|
|
<a class="pilcrow" href="#section-9">¶</a>
|
|
</div>
|
|
<p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
|
|
description of what the option does.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">buildRule</span></span> = (shortFlag, longFlag, description, options = {}) ->
|
|
match = longFlag.match(OPTIONAL)
|
|
longFlag = longFlag.match(LONG_FLAG)[<span class="number">1</span>]
|
|
{
|
|
name: longFlag.substr <span class="number">2</span>
|
|
shortFlag: shortFlag
|
|
longFlag: longFlag
|
|
description: description
|
|
hasArgument: !!(match <span class="keyword">and</span> match[<span class="number">1</span>])
|
|
isList: !!(match <span class="keyword">and</span> match[<span class="number">2</span>])
|
|
}</pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-10">
|
|
<div class="annotation">
|
|
|
|
<div class="pilwrap ">
|
|
<a class="pilcrow" href="#section-10">¶</a>
|
|
</div>
|
|
<p>Normalize arguments by expanding merged flags into multiple flags. This allows
|
|
you to have <code>-wl</code> be the same as <code>--watch --lint</code>.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class='highlight'><pre><span class="function"><span class="title">normalizeArguments</span></span> = (args) ->
|
|
args = args[..]
|
|
result = []
|
|
<span class="keyword">for</span> arg <span class="keyword">in</span> args
|
|
<span class="keyword">if</span> match = arg.match MULTI_FLAG
|
|
result.push <span class="string">'-'</span> + l <span class="keyword">for</span> l <span class="keyword">in</span> match[<span class="number">1</span>].split <span class="string">''</span>
|
|
<span class="keyword">else</span>
|
|
result.push arg
|
|
result</pre></div></div>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
</body>
|
|
</html>
|