19#if __has_include(<seqan3/version.hpp>)
20# include <seqan3/version.hpp>
23namespace sharg::detail
37 template <
typename value_type>
38 static std::string get_type_name_as_string(value_type
const & )
43 return "signed 8 bit integer";
45 return "unsigned 8 bit integer";
47 return "signed 16 bit integer";
49 return "unsigned 16 bit integer";
51 return "signed 32 bit integer";
53 return "unsigned 32 bit integer";
55 return "signed 64 bit integer";
57 return "unsigned 64 bit integer";
69 return "std::filesystem::path";
71 return sharg::detail::type_name_as_string<value_type>;
78 template <detail::is_container_option container_type>
79 static std::string get_type_name_as_string(container_type
const & )
81 typename container_type::value_type tmp{};
82 return get_type_name_as_string(tmp);
90 template <
typename option_value_type>
91 static std::string option_type_and_list_info(option_value_type
const & value)
93 return (
"(\fI" + get_type_name_as_string(value) +
"\fP)");
102 template <detail::is_container_option container_type>
103 static std::string option_type_and_list_info(container_type
const & container)
105 return (
"(\fIList\fP of \fI" + get_type_name_as_string(container) +
"\fP)");
119 if (short_id !=
'\0')
122 if (short_id !=
'\0' && !long_id.
empty())
125 if (!long_id.
empty())
126 term.
append(
"\fB--" + long_id +
"\fP");
142 for (
auto c : original)
170 auto it{flag_cluster.
begin()};
172 if (flag_cluster[0] ==
'-')
175 for (; it != flag_cluster.
end() - 1; ++it)
176 tmp.
append({
'-', *it,
',',
' '});
179 tmp.
append({
'a',
'n',
'd',
' ',
'-', flag_cluster[flag_cluster.
size() - 1]});
196 template <
typename option_type,
typename default_type>
197 static std::string get_default_message(option_type
const & SHARG_DOXYGEN_ONLY(option), default_type
const & value)
202 message <<
" Default: ";
204 if constexpr (detail::is_container_option<option_type>)
209 auto view = std::views::transform(value,
214 message << detail::to_string(view);
218 message << detail::to_string(value);
229 static constexpr bool needs_string_quote = option_is_string || (option_is_path && value_is_string);
231 if constexpr (needs_string_quote)
234 message << detail::to_string(value);
237 return message.str();
246template <
typename derived_type>
247class format_help_base :
public format_base
253 format_help_base() =
default;
254 format_help_base(format_help_base
const & pf) =
default;
255 format_help_base & operator=(format_help_base
const & pf) =
default;
256 format_help_base(format_help_base &&) =
default;
257 format_help_base & operator=(format_help_base &&) =
default;
258 ~format_help_base() =
default;
267 bool const advanced) :
268 version_check_dev_decision{version_updates},
269 command_names{names},
270 show_advanced_options{advanced}
278 template <
typename option_type,
typename val
idator_t>
279 void add_option(option_type & value, config<validator_t>
const & config)
281 std::string id = prep_id_for_help(config.short_id, config.long_id) +
" " + option_type_and_list_info(value);
284 if (config.default_message.empty())
285 info += ((config.required) ?
std::string{} : get_default_message(value, value));
287 info += get_default_message(value, config.default_message);
289 if (
auto const & validator_message = config.validator.get_help_page_message(); !validator_message.empty())
290 info +=
". " + validator_message;
292 store_help_page_element(
295 derived_t().print_list_item(
id, info);
303 template <
typename val
idator_t>
304 void add_flag(
bool & SHARG_DOXYGEN_ONLY(value), config<validator_t>
const & config)
306 store_help_page_element(
307 [
this,
id = prep_id_for_help(config.short_id, config.long_id), description = config.description]()
309 derived_t().print_list_item(id, description);
317 template <
typename option_type,
typename val
idator_t>
318 void add_positional_option(option_type & value, config<validator_t>
const & config)
321 auto positional_default_message = [&value]() ->
std::string
323 if constexpr (detail::is_container_option<option_type>)
325 return get_default_message(value, value);
334 auto positional_validator_message = [&config]() ->
std::string
336 if (
auto const & validator_message = config.validator.get_help_page_message(); !validator_message.empty())
337 return ". " + validator_message;
345 default_message = positional_default_message(),
346 validator_message = positional_validator_message(),
347 description = config.description]()
349 ++positional_option_count;
350 derived_t().print_list_item(detail::to_string(
"\fBARGUMENT-",
351 positional_option_count,
353 option_type_and_list_info(value)),
354 description + default_message + validator_message);
361 void parse(parser_meta_data & parser_meta)
365 derived_t().print_header();
367 if (!meta.synopsis.empty())
369 derived_t().print_section(
"Synopsis");
370 derived_t().print_synopsis();
373 if (!meta.description.empty())
375 derived_t().print_section(
"Description");
376 for (
auto desc : meta.description)
380 if (!command_names.empty())
382 derived_t().print_section(
"Subcommands");
383 derived_t().print_line(
"This program must be invoked with one of the following subcommands:",
false);
385 derived_t().print_line(
"- \fB" + name +
"\fP", false);
386 derived_t().print_line(
"See the respective help page for further details (e.g. by calling " + meta.app_name
387 +
" " + command_names[0] +
" -h).",
389 derived_t().print_line(
"The following options belong to the top-level parser and need to be "
390 "specified \fBbefore\fP the subcommand key word. Every argument after the "
391 "subcommand key word is passed on to the corresponding sub-parser.",
396 if (!positional_option_calls.empty())
397 derived_t().print_section(
"Positional Arguments");
400 for (
auto f : positional_option_calls)
404 derived_t().print_section(
"Options");
407 for (
auto f : parser_set_up_calls)
411 derived_t().print_subsection(
"Common options");
412 derived_t().print_list_item(
"\fB-h\fP, \fB--help\fP",
"Prints the help page.");
413 derived_t().print_list_item(
"\fB-hh\fP, \fB--advanced-help\fP",
414 "Prints the help page including advanced options.");
415 derived_t().print_list_item(
"\fB--version\fP",
"Prints the version information.");
416 derived_t().print_list_item(
"\fB--copyright\fP",
"Prints the copyright/license information.");
417 derived_t().print_list_item(
"\fB--export-help\fP (std::string)",
418 "Export the help page information. Value must be one of "
419 + detail::supported_exports +
".");
421 derived_t().print_list_item(
"\fB--version-check\fP (bool)",
422 "Whether to check for the newest app version. Default: true");
424 if (!meta.examples.empty())
426 derived_t().print_section(
"Examples");
427 for (
auto example : meta.examples)
435 derived_t().print_footer();
441 void add_section(
std::string const & title,
bool const advanced_only)
443 store_help_page_element(
446 derived_t().print_section(title);
455 void add_subsection(
std::string const & title,
bool const advanced_only)
457 store_help_page_element(
460 derived_t().print_subsection(title);
469 void add_line(
std::string const & text,
bool is_paragraph,
bool const advanced_only)
471 store_help_page_element(
472 [
this, text, is_paragraph]()
474 derived_t().print_line(text, is_paragraph);
485 store_help_page_element(
488 derived_t().print_list_item(key, desc);
508 parser_meta_data meta;
518 derived_type & derived_t()
520 return static_cast<derived_type &
>(*this);
524 void print_synopsis()
526 for (
unsigned i = 0; i < meta.synopsis.size(); ++i)
529 text.
append(meta.synopsis[i]);
532 derived_t().print_line(text,
false);
541 derived_t().print_line(text,
true);
550 derived_t().print_section(
"Version");
551 derived_t().print_line(derived_t().in_bold(
"Last update: ") + meta.date,
false);
552 derived_t().print_line(derived_t().in_bold(meta.app_name +
" version: ") + meta.version,
false);
553 derived_t().print_line(derived_t().in_bold(
"Sharg version: ") + version_str,
false);
555#ifdef SEQAN3_VERSION_CSTRING
556 std::string const seqan3_version_str{seqan3::seqan3_version_cstring};
557 derived_t().print_line(derived_t().in_bold(
"SeqAn version: ") + seqan3_version_str,
false);
560 if (!
empty(meta.url))
562 derived_t().print_section(
"Url");
563 derived_t().print_line(meta.url,
false);
571 if ((!
empty(meta.short_copyright)) || (!
empty(meta.long_copyright)) || (!
empty(meta.citation))
572 || (!
empty(meta.author)) || (!
empty(meta.email)))
574 derived_t().print_section(
"Legal");
576 if (!
empty(meta.short_copyright))
578 derived_t().print_line(derived_t().in_bold(meta.app_name +
" Copyright: ") + meta.short_copyright,
582 if (!
empty(meta.author))
584 derived_t().print_line(derived_t().in_bold(
"Author: ") + meta.author,
false);
587 if (!
empty(meta.email))
589 derived_t().print_line(derived_t().in_bold(
"Contact: ") + meta.email,
false);
592 derived_t().print_line(derived_t().in_bold(
"SeqAn Copyright: ")
593 +
"2006-2024 Knut Reinert, FU-Berlin; released under the 3-clause BSDL.",
596 if (!
empty(meta.citation))
598 derived_t().print_line(derived_t().in_bold(
"In your academic works please cite: ") + meta.citation,
602 if (!
empty(meta.long_copyright))
604 derived_t().print_line(
"For full copyright and/or warranty information see "
605 + derived_t().in_bold(
"--copyright") +
".",
616 unsigned positional_option_count{0};
620 bool show_advanced_options{
true};
634 void store_help_page_element(
std::function<
void()> printer,
bool const advanced,
bool const hidden)
636 if (!(hidden) && (!(advanced) || show_advanced_options))
637 parser_set_up_calls.
push_back(std::move(printer));
650 template <
typename val
idator_t>
651 void store_help_page_element(
std::function<
void()> printer, config<validator_t>
const & config)
653 if (!(config.hidden) && (!(config.advanced) || show_advanced_options))
654 parser_set_up_calls.push_back(std::move(printer));
Provides auxiliary information.
Provides sharg::config class.
Provides the concept sharg::detail::is_container_option.
T find_first_of(T... args)
T find_last_of(T... args)
update_notifications
Indicates whether application allows automatic update notifications by the sharg::parser.
Definition auxiliary.hpp:26
@ on
Automatic update notifications should be enabled.
Provides traits to inspect some information of a type, for example its name.
Provides some standard validators for (positional) options.
constexpr char const * sharg_version_cstring
The full version as null terminated string.
Definition version.hpp:64