• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

docs/H27-Apr-2019-2,3041,775

examples/H27-Apr-2019-1,9471,226

include/H27-Apr-2019-7,0254,441

test/H27-Apr-2019-6,6714,893

.gitignoreH A D27-Apr-2019184 2018

.travis.ymlH A D27-Apr-20191.8 KiB6450

LICENSEH A D27-Apr-20191.1 KiB2116

README.mdH A D27-Apr-201977.2 KiB2,2081,775

appveyor.ymlH A D27-Apr-2019382 2717

README.md

1clipp - command line interfaces for modern C++
2===========================================================
3
4[![Linux build status](https://travis-ci.org/muellan/clipp.svg?branch=master)](https://travis-ci.org/muellan/clipp) [![MSVC build status](https://ci.appveyor.com/api/projects/status/ci29ngpfks980i7g?svg=true)](https://ci.appveyor.com/project/muellan/clipp)
5
6Easy to use, powerful and expressive command line argument handling for C++11/14/17 contained in a **single header file**.
7
8- options, options+value(s), positional values, positional commands, nested alternatives, decision trees, joinable flags, custom value filters, ...
9- documentation generation (usage lines, man pages); error handling
10- lots of examples; large set of tests
11
12- ### [Quick Reference Table](#quick-reference)
13- ### [Overview (short examples)](#overview)
14- ### [Detailed Examples](#examples)
15- #### [Why yet another library for parsing command line arguments?](#motivation) / [Design goals](#design-goals)
16- #### [Requirements / Compilers](#requirements)
17
18
19
20## Quick Intro
21
22### Simple Use Case — Simple Setup!
23Consider this command line interface:
24```man
25SYNOPSIS
26    convert <input file> [-r] [-o <output format>] [-utf16]
27
28OPTIONS
29    -r, --recursive  convert files recursively
30    -utf16           use UTF-16 encoding
31```
32Here is the code that defines the positional value ```input file``` and the three options ```-r```, ```-o``` and ```-utf16```. If parsing fails, the above default man page-like snippet will be printed to stdout.
33```cpp
34#include <iostream>
35#include "clipp.h"
36using namespace clipp; using std::cout; using std::string;
37
38int main(int argc, char* argv[]) {
39    bool rec = false, utf16 = false;
40    string infile = "", fmt = "csv";
41
42    auto cli = (
43        value("input file", infile),
44        option("-r", "--recursive").set(rec).doc("convert files recursively"),
45        option("-o") & value("output format", fmt),
46        option("-utf16").set(utf16).doc("use UTF-16 encoding")
47    );
48
49    if(!parse(argc, argv, cli)) cout << make_man_page(cli, argv[0]);
50    // ...
51}
52```
53
54
55
56### A More Complex Example:
57```man
58SYNOPSIS
59    finder make <wordfile> -dict <dictionary> [--progress] [-v]
60    finder find <infile>... -dict <dictionary> [-o <outfile>] [-split|-nosplit] [-v]
61    finder help [-v]
62
63OPTIONS
64    --progress, -p           show progress
65    -o, --output <outfile>   write to file instead of stdout
66    -split, -nosplit         (do not) split output
67    -v, --version            show version
68```
69This CLI has three alternative commands (```make```, ```find```, ```help```), some positional value-arguments (```<wordfile>```, ```<infile>```) of which one is repeatable, a required flag with value-argument (```-dict <dictionary>```), an option with value-argument (```-o <outfile>```), one option with two alternatives (```-split```, ```-nosplit```) and two conventional options (```-v```, ```--progress```).
70
71Here is the code that defines the interface, generates the man page snippet above *and* handles the parsing result:
72```cpp
73using namespace clipp; using std::cout; using std::string;
74
75//variables storing the parsing result; initialized with their default values
76enum class mode {make, find, help};
77mode selected = mode::help;
78std::vector<string> input;
79string dict, out;
80bool split = false, progr = false;
81
82auto dictionary = required("-dict") & value("dictionary", dict);
83
84auto makeMode = (
85    command("make").set(selected,mode::make),
86    values("wordfile", input),
87    dictionary,
88    option("--progress", "-p").set(progr) % "show progress" );
89
90auto findMode = (
91    command("find").set(selected,mode::find),
92    values("infile", input),
93    dictionary,
94    (option("-o", "--output") & value("outfile", out)) % "write to file instead of stdout",
95    ( option("-split"  ).set(split,true) |
96      option("-nosplit").set(split,false) ) % "(do not) split output" );
97
98auto cli = (
99    (makeMode | findMode | command("help").set(selected,mode::help) ),
100    option("-v", "--version").call([]{cout << "version 1.0\n\n";}).doc("show version")  );
101
102if(parse(argc, argv, cli)) {
103    switch(selected) {
104        case mode::make: /* ... */ break;
105        case mode::find: /* ... */ break;
106        case mode::help: cout << make_man_page(cli, "finder"); break;
107    }
108} else {
109     cout << usage_lines(cli, "finder") << '\n';
110}
111```
112
113
114
115
116## Quick Reference
117
118Below are a few examples that should give you an idea for how clipp works.
119Consider this basic setup with a few variables that we want to set using
120command line arguments:
121```cpp
122int main(int argc, char* argv[]) {
123    using namespace clipp;
124
125    // define some variables
126    bool a = false, b = false;
127    int n = 0, k = 0;
128    double x = 0.0, y = 0.0;
129    std::vector<int> ids;
130
131    auto cli = ( /* CODE DEFINING COMMAND LINE INTERFACE GOES HERE */ );
132
133    parse(argc, argv, cli);    //excludes argv[0]
134
135    std::cout << usage_lines(cli, "exe") << '\n';
136}
137```
138
139| Interface (`usage_lines`)  | Code (content of `cli` parentheses )
140| -------------------------- | ------------------------------------
141| ` exe [-a] `               | ` option("-a", "--all").set(a)`
142| ` exe [--all] `            | ` option("--all", "-a", "--ALL").set(a)`
143| ` exe [-a] [-b] `          | ` option("-a").set(a), option("-b").set(b)`
144| ` exe -a `                 | ` required("-a").set(a)`
145| ` exe [-a] -b `            | ` option("-a").set(a), required("-b").set(b)`
146| ` exe [-n <times>] `       | ` option("-n", "--iter") & value("times", n) `
147| ` exe [-n [<times>]] `     | ` option("-n", "--iter") & opt_value("times", n) `
148| ` exe -n <times>  `        | ` required("-n", "--iter") & value("times", n) `
149| ` exe -n [<times>] `       | ` required("-n", "--iter") & opt_value("times", n) `
150| ` exe [-c <x> <y>]`        | ` option("-c") & value("x", x) & value("y", y)`
151| ` exe -c <x> <y> `         | ` required("-c") & value("x", x) & value("y", y)`
152| ` exe -c <x> [<y>] `       | ` required("-c") & value("x", x) & opt_value("y", y)`
153| ` exe [-l <lines>...] `    | ` option("-l") & values("lines", ids) `
154| ` exe [-l [<lines>...]] `  | ` option("-l") & opt_values("lines", ids) `
155| ` exe [-l <lines>]... `    | ` repeatable( option("-l") & value("lines", ids) ) `
156| ` exe -l <lines>... `      | ` required("-l") & values("lines", ids) `
157| ` exe -l [<lines>...] `    | ` required("-l") & opt_values("lines", ids) `
158| ` exe (-l <lines>)... `    | ` repeatable( required("-l") & value("lines", ids) ) `
159| ` exe fetch [-a] `         | ` command("fetch").set(k,1), option("-a").set(a) `
160| ` exe init \| fetch [-a] ` | ` command("init").set(k,0) \| (command("fetch").set(k,1), option("-a").set(a)) `
161| ` exe [-a\|-b]  `          | ` option("-a").set(a) \| option("-b").set(b) `
162| ` exe [-m a\|b] `          | ` option("-m") & (required("a").set(b) \| required("b").set(b)) `
163
164
165
166
167## Overview
168
169See the [examples](#examples) section for detailed explanations of each topic.
170
171Namespace qualifiers are omitted from all examples for better readability. All entities are defined in ```namespace clipp```.
172
173
174#### Basic Setup
175```cpp
176int main(int argc, char* argv[]) {
177    using namespace clipp;
178
179    auto cli = ( /* CODE DEFINING COMMAND LINE INTERFACE GOES HERE */ );
180    parse(argc, argv, cli);    //excludes argv[0]
181
182    //if you want to include argv[0]
183    //parse(argv, argv+argc, cli);
184}
185```
186
187There are two kinds of building blocks for command line interfaces: parameters and groups. Convieniently named factory functions produce parameters or groups with the desired settings applied.
188#### Parameters ([flag strings](#flag-strings), [commands](#commands), [positional values](#required-positional-values), [required flags](#required-flags), [repeatable parameters](#repeatable-parameters))
189```cpp
190bool a = false, f = false;
191string s; vector<string> vs;
192auto cli = (                             // matches  required  positional  repeatable
193    command("push"),                     // exactly      yes       yes         no
194    required("-f", "--file").set(f),     // exactly      yes       no          no
195    required("-a", "--all", "-A").set(a),  // exactly      no        no          no
196
197    value("file", s),                    // any arg      yes       yes         no
198    values("file", vs),                  // any arg      yes       yes         yes
199    opt_value("file", s),                // any arg      no        yes         no
200    opt_values("file", vs),              // any arg      no        yes         yes
201
202    //"catch all" parameter - useful for error handling
203    any_other(vs),                       // any arg      no        no          yes
204    //catches arguments that fulfill a predicate and aren't matched by other parameters
205    any(predicate, vs)                   // predicate    no        no          yes
206);
207```
208The functions above are convenience factories:
209```cpp
210bool f = true; string s;
211auto v1 = values("file", s);
212// is equivalent to:
213auto v2 = parameter{match::nonempty}.label("file").blocking(true).repeatable(true).set(s);
214
215auto r1 = required("-f", "--file").set(f);
216// is equivalent to:
217auto r2 = parameter{"-f", "--file"}.required(true).set(f);
218```
219 - a required parameter has to match at least one command line argument
220 - a repeatable parameter can match any number of arguments
221 - non-positional (=non-blocking) parameters can match arguments in any order
222 - a positional (blocking) parameter defines a "stop point", i.e., until it matches all parameters following it are not allowed to match; once it matched, all parameters preceding it (wihtin the current group) will become unreachable
223
224##### [Flags + Values](#options-with-values)
225If you want parameters to be matched in sequence, you can tie them together using either ```operator &``` or the grouping function ```in_sequence```:
226
227```cpp
228int n = 1; string s; vector<int> ls;
229auto cli = (
230    //option with required value
231    option("-n", "--repeat") & value("times", n),
232
233    //required flag with optional value
234    required("--file") & opt_value("name", s),
235
236    //option with exactly two values
237    option("-p", "--pos") & value("x") & value("y"),
238
239    //same as before                   v            v
240    in_sequence( option("-p", "--pos") , value("x") , value("y") ),
241
242    //option with at least one value (and optionally more)
243    option("-l") & values("lines", ls)
244);
245```
246
247##### [Filtering Value Parameters](#value-filters)
248Value parameters use a filter function to test if they are allowed to match an argument string. The default filter ```match::nonempty``` that is used by ```value```, ```values```, ```opt_value``` and ```opt_values``` will match any non-empty argument string.
249You can either supply other filter functions/function objects as first argument of ```value```, ```values```, etc. or use one of these built-in shorthand factory functions covering the most common cases:
250```cpp
251string name; double r = 0.0; int n = 0;
252auto cli = (
253    value("user", name),   // matches any non-empty string
254    word("user", name),    // matches any non-empty alphanumeric string
255    number("ratio", r),    // matches string representations of numbers
256    integer("times", n)    // matches string representations of integers
257);
258```
259Analogous to ```value```, ```opt_value```, etc. there are also functions for ```words```, ```opt_word```, etc.
260
261##### Value Parameters With [Custom Filters](#custom-value-filters)
262```cpp
263auto is_char = [](const string& arg) { return arg.size() == 1 && std::isalpha(arg[0]); };
264
265char c = ' ';
266                             // matches       required  positional  repeatable
267value(is_char, "c", c);      // one character  yes       yes         no
268```
269
270
271#### Groups
272 - [group](#grouping) mutually compatible parameters with parentheses and commas:
273   ```cpp
274   auto cli = ( option("-a"), option("-b"), option("-c") );
275   ```
276
277 - group mutually exclusive parameters as [alternatives](#alternatives) using ```operator |``` or ```one_of```:
278   ```cpp
279   auto cli1 = ( value("input_file") | command("list") | command("flush") );
280
281   auto cli2 = one_of( value("input_file") , command("list") , command("flush") );
282   ```
283
284 - group parameters so that they must be matched in sequence using ```operator &``` or ```in_sequence```:
285   ```cpp
286   double x = 0, y = 0, z = 0;
287   auto cli1 = ( option("-pos") & value("X",x) & value("Y",y) & value("Z",z) );
288
289   auto cli2 = in_sequence( option("-pos") , value("X",x) , value("Y",y) , value("Z",z) );
290   ```
291   Note that surrounding groups are not affected by this, so that ```-a``` and ```-b``` can be matched in any order while ```-b``` and the value ```X``` must match in sequence:
292   ```cpp
293   bool a = false, b = false; int x = 0;
294   auto cli = (  option("-a").set(a),  option("-b").set(b) & value("X",x)  );
295   ```
296
297 - groups can be nested and combined to form arbitrarily complex interfaces (see [here](#nested-alternatives) and [here](#complex-nestings)):
298   ```cpp
299   auto cli = ( command("push") | ( command("pull"), option("-f", "--force") )  );
300   ```
301
302 - groups can be repeatable as well:
303   ```cpp
304   auto cli1 = repeatable( command("flip") | command("flop") );
305   ```
306
307 - force common prefixes on a group of flags:
308   ```cpp
309   int x = 0;
310   auto cli1 = with_prefix("-", option("a"), option("b") & value("x",x), ... );
311                             // =>     -a           -b     ^unaffected^
312
313   auto cli2 = with_prefix_short_long("-", "--", option("a", "all"), option("b"), ... );
314                                                  // => -a  --all           -b
315   ```
316
317 - force common suffixes on a group of flags:
318   ```cpp
319   int x = 0;
320   auto cli1 = with_suffix("=", option("a") & value("x",x), ... );
321                             // =>      a=    ^unaffected^
322
323   auto cli2 = with_suffix_short_long(":", ":=", option("a", "all"), option("b"), ... );
324                                                  // =>  a:   all:=          b:
325   ```
326
327 - make a group of flags [joinable](#joinable-flags):
328   ```cpp
329   auto cli1 = joinable( option("-a"), option("-b"));  //will match "-a", "-b", "-ab", "-ba"
330
331   //works also with arbitrary common prefixes:
332   auto cli2 = joinable( option("--xA0"), option("--xB1"));  //will also match "--xA0B1" or "--xB1A0"
333   ```
334
335
336#### Interfacing With Your Code
337The easiest way to connect the command line interface to the rest of your code is to bind object values or function (object) calls to parameters (see also [here](#actions)):
338```cpp
339bool b = false; int i = 5; int m = 0; string x; ifstream fs;
340auto cli = (
341    option("-b").set(b),                      // "-b" detected -> set b to true
342    option("-m").set(m,2),                    // "-m" detected -> set m to 2
343    option("-x") & value("X", x),             // set x's value from arg string
344    option("-i") & opt_value("i", i),         // set i's value from arg string
345    option("-v").call( []{ cout << "v"; } ),  // call function (object) / lambda
346    option("-v")( []{ cout << "v"; } ),       // same as previous line
347    option("-f") & value("file").call([&](string f){ fs.open(f); })
348);
349```
350
351In production code one would probably use a settings class:
352```cpp
353struct settings { bool x = false; /* ... */ };
354
355settings cmdline_settings(int argc, char* argv[]) {
356    settings s;
357    auto cli = ( option("-x").set(s.x), /* ... */ );
358    parse(argc, argv, cli);
359    return s;
360}
361```
362Note that the target must either be:
363 - a fundamental type (```int, long int, float, double, ...```)
364 - a type that is convertible from ```const char*```
365 - a callable entity: function, function object / lambda
366   that either has an empty parameter list or exactly one parameter that is
367   convertible from ```const char*```
368
369
370#### Generating Documentation ([see also here](#documentation-generation))
371Docstrings for groups and for parameters can either be set with the member function ```doc``` or with ```operator %```:
372```cpp
373auto cli = (
374    (   option("x").set(x).doc("sets X"),
375        option("y").set(y) % "sets Y"
376    ),
377    "documented group 1:" % (
378        option("-g").set(g).doc("activates G"),
379        option("-h").set(h) % "activates H"
380    ),
381    (   option("-i").set(i) % "activates I",
382        option("-j").set(j) % "activates J"
383    ).doc("documented group 2:")
384);
385```
386
387Usage Lines:
388```cpp
389cout << usage_lines(cli, "progname") << '\n';
390
391//with formatting options
392auto fmt = doc_formatting{}
393           .first_column(3)
394           .last_column(79);
395cout << usage_lines(cli, "progname", fmt) << '\n';
396```
397
398Detailed Documentation:
399```cpp
400cout << documentation(cli) << '\n';
401
402//with formatting options
403auto fmt = doc_formatting{}
404           .first_column(7)
405           .doc_column(15)
406           .last_column(99);
407cout << documentation(cli, fmt) << '\n';
408```
409
410Man Pages:
411```cpp
412auto cli = ( /*CODE DEFINING COMMAND LINE INTERFACE GOES HERE*/ );
413cout << make_man_page(cli, "progname") << '\n';
414
415//with formatting options
416auto fmt = doc_formatting{}
417           .first_column(7)
418           .doc_column(15)
419           .last_column(99);
420cout << make_man_page(cli, "progname", fmt) << '\n';
421```
422
423
424#### (Error) Event Handlers ([see here](#error-handling), [and here](#per-parameter-parsing-report))
425Each parameter can have event handler functions attached to it. These are invoked once for each argument that is mapped to the parameter (or once per missing event):
426```cpp
427string file = "default.txt";
428auto param = required("-nof").set(file,"") |
429             required("-f") & value("file", file)
430                              // on 2nd, 3rd, 4th,... match (would be an error in this case)
431                              .if_repeated( [] { /* ... */ } )
432                              // if required value-param was missing
433                              .if_missing( [] { /* ... */ } )
434                              // if unreachable, e.g. no flag "-f" before filename
435                              .if_blocked( [] { /* ... */ } )
436                              // if match is in conflict with other alternative "-nof"
437                              .if_conflicted( [] { /* ... */ } );
438```
439The handler functions can also take an int, which is set to the argument index at which the event occurred first:
440```cpp
441string file = "default.txt";
442auto param = required("-nof").set(file,"") |
443             required("-f") & value("file", file)
444                              .if_repeated  ( [] (int argIdx) { /* ... */ } )
445                              .if_missing   ( [] (int argIdx) { /* ... */ } )
446                              .if_blocked   ( [] (int argIdx) { /* ... */ } )
447                              .if_conflicted( [] (int argIdx) { /* ... */ } );
448```
449
450
451#### Special Cases
452If we give ```-f -b``` or ```-b -f -a``` as command line arguments for the following CLI, an error will be reported, since the value after ```-f``` is not optional:
453```cpp
454auto cli = (  option("-a"),  option("-f") & value("filename"),  option("-b")  );
455```
456This behavior is fine for most use cases.
457But what if we want our program to take any string as a filename, because our filenames might also collide with flag names? We can make the value parameter [greedy](#greedy-parameters) with ```operator !```. This way, the next string after ```-f``` will always be matched with highest priority as soon as ```-f``` was given:
458```cpp
459auto cli = (  option("-a"),  option("-f") & !value("filename"),   option("-b")  );
460                                        //  ^~~~~~
461```
462Be **very careful** with greedy parameters!
463
464
465
466#### Parsing Result Analysis
467```cpp
468auto cli = ( /* your interface here */ );
469auto res = parse(argc, argv, cli);
470
471if(res.any_error()) { /* ... */ }
472
473//aggregated errors
474if(res.unmapped_args_count()) { /* ... */ }
475if(res.any_bad_repeat()) { /* ... */ }
476if(res.any_blocked())    { /* ... */ }
477if(res.any_conflict())   { /* ... */ }
478
479for(const auto& m : res.missing()) {
480    cout << "missing " << m.param() << " after index " << m.after_index() << '\n';
481}
482
483//per-argument mapping
484for(const auto& m : res) {
485    cout << m.index() << ": " << m.arg() << " -> " << m.param();
486    cout << " repeat #" << m.repeat();
487    if(m.blocked()) cout << " blocked";
488    if(m.conflict()) cout << " conflict";
489    cout << '\n';
490}
491```
492
493#### Writing Your Own Convenience Factories
494Sometimes it can make your CLI code more expressive and increase maintainability, if you create your own factory functions for making parameters:
495```cpp
496//value that can only connect to one object with automatic default value documentation
497template<class Target>
498clipp::parameter
499documented_value(const std::string& name, Target& tgt, const std::string& docstr) {
500    using std::to_string;
501    return clipp::value(name,tgt).doc(docstr + "(default: " + to_string(tgt) + ")");
502}
503```
504```cpp
505//value that only matches strings without prefix '-'
506template<class Target, class... Targets>
507clipp::parameter
508nodash_value(std::string label, Target&& tgt, Targets&&... tgts) {
509    return clipp::value(clipp::match::prefix_not{"-"}, std::move(label),
510               std::forward<Target>(tgt), std::forward<Targets>(tgts)...);
511}
512```
513
514
515
516
517## Examples
518
519Note that namespace qualifiers are omitted from all examples for better readability.
520The repository folder "examples" contains code for most of the following examples.
521
522- [options](#options)
523- [coding styles](#coding-styles)
524- [flag strings](#flag-strings)
525- [groups](#grouping)
526- [positional values](#required-positional-values)
527- [options with values](#options-with-values)
528- [options with multiple values](#options-with-multiple-values)
529- [required flags](#required-flags)
530- [repeatable parameters](#repeatable-parameters)
531- [actions](#actions)
532- [joinable flags](#joinable-flags)
533- [alternatives](#alternatives)
534- [commands](#commands)
535- [nested alternatives](#nested-alternatives)
536- [complex nestings](#complex-nestings)
537- [example from docopt](#an-example-from-docopt)
538- [value filters](#value-filters)
539- [greedy parameters](#greedy-parameters)
540- [generalized joinable parameters](#generalized-joinable-parameters)
541- [custom value filters](#custom-value-filters)
542- [sanity checks](#sanity-checks)
543- [basic error handling](#basic-error-handling)
544- [parsing](#parsing)
545- [documentation generation](#documentation-generation)
546- [documentation filtering](#documentation-filtering)
547
548
549
550### Options
551```man
552SYNOPSIS
553       switch [-a] [-b] [-c] [--hi]
554
555OPTIONS
556       -a          activates a
557       -b          activates b
558       -c, --noc   deactivates c
559       --hi        says hi
560```
561
562```cpp
563bool a = false, b = false, c = true; //target variables
564
565auto cli = (
566    option("-a").set(a)                  % "activates a",
567    option("-b").set(b)                  % "activates b",
568    option("-c", "--noc").set(c,false)   % "deactivates c",
569    option("--hi")([]{cout << "hi!\n";}) % "says hi");
570
571if(parse(argc, argv, cli))
572    cout << "a=" << a << "\nb=" << b << "\nc=" << c << '\n';
573else
574    cout << make_man_page(cli, "switch");
575```
576This will set ```a``` to true, if ```-a``` is found, ```b``` to true, if ```-b``` is found, ```c``` to false, if ```-c``` or ```--noc``` are found and prints "hi" if ```--hi``` is found in ```argv```. In case of parsing errors a man page will be printed.
577
578
579
580### Coding Styles
581If you like it more verbose use ```set``` to set variables, ```call``` to call functions and ```doc``` for docstrings. The sequence of member function calls doesn't matter.
582```cpp
583auto cli = (
584    option("-b").set(b).doc("activates b"),
585    option("-c", "--noc").set(c,false).doc("deactivates c"),
586    option("--hi").call([]{cout << "hi!\n";}).doc("says hi") );
587```
588
589#### You can also use ```operator >>``` and ```operator <<``` to define actions
590```cpp
591auto cli = (
592    option("-b")          % "activates b"   >> b,
593    option("-c", "--noc") % "deactivates c" >> set(c,false),
594    option("--hi")        % "says hi"       >> []{cout << "hi!\n";} );
595```
596
597```cpp
598auto cli = (
599    option("-b")          % "activates b"   >> b,
600    option("-c", "--noc") % "deactivates c" >> set(c,false),
601    option("--hi")        % "says hi"       >> []{cout << "hi!\n";} );
602```
603```cpp
604auto cli = (
605    b                    << option("-b")          % "activates b",
606    set(c,false)         << option("-c", "--noc") % "deactivates c",
607    []{cout << "hi!\n";} << option("--hi")        % "says hi" );
608
609```
610```cpp
611auto cli = (
612    "activates b"   % option("-b")          >> b,
613    "deactivates c" % option("-c", "--noc") >> set(c,false),
614    "says hi"       % option("--hi")        >> []{cout << "hi!\n";} );
615```
616Note that ```%``` has a higher precedence than ```<<``` and ```>>``` which means that you either have to keep the docstrings closer to the command line parameters than the actions or use parentheses.
617
618You should also have a look at [actions](#actions) for more details.
619
620
621#### Step-by-step configuration of parameters:
622```cpp
623int n = 1;
624
625auto optN = parameter{"-n", "-N", "--iterations", "--repeats"}.required(true);
626
627auto valN = parameter{match::any}
628    .label("times")
629    .set(n)
630    .call([](string s) { if(!str::represents_number(s)) throw runtime_error{"invalid value for 'times'"}; })
631    .if_missing([]{ cout << "value 'times' not found!\n"; })
632    .doc("number of iterations (default = " + std::to_string(n) + ")");
633
634auto cli = group{};
635cli.push_back(std::move(optN));
636cli.push_back(std::move(valN));
637
638// or:
639auto cli = group{std::move(optN), std::move(valN)};
640```
641
642
643
644### Flag Strings
645There are no limitations regarding formatting and you can have an arbitrary number of flags per command line parameter.
646```cpp
647bool onetwo = false;
648auto myopt = option("-1", "-2", "1", "2", ":1", ":2", "--no1", "--no2").set(onetwo);
649             //     ^----- will match any one of these strings ------^
650```
651
652#### Same prefix for all flags
653```cpp
654bool a = false, b = false;
655
656auto cli = with_prefix("-",
657    option("a").set(a),     // -a
658    option("b").set(b)      // -b
659);
660```
661
662#### Same prefix for all flags: single vs. multiple character(s)
663Single-letter flags will get the first prefix, flags with more than one letter will get the second one.
664```cpp
665bool a = false, b = false;
666
667auto cli = with_prefixes_short_long("-", "--",
668    option("a", "all").set(a),      // -a, --all
669    option("b", "bottom").set(b)    // -b, --bottom
670);
671```
672
673#### Same suffix for all flags
674```cpp
675bool a = false, b = false;
676
677auto cli = with_suffix(":",
678    option("a").set(a),     // a:
679    option("b").set(b)      // b:
680);
681```
682
683#### Same suffix for all flags: single vs. multiple character(s)
684Single-letter flags will get the first suffix (empty in this example), flags with more than one letter will get the second one.
685```cpp
686int a = 0, b = 0;
687
688auto cli = with_suffixes_short_long("", "=",
689    option("a", "all") & value("A", a),      // -a, --all=
690    option("b", "bottom") & value("B", b)    // -b, --bottom=
691);
692```
693
694#### Make Sure No Flag Occurs As Prefix Of Another Flag
695```cpp
696auto cli = ( /* your command line interface here */ );
697assert(cli.flags_are_prefix_free());
698```
699Note that identical flags will not trigger an error.
700
701
702### Grouping
703Groups can be nested (see [here](#nested-alternatives)) and have their own documentation string.
704The statement ```auto cli = ( ... );``` creates a group, if there are more than two parameters/groups declared inside the parentheses.
705
706```man
707SYNOPSIS
708        myprogram [x] [y] [a] [b] [-c] [-d] [-e] [-f]
709
710OPTIONS
711        x      sets X
712        y      sets Y
713
714        documented group 1:
715        a      activates A
716        b      activates B
717
718        documented group 2:
719        -c     activates C
720        -d     activates D
721
722        -e, -f activates E or F
723```
724
725```cpp
726bool x = false, y = false, a = false, b = false;
727bool g = false, h = false, e = false, f = false;
728
729auto cli = (
730    (   option("x").set(x) % "sets X",  //simple group
731        option("y").set(y) % "sets Y"
732    ),
733    (   option("a").set(a) % "activates A",
734        option("b").set(b) % "activates B"
735    ) % "documented group 1:"           //docstring after group
736    ,
737    "documented group 2:" % (           //docstring before group
738        option("-g").set(g) % "activates G",
739        option("-h").set(h) % "activates H"
740    ),
741    "activates E or F" % (
742        option("-e").set(e),        //no docstrings inside group
743        option("-f").set(f)
744    )
745);
746
747cout << make_man_page(cli, "myprogram");
748```
749
750The above example is in fact shorthand for this:
751```cpp
752group cli{
753    group{
754        parameter{"x"}.set(x).doc("sets X"),
755        parameter{"y"}.set(y).doc("sets Y")
756    },
757    group{
758        parameter{"a"}.set(a).doc("activates A"),
759        parameter{"b"}.set(b).doc("activates B")
760    }.doc("documented group 1:")
761    ,
762    group{
763        parameter{"-g"}.set(g).doc("activates G"),
764        parameter{"-h"}.set(h).doc("activates H")
765    }.doc("documented group 2:")
766    ,
767    group{
768        parameter{"-e"}.set(e),
769        parameter{"-f"}.set(f)
770    }.doc("activates E or F")
771};
772
773cout << make_man_page(cli, "myprogram");
774```
775
776You can of course also fill groups one-by-one:
777```cpp
778group cli;
779cli.push_back(option("x").sets(x).doc("sets X"));
780//...
781```
782
783
784
785### Required Positional Values
786```man
787SYNOPSIS
788        myprogram <infile> <outfile> [-s]
789
790OPTIONS
791        infile        input filename
792        outfile       output filename
793        -s, --split   split files
794```
795
796```cpp
797string ifile, ofile;
798bool split = false;
799auto cli = (
800    value("infile", ifile)             % "input filename",
801    value("outfile", ofile)            % "output filename",
802    option("-s", "--split").set(split) % "split files" );
803```
804
805#### Alternative Value Mapping Style
806```cpp
807auto cli = (
808     value("infile")         % "input filename"  >> ifile,
809     value("outfile")        % "output filename" >> ofile,
810     option("-s", "--split") % "split files"     >> split  );
811```
812See [here](#coding-styles) for more on possible mapping styles.
813
814
815
816### Options With Values
817Parameters can be sequenced using operator ```&``` or the function ```in_sequence```. Sequenced parameters can only be matched one after the other. This mechanism can be used to attach a value parameter to an option.
818
819```man
820SYNOPSIS
821       simplify [-n <count>] [-r <ratio>] [-m [<lines=5>]]
822
823OPTIONS
824       -n, --count <count>     number of iterations
825       -r, --ratio <ratio>     compression ratio
826       -m <lines=5>            merge lines (default: 5)
827```
828
829```cpp
830int n = 0;
831bool domerge = false;
832long m = 5;
833auto print_ratio = [](const char* r) { cout << "using ratio of " << r << '\n'; };
834
835auto cli = (
836    (option("-n", "--count") & value("count", n))           % "number of iterations",
837    (option("-r", "--ratio") & value("ratio", print_ratio)) % "compression ratio",
838    (option("-m").set(domerge) & opt_value("lines=5", m))   % "merge lines (default: 5)"
839);
840```
841
842
843#### Alternative Value Mapping Styles
844```cpp
845auto cli = (
846    (option("-n", "--count") & value("count") >> n                 ) % "number of iterations",
847    (option("-r", "--ratio") & value("ratio") >> print_ratio       ) % "compression ratio",
848    (option("-m"           ) & opt_value("lines=5") >> m >> domerge) % "merge lines (default: 5)"
849);
850```
851```cpp
852auto cli = (
853    (option("-n", "--count") & value("count").set(n))         % "number of iterations",
854    (option("-r", "--ratio") & value("ratio")(print_ratio))   % "compression ratio",
855    (option("-m").set(domerge) & opt_value("lines=5").set(m)) % "merge lines (default: 5)"
856);
857```
858See [here](#coding-styles) for more on coding styles.
859
860
861
862### Options With Multiple Values
863Parameters can be sequenced using operator ```&``` or the function ```in_sequence```. Sequenced parameters can only be matched one after the other. This mechanism can be used to attach multiple values to an option.
864
865```man
866SYNOPSIS
867       transform <geometry file> [-translate <x> <y> <z>] [-rotate <azimuth> <polar>]
868```
869
870```cpp
871string infile;
872bool tr = false, rot = false;
873double x = 0, y = 0, z = 0;
874double phi = 0, theta = 0;
875
876auto cli = (
877    value("geometry file", infile),
878    option("-translate").set(tr) & value("x", x) & value("y", y) & value("z", z),
879    option("-rotate").set(rot) & value("azimuth", phi) & value("polar", theta)
880);
881```
882
883Note that the following interface definition is equivalent to the above. Since ```value``` is positional we can list it with ```,```, but we have to make sure that the groups of values will only be matched after the options, hence the ```&```.
884```cpp
885auto cli = (
886    value("geometry file", infile),
887    option("-translate").set(tr) & ( value("x", x), value("y", y), value("z", z) ),
888    option("-rotate").set(rot)   & ( value("azimuth", phi) , value("polar", theta) )
889);
890```
891
892
893
894### Required Flags
895Required flags are usually used together with non-optional values. Note that ```-i``` and ```-o``` are not positional in the following example, i.e., the relative order in which command line arguments for ```-i```, ```-o``` and ```-r``` are provided is irrelevant.
896
897```man
898SYNOPSIS
899        myprogram [-r] -i <input dir> -o <output dir>
900
901OPTIONS
902        -r, --recursive
903                search in subdirectories
904        -i, --in <input dir>
905                path to input directory
906        -o, --out <output dir>
907                path to output directory
908```
909
910```cpp
911bool recurse = false;
912string inpath, outpath;
913
914auto cli = (
915    option("-r", "--recursive").set(recurse)                 % "search in subdirectories",
916    (required("-i", "--in" ) & value("input dir", inpath))   % "path to input directory",
917    (required("-o", "--out") & value("output dir", outpath)) % "path to output directory"
918);
919```
920
921
922
923### Repeatable Parameters
924```man
925SYNOPSIS
926        simplify <file>... [-c] [-i <line>...]
927
928OPTIONS
929        <file>...               input files
930        -c, --compress          compress results
931        -i, --ignore <line>...  lines to be ignored
932```
933
934```cpp
935vector<string> files;
936vector<int> lines;
937bool zip = false;
938auto cli = (
939    values("file", files)                                % "input files",
940    option("-c", "--compress").set(zip)                  % "compress results",
941    (option("-i", "--ignore") & integers("line", lines)) % "lines to be ignored"
942);
943```
944
945The call ```values("v")``` is shorthand for ```value("v").repeatable(true)```.
946
947Note, that the  value parameter ```line``` is repeatable, but the flag ```--ignore``` is not. So
948something like
949```
950    simplify file1 file2 --ignore 1 2 --ignore 3 4 -c
951```
952is taken to be an error.
953However, it is possible if you make the group of ```--ignore``` and ```line``` itself repeatable:
954
955#### Repeatable Groups of Options with Repeatable Values
956```man
957SYNOPSIS
958        simplify <file>... [-c] [-i <line>...]...
959
960OPTIONS
961        <file>...               input files
962        -c, --compress          compress results
963        -i, --ignore <line>...  lines to be ignored
964```
965
966```cpp
967vector<string> files;
968vector<int> lines;
969bool zip = false;
970auto cli = (
971    values("file", files)                            % "input files",
972    option("-c", "--compress").set(zip)              % "compress results",
973    repeatable(  // <-----
974        option("-i", "--ignore") & integers("line", lines)
975    )                                                % "lines to be ignored"
976);
977```
978Now both the option ```--ignore``` *and* the value parameter ```value``` are repeatable. In all of the following examples ```lines``` will be set to ```{1,2,3,4}``` and ```c``` will be set to ```true```:
979```
980    simplify file1 file2 -c --ignore 1 2 3 4
981    simplify file1 file2 --ignore 1 2 3 4 -c
982    simplify file1 file2 --ignore 1 -c --ignore 2 3 4
983    simplify file1 file2 --ignore 1 2 --ignore 3 4 -c
984    simplify file1 file2 --ignore 1 --ignore 2 -c --ignore 3 --ignore 4
985    simplify file1 file2 -c --ignore1 --ignore2 --ignore3 --ignore4
986```
987
988
989
990### Actions
991Actions are executed if a parameter matched an argument string in the command line arguments list. Actions are defined using the following member functions or operators:
992
993- ```parameter::call(f)``` or ```parameter::operator () (f)```: call a callable entity ```f``` (function, lambda, custom function object) for each one of the matched argument strings. If ```f``` accepts exactly one parameter that is convertible from ```const char*```, the command line argument is passed to it. If the parameter list is empty, it is simply called without argument.
994
995- ```parameter::set(target, value)```: assign a fixed value to a target object; note that the assignment ```target = value;``` must be a valid statement
996
997- ```parameter::set(target)```:
998    - A ```bool``` target is set to true if the flag/value is present and **left unchanged otherwise**.
999    - A target object of fundamental type ```T``` (```int```, ```long```, ```float```, ```double```, ...) will be assigned the result of converting the argument string to type ```T```.
1000    - Targets of type ```std::vector<T>``` are appended with a value for each matched argument string. Note that ```T``` must either be (explicitly) convertible from ```const char*``` or a fundamental type.
1001
1002- ```operator <<``` or ```operator >>``` assign arg strings to lvalues or call callable entities. Which kind of action will be performed is automatically determined through overload resolution.
1003
1004
1005#### Predefined Functions
1006```cpp
1007int x = 0;                   // equivalent to:
1008option("-x")(set(x))         // option("-x").set(x)
1009option("-x")(set(x,2))       // option("-x").set(x,2)
1010option("-x")(increment(x))   // option("-x")([&]{++x;})
1011option("-x")(decrement(x))   // option("-x")([&]{--x;})
1012
1013bool b = false;              // equivalent to:
1014option("-b")(flip(b))        // option("-x")([&]{b = !b;})
1015```
1016
1017
1018#### Some Examples
1019```cpp
1020bool a = false, b = false;
1021int i = 1, n = 0, m = 0;
1022float x = 0.0f;
1023
1024auto cli = (                           //INFORMAL description
1025    option("-a").set(a),               //if(found("-a")) a = true;
1026    option("-b") >> b,                 //if(found("-b")) b = true;
1027    option("--toggle").call(flip(b)),  //if(found("--toggle")) flip(b);
1028
1029    value("n").set(n),                 //n = std::atoi(arg);
1030    option("-i") & value("#",i),       //if(found("-i arg")) i = std::atoi(arg);
1031    option("-1").set(m,1),             //if(found("-1")) m = 1;
1032    option("-2").set(m,2),             //if(found("-2")) m = 2;
1033
1034    //if(found("-z")) call_lambda_with_arg("-z");
1035    option("-z").call([](const char* s) { cout << s; }),
1036
1037    //using 'operator()' instead of 'call'
1038    //if(found("bob")) call_lambda_with_arg("bob");
1039    option("bob")([](const std::string& s) { cout << s; }),
1040
1041    //for_each_occurence("-x arg", call_lambda_with_arg(arg));
1042    repeatable( option("-x") & value("X")([&](const char* s) { x = std::atof(s); }) ),
1043
1044    option("--all") >> []()              { cout << "found --all\n"; }
1045                    >> [](const char* s) { cout << "found flag " << s << '\n'; };
1046);
1047```
1048
1049
1050
1051### Joinable Flags
1052```man
1053SYNOPSIS
1054        edit <file> [-rbs] ([:vim] [:st3] [:atom] [:emacs])
1055
1056OPTIONS
1057        -r      open read-only
1058        -b      use backup file
1059        -s      use swap file
1060
1061        :vim, :st3, :atom, :emacs
1062                editor(s) to use; multiple possible
1063```
1064
1065```cpp
1066std::string file;
1067bool readonly = false, usebackup = false, useswap = false;
1068enum class editor {vim, sublime3, atom, emacs};
1069std::vector<editor> editors;
1070auto add = [&](editor e){ return [&]{ editors.push_back(e); }; };
1071
1072auto cli = (
1073    value("file", file),
1074    joinable(
1075        option("-r").set(readonly)  % "open read-only",
1076        option("-b").set(usebackup) % "use backup file",
1077        option("-s").set(useswap)   % "use swap file"
1078    ),
1079    joinable(
1080        option(":vim")    >> add(editor::vim),
1081        option(":st3")    >> add(editor::sublime3),
1082        option(":atom")   >> add(editor::atom),
1083        option(":emacs")  >> add(editor::emacs)
1084    ) % "editor(s) to use; multiple possible"
1085);
1086```
1087- Flags can be joined regardless of their length (second group in the example).
1088- If the flags have a common prefix (```-``` or ```:``` in the example) it must be given at least
1089  once as leading prefix in the command line argument.
1090- Allowed args for the first group are:
1091  ```-r```, ```-b```, ```-s```, ```-rb```, ```-br```, ```-rs```, ```-sr```,
1092  ```-sb```, ```-bs```, ```-rbs```, ```-rsb```, ...
1093- Allowed args for the second group are:
1094  ```:vim```, ```:vim:atom```, ```:emacs:st3```, ```:vimatom```, ...
1095
1096#### More Examples
1097
1098| joinable flags           | valid args                                                                         |
1099| ------------------------ | ---------------------                                                              |
1100| ```a```, ```b```         | ```ab```, ```ba```, ```a```, ```b```                                               |
1101| ```-a```, ```-b```       | ```-ab```, ```-ba```, ```-a```, ```-b```, ```-a-b```, ```-b-a```                   |
1102| ```--a```, ```--b```     | ```--ab```, ```--ba```, ```--a```, ```--b```, ```--a--b```, ```--b--a```           |
1103| ```,a```, ```,b```       | ```,ab```, ```,ba```, ```,a```, ```,b```, ```,a,b```, ```,b,a```                   |
1104| ```Xab```, ```Xcd```     | ```Xabcd```, ```Xcdab```, ```XabXcd```, ```XcdXab```, ```Xab```, ```Xcd```         |
1105| ```x:ab```, ```x:cd```   | ```x:abcd```, ```x:cdab```, ```x:abx:cd```, ```x:cdx:ab```, ```x:ab```, ```x:cd``` |
1106
1107
1108
1109### Alternatives
1110```man
1111SYNOPSIS
1112        find <file>... -s <expr> [any|all]
1113
1114OPTIONS
1115        <file>...  input filenames
1116        -s <expr>  string to look for
1117        any        report as soon as any matches
1118        all        report only if all match
1119```
1120
1121```cpp
1122vector<string> files;
1123string expr;
1124bool ifany = false, ifall = false;
1125
1126auto cli = (
1127    values("file", files)                  % "input filenames",
1128    (required("-s") & value("expr", expr)) % "string to look for",
1129    option("any").set(ifany)               % "report as soon as any matches" |
1130    option("all").set(ifall)               % "report only if all match"
1131);
1132```
1133
1134If you like it more verbose you can use the function ```one_of``` instead of ```operator |```:
1135```cpp
1136auto cli = (
1137    values("file", files)                  % "input filenames",
1138    (required("-s") & value("expr", expr)) % "string to look for",
1139    one_of( option("any").set(ifany)       % "report as soon as any matches",
1140            option("all").set(ifall)       % "report only if all match" )
1141);
1142```
1143
1144
1145#### gcc-style switches
1146```man
1147SYNOPSIS
1148        format [-o <output file>] [-falign|-fnoalign)]
1149
1150OPTIONS
1151        -o, --out <file>
1152                output filename
1153
1154        -falign, -fnoalign
1155                control alignment
1156```
1157
1158```cpp
1159string outfile = "a.out";
1160bool align = false;
1161
1162auto cli = (
1163    (option("-o", "--out") & value("output file", outfile)) % "output filename",
1164    ( option("-falign"  ).set(align,true) |
1165      option("-fnoalign").set(align,false) )                % "control alignment"
1166);
1167```
1168
1169Note, that the documentation string is attached to the group of parameters for better readability.
1170
1171
1172#### non-redundant prefix specification
1173```cpp
1174//has the same meaning as the code above
1175string outfile = "a.out";
1176bool align = false;
1177
1178auto cli = (
1179    (option("-o", "--out") & value("output file", outfile)) % "output filename",
1180    with_prefix("-f", option("align"  ).set(align,true) |
1181                      option("noalign").set(align,false) )  % "control alignment"
1182);
1183```
1184
1185
1186#### merge alternatives with common prefixes in documentation
1187```man
1188Usage:   format [-o <output file>] [-f(align|noalign)]
1189```
1190```cpp
1191auto fmt = doc_formatting{}.merge_alternative_flags_with_common_prefix(true);
1192cout << usage_lines(cli, "format", fmt) << '\n';
1193```
1194
1195
1196
1197### Commands
1198**= positional, required flags**
1199```man
1200SYNOPSIS
1201        make_doc new <filename> [-e <enc>]
1202
1203OPTIONS
1204        -e, --encoding  'utf8' or 'cp1252', default is UTF-8
1205
1206```
1207
1208```cpp
1209std::string fname;
1210std::string enc = "utf8";
1211
1212auto cli = (
1213    command("new"),
1214    value("filename", fname),
1215    option("-e", "--encoding") & value("enc", enc).doc("'utf8' or 'cp1252', default is " + enc)
1216);
1217```
1218
1219
1220
1221### Nested Alternatives
1222```man
1223SYNOPSIS
1224        image-find help
1225        image-find build (new|add) <file>... [-v] [-b [<size=1024>]] [--init|--no-init]
1226        image-find query <infile> -o <outfile> [-f <format>]
1227
1228OPTIONS
1229        -v, --verbose
1230                print detailed report
1231
1232        -b, --buffer [<size=1024>]
1233                sets buffer size in KiByte
1234
1235        --init, --no-init
1236                do or don't initialize
1237
1238        -f, --out-format <format>
1239                determine output format
1240```
1241
1242Value handling actions are omitted; see examples/nested_alternatives.cpp for a fully functional demo.
1243```cpp
1244auto cli = (
1245    command("help")
1246    | ( command("build"),
1247        ( command("new") | command("add")),
1248        values("file"),
1249        option("-v", "--verbose")                           % "print detailed report",
1250        (option("-b", "--buffer") & opt_value("size=1024")) % "sets buffer size in KiByte",
1251        ( option("--init") | option("--no-init") )          % "do or don't initialize"
1252    )
1253    | ( command("query"),
1254        value("infile"),
1255        required("-o", "--out") & value("outfile"),
1256        (option("-f", "--out-format") & value("format"))  % "determine output format"
1257    )
1258);
1259```
1260
1261Note:
1262```
1263doc_formatting::split_alternatives(bool)             //default: true
1264doc_formatting::alternatives_min_split_size(int)     //default: 3
1265```
1266control if the usage is split up into several lines if any group inside an alternative exceeds a given minimum size.
1267
1268
1269
1270### Complex Nestings
1271The combination of blocking parameters, alternatives and grouping makes it possible to define interfaces with decision trees/DAGs of arbitrary complexity.
1272```man
1273SYNOPSIS
1274    complex_nesting [-v] [-i] (copy|move) [--all] [--replace] [-f] <files>... [-r] [-h]
1275    complex_nesting [-v] [-i] compare (date|content) [-b] [-q] <files>... [-r] [-h]
1276    complex_nesting [-v] [-i] merge (diff|patch) -o <outdir> [--show-conflicts] <files>... [-r] [-h]
1277    complex_nesting [-v] [-i] merge content [--git-style] [-m <marker>] -o <outdir> [--show-conflicts] <files>... [-r] [-h]
1278    complex_nesting [-v] [-i] list <files>... [-r] [-h]
1279
1280OPTIONS
1281    user interface options:
1282        -v, --verbose      show detailed output
1283        -i, --interactive  use interactive mode
1284
1285    copy mode:
1286        --all              copy all
1287        --replace          replace existing files
1288        -f, --force        don't ask for confirmation
1289
1290    compare mode:
1291        -b, --binary       compare files byte by byte
1292        -q, --quick        use heuristics for faster comparison
1293
1294    merge mode:
1295        diff               merge using diff
1296        patch              merge using patch
1297        content            merge based on content
1298
1299        content based merge options:
1300            --git-style    emulate git's merge behavior
1301            <marker>       merge marker symbol
1302
1303        <outdir>           target directory for merge result
1304        --show-conflicts   show merge conflicts during run
1305
1306    mode-independent options:
1307        <files>...         input files
1308        -r, --recursive    descend into subdirectories
1309        -h, --help         show help
1310```
1311
1312Actions and target variables are omitted in the code.
1313```cpp
1314auto copyMode = "copy mode:" % (
1315    command("copy") | command("move"),
1316    option("--all")         % "copy all",
1317    option("--replace")     % "replace existing files",
1318    option("-f", "--force") % "don't ask for confirmation"
1319);
1320
1321auto compareMode = "compare mode:" % (
1322    command("compare"),
1323    (command("date") | command("content")),
1324    option("-b", "--binary") % "compare files byte by byte",
1325    option("-q", "--quick")  % "use heuristics for faster comparison"
1326);
1327
1328auto mergeAlgo = (
1329    command("diff")  % "merge using diff"  |
1330    command("patch") % "merge using patch" |
1331    (   command("content") % "merge based on content",
1332        "content based merge options:" % (
1333          option("--git-style") % "emulate git's merge behavior",
1334          option("-m", "--marker") & value("marker") % "merge marker symbol"
1335        )
1336    )
1337);
1338
1339auto mergeMode = "merge mode:" % (
1340    command("merge"),
1341    mergeAlgo,
1342    required("-o") & value("outdir") % "target directory for merge result",
1343    option("--show-conflicts")       % "show merge conflicts during run"
1344);
1345
1346auto firstOpt = "user interface options:" % (
1347    option("-v", "--verbose")     % "show detailed output",
1348    option("-i", "--interactive") % "use interactive mode"
1349);
1350auto lastOpt = "mode-independent options:" % (
1351    values("files")             % "input files",
1352    option("-r", "--recursive") % "descend into subdirectories",
1353    option("-h", "--help")      % "show help"
1354);
1355
1356auto cli = (
1357    firstOpt,
1358    copyMode | compareMode | mergeMode | command("list"),
1359    lastOpt
1360);
1361
1362if(parse(argc, argv, cli)) {
1363     // program logic...
1364} else {
1365    auto fmt = doc_formatting{}.doc_column(31);
1366    cout << make_man_page(cli, argv[0], fmt) << '\n';
1367}
1368```
1369
1370You could of course write down everything as one big expression (docstrings are omitted)...:
1371```cpp
1372auto cli = (
1373    option("-v", "--verbose"),
1374    option("-i", "--interactive"),
1375    (
1376        (   (command("copy") | command("move")),
1377            option("--all"), option("--replace"),
1378            option("-f", "--force")
1379        )
1380        | ( command("compare"),
1381            (command("date") | command("content")),
1382            option("-b", "--binary"), option("-q", "--quick")
1383        )
1384        | ( command("merge"),
1385            (
1386                ( command("content"),
1387                  option("--git-style"),
1388                  option("-m", "--marker") & value("marker")
1389                )
1390                | command("diff")
1391                | command("patch")
1392            ),
1393            required("-o") & value("outdir"),
1394            option("--show-conflicts")
1395        )
1396        | command("list")
1397    ),
1398    values("files"),
1399    option("-r", "--recursive"),
1400    option("-h", "--help")
1401);
1402 ```
1403...but it is probably more readable and maintainable if you break up the CLI definition into logical parts.
1404
1405Note:
1406```
1407doc_formatting::split_alternatives(bool)             //default: true
1408doc_formatting::alternatives_min_split_size(int)     //default: 3
1409```
1410control whether the usage is split up into several lines if any group inside an alternative  exceeds a given minimum size.
1411
1412
1413
1414### An Example From [docopt]
1415```man
1416Naval Fate.
1417
1418Usage:
1419  naval_fate ship new <name>...
1420  naval_fate ship <name> move <x> <y> [--speed= <kn>]
1421  naval_fate ship shoot <x> <y>
1422  naval_fate mine (set|remove) <x> <y> [--moored|--drifting]
1423  naval_fate -h | --help
1424  naval_fate --version
1425
1426Options:
1427  --speed= <kn>  Speed in knots [default: 10].
1428  --moored       Moored (anchored) mine.
1429  --drifting     Drifting mine.
1430  -h, --help     Show this screen.
1431  --version      Show version.
1432```
1433
1434This code defines the command line interface, handles the parsing result and
1435generates the above man page snippet.
1436```cpp
1437int x = 0, y = 0;
1438float speed = 0.0f;
1439bool drift = true;
1440vector<string> names;
1441enum class mode { none, help, shipnew, shipmove, shipshoot, mineset, minerem};
1442mode selected = mode::none;
1443
1444//define command line interface
1445auto coordinates = ( value("x", x), value("y", y) );
1446
1447auto shipnew  = ( command("new").set(selected,mode::shipnew),
1448                  values("name", names) );
1449
1450auto shipmove = (
1451    value("name", names),
1452    command("move").set(selected,mode::shipmove), coordinates,
1453    option("--speed=") & value("kn",speed) % "Speed in knots [default: 10]");
1454
1455auto shipshoot = ( command("shoot").set(selected,mode::shipshoot),
1456                   coordinates );
1457
1458auto mines = (
1459    command("mine"),
1460    (command("set"   ).set(selected,mode::mineset) |
1461     command("remove").set(selected,mode::minerem) ),
1462    coordinates,
1463    (option("--moored"  ).set(drift,false) % "Moored (anchored) mine." |
1464     option("--drifting").set(drift,true)  % "Drifting mine."          )
1465);
1466
1467auto navalcli = (
1468    ( command("ship"), ( shipnew | shipmove | shipshoot ) )
1469    | mines,
1470    | command("-h", "--help").set(selected,mode::help)     % "Show this screen."
1471    | command("--version")([]{ cout << "version 1.0\n"; }) % "Show version."
1472);
1473
1474parse(argc, argv, navalcli);
1475
1476//handle results
1477switch(m) {
1478    case mode::none:
1479        break;
1480    case mode::help: {
1481        auto fmt = doc_formatting{}
1482            .first_column(2).doc_column(16)
1483            .max_flags_per_param_in_usage(4);
1484
1485        cout << "Naval Fate.\n\nUsage:\n"
1486             << usage_lines(navalcli, "naval_fate", fmt)
1487             << "\n\nOptions:\n"
1488             << documentation(navalcli, fmt) << '\n';
1489        }
1490        break;
1491    }
1492    //...
1493}
1494```
1495
1496
1497
1498
1499### Value Filters
1500If a parameter doesn't have flags, i.e. it is a value-parameter, a filter function will be used to test if it matches an argument string. The default filter is ```clipp::match::nonempty``` which will match any non-empty argument string.
1501If you want more control over what is matched, you can use some other predefined filters or you can write your own ones (see [here](#custom-value-filters)).
1502
1503```man
1504Usage:   exec [-n <times>] [-l <line>...] [-b <ratio>] [-f <term>]
1505```
1506
1507```cpp
1508int n = 1;
1509std::vector<int> lines;
1510double r = 1.0;
1511string term, name;
1512auto cli = (
1513    option("-n", "--repeat") & integer("times", n),
1514    option("-l", "--line")   & integers("#", lines),
1515    option("-r", "--ratio)   & number("ratio", r),
1516    option("-f", "--find")   & word("term", term)
1517);
1518```
1519
1520#### Predefined Filtering Value-Parameters
1521```cpp
1522auto cli = (
1523    value("x"),    //non-empty string
1524    word("x"),     //alphanumeric string
1525    number("x"),   //string representing integer or floating point number
1526    integer("x")   //string representing integral number
1527);
1528```
1529Note that there are additional functions for
1530 - optional parameters: ```opt_value```, ```opt_word```, ...
1531 - repeatable parameters: ```values```, ```words```, ...
1532 - repeatable, optional parameters: ```opt_values```, ```opt_words```, ...
1533
1534
1535#### Using Filters Explicitly
1536Two kinds of filters are supported right now that can be passed as first argument of ```value```, ```values```, ```opt_value``` or ```opt_values``` as well as argument of the constructor ```parameter::parameter(Filter&&)```
1537 - Predicates ```(const string&) -> bool```
1538   which should return true if and only if an argument is an exact match.
1539
1540 - Substring matchers ```(const string&) -> subrange```
1541   which in case of a match also indicate the position and length of the matched substring within a command line argument.
1542
1543```cpp
1544string s;
1545value( match::length{1,5}, "str", s);
1546
1547//or using the parameter class directly
1548auto p = parameter{ match::length{1,5} }
1549         .positional(true).required(true)
1550         .label("str").set(s);
1551```
1552There are a couple of predefined filters in ```namespace clipp::match```, but you can of course write your own ones (see [here](#custom-value-filters)).
1553
1554Here is another example that makes sure we don't catch any value starting with "-" as a filename:
1555```cpp
1556auto cli = (
1557    option("-a")
1558    option("-f") & value(match::prefix_not("-"), "filename"),
1559    option("-b")
1560);
1561```
1562
1563```cpp
1564namespace clipp {
1565namespace match {
1566
1567  //simple predicates
1568  bool none (const string&);
1569  bool any (const string&);
1570  bool nonempty (const string&);
1571  bool alphabetic (const string&);
1572  bool alphanumeric (const string&);
1573
1574  //filters with settings and substring matching
1575  class numbers {
1576      explicit numbers(char decimalPoint = '.', char digitSeparator = ',', char exponentSeparator = 'e');
1577      subrange operator () (const string& arg);
1578  };
1579
1580  class integers {
1581      explicit integers(char digitSeparator = ',');
1582      subrange operator () (const string& arg);
1583  };
1584
1585  class substring {
1586      explicit substring(const string& str);
1587      subrange operator () (const string& arg);
1588  };
1589
1590  class prefix {
1591      explicit prefix(const string& prefix);
1592      subrange operator () (const string& arg);
1593  };
1594
1595  class prefix_not {
1596      explicit prefix_not(const string& prefix);
1597      subrange operator () (const string& arg);
1598  };
1599
1600  class length {
1601      explicit length(size_t exact);
1602      explicit length(size_t min, size_t max);
1603      subrange operator () (const string& arg);
1604  };
1605
1606} }
1607```
1608
1609
1610
1611### Greedy Parameters
1612
1613By default, the parser tries to identify a command line argument (in that order) as
1614 - a single flag
1615 - a concatenation of multiple, _joinable_ flags (in any order)
1616 - a concatenation of a _joinable_ flag sequence in the order defined in the CLI code
1617 - a single value parameter
1618 - a concatenation of a _joinable_ flag/value sequence in the order defined in the CLI code
1619 - a concatenation of _joinable_ flags & values in no particular order
1620
1621If no match was found, the parser tries the same list again without any restrictions imposed by blocking (positional) parameters, conflicting alternatives, etc. If this leads to any match, an error will be reported. This way, _potential_, but illegal matches can be found and, e.g., conflicting alternatives can be reported.
1622
1623Consider this CLI:
1624```cpp
1625auto cli = (  option("-a"),  option("-f") & value("filename"),  option("-b")  );
1626```
1627If we give ```-f -b``` or ```-b -f -a``` as command line arguments, an error will be reported, since the value after ```-f``` is not optional.
1628
1629This behavior is fine for most use cases.
1630But what if we want our program to take any string as a filename, because our filenames might also collide with flag names? We can make the ```filename``` value parameter greedy, so that the next string after ```-f``` will always be matched with highest priority as soon as ```-f``` was given:
1631```cpp
1632auto cli = (  option("-a"),  option("-f") & greedy(value("filename")),  option("-b")  );
1633```
1634or using ```operator !```:
1635```cpp
1636auto cli = (  option("-a"),  option("-f") & !value("filename"),   option("-b")  );
1637```
1638
1639Now, every string coming after an ```-f``` will be used as filename.
1640
1641If we don't want just *any* kind of match accepted, but still retain a higher priority for a value parameter, we could use a [value filter](#value-filters):
1642```cpp
1643auto cli = (
1644    (   command("A"),
1645        option("-f") & !value(match::prefix_not("-"), "filename"),
1646        option("-b")
1647    ) |
1648    (   command("B"),
1649        option("-x")
1650    )
1651);
1652```
1653This way, the command line arguments ```A -f B``` will set the filename to "B" and produce no conflict error between the alternative commands ```A``` and ```B``` but ```A -f -b``` will still give an error.
1654
1655Note, that there is an inherent decision problem: either we want the ```filename``` value to match no matter what, or we won't get proper error handling if someone forgets to specify a filename and gives ```A -f -b``` Also, there might be interfaces where we really want to catch something like ```A -f B``` as a command conflict.
1656
1657
1658
1659
1660### Generalized Joinable Parameters
1661
1662Not only flags, but arbitrary combinations of flags and values can be made joinable. This feature is especially powerful if combined with repeatable groups.
1663Important: in order for an argument to be matched by such expressions, no parameter requirements must be violated during the matching. Also, no partial argument matches are allowed.
1664
1665#### Example 1: Counting Letters
1666```man
1667Usage:   counter [a|b]...
1668```
1669
1670```cpp
1671int as = 0, bs = 0;
1672
1673auto cli = joinable( repeatable(
1674        option("a").call([&]{++as;}) |
1675        option("b").call([&]{++bs;})
1676    ) );
1677
1678if(parse(argc, argv, cli))
1679    cout << "as: " << as << "\nbs: " << bs << '\n';
1680else
1681    cout << "Usage:\n" << usage_lines(cli, argv[0]) << '\n';
1682```
1683
1684Valid input includes:
1685```
1686$ ./counter a
1687$ ./counter b
1688$ ./counter ab
1689$ ./counter abba
1690$ ./counter a b baba
1691$ ./counter a babba abab abbbbba b a ba a
1692    ...
1693```
1694
1695#### Example 2: Listing Numbers
1696```man
1697Usage:   numbers ([,] [<number>])...
1698```
1699
1700```cpp
1701std::vector<double> nums;
1702
1703auto cli = joinable(repeatable( option(",") , opt_number("number", nums) ));
1704
1705if(parse(argc, argv, cli)) {
1706    cout << "numbers:\n";
1707    for(auto n : nums) cout << n << '\n';
1708} else {
1709    cout << "Usage:\n" << usage_lines(cli, argv[0]) << '\n';
1710}
1711```
1712
1713Valid input includes:
1714```
1715$ ./numbers 1
1716$ ./numbers 1 2 3
1717$ ./numbers 1 , 2
1718$ ./numbers 1 , 2 , 3
1719$ ./numbers 1, 2, 3
1720$ ./numbers 1 ,2 ,3
1721$ ./numbers 1,2
1722$ ./numbers 1,2,3
1723$ ./numbers 1.1 , 2
1724$ ./numbers 1,2.3,4.5
1725$ ./numbers 1,2,3 4.2 5,6 2 7.1,8.23,9
1726```
1727
1728**Warning:** Be careful with joinable and repeatable parameters! The resulting command line interface might be a lot less intuitive to use than you think. It can also be hard to get the "grammar" of complex parsing expressions right.
1729The following definition for example, contains a subtle pitfall:
1730```cpp
1731auto cli = joinable(repeatable( option(",") , number("number", nums) ));
1732//                                            ^^^ non-optional
1733```
1734This will not match arguments like ```"1,"```. This is, because, if the repeat group is 'hit' by any of its child parameters, all non-optional parameters must also match within the current 'repeat cycle'. So, if the parser hits the ```","``` it expects to find a number arg as well, because it is blocking (positional) and required. Only after seeing this number can it enter the next repeat cycle. Thus, the argument will not be matched, since joined matches are only valid if no error occured. Making the number optional solves the problem.
1735
1736
1737### Custom Value Filters
1738Two kinds of filters are supported right now that can be passed as first argument of ```value```, ```values```, ```opt_value``` or ```opt_values``` as well as argument of the constructor ```parameter::parameter(Filter&&)```:
1739
1740 - Predicates ```(const string&) -> bool```
1741   which should return true if and only if an argument is an exact match.
1742
1743 - Substring matchers ```(const string&) -> subrange```
1744   which in case of a match also indicate the position and length of the matched substring within a command line argument.
1745
1746
1747#### Simple Predicate Example
1748 ```man
1749Usage:   annotate auto | (label <character>)
1750```
1751
1752```cpp
1753auto is_char = [](const string& arg) { return arg.size() == 1 && std::isalpha(arg[0]); };
1754
1755char lbl = ' ';
1756auto cli = (  command("auto") | ( command("label"), value(is_char, "character", lbl) )  );
1757```
1758
1759
1760#### Substring Matcher Example
1761
1762Let's write a program that takes strings and lists all tag names (```<tag>```) contained in them:
1763```man
1764Usage:   tagnames <string>...
1765```
1766
1767```cpp
1768//custom filter
1769auto tag_name = [] (const string& arg) {
1770    if(arg.size() < 3) return subrange{}; //too short
1771    auto i = arg.find("<");
1772    if(i == string::npos) return subrange{}; //no tag start found
1773    auto j = arg.find(">", i+1);
1774    if(j == string::npos) return subrange{}; //didn't find end of tag
1775    return subrange{i,j-i+1}; //partial match {start, length}
1776};
1777
1778std::set<string> tags;
1779auto cli = joinable(
1780    values(tag_name, "string",
1781           [&](const string& arg){ if(arg[1] != '/') tags.insert(arg);})
1782);
1783
1784if(parse(argc, argv, cli)) {
1785    cout << "tag names:\n";
1786    for(const auto& t : tags) cout << t << '\n';
1787} else {
1788    cout << "Usage:\n" << usage_lines(cli, "tagnames") << '\n';
1789}
1790```
1791
1792```
1793$ ./tagnames "<cee><d><e></e></d></cee>" "<a><bo></bo></a>"
1794tag names:
1795<a>
1796<bo>
1797<cee>
1798<d>
1799<e>
1800```
1801
1802
1803
1804### Sanity Checks
1805
1806Check, if no flag occurs as prefix of any other flag (identical flags will be ignored):
1807```cpp
1808auto cli = ( /* command line interface definition */);
1809
1810assert( cli.flags_are_prefix_free() );
1811```
1812
1813Check common prefix of all flags, like for example "-" (or "/" on Windows):
1814```cpp
1815auto cli = ( /* command line interface definition */);
1816
1817assert( cli.common_flag_prefix() == "-" );
1818```
1819
1820
1821
1822### Basic Error Handling
1823
1824Each parameter can have error handler functions/lambdas/function objects for different fail cases attached to it:
1825 - ```if_repeated``` is raised each time an argument is mapped to a parameter regardless of that parameter's repeatability setting
1826 - ```if_missing``` is raised if a required parameter has no argument associated with it
1827 - ```if_conflicted``` is raised if two or more arguments are mapped to more than one parameter of a group of alternatives
1828 - ```if_blocked``` is raised if an argument can only be mapped to a parameter that was not reachable at the time (e.g. because a positional value was expected before that parameter or the parameter was in a non-active alternative branch)
1829
1830#### Example:
1831```man
1832Usage:   send <file> -t <target>... [--http|--ftp]
1833```
1834
1835```cpp
1836string filename;
1837vector<string> targets;
1838vector<string> wrong;
1839bool http = true;
1840
1841auto istarget = match::prefix_not("-");
1842
1843auto cli = (
1844    value("file", filename)
1845        .if_missing([]{ cout << "You need to provide a source filename!\n"; } )
1846        .if_repeated([](int idx){ cout << "Only one source file allowed! (index " << idx << ")\n"; } )
1847    ,
1848    required("-t") & values(istarget, "target", targets)
1849        .if_missing([]{ cout << "You need to provide at least one target filename!\n"; } )
1850        .if_blocked([]{ cout << "Target names must not be given before the source file name!\n"; })
1851    ,
1852    option("--http").set(http,true) |
1853    option("--ftp").set(http,false) % "protocol, default is http"
1854        .if_conflicted([]{ cout << "You can only use one protocol at a time!\n"; } )
1855    ,
1856    any_other(wrong)
1857);
1858
1859if(parse(argc, argv, cli) && wrong.empty()) {
1860    cout << "OK\n";
1861    /* ... */
1862} else {
1863    for(const auto& arg : wrong) cout << "'" << arg << "' is not a valid argument\n";
1864    cout << "Usage:" << usage_lines(cli,argv[0]) << '\n';
1865}
1866```
1867An error handler can either have an empty parameter list or take an ```int``` which is set to the command line argument index where the error occured first.
1868
1869The catch-all parameter made by ```any_other``` is used to catch command line arguments that are not supported.
1870
1871The value parameter ```target``` will only match command line arguments that do not begin with ```"-"```, so that wrongly spelled options cannot be parsed as ```target``` value.
1872
1873
1874### Parsing
1875```cpp
1876auto cli = (
1877    command("make"),
1878    value("file")           % "name of file to make",
1879    option("-f", "--force") % "overwrite existing file"
1880);
1881
1882//excludes argv[0]
1883parse(argc, argv, cli);
1884
1885//if you want to include argv[0]
1886parse(argv, argv+argc, cli);
1887
1888parse({"make", "out.txt"}, cli);
1889
1890auto args = std::vector<std::string> {"make", "out.txt", "-f"};
1891parse(args, cli);
1892```
1893
1894The parse functions return an object of ```parsing_result``` which can be used for detailed analysis and will (explicitly) convert to false if any error occured during parsing.
1895```cpp
1896auto result = parse(argc, argv, cli);
1897
1898auto doc_label = [](const parameter& p) {
1899    if(!p.flags().empty()) return p.flags().front();
1900    if(!p.label().empty()) return p.label();
1901    return doc_string{"<?>"};
1902};
1903
1904cout << "args -> parameter mapping:\n";
1905for(const auto& m : result) {
1906    os << "#" << m.index() << " " << m.arg() << " -> ";
1907    auto p = m.param();
1908    if(p) {
1909        os << doc_label(*p) << " \t";
1910        if(m.repeat() > 0) {
1911            os << (m.bad_repeat() ? "[bad repeat " : "[repeat ")
1912               <<  m.repeat() << "]";
1913        }
1914        if(m.blocked())  os << " [blocked]";
1915        if(m.conflict()) os << " [conflict]";
1916        os << '\n';
1917    }
1918    else {
1919        os << " [unmapped]\n";
1920    }
1921}
1922
1923cout << "missing parameters:\n";
1924for(const auto& m : result.missing()) {
1925    auto p = m.param();
1926    if(p) {
1927        os << doc_label(*p) << " \t";
1928        os << " [missing after " << m.after_index() << "]\n";
1929    }
1930}
1931
1932```
1933
1934
1935
1936### Documentation Generation
1937Generate usage lines and documentation from parameters:
1938```cpp
1939auto cli = ( /* command line interface definition */ );
1940
1941//used default formatting
1942cout << "Usage:\n" << usage_lines(cli, "progname")
1943     << "\nOptions:\n" << documentation(cli) << '\n';
1944```
1945... or generate an entire man page in one go:
1946```cpp
1947auto cli = ( /* command line interface definition */ );
1948
1949cout << make_man_page(cli, "progname")
1950        .prepend_section("DESCRIPTION", "    The best thing since sliced bread.")
1951        .append_section("LICENSE", "    GPL3");
1952```
1953
1954#### Example
1955```man
1956DESCRIPTION
1957    Builds a database of words from text files.
1958
1959SYNOPSIS
1960    worddb help
1961    worddb build (new|add) <file>
1962    worddb query -i <infile> [-p]
1963    worddb info space
1964    worddb info statistics (words|chars)
1965    worddb remove (any|all) <regex>
1966    worddb modify [-c] [-u] [-m <size>]
1967
1968OPTIONS
1969    build commands
1970        new                  make new database
1971        add                  append to existing database
1972
1973    query settings
1974        <infile>             input file
1975        -p, --pretty-print   human friendly output
1976
1977    database info modes
1978        space                detailed memory occupation analysis
1979
1980        statistics analysis
1981            words            word frequency table
1982            chars            character frequency table
1983
1984    remove mode
1985        <regex>              regular expression filter
1986
1987    modification operations
1988        -c, --compress       compress database in-memory
1989        -u, --unique         keep only unique entries
1990        -m, --memlimit       max. size in RAM
1991
1992LICENSE
1993    GPL3
1994 ```
1995
1996The full code:
1997```cpp
1998auto cli = (
1999    command("help") |
2000    ( command("build"),
2001        "build commands" %
2002        (   command("new")  % "make new database"
2003          | command("add")  % "append to existing database"
2004        ),
2005        value("file")
2006    ) |
2007    ( command("query"),
2008        "query settings" %
2009        (   required("-i", "--input") & value("infile") % "input file",
2010            option("-p", "--pretty-print") % "human friendly output")
2011    ) |
2012    ( command("info"),
2013        "database info modes" % (
2014            command("space") % "detailed memory occupation analysis" |
2015            (
2016                command("statistics"),
2017                "statistics analysis" % (
2018                    command("words") % "word frequency table" |
2019                    command("chars") % "character frequency table"
2020                )
2021            )
2022        )
2023    ) |
2024    "remove mode" % (
2025        command("remove"),
2026        "modify" % ( command("any") | command("all") ),
2027        value("regex") % "regular expression filter"
2028    ) |
2029    ( command("modify"),
2030        "modification operations" % (
2031            option("-c", "--compress") % "compress database in-memory",
2032            option("-u", "--unique")   % "keep only unique entries",
2033            option("-m", "--memlimit") % "max. size in RAM" & value("size")
2034        )
2035    )
2036);
2037
2038auto fmt = doc_formatting{} .first_column(4) .doc_column(28) .last_column(80);
2039
2040cout << make_man_page(cli, "worddb", fmt)
2041    .prepend_section("DESCRIPTION", "    Builds a database of words from text files.")
2042    .append_section("LICENSE", "    GPL3") << '\n';
2043```
2044
2045
2046#### Formatting Options
2047```cpp
2048//all formatting options (with their default values)
2049auto fmt = doc_formatting{}
2050    .first_column(8)                           //left border column for text body
2051    .doc_column(20)                            //column where parameter docstring starts
2052    .last_column(100)                          //right border column for text body
2053    .indent_size(4)                            //indent of documentation lines for children of a documented group
2054    .line_spacing(0)                           //number of empty lines after single documentation lines
2055    .paragraph_spacing(1)                      //number of empty lines before and after paragraphs
2056    .flag_separator(", ")                      //between flags of the same parameter
2057    .param_separator(" ")                      //between parameters
2058    .group_separator(" ")                      //between groups (in usage)
2059    .alternative_param_separator("|")          //between alternative flags
2060    .alternative_group_separator(" | ")        //between alternative groups
2061    .surround_group("(", ")")                  //surround groups with these
2062    .surround_alternatives("(", ")")           //surround group of alternatives with these
2063    .surround_alternative_flags("", "")        //surround alternative flags with these
2064    .surround_joinable("(", ")")               //surround group of joinable flags with these
2065    .surround_optional("[", "]")               //surround optional parameters with these
2066    .surround_repeat("", "...")                //surround repeatable parameters with these
2067    .surround_value("<", ">")                  //surround values with these
2068    .empty_label("")                           //used if parameter has no flags and no label
2069    .max_flags_per_param_in_usage(1)           //max. # of flags per parameter in usage
2070    .max_flags_per_param_in_doc(32)            //max. # of flags per parameter in detailed documentation
2071    .split_alternatives(true)                  //split usage into several lines for large alternatives
2072    .alternatives_min_split_size(3)            //min. # of parameters for separate usage line
2073    .merge_alternative_flags_with_common_prefix(false)  //-ab(cdxy|xy) instead of -abcdxy|-abxy
2074    .merge_joinable_flags_with_common_prefix(true)     //-abc instead of -a -b -c
2075    .ignore_newline_chars(false)               //ignore '\n' in docstrings
2076    ;
2077
2078cout << "Usage:\n" << usage_lines(cli, "progname", fmt)
2079     << "\nOptions:\n" << documentation(cli, fmt) << '\n';
2080
2081//or generate entire man page in one go
2082cout << make_man_page(cli, "progname", fmt)
2083        .prepend_section("DESCRIPTION", "This program lets you format text.")
2084        .append_section("LICENSE", "GPLv3");
2085```
2086
2087
2088
2089### Documentation Filtering
2090
2091The documentation generator class ```documentation``` can also take an additional third constructor argument that allows to filter parameters according to their properties.
2092
2093```cpp
2094int main(int argc, char* argv[]) {
2095    auto cli = (
2096        value("input file"),
2097        option("-r", "--recursive").set(rec).doc("convert files recursively"),
2098        option("-o") & value("output format", fmt),
2099        option("-utf16").set(utf16).doc("use UTF-16 encoding")
2100    );
2101
2102    auto fmt = doc_formatting{}.doc_column(28);
2103
2104    auto filter = param_filter{}.prefix("--");
2105
2106    cout << "Usage:\n" << usage_lines(cli, argv[0]) << "\n\n"
2107         << "Parameters:\n" << documentation(cli, fmt, filter) << '\n';}
2108```
2109
2110Which results in:
2111```man
2112Usage:
2113        convert <input file> [-r] [-o <output format>] [-utf16]
2114
2115Parameters:
2116        -r, --recursive    convert files recursively
2117```
2118
2119#### Parameter Filters
2120
2121Any function/lambda that maps a parameter to a bool can be used as filter
2122predicate. CLIPP also comes with a default parameter filter class:
2123```cpp
2124//all param_filter options (with their default values)
2125auto filter = param_filter{}
2126    .prefix("")               //only parameters with given prefix
2127    .required(tri::either)    //required parameters
2128    .blocking(tri::either)    //blocking/positional parameters
2129    .repeatable(tri::either)  //repeatable parameters
2130    .has_doc(tri::yes)        //parameters with/without docstrings
2131    ;
2132```
2133which uses a dedicated tristate type:
2134```cpp
2135namespace clipp {
2136   enum class tri { no, yes, either };
2137}
2138```
2139
2140
2141## Motivation
2142Well, I didn't find a library that makes building simple command line interfaces simple, yet can also be used to build complex CLIs. I really don't want to write 20 lines of boilerplate just to have 3 simple command line options. I also don't want to drag along monstrosities like boost or Qt for that. Over time, *clipp* evolved into a domain specific language (in pure C++) that I hope can at least somewhat approach the readability of [docopt] but can leverage the benefits (toolability, etc.) of C++'s type system.
2143
2144
2145#### Other libraries (Boost, POCO, Qt, adishavit/Argh, Taywee/args ... or 'getopt')
2146 - often involve a lot of boilerplate (also for very simple use cases)
2147 - Some libs might be okay in terms of usability, but don't let you build complex interfaces
2148   with nested alternatives, mixed commands & options, positional values, more than 2 flags per option, etc.
2149 - I really like ad-hoc parsers like [Argh](https://github.com/adishavit/argh) for their simplicity, but they don't generate usage / man pages and don't allow complex interfaces with error checking.
2150 - Most libs make it really hard to figure out the resulting command line interface by looking at the code (OK, you be the judge if I did a better job at this...).
2151 - Some libs come with a ton of dependencies (Qt, Boost). I want a single header file!
2152 - Some libs require the separation of code related to one command/option. I find this harder to maintain than having everything related to one option in one place.
2153 - Sometimes flag strings of commands/options have to be repeated several times over.
2154 - Many libs come with restrictions regarding flag names, formatting, joinability, etc.
2155
2156
2157#### What about [docopt]?
2158I like the basic idea, but I don't like redundancy in code, especially if it involves repeating string literals. Docopt generates a command line argument parser from a "man page docstring". After parsing, you have to query a dictionary to get values or check for option presence. That means you either have to mention the same flag names twice (in the docstring *and* in the query) or you have to use string variables which makes the docstring hard to read and kind of defeats the purpose of docopt. Furthermore, the code tends to be littered with string-to-whatever conversions.
2159
2160I also wanted the ability to keep *everything* related to one option/command/value together in the code which I found very useful for programs with lots of command line options. Docopt doesn't let you do that since the interface definition and the code performing any actions is always separated (unless you give up on the "beautiful doc page" idea at the heart of docopt and build your input string to the parser generator piece-by-piece).
2161
2162
2163
2164
2165## Design Goals
2166 - minimize boilerplate
2167 - simple code for simple use cases
2168 - good code readability (as far as C++ allows for it)
2169 - avoid ambiguities
2170 - eliminate repetitions
2171 - ability to keep code related to one option/command/value together
2172 - support many different command line interface conventions
2173 - support different coding styles, conventions & tastes
2174 - value semantics wherever possible
2175 - do not break clipp's general interface and conventions in the future
2176
2177
2178
2179
2180## Requirements
2181  - requires a mostly C++11 conforming compiler
2182
2183### Compilers, clipp compiles with
2184  - g++ 5.3.0, g++ 5.4.1, g++ 6, g++ 7
2185  - clang++ 3.8, clang++ 3.9, clang++ 4.0, clang++ 5.0
2186  - MSVC 14.11.25503 (compiler 19.11.25547)
2187
2188
2189
2190
2191## Feedback
2192I would be delighted to hear from anyone who uses *clipp* in their project(s). If you find bugs or design flaws or want to suggest improvements please open an issue or submit a pull request.
2193
2194
2195
2196
2197## Development
2198*clipp* is still very young, so I probably won't add new features any time soon and rather:
2199 - fix bugs
2200 - improve test cases and coverage
2201 - add more code documentation
2202 - clean up the code / make it more understandable
2203 - add the ability to use other string classes
2204
2205
2206[docopt]: http://docopt.org
2207
2208