22#if __has_include(<seqan3/version.hpp>)
23# include <seqan3/version.hpp>
26namespace sharg::detail
40 template <
typename value_type>
41 static std::string get_type_name_as_string(value_type
const & )
45 if constexpr (std::is_same_v<type, int8_t>)
46 return "signed 8 bit integer";
47 else if constexpr (std::is_same_v<type, uint8_t>)
48 return "unsigned 8 bit integer";
49 else if constexpr (std::is_same_v<type, int16_t>)
50 return "signed 16 bit integer";
51 else if constexpr (std::is_same_v<type, uint16_t>)
52 return "unsigned 16 bit integer";
53 else if constexpr (std::is_same_v<type, int32_t>)
54 return "signed 32 bit integer";
55 else if constexpr (std::is_same_v<type, uint32_t>)
56 return "unsigned 32 bit integer";
57 else if constexpr (std::is_same_v<type, int64_t>)
58 return "signed 64 bit integer";
59 else if constexpr (std::is_same_v<type, uint64_t>)
60 return "unsigned 64 bit integer";
61 else if constexpr (std::is_same_v<type, double>)
63 else if constexpr (std::is_same_v<type, float>)
65 else if constexpr (std::is_same_v<type, bool>)
67 else if constexpr (std::is_same_v<type, char>)
69 else if constexpr (std::is_same_v<type, std::string>)
71 else if constexpr (std::is_same_v<type, std::filesystem::path>)
72 return "std::filesystem::path";
74 return sharg::detail::type_name_as_string<value_type>;
81 template <detail::is_container_option container_type>
82 static std::string get_type_name_as_string(container_type
const & )
84 typename container_type::value_type tmp{};
85 return get_type_name_as_string(tmp);
93 template <
typename option_value_type>
94 static std::string option_type_and_list_info(option_value_type
const & value)
96 return (
"(\\fI" + get_type_name_as_string(value) +
"\\fP)");
105 template <detail::is_container_option container_type>
106 static std::string option_type_and_list_info(container_type
const & container)
108 return (
"(\\fIList\\fP of \\fI" + get_type_name_as_string(container) +
"\\fP)");
122 if (short_id !=
'\0')
123 term =
"\\fB-" +
std::string(1, short_id) +
"\\fP";
125 if (short_id !=
'\0' && !long_id.
empty())
128 if (!long_id.
empty())
129 term.
append(
"\\fB--" + long_id +
"\\fP");
145 for (
auto c : original)
173 auto it{flag_cluster.
begin()};
175 if (flag_cluster[0] ==
'-')
178 for (; it != flag_cluster.
end() - 1; ++it)
179 tmp.
append({
'-', *it,
',',
' '});
182 tmp.
append({
'a',
'n',
'd',
' ',
'-', flag_cluster[flag_cluster.
size() - 1]});
193template <
typename derived_type>
194class format_help_base :
public format_base
200 format_help_base() =
default;
201 format_help_base(format_help_base
const & pf) =
default;
202 format_help_base & operator=(format_help_base
const & pf) =
default;
203 format_help_base(format_help_base &&) =
default;
204 format_help_base & operator=(format_help_base &&) =
default;
205 ~format_help_base() =
default;
214 bool const advanced) :
215 version_check_dev_decision{version_updates},
216 command_names{names},
217 show_advanced_options{advanced}
225 template <
typename option_type,
typename config_type>
226 void add_option(option_type & value, config_type
const & config)
228 std::string id = prep_id_for_help(config.short_id, config.long_id) +
" " + option_type_and_list_info(value);
230 if (config.default_message.empty())
231 info += ((config.required) ?
std::string{
" "} : detail::to_string(
" Default: ", value,
". "));
233 info += detail::to_string(
" Default: ", config.default_message,
". ");
235 info += config.validator.get_help_page_message();
237 store_help_page_element(
240 derived_t().print_list_item(
id, info);
248 template <
typename config_type>
249 void add_flag(
bool & SHARG_DOXYGEN_ONLY(value), config_type
const & config)
251 store_help_page_element(
252 [
this,
id = prep_id_for_help(config.short_id, config.long_id), description = config.description]()
254 derived_t().print_list_item(id, description);
262 template <
typename option_type,
typename config_type>
263 void add_positional_option(option_type & value, config_type
const & config)
265 positional_option_calls.push_back(
266 [
this, &value, description = config.description, validator = config.validator]()
268 ++positional_option_count;
269 derived_t().print_list_item(detail::to_string(
"\\fBARGUMENT-",
270 positional_option_count,
272 option_type_and_list_info(value)),
275 ((detail::is_container_option<option_type>)
276 ? detail::to_string(
" Default: ", value,
". ")
278 + validator.get_help_page_message());
286 void parse(parser_meta_data & parser_meta)
290 derived_t().print_header();
292 if (!meta.synopsis.empty())
294 derived_t().print_section(
"Synopsis");
295 derived_t().print_synopsis();
298 if (!meta.description.empty())
300 derived_t().print_section(
"Description");
301 for (
auto desc : meta.description)
305 if (!command_names.empty())
307 derived_t().print_section(
"Subcommands");
308 derived_t().print_line(
"This program must be invoked with one of the following subcommands:",
false);
310 derived_t().print_line(
"- \\fB" + name +
"\\fP",
false);
311 derived_t().print_line(
"See the respective help page for further details (e.g. by calling " + meta.app_name
312 +
" " + command_names[0] +
" -h).",
314 derived_t().print_line(
"The following options below belong to the top-level parser and need to be "
315 "specified \\fBbefore\\fP the subcommand key word. Every argument after the "
316 "subcommand key word is passed on to the corresponding sub-parser.",
321 if (!positional_option_calls.empty())
322 derived_t().print_section(
"Positional Arguments");
325 for (
auto f : positional_option_calls)
329 derived_t().print_section(
"Options");
332 for (
auto f : parser_set_up_calls)
336 derived_t().print_subsection(
"Common options");
337 derived_t().print_list_item(
"\\fB-h\\fP, \\fB--help\\fP",
"Prints the help page.");
338 derived_t().print_list_item(
"\\fB-hh\\fP, \\fB--advanced-help\\fP",
339 "Prints the help page including advanced options.");
340 derived_t().print_list_item(
"\\fB--version\\fP",
"Prints the version information.");
341 derived_t().print_list_item(
"\\fB--copyright\\fP",
"Prints the copyright/license information.");
342 derived_t().print_list_item(
"\\fB--export-help\\fP (std::string)",
343 "Export the help page information. Value must be one of [html, man, ctd, cwl].");
345 derived_t().print_list_item(
"\\fB--version-check\\fP (bool)",
346 "Whether to check for the newest app version. Default: true.");
348 if (!meta.examples.empty())
350 derived_t().print_section(
"Examples");
351 for (
auto example : meta.examples)
359 derived_t().print_footer();
365 void add_section(
std::string const & title,
bool const advanced_only)
367 store_help_page_element(
370 derived_t().print_section(title);
379 void add_subsection(
std::string const & title,
bool const advanced_only)
381 store_help_page_element(
384 derived_t().print_subsection(title);
393 void add_line(
std::string const & text,
bool is_paragraph,
bool const advanced_only)
395 store_help_page_element(
396 [
this, text, is_paragraph]()
398 derived_t().print_line(text, is_paragraph);
409 store_help_page_element(
412 derived_t().print_list_item(key, desc);
432 parser_meta_data meta;
442 derived_type & derived_t()
444 return static_cast<derived_type &
>(*this);
448 void print_synopsis()
450 for (
unsigned i = 0; i < meta.synopsis.size(); ++i)
453 text.
append(meta.synopsis[i]);
456 derived_t().print_line(text,
false);
465 derived_t().print_line(text,
true);
474 derived_t().print_section(
"Version");
475 derived_t().print_line(derived_t().in_bold(
"Last update: ") + meta.date,
false);
476 derived_t().print_line(derived_t().in_bold(meta.app_name +
" version: ") + meta.version,
false);
477 derived_t().print_line(derived_t().in_bold(
"Sharg version: ") + version_str,
false);
479#ifdef SEQAN3_VERSION_CSTRING
480 std::string const seqan3_version_str{seqan3::seqan3_version_cstring};
481 derived_t().print_line(derived_t().in_bold(
"SeqAn version: ") + seqan3_version_str,
false);
484 if (!
empty(meta.url))
486 derived_t().print_section(
"Url");
487 derived_t().print_line(meta.url,
false);
495 if ((!
empty(meta.short_copyright)) || (!
empty(meta.long_copyright)) || (!
empty(meta.citation))
496 || (!
empty(meta.author)) || (!
empty(meta.email)))
498 derived_t().print_section(
"Legal");
500 if (!
empty(meta.short_copyright))
502 derived_t().print_line(derived_t().in_bold(meta.app_name +
" Copyright: ") + meta.short_copyright,
506 if (!
empty(meta.author))
508 derived_t().print_line(derived_t().in_bold(
"Author: ") + meta.author,
false);
511 if (!
empty(meta.email))
513 derived_t().print_line(derived_t().in_bold(
"Contact: ") + meta.email,
false);
516 derived_t().print_line(derived_t().in_bold(
"SeqAn Copyright: ")
517 +
"2006-2023 Knut Reinert, FU-Berlin; released under the 3-clause BSDL.",
520 if (!
empty(meta.citation))
522 derived_t().print_line(derived_t().in_bold(
"In your academic works please cite: ") + meta.citation,
526 if (!
empty(meta.long_copyright))
528 derived_t().print_line(
"For full copyright and/or warranty information see "
529 + derived_t().in_bold(
"--copyright") +
".",
540 unsigned positional_option_count{0};
544 bool show_advanced_options{
true};
558 void store_help_page_element(
std::function<
void()> printer,
bool const advanced,
bool const hidden)
560 if (!(hidden) && (!(advanced) || show_advanced_options))
561 parser_set_up_calls.
push_back(std::move(printer));
574 void store_help_page_element(
std::function<
void()> printer, config<auto>
const & config)
576 if (!(config.hidden) && (!(config.advanced) || show_advanced_options))
577 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:29
@ 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:66