63 class format_help :
public format_base
70 format_help() =
default;
71 format_help(format_help
const & pf) =
default;
72 format_help & operator=(format_help
const & pf) =
default;
73 format_help(format_help &&) =
default;
74 format_help & operator=(format_help &&) =
default;
80 format_help(
bool advanced) :
81 show_advanced_options(advanced)
85 ~format_help() =
default;
100 template <
typename option_type,
typename val
idator_type>
101 void add_option(option_type & value,
103 std::string
const & long_id,
104 std::string
const & desc,
106 validator_type && validator)
108 parser_set_up_calls.push_back([=, &value]()
111 print_list_item(prep_id_for_help(short_id, long_id) +
" " + option_type_and_list_info(value),
112 (desc +
" " + validator.get_help_page_message()));
123 void add_flag(
bool & ,
125 std::string
const & long_id,
126 std::string
const & desc,
129 parser_set_up_calls.push_back([=] ()
131 if (!(spec & option_spec::HIDDEN) && (!(spec & option_spec::ADVANCED) || show_advanced_options))
132 print_list_item(prep_id_for_help(short_id, long_id), desc);
145 template <
typename option_type,
typename val
idator_type>
146 void add_positional_option(option_type & value,
147 std::string
const & desc,
148 validator_type & validator)
150 positional_option_calls.push_back([=, &value]()
152 ++positional_option_count;
153 std::string key{
"\\fBARGUMENT-" + std::to_string(positional_option_count) +
"\\fP " + option_type_and_list_info(value)};
154 print_list_item(key, (desc +
" " + validator.get_help_page_message()));
161 void parse(argument_parser_meta_data & parser_meta)
167 if (!meta.synopsis.empty())
169 print_section(
"Synopsis");
173 if (!meta.description.empty())
175 print_section(
"Description");
176 for (
auto desc : meta.description)
181 if (!positional_option_calls.empty())
182 print_section(
"Positional Arguments");
185 for (
auto f : positional_option_calls)
189 if (!parser_set_up_calls.empty())
190 print_section(
"Options");
193 for (
auto f : parser_set_up_calls)
196 if (!meta.examples.empty())
198 print_section(
"Examples");
199 for (
auto example : meta.examples)
205 throw parser_interruption();
211 void add_section(std::string
const & title)
213 parser_set_up_calls.push_back([=] ()
215 print_section(title);
222 void add_subsection(std::string
const & title)
224 parser_set_up_calls.push_back([=] ()
226 print_subsection(title);
234 void add_line(std::string
const & text,
bool line_is_paragraph)
236 parser_set_up_calls.push_back([=] ()
238 print_line(text, line_is_paragraph);
246 void add_list_item(std::string
const & key, std::string
const & desc)
248 parser_set_up_calls.push_back([=] ()
250 print_list_item(key, desc);
268 argument_parser_meta_data meta;
273 struct console_layout_struct
276 unsigned screenWidth;
278 unsigned defaultScreenWidth;
280 unsigned maximalScreenWidth;
282 unsigned minimalScreenWidth;
284 unsigned leftPadding;
286 unsigned centerPadding;
288 unsigned rightPadding;
290 unsigned leftColumnWidth;
292 unsigned rightColumnWidth;
294 unsigned rightColumnTab;
297 console_layout_struct() :
298 screenWidth{0}, defaultScreenWidth{80}, maximalScreenWidth{120}, minimalScreenWidth{40},
299 leftPadding{4}, centerPadding{2}, rightPadding{2}, leftColumnWidth{4}, rightColumnWidth{0}
302 unsigned cols = get_terminal_width();
303 screenWidth = (cols > 0) ? cols : defaultScreenWidth;
304 screenWidth = std::max(screenWidth, minimalScreenWidth);
305 screenWidth = std::min(screenWidth, maximalScreenWidth);
306 screenWidth -= rightPadding;
308 rightColumnWidth = screenWidth - leftPadding - leftColumnWidth - centerPadding - rightPadding;
309 rightColumnTab = leftPadding + leftColumnWidth + centerPadding;
316 std::ostream_iterator<char> out(std::cout);
318 std::cout << meta.app_name;
319 if (!
empty(meta.short_description))
320 std::cout <<
" - " << meta.short_description;
323 unsigned len = text_width(meta.app_name) + (
empty(meta.short_description) ? 0 : 3) +
324 text_width(meta.short_description);
325 std::fill_n(out, len,
'=');
330 void print_synopsis()
332 for (
unsigned i = 0; i < meta.synopsis.size(); ++i)
334 std::string text =
"\\fB";
335 text.append(meta.app_name);
336 text.append(
"\\fP ");
337 text.append(meta.synopsis[i]);
339 print_line(text,
false);
346 void print_section(std::string
const & title)
348 std::ostream_iterator<char> out(std::cout);
349 std::cout <<
'\n' << to_text(
"\\fB");
350 std::transform(title.begin(), title.end(), out, [] (
unsigned char c) {
return std::toupper(c); });
351 std::cout << to_text(
"\\fP") <<
'\n';
352 prev_was_paragraph =
false;
358 void print_subsection(std::string
const & title)
360 std::ostream_iterator<char> out(std::cout);
361 std::cout <<
'\n' << to_text(
"\\fB");
362 std::fill_n(out, layout.leftPadding / 2,
' ');
363 std::cout << title << to_text(
"\\fP") <<
'\n';
364 prev_was_paragraph =
false;
372 void print_line(std::string
const & text,
bool const line_is_paragraph)
374 if (prev_was_paragraph)
377 std::ostream_iterator<char> out(std::cout);
378 std::fill_n(out, layout.leftPadding,
' ');
379 print_text(text, layout, layout.leftPadding);
380 prev_was_paragraph = line_is_paragraph;
386 void print_line(std::string
const & text)
388 print_line(text,
true);
405 void print_list_item(std::string
const & term, std::string
const & desc)
407 if (prev_was_paragraph)
410 std::ostream_iterator<char> out(std::cout);
413 std::fill_n(out, layout.leftPadding,
' ');
414 std::cout << to_text(term);
415 unsigned pos = layout.leftPadding + term.size();
416 if (pos + layout.centerPadding > layout.rightColumnTab)
421 std::fill_n(out, layout.rightColumnTab - pos,
' ');
422 print_text(desc, layout, layout.rightColumnTab);
424 prev_was_paragraph =
false;
430 std::ostream_iterator<char> out(std::cout);
433 std::cout <<
"\n" << to_text(
"\\fB") <<
"VERSION" << to_text(
"\\fP") <<
"\n";
434 std::fill_n(out, layout.leftPadding,
' ');
435 std::cout << to_text(
"\\fB") <<
"Last update: " << to_text(
"\\fP") << meta.date <<
"\n";
436 std::fill_n(out, layout.leftPadding,
' ');
437 std::cout << to_text(
"\\fB") << meta.app_name <<
" version: " << to_text(
"\\fP") << meta.version <<
"\n";
438 std::fill_n(out, layout.leftPadding,
' ');
439 std::cout << to_text(
"\\fB") <<
"SeqAn version: " << to_text(
"\\fP") <<
SEQAN3_VERSION_MAJOR <<
'.' 442 if (!
empty(meta.url))
444 std::cout <<
"\n" << to_text(
"\\fB") <<
"URL" << to_text(
"\\fP") <<
"\n";
445 std::fill_n(out, layout.leftPadding,
' ');
446 std::cout << meta.url <<
"\n";
456 std::ostream_iterator<char> out(std::cout);
459 if ((!
empty(meta.short_copyright)) || (!
empty(meta.long_copyright)) || (!
empty(meta.citation)))
461 std::cout <<
"\n" << to_text(
"\\fB") <<
"LEGAL" << to_text(
"\\fP") <<
"\n";
463 if (!
empty(meta.short_copyright))
465 std::fill_n(out, layout.leftPadding,
' ');
466 std::cout << to_text(
"\\fB") << meta.app_name <<
" Copyright: " 467 << to_text(
"\\fP") << meta.short_copyright <<
"\n";
469 std::fill_n(out, layout.leftPadding,
' ');
470 std::cout << to_text(
"\\fB") <<
"SeqAn Copyright: " << to_text(
"\\fP")
471 <<
"2006-2015 Knut Reinert, FU-Berlin; released under the 3-clause BSDL.\n";
472 if (!
empty(meta.citation))
474 std::fill_n(out, layout.leftPadding,
' ');
475 std::cout << to_text(
"\\fB") <<
"In your academic works please cite: " << to_text(
"\\fP")
476 << meta.citation <<
"\n";
478 if (!
empty(meta.long_copyright))
480 std::fill_n(out, layout.leftPadding,
' ');
481 std::cout <<
"For full copyright and/or warranty information see " << to_text(
"\\fB")
482 <<
"--copyright" << to_text(
"\\fP") <<
".\n";
490 std::string to_text(std::string
const & str)
494 for (
auto it = str.begin(); it != str.end(); ++it)
500 assert(it != str.end());
503 result.push_back(*it);
508 assert(it != str.end());
512 result.append(
"\033[4m");
517 result.append(
"\033[1m");
522 result.append(
"\033[0m");
526 result.append(
"\\f");
527 result.push_back(*it);
532 result.push_back(
'\\');
533 result.push_back(*it);
538 result.push_back(*it);
549 unsigned text_width(std::string
const & text)
553 for (
unsigned i = 0; i < text.size(); ++i)
561 if (i + 1 == text.size())
567 if (text[i + 1] ==
'\\' || text[i + 1] ==
'-')
574 if (i + 2 == text.size())
581 if (text[i + 1] ==
'f')
583 if (text[i + 2] ==
'B' || text[i + 2] ==
'I' || text[i + 2] ==
'P')
598 void print_text(std::string
const & text,
599 console_layout_struct
const & layout,
603 std::ostream_iterator<char> out(std::cout);
606 std::istringstream iss(text.c_str());
607 std::vector<std::string> tokens;
608 std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(),
613 std::fill_n(out, tab - pos,
' ');
616 typedef std::vector<std::string>::const_iterator TConstIter;
617 for (TConstIter it = tokens.begin(); it != tokens.end(); ++it)
619 if (it == tokens.begin())
621 std::cout << to_text(*it);
622 pos += text_width(*it);
623 if (pos > layout.screenWidth)
626 std::fill_n(out, tab,
' ');
632 if (pos + 1 + text_width(*it) > layout.screenWidth)
636 fill_n(out, tab,
' ');
637 std::cout << to_text(*it);
638 pos = tab + text_width(*it);
643 std::cout << to_text(*it);
644 pos += text_width(*it) + 1;
653 std::vector<std::function<void()>> parser_set_up_calls;
655 std::vector<std::function<void()>> positional_option_calls;
657 unsigned positional_option_count{0};
659 bool prev_was_paragraph{
false};
661 bool show_advanced_options{
false};
663 console_layout_struct layout;
675 class format_short_help :
public format_help
681 void parse(argument_parser_meta_data
const & parser_meta)
687 if (!parser_meta.synopsis.empty())
690 print_line(
"Try -h or --help for more information.\n");
692 throw parser_interruption();
705 class format_version :
public format_help
720 template <
typename option_type,
typename val
idator_type>
721 void add_option(option_type & value,
723 std::string
const & long_id,
724 std::string
const & desc,
726 validator_type && validator)
728 parser_set_up_calls.push_back([=, &value]()
730 if (!(spec & option_spec::HIDDEN) && (!(spec & option_spec::ADVANCED) || show_advanced_options))
731 print_list_item(prep_id_for_help(short_id, long_id) +
" " + option_type_and_list_info(value),
732 (desc +
" " + validator.get_help_page_message()));
745 void add_flag(
bool & value,
747 std::string
const & long_id,
748 std::string
const & desc,
751 parser_set_up_calls.push_back([=, &value] ()
753 if (!(spec & option_spec::HIDDEN) && (!(spec & option_spec::ADVANCED) || show_advanced_options))
754 print_list_item(prep_id_for_help(short_id, long_id), desc);
767 template <
typename option_type,
typename val
idator_type>
768 void add_positional_option(option_type & value,
769 std::string
const & desc,
770 validator_type && validator)
772 positional_option_calls.push_back([=, &value]()
774 ++positional_option_count;
775 std::string key{
"\\fBARGUMENT " + std::to_string(positional_option_count) +
"\\fP " + option_type_and_list_info(value)};
776 print_list_item(key, (desc +
" " + validator.get_help_page_message()));
783 void parse(argument_parser_meta_data & parser_meta)
790 throw parser_interruption();
#define SEQAN3_VERSION_MINOR
The minor version as MACRO.
Definition: version.hpp:49
constexpr auto transform
A range adaptor that takes a invocable and returns a view of the elements with the invocable applied...
Definition: transform.hpp:95
Definition: auxiliary.hpp:72
::ranges::copy copy
Alias for ranges::copy. Copies a range of elements to a new location.
Definition: ranges:200
Checks if program is run interactively and retrieves dimensions of terminal (Transferred from seqan2)...
Definition: aligned_sequence_concept.hpp:288
Definition: auxiliary.hpp:68
::ranges::empty empty
Alias for ranges::empty. Checks whether a range is empty.
Definition: ranges:205
option_spec
Used to further specify argument_parser options/flags.
Definition: auxiliary.hpp:60
constexpr auto back_inserter(container_t &container)
Create a std::back_insert_iterator for the argument.
Definition: iterator:79
#define SEQAN3_VERSION_PATCH
The patch version as MACRO.
Definition: version.hpp:51
#define SEQAN3_VERSION_MAJOR
The major version as MACRO.
Definition: version.hpp:47
Contains SeqAn version macros and global variables.