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;
212 command_names{names},
213 show_advanced_options{advanced}
221 template <
typename option_type,
typename config_type>
222 void add_option(option_type & value, config_type
const & config)
224 std::string id = prep_id_for_help(config.short_id, config.long_id) +
" " + option_type_and_list_info(value);
226 if (config.default_message.empty())
227 info += ((config.required) ?
std::string{
" "} : detail::to_string(
" Default: ", value,
". "));
229 info += detail::to_string(
" Default: ", config.default_message,
". ");
231 info += config.validator.get_help_page_message();
233 store_help_page_element(
236 derived_t().print_list_item(
id, info);
244 template <
typename config_type>
245 void add_flag(
bool & SHARG_DOXYGEN_ONLY(value), config_type
const & config)
247 store_help_page_element(
248 [
this,
id = prep_id_for_help(config.short_id, config.long_id), description = config.description]()
250 derived_t().print_list_item(id, description);
258 template <
typename option_type,
typename config_type>
259 void add_positional_option(option_type & value, config_type
const & config)
261 positional_option_calls.push_back(
262 [
this, &value, description = config.description, validator = config.validator]()
264 ++positional_option_count;
265 derived_t().print_list_item(detail::to_string(
"\\fBARGUMENT-",
266 positional_option_count,
268 option_type_and_list_info(value)),
271 ((detail::is_container_option<option_type>)
272 ? detail::to_string(
" Default: ", value,
". ")
274 + validator.get_help_page_message());
282 void parse(parser_meta_data & parser_meta)
286 derived_t().print_header();
288 if (!meta.synopsis.empty())
290 derived_t().print_section(
"Synopsis");
291 derived_t().print_synopsis();
294 if (!meta.description.empty())
296 derived_t().print_section(
"Description");
297 for (
auto desc : meta.description)
301 if (!command_names.empty())
303 derived_t().print_section(
"Subcommands");
304 derived_t().print_line(
"This program must be invoked with one of the following subcommands:",
false);
306 derived_t().print_line(
"- \\fB" + name +
"\\fP",
false);
307 derived_t().print_line(
"See the respective help page for further details (e.g. by calling " + meta.app_name
308 +
" " + command_names[0] +
" -h).",
310 derived_t().print_line(
"The following options below belong to the top-level parser and need to be "
311 "specified \\fBbefore\\fP the subcommand key word. Every argument after the "
312 "subcommand key word is passed on to the corresponding sub-parser.",
317 if (!positional_option_calls.empty())
318 derived_t().print_section(
"Positional Arguments");
321 for (
auto f : positional_option_calls)
325 if (!parser_set_up_calls.empty())
326 derived_t().print_section(
"Options");
329 for (
auto f : parser_set_up_calls)
332 if (!meta.examples.empty())
334 derived_t().print_section(
"Examples");
335 for (
auto example : meta.examples)
343 derived_t().print_footer();
351 void add_section(
std::string const & title,
bool const advanced_only)
353 store_help_page_element(
356 derived_t().print_section(title);
365 void add_subsection(
std::string const & title,
bool const advanced_only)
367 store_help_page_element(
370 derived_t().print_subsection(title);
379 void add_line(
std::string const & text,
bool is_paragraph,
bool const advanced_only)
381 store_help_page_element(
382 [
this, text, is_paragraph]()
384 derived_t().print_line(text, is_paragraph);
395 store_help_page_element(
398 derived_t().print_list_item(key, desc);
418 parser_meta_data meta;
425 derived_type & derived_t()
427 return static_cast<derived_type &
>(*this);
431 void print_synopsis()
433 for (
unsigned i = 0; i < meta.synopsis.size(); ++i)
436 text.
append(meta.synopsis[i]);
439 derived_t().print_line(text,
false);
448 derived_t().print_line(text,
true);
457 derived_t().print_section(
"Version");
458 derived_t().print_line(derived_t().in_bold(
"Last update: ") + meta.date,
false);
459 derived_t().print_line(derived_t().in_bold(meta.app_name +
" version: ") + meta.version,
false);
460 derived_t().print_line(derived_t().in_bold(
"Sharg version: ") + version_str,
false);
462#ifdef SEQAN3_VERSION_CSTRING
463 std::string const seqan3_version_str{seqan3::seqan3_version_cstring};
464 derived_t().print_line(derived_t().in_bold(
"SeqAn version: ") + seqan3_version_str,
false);
467 if (!
empty(meta.url))
469 derived_t().print_section(
"Url");
470 derived_t().print_line(meta.url,
false);
478 if ((!
empty(meta.short_copyright)) || (!
empty(meta.long_copyright)) || (!
empty(meta.citation))
479 || (!
empty(meta.author)) || (!
empty(meta.email)))
481 derived_t().print_section(
"Legal");
483 if (!
empty(meta.short_copyright))
485 derived_t().print_line(derived_t().in_bold(meta.app_name +
" Copyright: ") + meta.short_copyright,
489 if (!
empty(meta.author))
491 derived_t().print_line(derived_t().in_bold(
"Author: ") + meta.author,
false);
494 if (!
empty(meta.email))
496 derived_t().print_line(derived_t().in_bold(
"Contact: ") + meta.email,
false);
499 derived_t().print_line(derived_t().in_bold(
"SeqAn Copyright: ")
500 +
"2006-2022 Knut Reinert, FU-Berlin; released under the 3-clause BSDL.",
503 if (!
empty(meta.citation))
505 derived_t().print_line(derived_t().in_bold(
"In your academic works please cite: ") + meta.citation,
509 if (!
empty(meta.long_copyright))
511 derived_t().print_line(
"For full copyright and/or warranty information see "
512 + derived_t().in_bold(
"--copyright") +
".",
523 unsigned positional_option_count{0};
527 bool show_advanced_options{
true};
541 void store_help_page_element(
std::function<
void()> printer,
bool const advanced,
bool const hidden)
543 if (!(hidden) && (!(advanced) || show_advanced_options))
544 parser_set_up_calls.
push_back(std::move(printer));
557 void store_help_page_element(
std::function<
void()> printer, config<auto>
const & config)
559 if (!(config.hidden) && (!(config.advanced) || show_advanced_options))
560 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)
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