/documentation/docs/optparse.html

http://github.com/jashkenas/coffee-script · HTML · 366 lines · 259 code · 107 blank · 0 comment · 0 complexity · 626acfb49f15017332731849dbd26900 MD5 · raw file

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>optparse.coffee</title>
  5. <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  6. <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  7. <link rel="stylesheet" media="all" href="docco.css" />
  8. </head>
  9. <body>
  10. <div id="container">
  11. <div id="background"></div>
  12. <ul id="jump_to">
  13. <li>
  14. <a class="large" href="javascript:void(0);">Jump To &hellip;</a>
  15. <a class="small" href="javascript:void(0);">+</a>
  16. <div id="jump_wrapper">
  17. <div id="jump_page_wrapper">
  18. <div id="jump_page">
  19. <a class="source" href="browser.html">
  20. browser.coffee
  21. </a>
  22. <a class="source" href="cake.html">
  23. cake.coffee
  24. </a>
  25. <a class="source" href="coffee-script.html">
  26. coffee-script.coffee
  27. </a>
  28. <a class="source" href="command.html">
  29. command.coffee
  30. </a>
  31. <a class="source" href="grammar.html">
  32. grammar.coffee
  33. </a>
  34. <a class="source" href="helpers.html">
  35. helpers.coffee
  36. </a>
  37. <a class="source" href="index.html">
  38. index.coffee
  39. </a>
  40. <a class="source" href="lexer.html">
  41. lexer.coffee
  42. </a>
  43. <a class="source" href="nodes.html">
  44. nodes.coffee
  45. </a>
  46. <a class="source" href="optparse.html">
  47. optparse.coffee
  48. </a>
  49. <a class="source" href="register.html">
  50. register.coffee
  51. </a>
  52. <a class="source" href="repl.html">
  53. repl.coffee
  54. </a>
  55. <a class="source" href="rewriter.html">
  56. rewriter.coffee
  57. </a>
  58. <a class="source" href="scope.html">
  59. scope.litcoffee
  60. </a>
  61. <a class="source" href="sourcemap.html">
  62. sourcemap.litcoffee
  63. </a>
  64. </div>
  65. </div>
  66. </li>
  67. </ul>
  68. <ul class="sections">
  69. <li id="title">
  70. <div class="annotation">
  71. <h1>optparse.coffee</h1>
  72. </div>
  73. </li>
  74. <li id="section-1">
  75. <div class="annotation">
  76. <div class="pilwrap ">
  77. <a class="pilcrow" href="#section-1">&#182;</a>
  78. </div>
  79. </div>
  80. <div class="content"><div class='highlight'><pre>{repeat} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span></pre></div></div>
  81. </li>
  82. <li id="section-2">
  83. <div class="annotation">
  84. <div class="pilwrap ">
  85. <a class="pilcrow" href="#section-2">&#182;</a>
  86. </div>
  87. <p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
  88. Use it like so:</p>
  89. <pre><code>parser = <span class="hljs-keyword">new</span> OptionParser switches, helpBanner
  90. options = parser.parse process.argv
  91. </code></pre><p>The first non-option is considered to be the start of the file (and file
  92. option) list, and all subsequent arguments are left unparsed.</p>
  93. </div>
  94. <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.OptionParser = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OptionParser</span></span></pre></div></div>
  95. </li>
  96. <li id="section-3">
  97. <div class="annotation">
  98. <div class="pilwrap ">
  99. <a class="pilcrow" href="#section-3">&#182;</a>
  100. </div>
  101. <p>Initialize with a list of valid options, in the form:</p>
  102. <pre><code>[short-flag, long-flag, description]
  103. </code></pre><p>Along with an an optional banner for the usage help.</p>
  104. </div>
  105. <div class="content"><div class='highlight'><pre> <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(rules, <span class="hljs-property">@banner</span>)</span> -&gt;</span>
  106. <span class="hljs-property">@rules</span> = buildRules rules</pre></div></div>
  107. </li>
  108. <li id="section-4">
  109. <div class="annotation">
  110. <div class="pilwrap ">
  111. <a class="pilcrow" href="#section-4">&#182;</a>
  112. </div>
  113. <p>Parse the list of arguments, populating an <code>options</code> object with all of the
  114. specified options, and return it. Options after the first non-option
  115. argument are treated as arguments. <code>options.arguments</code> will be an array
  116. containing the remaining arguments. This is a simpler API than many option
  117. parsers that allow you to attach callback actions for every flag. Instead,
  118. you’re responsible for interpreting the options object.</p>
  119. </div>
  120. <div class="content"><div class='highlight'><pre> <span class="hljs-attribute">parse</span>: <span class="hljs-function"><span class="hljs-params">(args)</span> -&gt;</span>
  121. options = <span class="hljs-attribute">arguments</span>: []
  122. skippingArgument = <span class="hljs-literal">no</span>
  123. originalArgs = args
  124. args = normalizeArguments args
  125. <span class="hljs-keyword">for</span> arg, i <span class="hljs-keyword">in</span> args
  126. <span class="hljs-keyword">if</span> skippingArgument
  127. skippingArgument = <span class="hljs-literal">no</span>
  128. <span class="hljs-keyword">continue</span>
  129. <span class="hljs-keyword">if</span> arg <span class="hljs-keyword">is</span> <span class="hljs-string">'--'</span>
  130. pos = originalArgs.indexOf <span class="hljs-string">'--'</span>
  131. options.arguments = options.arguments.concat originalArgs[(pos + <span class="hljs-number">1</span>)..]
  132. <span class="hljs-keyword">break</span>
  133. isOption = !!(arg.match(LONG_FLAG) <span class="hljs-keyword">or</span> arg.match(SHORT_FLAG))</pre></div></div>
  134. </li>
  135. <li id="section-5">
  136. <div class="annotation">
  137. <div class="pilwrap ">
  138. <a class="pilcrow" href="#section-5">&#182;</a>
  139. </div>
  140. <p>the CS option parser is a little odd; options after the first
  141. non-option argument are treated as non-option arguments themselves</p>
  142. </div>
  143. <div class="content"><div class='highlight'><pre> seenNonOptionArg = options.arguments.length &gt; <span class="hljs-number">0</span>
  144. <span class="hljs-keyword">unless</span> seenNonOptionArg
  145. matchedRule = <span class="hljs-literal">no</span>
  146. <span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> <span class="hljs-property">@rules</span>
  147. <span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">is</span> arg <span class="hljs-keyword">or</span> rule.longFlag <span class="hljs-keyword">is</span> arg
  148. value = <span class="hljs-literal">true</span>
  149. <span class="hljs-keyword">if</span> rule.hasArgument
  150. skippingArgument = <span class="hljs-literal">yes</span>
  151. value = args[i + <span class="hljs-number">1</span>]
  152. options[rule.name] = <span class="hljs-keyword">if</span> rule.isList <span class="hljs-keyword">then</span> (options[rule.name] <span class="hljs-keyword">or</span> []).concat value <span class="hljs-keyword">else</span> value
  153. matchedRule = <span class="hljs-literal">yes</span>
  154. <span class="hljs-keyword">break</span>
  155. <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">"unrecognized option: <span class="hljs-subst">#{arg}</span>"</span> <span class="hljs-keyword">if</span> isOption <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> matchedRule
  156. <span class="hljs-keyword">if</span> seenNonOptionArg <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> isOption
  157. options.arguments.push arg
  158. options</pre></div></div>
  159. </li>
  160. <li id="section-6">
  161. <div class="annotation">
  162. <div class="pilwrap ">
  163. <a class="pilcrow" href="#section-6">&#182;</a>
  164. </div>
  165. <p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
  166. of the valid options, for <code>--help</code> and such.</p>
  167. </div>
  168. <div class="content"><div class='highlight'><pre> <span class="hljs-attribute">help</span>:<span class="hljs-function"> -&gt;</span>
  169. lines = []
  170. lines.unshift <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@banner</span>}</span>\n"</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@banner</span>
  171. <span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> <span class="hljs-property">@rules</span>
  172. spaces = <span class="hljs-number">15</span> - rule.longFlag.length
  173. spaces = <span class="hljs-keyword">if</span> spaces &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> repeat <span class="hljs-string">' '</span>, spaces <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
  174. letPart = <span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">then</span> rule.shortFlag + <span class="hljs-string">', '</span> <span class="hljs-keyword">else</span> <span class="hljs-string">' '</span>
  175. lines.push <span class="hljs-string">' '</span> + letPart + rule.longFlag + spaces + rule.description
  176. <span class="hljs-string">"\n<span class="hljs-subst">#{ lines.join(<span class="hljs-string">'\n'</span>) }</span>\n"</span></pre></div></div>
  177. </li>
  178. <li id="section-7">
  179. <div class="annotation">
  180. <div class="pilwrap ">
  181. <a class="pilcrow" href="#section-7">&#182;</a>
  182. </div>
  183. <h2 id="helpers">Helpers</h2>
  184. </div>
  185. </li>
  186. <li id="section-8">
  187. <div class="annotation">
  188. <div class="pilwrap ">
  189. <a class="pilcrow" href="#section-8">&#182;</a>
  190. </div>
  191. </div>
  192. </li>
  193. <li id="section-9">
  194. <div class="annotation">
  195. <div class="pilwrap ">
  196. <a class="pilcrow" href="#section-9">&#182;</a>
  197. </div>
  198. <p>Regex matchers for option flags.</p>
  199. </div>
  200. <div class="content"><div class='highlight'><pre>LONG_FLAG = <span class="hljs-regexp">/^(--\w[\w\-]*)/</span>
  201. SHORT_FLAG = <span class="hljs-regexp">/^(-\w)$/</span>
  202. MULTI_FLAG = <span class="hljs-regexp">/^-(\w{2,})/</span>
  203. OPTIONAL = <span class="hljs-regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
  204. </li>
  205. <li id="section-10">
  206. <div class="annotation">
  207. <div class="pilwrap ">
  208. <a class="pilcrow" href="#section-10">&#182;</a>
  209. </div>
  210. <p>Build and return the list of option rules. If the optional <em>short-flag</em> is
  211. unspecified, leave it out by padding with <code>null</code>.</p>
  212. </div>
  213. <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRules</span> = <span class="hljs-params">(rules)</span> -&gt;</span>
  214. <span class="hljs-keyword">for</span> tuple <span class="hljs-keyword">in</span> rules
  215. tuple.unshift <span class="hljs-literal">null</span> <span class="hljs-keyword">if</span> tuple.length &lt; <span class="hljs-number">3</span>
  216. buildRule tuple...</pre></div></div>
  217. </li>
  218. <li id="section-11">
  219. <div class="annotation">
  220. <div class="pilwrap ">
  221. <a class="pilcrow" href="#section-11">&#182;</a>
  222. </div>
  223. <p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
  224. description of what the option does.</p>
  225. </div>
  226. <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRule</span> = <span class="hljs-params">(shortFlag, longFlag, description, options = {})</span> -&gt;</span>
  227. match = longFlag.match(OPTIONAL)
  228. longFlag = longFlag.match(LONG_FLAG)[<span class="hljs-number">1</span>]
  229. {
  230. <span class="hljs-attribute">name</span>: longFlag.substr <span class="hljs-number">2</span>
  231. <span class="hljs-attribute">shortFlag</span>: shortFlag
  232. <span class="hljs-attribute">longFlag</span>: longFlag
  233. <span class="hljs-attribute">description</span>: description
  234. <span class="hljs-attribute">hasArgument</span>: !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">1</span>])
  235. <span class="hljs-attribute">isList</span>: !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">2</span>])
  236. }</pre></div></div>
  237. </li>
  238. <li id="section-12">
  239. <div class="annotation">
  240. <div class="pilwrap ">
  241. <a class="pilcrow" href="#section-12">&#182;</a>
  242. </div>
  243. <p>Normalize arguments by expanding merged flags into multiple flags. This allows
  244. you to have <code>-wl</code> be the same as <code>--watch --lint</code>.</p>
  245. </div>
  246. <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">normalizeArguments</span> = <span class="hljs-params">(args)</span> -&gt;</span>
  247. args = args[..]
  248. result = []
  249. <span class="hljs-keyword">for</span> arg <span class="hljs-keyword">in</span> args
  250. <span class="hljs-keyword">if</span> match = arg.match MULTI_FLAG
  251. result.push <span class="hljs-string">'-'</span> + l <span class="hljs-keyword">for</span> l <span class="hljs-keyword">in</span> match[<span class="hljs-number">1</span>].split <span class="hljs-string">''</span>
  252. <span class="hljs-keyword">else</span>
  253. result.push arg
  254. result</pre></div></div>
  255. </li>
  256. </ul>
  257. </div>
  258. </body>
  259. </html>