| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | # argv.js
 | 
					
						
							| 
									
										
										
										
											2020-06-29 03:24:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | Simple argv parser | 
					
						
							| 
									
										
										
										
											2020-06-29 03:24:42 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | ## Motivation
 | 
					
						
							| 
									
										
										
										
											2020-06-29 03:24:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 03:17:47 +03:00
										 |  |  | I needed a new argv parser for a quick and dirty project I was working  | 
					
						
							|  |  |  | on and evaluating and selecting the proper existing parser and then  | 
					
						
							|  |  |  | learning its API, quirks and adapting the architecture to it seemed  | 
					
						
							|  |  |  | to be more complicated, require more effort and far less fun than  | 
					
						
							|  |  |  | putting together a trivial parser myself in a couple of hours.   | 
					
						
							| 
									
										
										
										
											2020-06-29 03:24:42 +03:00
										 |  |  | This code is an evolution of that parser. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | ## Features
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - Simple | 
					
						
							| 
									
										
										
										
											2020-07-19 18:33:48 +03:00
										 |  |  | - Supports both the _option_ (a-la `ls`) and _command_ (a-la `git`) paradigms | 
					
						
							| 
									
										
										
										
											2020-07-01 13:55:52 +03:00
										 |  |  | - Nestable   | 
					
						
							|  |  |  |   parsers can be nested as option/command handlers defining independent  | 
					
						
							|  |  |  |   nested contexts | 
					
						
							|  |  |  | - Option expansion   | 
					
						
							|  |  |  |   `-abc` expands to `-a -b -c` if `-abc` is not defined | 
					
						
							|  |  |  | - Option/command value passing   | 
					
						
							|  |  |  |   implicit `-a 123` (requires definition or manual handling) or explicit  | 
					
						
							|  |  |  |   `-a=123` | 
					
						
							| 
									
										
										
										
											2020-07-19 18:33:48 +03:00
										 |  |  | - Environment variable option/command value defaults | 
					
						
							| 
									
										
										
										
											2020-07-26 01:51:36 +03:00
										 |  |  | - Option/command value conversion | 
					
						
							|  |  |  | - Option/command value collection | 
					
						
							| 
									
										
										
										
											2020-07-19 18:33:48 +03:00
										 |  |  | - Multiple option prefix support | 
					
						
							|  |  |  | - Reasonable defaults: | 
					
						
							|  |  |  |   - `-help` – generate and print help | 
					
						
							|  |  |  |   - `-version` – print version | 
					
						
							|  |  |  |   - `-` – stop argument processing | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | - Extensible: | 
					
						
							|  |  |  |   - Hooks for dynamic option/command handling | 
					
						
							|  |  |  |   - Customizable error and stop condition handling | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | ## Planned Features
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - Run `<command>-<sub-command>` scripts | 
					
						
							| 
									
										
										
										
											2020-07-26 01:51:36 +03:00
										 |  |  | - Option doc grouping (???) | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 13:55:52 +03:00
										 |  |  | <!-- XXX ### Alternatives --> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | ## Contents
 | 
					
						
							|  |  |  | - [argv.js](#argvjs) | 
					
						
							|  |  |  | 	- [Motivation](#motivation) | 
					
						
							|  |  |  | 	- [Features](#features) | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 	- [Planned Features](#planned-features) | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 	- [Contents](#contents) | 
					
						
							|  |  |  | 	- [Installation](#installation) | 
					
						
							|  |  |  | 	- [Basic usage](#basic-usage) | 
					
						
							|  |  |  | 	- [Configuration](#configuration) | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 		- [Option/command configuration](#optioncommand-configuration) | 
					
						
							|  |  |  | 			- [`<option>.handler(..)`](#optionhandler) | 
					
						
							|  |  |  | 			- [`<option>.doc`](#optiondoc) | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | 			- [`<option>.priority`](#optionpriority) | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 			- [`<option>.arg`](#optionarg) | 
					
						
							|  |  |  | 			- [`<option>.type`](#optiontype) | 
					
						
							| 
									
										
										
										
											2020-07-26 01:17:02 +03:00
										 |  |  | 			- [`<option>.collect`](#optioncollect) | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 			- [`<option>.env`](#optionenv) | 
					
						
							|  |  |  | 			- [`<option>.default`](#optiondefault) | 
					
						
							|  |  |  | 			- [`<option>.required`](#optionrequired) | 
					
						
							|  |  |  | 			- [`<option>.valueRequired`](#optionvaluerequired) | 
					
						
							|  |  |  | 		- [Built-in options](#built-in-options) | 
					
						
							| 
									
										
										
										
											2020-07-26 01:51:36 +03:00
										 |  |  | 			- [`-` / `--`](#-----) | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 			- [`-*` / `@*`](#---) | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 			- [`-v` / `--version`](#-v----version) | 
					
						
							|  |  |  | 			- [`-h` / `--help`](#-h----help) | 
					
						
							|  |  |  | 				- [Value placeholders](#value-placeholders) | 
					
						
							|  |  |  | 				- [Automatically defined values](#automatically-defined-values) | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | 				- [`<parser>.doc`](#parserdoc) | 
					
						
							|  |  |  | 				- [`<parser>.usage`](#parserusage) | 
					
						
							|  |  |  | 				- [`<parser>.version`](#parserversion) | 
					
						
							|  |  |  | 				- [`<parser>.license`](#parserlicense) | 
					
						
							|  |  |  | 				- [`<parser>.examples`](#parserexamples) | 
					
						
							|  |  |  | 				- [`<parser>.footer`](#parserfooter) | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 				- [More control over help...](#more-control-over-help) | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 		- [Nested parsers](#nested-parsers) | 
					
						
							|  |  |  | 	- [Components and API](#components-and-api) | 
					
						
							|  |  |  | 		- [`THEN`, `STOP` and `ERROR`](#then-stop-and-error) | 
					
						
							|  |  |  | 		- [`Parser(..)`](#parser) | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | 			- [`<parser>.then(..)`](#parserthen) | 
					
						
							|  |  |  | 			- [`<parser>.stop(..)`](#parserstop) | 
					
						
							|  |  |  | 			- [`<parser>.error(..)`](#parsererror) | 
					
						
							|  |  |  | 			- [`<parser>.off(..)`](#parseroff) | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 			- [`<parser>(..)`](#parser-1) | 
					
						
							|  |  |  | 	- [Advanced parser API](#advanced-parser-api) | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | 		- [`<parser>.print(..)` / `<parser>.printError(..)`](#parserprint--parserprinterror) | 
					
						
							|  |  |  | 		- [`<parser>.handlerDefault(..)`](#parserhandlerdefault) | 
					
						
							|  |  |  | 		- [`<parser>.handleArgumentValue(..)`](#parserhandleargumentvalue) | 
					
						
							|  |  |  | 		- [`<parser>.handleErrorExit(..)`](#parserhandleerrorexit) | 
					
						
							| 
									
										
										
										
											2020-07-27 03:13:40 +03:00
										 |  |  | 		- [`<parser>.handle(..)`](#parserhandle) | 
					
						
							|  |  |  | 		- [`<parser>.setHandlerValue(..)`](#parsersethandlervalue) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:17:15 +03:00
										 |  |  | 		- [More...](#more) | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | 	- [License](#license) | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 13:55:52 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | ## Installation
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```shell | 
					
						
							|  |  |  | $ npm install ig-argv | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Basic usage
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Create a script and make it runnable | 
					
						
							|  |  |  | ```shell | 
					
						
							| 
									
										
										
										
											2020-07-01 03:12:55 +03:00
										 |  |  | $ touch script.js | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | $ chmod +x script.js | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Now for the code | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  | #!/usr/bin/env node
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // compatible with both node's and RequireJS' require(..) | 
					
						
							|  |  |  | var argv = require('ig-argv') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var parser = argv.Parser({ | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 		// option definitions... | 
					
						
							|  |  |  | 		// ... | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	.then(function(){ | 
					
						
							|  |  |  | 		// things to do after the options are handled... | 
					
						
							|  |  |  | 		// ... | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // run the parser... | 
					
						
							| 
									
										
										
										
											2020-07-18 20:17:15 +03:00
										 |  |  | __filename == require.main | 
					
						
							|  |  |  | 	&& parser(process.argv) | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Option definitions in a bit more detail | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | XXX make this a set of practical options and leave the attr explanation to later... | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  | var parser = argv.Parser({ | 
					
						
							| 
									
										
										
										
											2020-07-19 18:27:58 +03:00
										 |  |  | 		// doc sections... | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | 		varsion: '0.0.1', | 
					
						
							| 
									
										
										
										
											2020-07-19 18:27:58 +03:00
										 |  |  | 		doc: 'Example script options', | 
					
						
							|  |  |  | 		author: 'John Smith <j.smith@some-mail.com>', | 
					
						
							|  |  |  | 		footer: 'Written by $AUTHOR ($VERSION / $LICENSE).', | 
					
						
							|  |  |  | 		license: 'BSD-3-Clause', | 
					
						
							| 
									
										
										
										
											2020-07-18 20:17:15 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 		// alias, this tells the parser that '-b' is the same as '-basic' | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 		'-b': '-basic', | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 		// basic quick-n-dirty option... | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 		'-basic': function(opts, key, value){ | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 			// ... | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 		// basic value-getter option... | 
					
						
							|  |  |  | 		'-value': { | 
					
						
							|  |  |  | 			doc: 'Value option', | 
					
						
							|  |  |  | 			arg: 'X | x', | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 		// full option settings... | 
					
						
							|  |  |  | 		'-f': '-full', | 
					
						
							|  |  |  | 		'-full': { | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 			// option doc (optional) | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 			doc: 'Option help', | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 			// option value to be displayed in help (optional) | 
					
						
							| 
									
										
										
										
											2020-07-06 00:28:28 +03:00
										 |  |  | 			// NOTE: "attr" is used as a key to set the value if .handler | 
					
						
							|  |  |  | 			//		was not defined and is ingored in all other cases... | 
					
						
							|  |  |  | 			arg: 'VALUE | attr', | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 			// value type handler (optional) | 
					
						
							|  |  |  | 			type: 'int', | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 			// envioroment value (optional) | 
					
						
							|  |  |  | 			env: 'VALUE', | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 			// default value (optional) | 
					
						
							|  |  |  | 			default: 123, | 
					
						
							| 
									
										
										
										
											2020-07-18 20:17:15 +03:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 			// required status (optional) | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 			required: false, | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// handler (optional) | 
					
						
							|  |  |  | 			handler: function(opts, key, value){ | 
					
						
							|  |  |  | 				// ... | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// command... | 
					
						
							|  |  |  | 		// NOTE: the only difference between an option and a command is | 
					
						
							|  |  |  | 		//		the prefix ('-' vs. '@') that determines how it is parsed, | 
					
						
							|  |  |  | 		//		otherwise they are identical and can alias each other... | 
					
						
							|  |  |  | 		'@cmd', '@command', | 
					
						
							|  |  |  | 		'@command': { | 
					
						
							|  |  |  | 			// ... | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// example command-option alias... | 
					
						
							|  |  |  | 		'@help': '-help', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// nested parser... | 
					
						
							|  |  |  | 		'@nested': argv.Parser({ | 
					
						
							| 
									
										
										
										
											2020-07-17 00:01:47 +03:00
										 |  |  | 				// ... | 
					
						
							|  |  |  | 			}).then(function(){ | 
					
						
							|  |  |  | 				// ... | 
					
						
							|  |  |  | 			}), | 
					
						
							| 
									
										
										
										
											2020-07-18 20:17:15 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// ... | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | 	}) | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | This will create a parser that supports the following: | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | ```shell | 
					
						
							|  |  |  | $ ./script.js --help  | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | $ ./script.js --value 321 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $ ./script.js --value=321 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | $ ./script.js command | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $ ./script.js nested -h | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $ ./script.js -fb | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 18:49:55 +03:00
										 |  |  | ## Configuration
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | Parser(<spec>) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | The `<spec>` object is "merged" into the `<parser>` instance overriding  | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | or extending it's API/data. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `<parser>` expects/handles the following data in the `<spec>` object: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - the configuration attributes and methods   | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 	Attributes and methods used to configure, modify, extend or overload  | 
					
						
							|  |  |  | 	parser functionality. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Note that these attributes are the same attributes inherited by `<parser>` | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 	and are simply merged into the new instance created by `Parser(..)`, thus  | 
					
						
							|  |  |  | 	there are no restrictions on what attributes/methods can be overloaded  | 
					
						
							|  |  |  | 	or extended in this way, but care must be taken when overloading elements  | 
					
						
							|  |  |  | 	that were not designed to be overloaded. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | - option/command definitions   | 
					
						
							|  |  |  | 	The keys for these are prefixed either by `"-"` for options or by `"@"`  | 
					
						
							|  |  |  | 	for commands and are either _objects_, _functions_ or _parser_ instances. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	The only difference between an _option_ and a _command_ is that the former  | 
					
						
							|  |  |  | 	are passed to the _script_ with a `"-"` or `"--"` prefix (by default) and  | 
					
						
							|  |  |  | 	the later are passed by name without prefixes.  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	In all other regards options and commands are the same. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - option/command aliases   | 
					
						
							|  |  |  | 	An alias is an option/command key with a _string_ value.   | 
					
						
							|  |  |  | 	That value _references_ a different option or command, i.e. is an  | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | 	option/command name. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | 	Looping (referencing the original alias) or dead-end (referencing  | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | 	non-existent options) aliases are ignored. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Option/command configuration
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### `<option>.handler(..)`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Option handler. | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  | '-option': { | 
					
						
							|  |  |  | 	handler: function(opts, key, value){ | 
					
						
							|  |  |  | 		// handle the option... | 
					
						
							|  |  |  | 		// ... | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | }, | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2020-07-19 20:59:27 +03:00
										 |  |  | or a shorthand: | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  | '-option': function(opts, key, value){ | 
					
						
							|  |  |  | 	// handle the option... | 
					
						
							|  |  |  | 	// ... | 
					
						
							|  |  |  | }, | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | The handler gets called if the option is given or if it was not explicitly  | 
					
						
							|  |  |  | given but has a default value set. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | `opts` contains the mutable list of arguments passed to the script | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | starting just after the currently handled option/command. If the handler | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | needs to handle it's own arguments it can modify this list in place and | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | the _parser_ will continue from the resulting state. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | One use-case for this would be and option handler that needs to handle | 
					
						
							|  |  |  | it's arguments in a custom manner, for example for handling multiple  | 
					
						
							|  |  |  | arguments. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | `key` is the actual normalized (`[<prefix-char>]<name-str>`) | 
					
						
							|  |  |  | option/command triggering the `.handler(..)`. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | This can be useful to identify the actual option triggering the handler | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | when using aliases, if a single handler is used for multiple options, or | 
					
						
							|  |  |  | when it is needed to handle a specific prefix differently (a-la `find`'s  | 
					
						
							|  |  |  | syntax with `+option` and `-option` having different semantics). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `value` gets the value passed to the option.  | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | A _value_ can be passed either explicitly passed (via `=` syntax),  | 
					
						
							|  |  |  | implicitly parsed from the `argv` via the `<option>.arg` definition or  | 
					
						
							|  |  |  | is `undefined` otherwise. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | A handler can return one of the `THEN`, `STOP` or `ERROR` to control | 
					
						
							|  |  |  | further parsing and/or execution. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | (See: [`THEN`, `STOP` and `ERROR`](#then-stop-and-error) for more info.) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | #### `<option>.doc`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Option/command documentation string used in `-help`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-25 21:48:22 +03:00
										 |  |  | If this is set to `false` the option will be hidden from `-help`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | #### `<option>.priority`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Option/command priority in the `-help`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Can be a positive or negative number or `undefined`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ordering is as follows: | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | - options in descending positive `.priority`, | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | - options with undefined `.priority` in order of definition, | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | - options in descending negative `.priority`. | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Note that options and commands are grouped separately. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #### `<option>.arg`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Option/command argument definition. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | arg: '<arg-name>' | 
					
						
							|  |  |  | arg: '<arg-name> | <key>' | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | If defined and no explicit value is passed to the option command (via `=`) | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | then the _parser_ will consume the directly next non-option if present in | 
					
						
							|  |  |  | `argv` as a value, passing it to the `<option>.type` handler, if defined, | 
					
						
							|  |  |  | then the `<option>.handler(..)`, if defined, or setting it to `<key>` | 
					
						
							|  |  |  | otherwise. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | Sets the option/command argument name given in `-help` for the option | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | and the key where the value will be written. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `<key>` is not used if `<option>.handler(..)` is defined. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### `<option>.type`
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | Option/command argument type definition.  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The given type handler will be used to convert the option value before | 
					
						
							|  |  |  | it is passed to the handler or set to the given `<key>`. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Supported types: | 
					
						
							| 
									
										
										
										
											2020-07-26 01:51:36 +03:00
										 |  |  | - `"string"` (default behavior) | 
					
						
							|  |  |  | - `"bool"` | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | - `"int"` | 
					
						
							|  |  |  | - `"float"` | 
					
						
							|  |  |  | - `"number"` | 
					
						
							| 
									
										
										
										
											2020-07-26 01:17:02 +03:00
										 |  |  | - `"date"` – expects a `new Date(..)` compatible date string | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | - `"list"` – expects a `","`-separated value, split and written as  | 
					
						
							| 
									
										
										
										
											2020-07-26 01:51:36 +03:00
										 |  |  | 	an `Array` object | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | Type handlers are defined in `Parser.typeHandlers` or can be overwritten | 
					
						
							|  |  |  | by `<spec>.typeHandlers`. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 01:17:02 +03:00
										 |  |  | If not set values are written as strings.  | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | Defining a new global type handler: | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  | // check if a value is email-compatible... | 
					
						
							|  |  |  | argv.Parser.typeHandlers.email = function(value, ...options){ | 
					
						
							|  |  |  | 	if(!/[a-zA-Z][a-zA-Z.-]*@[a-zA-Z.-]+/.test(value)){ | 
					
						
							|  |  |  | 		throw new TypeRrror('email: format error:', value) } | 
					
						
							|  |  |  | 	return value } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Defining a local to parser instance type handler: | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  | var parser = new Parser({ | 
					
						
							|  |  |  | 	// Note that inheriting from the global type handlers is required  | 
					
						
							|  |  |  | 	// only if one needs to use the global types, otherwise just setting | 
					
						
							|  |  |  | 	// a bare object is enough... | 
					
						
							|  |  |  | 	typeHandlers: Object.assign(Object.create(Parser.typeHandlers), { | 
					
						
							|  |  |  | 		email: function(value, ...options){ | 
					
						
							|  |  |  | 			// ... | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// ... | 
					
						
							|  |  |  | 	}), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ... | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 01:17:02 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #### `<option>.collect`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Option value collection mode. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The given handler will be used to _collect_ values passed to multiple  | 
					
						
							| 
									
										
										
										
											2020-07-26 01:51:36 +03:00
										 |  |  | occurrences of the option and write the result to `<key>`. | 
					
						
							| 
									
										
										
										
											2020-07-26 01:17:02 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Supported collection modes: | 
					
						
							|  |  |  | - `"list"` – group values into an `Array` object | 
					
						
							|  |  |  | - `"set"` – group values into a `Set` object | 
					
						
							| 
									
										
										
										
											2020-07-27 19:02:43 +03:00
										 |  |  | - `"string"` – concatenate values into a string.   | 
					
						
							|  |  |  |   This also supports an optional separator, for example `"string|\t"` will  | 
					
						
							|  |  |  |   collect values into a string joining them with a tab (i.e. `"\t"`).   | 
					
						
							|  |  |  |   Default separator is: `" "` | 
					
						
							|  |  |  | - `"toggle"` – toggle option value (bool).   | 
					
						
							|  |  |  |   Note that the actual value assigned to an option is ignored here and can | 
					
						
							|  |  |  |   be omitted. | 
					
						
							| 
									
										
										
										
											2020-07-26 01:17:02 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Type handlers are defined in `Parser.valueCollectors` or can be overwritten | 
					
						
							|  |  |  | by `<spec>.valueCollectors`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `<option>.collect` can be used in conjunction with `<option>.type` to both  | 
					
						
							|  |  |  | convert and collect values. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 19:02:43 +03:00
										 |  |  | If not set, each subsequent option will overwrite the previously set value. | 
					
						
							| 
									
										
										
										
											2020-07-26 01:51:36 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | Defining a global value collector: | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  | // '+' prefixed flags will add values to set while '-' prefixed flag will  | 
					
						
							|  |  |  | // remove value from set... | 
					
						
							|  |  |  | argv.Parser.valueCollectors.Set = function(value, current, key){  | 
					
						
							|  |  |  | 	current = current || new Set() | 
					
						
							|  |  |  | 	return key[0] != '-' ? | 
					
						
							|  |  |  | 		current.add(value)  | 
					
						
							|  |  |  | 		: (cur.delete(value), current) } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Defining handlers local to a parser instance handler is the same as for  | 
					
						
							|  |  |  | [type handlers](#optiontype) above. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #### `<option>.env`
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | Determines the environment variable to be used as the default value for | 
					
						
							|  |  |  | option/command, if set. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | If this is set, the corresponding environment variable is non-zero and | 
					
						
							|  |  |  | `<option>.handler(..)` is defined, the handler will be called regardless | 
					
						
							|  |  |  | of weather the option was given by the user or not. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### `<option>.default`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Sets the default value for option/command's value. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | If this is set to a value other than `undefined` and | 
					
						
							|  |  |  | `<option>.handler(..)` is defined, the handler will be called regardless | 
					
						
							|  |  |  | of weather the option was given by the user or not. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### `<option>.required`
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | Sets weather the _parser_ should complain/err if option/command is | 
					
						
							|  |  |  | not given. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### `<option>.valueRequired`
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | Sets weather the _parser_ should complain/err if option/value value is | 
					
						
							|  |  |  | not given. | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Built-in options
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | #### `-` / `--`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Stop processing further options. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This can be used to terminate nested parsers or to stop option processing | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | in the root parser to handle the rest of the options in `<parser>.then(..)`, | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | for example. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | #### `-*` / `@*`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Handle options/commands for which no definition is found. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | By default `-*` will print an "unhandled option/command" error and terminate. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | By default `@*` is an alias to `-*`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | #### `-v` / `--version`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This will output the value of `.version` and exit. | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | #### `-h` / `--help`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | By default `-help` will output in the following format: | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <usage> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <doc> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Options: | 
					
						
							| 
									
										
										
										
											2020-07-05 00:05:38 +03:00
										 |  |  | 	<option-spec> <option-val>		 | 
					
						
							|  |  |  | 				- <option-doc> | 
					
						
							|  |  |  | 				  (<opt-required>, <opt-default>, <opt-env>) | 
					
						
							|  |  |  | 	... | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Dynamic options: | 
					
						
							| 
									
										
										
										
											2020-07-05 00:05:38 +03:00
										 |  |  | 	... | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Commands: | 
					
						
							| 
									
										
										
										
											2020-07-05 00:05:38 +03:00
										 |  |  | 	... | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Examples: | 
					
						
							| 
									
										
										
										
											2020-07-05 00:05:38 +03:00
										 |  |  | 	... | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | <footer> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | All sections are optional and will not be rendered if they contain no data. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | ##### Value placeholders
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | All documentation strings can contain special placeholders that  | 
					
						
							|  |  |  | will get replaced with appropriate values when rendering help. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - `$SCRIPTNAME` replaced with the value of `.scriptName`, | 
					
						
							|  |  |  | - `$VERSION` replaced with `.version`, | 
					
						
							|  |  |  | - `$LICENSE` replaced with `.license`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | ##### Automatically defined values
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | These values are set by the parser just before parsing starts: | 
					
						
							|  |  |  | - `.script` - full script path, usually this is the value of `argv[0]`, | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | - `.scriptName` - base name of the script, | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | - `.scriptPath` - path of the script. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | These will be overwritten when the parser is called. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | ##### `<parser>.doc`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | Script documentation. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <spec>.doc = <string> | <function> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Default value: `undefined` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | ##### `<parser>.usage`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | Basic usage hint. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <spec>.usage = <string> | <function> | undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Default value: `"$SCRIPTNAME [OPTIONS]"` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | ##### `<parser>.version`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | Version number. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <spec>.usage = <string> | <function> | undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If this is not defined `-version` will print `"0.0.0"`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Default value: `undefined` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | ##### `<parser>.license`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | Short license information. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <spec>.usage = <string> | <function> | undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Default value: `undefined` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | ##### `<parser>.examples`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <spec>.usage = <string> | <list> | <function> | undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Example list format: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	[ | 
					
						
							|  |  |  | 		[<example-code>, <example-doc>, ...], | 
					
						
							|  |  |  | 		... | 
					
						
							|  |  |  | 	] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Default value: `undefined` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | ##### `<parser>.footer`
 | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Additional information. | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     <spec>.footer = <string> | <function> | undefined | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Default value: `undefined` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 18:06:17 +03:00
										 |  |  | ##### More control over help...
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | For more info on help formatting see `<parser>.help*` attributes in the [source](./argv.js). | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Nested parsers
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | An option/command handler can be a _parser instance_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | From the point of view of the _nested parser_ nothing is different –  | 
					
						
							|  |  |  | it gets passed the remaining list of arguments and handles it on it's own. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The _containing parser_ treats the nested parser just like any normal  | 
					
						
							|  |  |  | handler with it's attributes and API. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Note that if the _nested parser_ consumes the rest of the arguments, | 
					
						
							|  |  |  | the _containing parser_ is left with an empty list and it will stop  | 
					
						
							|  |  |  | parsing and return normally. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A way to explicitly stop the _nested parser_ processing at a specific  | 
					
						
							|  |  |  | point in the argument list is to pass it a `-` argument at that point. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For example: | 
					
						
							|  |  |  | ```shell | 
					
						
							|  |  |  | $ script -a nested -b -c - -x -y -z | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Here `script` will handle `-a` then delegate to `nested` which in turn | 
					
						
							|  |  |  | will consume `-b`, `-c` and on `-` return, rest of the arguments are  | 
					
						
							|  |  |  | again handled by `script`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is similar to the way programming languages handle passing arguments  | 
					
						
							|  |  |  | to functions, for example in [Lisp](https://en.wikipedia.org/wiki/Common_Lisp)  | 
					
						
							|  |  |  | this is similar to: | 
					
						
							|  |  |  | ```lisp | 
					
						
							|  |  |  | (script a (nested b c) x y z) | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | And in _C-like-call-syntax_ languages like  | 
					
						
							|  |  |  | [C](https://en.wikipedia.org/wiki/C_(programming_language))/[Python](https://python.org)/JavaScript/...  | 
					
						
							|  |  |  | this would (a bit less cleanly) be: | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  | script(a, nested(b, c), x, y, z) | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The difference here is that `nested` has control over what it handles, and | 
					
						
							|  |  |  | depending on its definition, can either override the default `-` option as  | 
					
						
							|  |  |  | well as stop handling arguments at any point it chooses (similar to _words_  | 
					
						
							|  |  |  | in stack languages like [Fort](https://en.wikipedia.org/wiki/Forth_(programming_language))  | 
					
						
							|  |  |  | or [Factor](https://factorcode.org/)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <!-- 
 | 
					
						
							|  |  |  | XXX split ./lang.js from ./test.js... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See [lang.js](./lang.js) for more fun with argv and programming languages ;) | 
					
						
							|  |  |  | --> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## Components and API
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### `THEN`, `STOP` and `ERROR`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Values that if returned by option/command handlers can control the parse flow. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | - `THEN` – Stop parsing and call `<parser>.then(..)` callbacks. | 
					
						
							|  |  |  | - `STOP` – Stop parsing and call `<parser>.stop(..)` callbacks,  | 
					
						
							|  |  |  |   skipping `<parser>.then(..)`. | 
					
						
							|  |  |  | - `ERROR` – Stop parsing, call `<parser>.error(..)` callbacks and | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  |   exit with an error. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 20:17:15 +03:00
										 |  |  | ### `Parser(..)` 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Construct a parser instance | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | Parser(<spec>) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 20:17:15 +03:00
										 |  |  | See [`<parser>(..)`](#parser-1) for more info. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | #### `<parser>.then(..)`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Add callback to `then` "event". | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <parser>.then(<callback>) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | callback(<unhandled>, <root-value>, <rest>) | 
					
						
							|  |  |  | 	-> <obj> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 19:24:42 +03:00
										 |  |  | `then` is triggered when parsing is done or stopped from an option | 
					
						
							|  |  |  | handler by returning `THEN`. | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | #### `<parser>.stop(..)`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Add callback to `stop` "event". | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <parser>.stop(<callback>) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | callback(<arg>, <rest>) | 
					
						
							|  |  |  | 	-> <obj> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `stop` is triggered when a handler returns `STOP`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | #### `<parser>.error(..)`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Add callback to `error` "event". | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <parser>.error(<callback>) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | callback(<reason>, <arg>, <rest>) | 
					
						
							|  |  |  | 	-> <obj> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `error` is triggered when a handler returns `ERROR`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | #### `<parser>.off(..)`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Remove callback from "event". | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 	<parser>.off(<event>, <callback>) | 
					
						
							|  |  |  | 		-> <parser> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### `<parser>(..)`
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | Execute the `parser` instance. | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Run the parser on `process.argv` | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <parser>() | 
					
						
							|  |  |  | 	-> <result> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Explicitly pass a list of arguments where `<argv>[0]` is treated as  | 
					
						
							|  |  |  | the script path. | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <parser>(<argv>) | 
					
						
							|  |  |  | 	-> <result> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 20:21:03 +03:00
										 |  |  | Explicitly pass both a list of arguments and script path. | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | <parser>(<argv>, <main>) | 
					
						
							|  |  |  | 	-> <result> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If `<main>` is present in `<argv>` all the arguments before it will  | 
					
						
							|  |  |  | be ignored, otherwise the whole list is processed as if `<main>` was  | 
					
						
							|  |  |  | its head. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | ## Advanced parser API
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | ### `<parser>.print(..)` / `<parser>.printError(..)`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | Handle how `<parser>` prints things. | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | `<parser>.print(..)` and `<parser>.printError(..)` are very similar but handle different  | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | cases, similar to `console.log(..)` and `console.error(..)` | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <parser>.print(...) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <parser>.printError(...) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Both support callback binding: | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <parser>.print(<func>) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <parser>.printError(<func>) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | Both `<parser>.print(..)` and `<parser>.printError(..)` can safely be  | 
					
						
							|  |  |  | overloaded if the callback feature is not going to be used by the user  | 
					
						
							|  |  |  | – the print callbacks are not used internally.   | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | For full callback API see: `extra.afterCallback(..)` in [argv.js](./argv.js). | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### `<parser>.handlerDefault(..)`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | Called when `<option>.handler(..)` is not defined. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | By default this sets option values on the _parsed_ object. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | ### `<parser>.handleArgumentValue(..)`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | Handle argument value conversion. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | By default this handles the `<option>.type` mechanics. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If this is set to `false` values will be set as-is. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 21:24:19 +03:00
										 |  |  | ### `<parser>.handleErrorExit(..)`
 | 
					
						
							| 
									
										
										
										
											2020-07-04 21:48:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-19 20:58:22 +03:00
										 |  |  | Handle exit on error. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | By default this will call process.exit(1) for the _root parser_ and does  | 
					
						
							|  |  |  | nothing for _nested parsers_. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If set to `false` the _parser_ will simply return like any normal function. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-27 03:13:40 +03:00
										 |  |  | ### `<parser>.handle(..)`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Manually trigger `<arg>` handling. | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <parser>.handle(<arg>, <rest>, <key>, <value>) | 
					
						
							|  |  |  | 	-> <res> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is intended to be used for delegating handling from one handler to  | 
					
						
							|  |  |  | another. Note that this does not handle errors or other protocols handled | 
					
						
							|  |  |  | by `<parser>(..)`, this only calls the `<arg>` handler (or if it was not  | 
					
						
							|  |  |  | defined the _default handler_) so it is not recommended for this to be  | 
					
						
							|  |  |  | called from outside an option handler method/function. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is not intended for overloading. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### `<parser>.setHandlerValue(..)`
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Set handler value manually, this uses `<handler>.arg` and if not set `<key>` to  | 
					
						
							|  |  |  | write `<value>` on the _parsed_ object. | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <parser>.setHandlerValue(<handler>, <key>, <value>) | 
					
						
							|  |  |  | 	-> <parser> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is useful when extending `argv.js`, for client code values can be set  | 
					
						
							|  |  |  | directly. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is not intended for overloading. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 20:17:15 +03:00
										 |  |  | ### More...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For more info see the [source](./argv.js). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 03:09:23 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## License
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [BSD 3-Clause License](./LICENSE) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Copyright (c) 2016-2020, Alex A. Naanou,   | 
					
						
							|  |  |  | All rights reserved. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 00:05:38 +03:00
										 |  |  | <!-- vim:set ts=4 sw=4 spell : --> |