26namespace seqan3::detail
40 template <
typename value_type>
41 static std::string get_type_name_as_string(value_type
const & )
43 using type = std::decay_t<value_type>;
44 using types = type_list<int8_t,
57 std::filesystem::path>;
58 std::vector<std::string> names{
"signed 8 bit integer",
59 "unsigned 8 bit integer",
60 "signed 16 bit integer",
61 "unsigned 16 bit integer",
62 "signed 32 bit integer",
63 "unsigned 32 bit integer",
64 "signed 64 bit integer",
65 "unsigned 64 bit integer",
71 "std::filesystem::path"};
74 return names[list_traits::find<type, types>];
76 return detail::type_name_as_string<value_type>;
83 template <detail::is_container_option container_type>
84 static std::string get_type_name_as_string(container_type
const & )
86 typename container_type::value_type tmp{};
87 return get_type_name_as_string(tmp);
95 template <
typename option_value_type>
96 static std::string option_type_and_list_info(option_value_type
const & value)
98 return (
"(\\fI" + get_type_name_as_string(value) +
"\\fP)");
107 template <detail::is_container_option container_type>
108 static std::string option_type_and_list_info(container_type
const & container)
110 return (
"(\\fIList\\fP of \\fI" + get_type_name_as_string(container) +
"\\fP)");
120 static std::string prep_id_for_help(
char const short_id, std::string
const & long_id)
124 if (short_id !=
'\0')
125 term =
"\\fB-" + std::string(1, short_id) +
"\\fP";
127 if (short_id !=
'\0' && !long_id.
empty())
130 if (!long_id.
empty())
131 term.
append(
"\\fB--" + long_id +
"\\fP");
142 std::string escape_special_xml_chars(std::string
const & original)
147 for (
auto c : original)
172 static std::string expand_multiple_flags(std::string
const & flag_cluster)
175 auto it{flag_cluster.
begin()};
177 if (flag_cluster[0] ==
'-')
180 for (; it != flag_cluster.
end() - 1; ++it)
181 tmp.
append({
'-', *it,
',',
' '});
184 tmp.
append({
'a',
'n',
'd',
' ',
'-', flag_cluster[flag_cluster.
size() - 1]});
195template <
typename derived_type>
196class format_help_base :
public format_base
202 format_help_base() =
default;
203 format_help_base(format_help_base
const & pf) =
default;
204 format_help_base & operator=(format_help_base
const & pf) =
default;
205 format_help_base(format_help_base &&) =
default;
206 format_help_base & operator=(format_help_base &&) =
default;
207 ~format_help_base() =
default;
213 format_help_base(std::vector<std::string>
const & names,
bool const advanced) :
214 command_names{names},
223 template <
typename option_type,
typename val
idator_type>
224 void add_option(option_type & value,
226 std::string
const & long_id,
227 std::string
const & desc,
229 validator_type && option_validator)
231 std::string
id = prep_id_for_help(short_id, long_id) +
" " + option_type_and_list_info(value);
232 std::string info{desc};
233 info += ((spec &
option_spec::required) ? std::string{
" "} : detail::to_string(
" Default: ", value,
". "));
234 info += option_validator.get_help_page_message();
235 store_help_page_element(
238 derived_t().print_list_item(
id, info);
246 void add_flag(
bool & SEQAN3_DOXYGEN_ONLY(value),
248 std::string
const & long_id,
249 std::string
const & desc,
252 std::string
id = prep_id_for_help(short_id, long_id);
253 store_help_page_element(
256 derived_t().print_list_item(
id, desc);
264 template <
typename option_type,
typename val
idator_type>
265 void add_positional_option(option_type & value, std::string
const & desc, validator_type & option_validator)
267 std::string msg = option_validator.get_help_page_message();
269 positional_option_calls.push_back(
270 [
this, &value, desc, msg]()
272 ++positional_option_count;
273 derived_t().print_list_item(detail::to_string(
"\\fBARGUMENT-",
274 positional_option_count,
276 option_type_and_list_info(value)),
279 ((detail::is_container_option<option_type>)
280 ? detail::to_string(
" Default: ", value,
". ")
289 void parse(argument_parser_meta_data & parser_meta)
293 derived_t().print_header();
295 if (!meta.synopsis.empty())
297 derived_t().print_section(
"Synopsis");
298 derived_t().print_synopsis();
301 if (!meta.description.empty())
303 derived_t().print_section(
"Description");
304 for (
auto desc : meta.description)
308 if (!command_names.empty())
310 derived_t().print_section(
"Subcommands");
311 derived_t().print_line(
"This program must be invoked with one of the following subcommands:",
false);
312 for (std::string
const & name : command_names)
313 derived_t().print_line(
"- \\fB" + name +
"\\fP",
false);
314 derived_t().print_line(
"See the respective help page for further details (e.g. by calling " + meta.app_name
315 +
" " + command_names[0] +
" -h).",
317 derived_t().print_line(
"The following options below belong to the top-level parser and need to be "
318 "specified \\fBbefore\\fP the subcommand key word. Every argument after the "
319 "subcommand key word is passed on to the corresponding sub-parser.",
324 if (!positional_option_calls.empty())
325 derived_t().print_section(
"Positional Arguments");
328 for (
auto f : positional_option_calls)
332 if (!parser_set_up_calls.empty())
333 derived_t().print_section(
"Options");
336 for (
auto f : parser_set_up_calls)
339 if (!meta.examples.empty())
341 derived_t().print_section(
"Examples");
342 for (
auto example : meta.examples)
350 derived_t().print_footer();
358 void add_section(std::string
const & title,
option_spec const spec)
360 store_help_page_element(
363 derived_t().print_section(title);
371 void add_subsection(std::string
const & title,
option_spec const spec)
373 store_help_page_element(
376 derived_t().print_subsection(title);
384 void add_line(std::string
const & text,
bool is_paragraph,
option_spec const spec)
386 store_help_page_element(
387 [
this, text, is_paragraph]()
389 derived_t().print_line(text, is_paragraph);
397 void add_list_item(std::string
const & key, std::string
const & desc,
option_spec const spec)
399 store_help_page_element(
402 derived_t().print_list_item(key, desc);
421 argument_parser_meta_data meta;
428 derived_type & derived_t()
430 return static_cast<derived_type &
>(*this);
434 void print_synopsis()
436 for (
unsigned i = 0; i < meta.synopsis.size(); ++i)
438 std::string text =
"\\fB";
439 text.
append(meta.synopsis[i]);
442 derived_t().print_line(text,
false);
449 void print_line(std::string
const & text)
451 derived_t().print_line(text,
true);
460 derived_t().print_section(
"Version");
461 derived_t().print_line(derived_t().in_bold(
"Last update: ") + meta.date,
false);
462 derived_t().print_line(derived_t().in_bold(meta.app_name +
" version: ") + meta.version,
false);
463 derived_t().print_line(derived_t().in_bold(
"SeqAn version: ") + version_str,
false);
465 if (!
empty(meta.url))
467 derived_t().print_section(
"Url");
468 derived_t().print_line(meta.url,
false);
476 if ((!
empty(meta.short_copyright)) || (!
empty(meta.long_copyright)) || (!
empty(meta.citation))
477 || (!
empty(meta.author)) || (!
empty(meta.email)))
479 derived_t().print_section(
"Legal");
481 if (!
empty(meta.short_copyright))
483 derived_t().print_line(derived_t().in_bold(meta.app_name +
" Copyright: ") + meta.short_copyright,
487 if (!
empty(meta.author))
489 derived_t().print_line(derived_t().in_bold(
"Author: ") + meta.author,
false);
492 if (!
empty(meta.email))
494 derived_t().print_line(derived_t().in_bold(
"Contact: ") + meta.email,
false);
497 derived_t().print_line(derived_t().in_bold(
"SeqAn Copyright: ")
498 +
"2006-2025 Knut Reinert, FU-Berlin; released under the 3-clause BSDL.",
501 if (!
empty(meta.citation))
503 derived_t().print_line(derived_t().in_bold(
"In your academic works please cite: ") + meta.citation,
507 if (!
empty(meta.long_copyright))
509 derived_t().print_line(
"For full copyright and/or warranty information see "
510 + derived_t().in_bold(
"--copyright") +
".",
517 std::vector<std::function<void()>> parser_set_up_calls;
519 std::vector<std::function<void()>> positional_option_calls;
521 unsigned positional_option_count{0};
523 std::vector<std::string> command_names{};
525 bool show_advanced_options{
true};
538 void store_help_page_element(std::function<
void()> printer,
option_spec const spec)
541 parser_set_up_calls.push_back(std::move(printer));
Provides the concept seqan3::detail::is_container_option.
Provides auxiliary information.
Provides parser related exceptions.
T find_first_of(T... args)
T find_last_of(T... args)
option_spec
Used to further specify argument_parser options/flags.
Definition auxiliary.hpp:249
@ advanced
Definition auxiliary.hpp:256
@ hidden
Definition auxiliary.hpp:260
@ required
Definition auxiliary.hpp:251
constexpr bool contains
Whether a type occurs in a type list or not.
Definition type_list/traits.hpp:249
constexpr char const * seqan3_version_cstring
The full version as null terminated string.
Definition version.hpp:64
Provides traits to inspect some information of a type, for example its name.
Provides some standard validators for (positional) options.
Provides SeqAn version macros and global variables.