docs mostly done...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-07-19 20:58:22 +03:00
parent fffdee3563
commit 8d5b2ef74b
2 changed files with 153 additions and 28 deletions

174
README.md
View File

@ -66,6 +66,7 @@ This code is an evolution of that parser.
- [`<option>.valueRequired`](#optionvaluerequired) - [`<option>.valueRequired`](#optionvaluerequired)
- [Built-in options](#built-in-options) - [Built-in options](#built-in-options)
- [`-` / `--`](#ulli---liul) - [`-` / `--`](#ulli---liul)
- [`-*` / `@*`](#---)
- [`-v` / `--version`](#-v----version) - [`-v` / `--version`](#-v----version)
- [`-h` / `--help`](#-h----help) - [`-h` / `--help`](#-h----help)
- [Value placeholders](#value-placeholders) - [Value placeholders](#value-placeholders)
@ -89,7 +90,6 @@ This code is an evolution of that parser.
- [Advanced parser API](#advanced-parser-api) - [Advanced parser API](#advanced-parser-api)
- [`.print(..)` / `.printError(..)`](#print--printerror) - [`.print(..)` / `.printError(..)`](#print--printerror)
- [`.handlerDefault(..)`](#handlerdefault) - [`.handlerDefault(..)`](#handlerdefault)
- [`.handleArgument(..)`](#handleargument)
- [`.handleArgumentValue(..)`](#handleargumentvalue) - [`.handleArgumentValue(..)`](#handleargumentvalue)
- [`.handleErrorExit(..)`](#handleerrorexit) - [`.handleErrorExit(..)`](#handleerrorexit)
- [More...](#more) - [More...](#more)
@ -230,20 +230,20 @@ Parser(<spec>)
-> <parser> -> <parser>
``` ```
The `<spec>` object is "merged" int the `<parser>` instance overriding The `<spec>` object is "merged" into the `<parser>` instance overriding
or extending it's API/data. or extending it's API/data.
The `<parser>` expects/handles the following data in the `<spec>` object: The `<parser>` expects/handles the following data in the `<spec>` object:
- the configuration attributes and methods - the configuration attributes and methods
This sections lists attributes and methods designed to be set/modified in Attributes and methods used to configure, modify, extend or overload
`<spec>` passed to `Parser(..)`. parser functionality.
Note that these attributes are the same attributes inherited by `<parser>` Note that these attributes are the same attributes inherited by `<parser>`
and are simply merged into the new instance created by `Parser(..)`, this and are simply merged into the new instance created by `Parser(..)`, thus
there are no restrictions on what attributes/methods can be overloaded in there are no restrictions on what attributes/methods can be overloaded
this way but care must be taken when overloading elements that were not or extended in this way, but care must be taken when overloading elements
designed to be overloaded. that were not designed to be overloaded.
- option/command definitions - option/command definitions
The keys for these are prefixed either by `"-"` for options or by `"@"` The keys for these are prefixed either by `"-"` for options or by `"@"`
@ -271,13 +271,6 @@ The `<parser>` expects/handles the following data in the `<spec>` object:
Option handler. Option handler.
```javascript
'-option': function(opts, key, value){
// handle the option...
// ...
},
```
or
```javascript ```javascript
'-option': { '-option': {
handler: function(opts, key, value){ handler: function(opts, key, value){
@ -286,28 +279,40 @@ or
}, },
}, },
``` ```
or
Or a shorthand:
```javascript
'-option': function(opts, key, value){
// handle the option...
// ...
},
```
The handler gets called if the option is given or if it has a default The handler gets called if the option is given or if it was not explicitly
value but was not given. given but has a default value set.
`opts` contains the mutable list of arguments passed to the script `opts` contains the mutable list of arguments passed to the script
starting with but not including the current argument. If the handler starting just after the currently handled option/command. If the handler
needs to handle it's own arguments it can modify this list in place and needs to handle it's own arguments it can modify this list in place and
the _parser_ will continue from that state. the _parser_ will continue from the resulting state.
One usecase for this would be and option handler that needs to handle One use-case for this would be and option handler that needs to handle
it's arguemnts on its own. it's arguments in a custom manner, for example for handling multiple
arguments.
`key` is the actual normalized (`[<prefix-char>]<name-str>`) `key` is the actual normalized (`[<prefix-char>]<name-str>`)
option/command triggering the `.handler(..)`. option/command triggering the `.handler(..)`.
This can be useful to identify the actual option triggering the handler This can be useful to identify the actual option triggering the handler
when using aliases or if a single handler is used for multiple options, or 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`). when it is needed to handle a specific prefix differently (a-la `find`'s
syntax with `+option` and `-option` having different semantics).
`value` is the option value. A _value_ either ecplicitly passed (via `value` gets the value passed to the option.
`=` syntax), implicitly parsed from the `argv` via the `<option>.arg`
definition or `undefined` otherwise. A _value_ can be passed either explicitly passed (via `=` syntax),
implicitly parsed from the `argv` via the `<option>.arg` definition or
is `undefined` otherwise.
A handler can return one of the `THEN`, `STOP` or `ERROR` to control A handler can return one of the `THEN`, `STOP` or `ERROR` to control
further parsing and/or execution. further parsing and/or execution.
@ -318,6 +323,7 @@ further parsing and/or execution.
Option/command documentation string used in `-help`. Option/command documentation string used in `-help`.
#### `<option>.priority` #### `<option>.priority`
Option/command priority in the `-help`. Option/command priority in the `-help`.
@ -414,6 +420,15 @@ in the root parser to handle the rest of the options in `.then(..)`,
for example. for example.
#### `-*` / `@*`
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 `-*`.
#### `-v` / `--version` #### `-v` / `--version`
This will output the value of `.version` and exit. This will output the value of `.version` and exit.
@ -456,6 +471,7 @@ will get replaced with appropriate values when rendering help.
- `$VERSION` replaced with `.version`, - `$VERSION` replaced with `.version`,
- `$LICENSE` replaced with `.license`. - `$LICENSE` replaced with `.license`.
##### Automatically defined values ##### Automatically defined values
These values are set by the parser just before parsing starts: These values are set by the parser just before parsing starts:
@ -465,6 +481,7 @@ These values are set by the parser just before parsing starts:
These will be overwritten when the parser is called. These will be overwritten when the parser is called.
##### `.doc` ##### `.doc`
Script documentation. Script documentation.
@ -472,6 +489,7 @@ Script documentation.
Default value: `undefined` Default value: `undefined`
##### `.usage` ##### `.usage`
Basic usage hint. Basic usage hint.
@ -479,6 +497,7 @@ Basic usage hint.
Default value: `"$SCRIPTNAME [OPTIONS]"` Default value: `"$SCRIPTNAME [OPTIONS]"`
##### `.version` ##### `.version`
Version number. Version number.
@ -488,6 +507,7 @@ If this is not defined `-version` will print `"0.0.0"`.
Default value: `undefined` Default value: `undefined`
##### `.license` ##### `.license`
Short license information. Short license information.
@ -495,6 +515,7 @@ Short license information.
Default value: `undefined` Default value: `undefined`
##### `.examples` ##### `.examples`
<spec>.usage = <string> | <list> | <function> | undefined <spec>.usage = <string> | <list> | <function> | undefined
@ -508,6 +529,7 @@ Example list format:
Default value: `undefined` Default value: `undefined`
##### `.footer` ##### `.footer`
Aditional information. Aditional information.
@ -523,6 +545,57 @@ For more info on help formatting see `.help*` attributes in the [source](./argv.
### Nested parsers ### Nested parsers
An option/command handler can be a _parser instance_.
From the point of view of the _nested parser_ nothing is different &ndash;
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 ;)
-->
## Components and API ## Components and API
@ -628,18 +701,65 @@ If `<main>` is present in `<argv>` all the arguments before it will
be ignored, otherwise the whole list is processed as if `<main>` was be ignored, otherwise the whole list is processed as if `<main>` was
its head. its head.
## Advanced parser API ## Advanced parser API
### `.print(..)` / `.printError(..)` ### `.print(..)` / `.printError(..)`
Handle how `Parser(..)` prints things.
`.print(..)` and `.printError(..)` are very similar but handle different
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>
```
Both `.print(..)` and `.printError(..)` can safely be overloaded if the
callback feature is not going to be used by the user &ndash; the print
callbacks are not used internally.
For full callback support see: `extra.afterCallback(..)` in [argv.js](./argv.js).
### `.handlerDefault(..)` ### `.handlerDefault(..)`
### `.handleArgument(..)` Called when `<option>.handler(..)` is not defined.
By default this sets option values on the _parsed_ object.
### `.handleArgumentValue(..)` ### `.handleArgumentValue(..)`
Handle argument value conversion.
By default this handles the `<option>.type` mechanics.
If this is set to `false` values will be set as-is.
### `.handleErrorExit(..)` ### `.handleErrorExit(..)`
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.
### More... ### More...
For more info see the [source](./argv.js). For more info see the [source](./argv.js).

View File

@ -41,6 +41,9 @@ module.ERROR =
//--------------------------------------------------------------------- //---------------------------------------------------------------------
// helpers... // helpers...
module.extra = {}
// //
// afterCallback(name) // afterCallback(name)
// -> func // -> func
@ -60,7 +63,9 @@ module.ERROR =
// post_action(...args) // post_action(...args)
// -> ... // -> ...
// //
var afterCallback = function(name, pre, post){ var afterCallback =
module.extra.afterCallback =
function(name, pre, post){
var attr = '__after_'+ name var attr = '__after_'+ name
return function(...args){ return function(...args){
var that = this var that = this