Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Adding information only to the advanced help pages is now possible. #1652

Merged
merged 3 commits into from
Mar 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ Note that 3.1.0 will be the first API stable release and interfaces in this rele

## New features

#### Argument Parser

* The following functions accept a `seqan3::argument_parser::option_spec::ADVANCED` to control what is
displayed on the (advanced) help page:
* `seqan3::argument_parser::add_section`
* `seqan3::argument_parser::add_subsection`
* `seqan3::argument_parser::add_line`
* `seqan3::argument_parser::add_list_item`
Note that other `seqan3::argument_parser::option_spec`s like `REQUIRED` are ignored.

#### I/O

* The `seqan3::format_fasta` accepts the file extenstion `.fas` as a valid extension for the FASTA format
Expand Down
31 changes: 19 additions & 12 deletions include/seqan3/argument_parser/argument_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ class argument_parser
char const short_id,
std::string const & long_id,
std::string const & desc,
option_spec const & spec = option_spec::DEFAULT,
option_spec const spec = option_spec::DEFAULT,
validator_type validator = validator_type{}) // copy to bind rvalues
{
if (sub_parser != nullptr)
Expand All @@ -262,7 +262,7 @@ class argument_parser
char const short_id,
std::string const & long_id,
std::string const & desc,
option_spec const & spec = option_spec::DEFAULT)
option_spec const spec = option_spec::DEFAULT)
{
verify_identifiers(short_id, long_id);
// copy variables into the lambda because the calls are pushed to a stack
Expand Down Expand Up @@ -420,38 +420,45 @@ class argument_parser

/*!\brief Adds an help page section to the seqan3::argument_parser.
* \param[in] title The title of the section.
* \param[in] spec Whether to always display this section title (seqan3::option_spec::DEFAULT), only when showing
* the advanced help page (seqan3::option_spec::ADVANCED) or never (seqan3::option_spec::HIDDEN).
* \details This only affects the help page and other output formats.
*/
void add_section(std::string const & title)
void add_section(std::string const & title, option_spec const spec = option_spec::DEFAULT)
{
std::visit([&] (auto & f) { f.add_section(title); }, format);
std::visit([&] (auto & f) { f.add_section(title, spec); }, format);
}

/*!\brief Adds an help page subsection to the seqan3::argument_parser.
* \param[in] title The title of the subsection.
* \param[in] spec Whether to always display this subsection title (seqan3::option_spec::DEFAULT), only when showing
* the advanced help page (seqan3::option_spec::ADVANCED) or never (seqan3::option_spec::HIDDEN).
* \details This only affects the help page and other output formats.
*/
void add_subsection(std::string const & title)
void add_subsection(std::string const & title, option_spec const spec = option_spec::DEFAULT)
{
std::visit([&] (auto & f) { f.add_subsection(title); }, format);
std::visit([&] (auto & f) { f.add_subsection(title, spec); }, format);
}

/*!\brief Adds an help page text line to the seqan3::argument_parser.
* \param[in] text The text to print.
* \param[in] line_is_paragraph Whether to insert as paragraph
* or just a line (Default: false).
* \param[in] is_paragraph Whether to insert as paragraph or just a line (Default: false).
* \param[in] spec Whether to always display this line (seqan3::option_spec::DEFAULT), only when showing
* the advanced help page (seqan3::option_spec::ADVANCED) or never (seqan3::option_spec::HIDDEN).
* \details
* If the line is not a paragraph (false), only one line break is appended, otherwise two line breaks are appended.
* This only affects the help page and other output formats.
*/
void add_line(std::string const & text, bool line_is_paragraph = false)
void add_line(std::string const & text, bool is_paragraph = false, option_spec const spec = option_spec::DEFAULT)
{
std::visit([&] (auto & f) { f.add_line(text, line_is_paragraph); }, format);
std::visit([&] (auto & f) { f.add_line(text, is_paragraph, spec); }, format);
}

/*!\brief Adds an help page list item (key-value) to the seqan3::argument_parser.
* \param[in] key The key of the key-value pair of the list item.
* \param[in] desc The value of the key-value pair of the list item.
* \param[in] spec Whether to always display this list item (seqan3::option_spec::DEFAULT), only when showing
* the advanced help page (seqan3::option_spec::ADVANCED) or never (seqan3::option_spec::HIDDEN).
*
* \details
*
Expand All @@ -465,9 +472,9 @@ class argument_parser
* Super important integer for age.
*```
*/
void add_list_item(std::string const & key, std::string const & desc)
void add_list_item(std::string const & key, std::string const & desc, option_spec const spec = option_spec::DEFAULT)
{
std::visit([&] (auto & f) { f.add_list_item(key, desc); }, format);
std::visit([&] (auto & f) { f.add_list_item(key, desc, spec); }, format);
}
//!\}

Expand Down
111 changes: 42 additions & 69 deletions include/seqan3/argument_parser/detail/format_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,68 +223,38 @@ class format_help_base : public format_base

public:
/*!\brief Adds a seqan3::print_list_item call to be evaluated later on.
*
* \tparam option_type The type of variable in which to store the given command line argument.
* \tparam validator_type The type of validator applied to the value after parsing.
*
* \param[out] value The variable in which to store the given command line argument.
* \param[in] short_id The short identifier for the option (e.g. 'i').
* \param[in] long_id The long identifier for the option (e.g. "integer").
* \param[in] desc The description of the option.
* \param[in] spec Advanced option specification, see seqan3::option_spec.
* \param[in] validator The validator applied to the value after parsing (callable).
* \copydetails seqan3::argument_parser::add_option
*/
template <typename option_type, typename validator_type>
void add_option(option_type & value,
char const short_id,
std::string const & long_id,
std::string const & desc,
option_spec const & spec,
option_spec const spec,
validator_type && validator)
{
std::string msg = validator.get_help_page_message();

parser_set_up_calls.push_back([this, &value, short_id, long_id, desc, spec, msg] ()
{
if (!(spec & option_spec::HIDDEN) && (!(spec & option_spec::ADVANCED) || show_advanced_options))
derived_t().print_list_item(prep_id_for_help(short_id, long_id) +
" " + option_type_and_list_info(value),
desc +
((spec & option_spec::REQUIRED)
? std::string{" "}
: detail::to_string(" Default: ", value, ". ")) +
msg);
});
std::string id = prep_id_for_help(short_id, long_id) + " " + option_type_and_list_info(value);
std::string info{desc};
info += ((spec & option_spec::REQUIRED) ? std::string{" "} : detail::to_string(" Default: ", value, ". "));
info += validator.get_help_page_message();
store_help_page_element([this, id, info] () { derived_t().print_list_item(id, info); }, spec);
}

/*!\brief Adds a seqan3::print_list_item call to be evaluated later on.
*
* \param[in] short_id The short identifier for the flag (e.g. 'i').
* \param[in] long_id The long identifier for the flag (e.g. "integer").
* \param[in] desc The description of the flag.
* \param[in] spec Advanced flag specification, see seqan3::option_spec.
* \copydetails seqan3::argument_parser::add_flag
*/
void add_flag(bool & /*value*/,
void add_flag(bool & SEQAN3_DOXYGEN_ONLY(value),
char const short_id,
std::string const & long_id,
std::string const & desc,
option_spec const & spec)
option_spec const spec)
{
parser_set_up_calls.push_back([this, short_id, long_id, desc, spec] ()
{
if (!(spec & option_spec::HIDDEN) && (!(spec & option_spec::ADVANCED) || show_advanced_options))
derived_t().print_list_item(prep_id_for_help(short_id, long_id), desc);
});
std::string id = prep_id_for_help(short_id, long_id);
store_help_page_element([this, id, desc] () { derived_t().print_list_item(id, desc); }, spec);
}

/*!\brief Adds a seqan3::print_list_item call to be evaluated later on.
*
* \tparam option_type The type of variable in which to store the given command line argument.
* \tparam validator_type The type of validator applied to the value after parsing.
*
* \param[out] value The variable in which to store the given command line argument.
* \param[in] desc The description of the positional option.
* \param[in] validator The validator applied to the value after parsing (callable).
* \copydetails seqan3::argument_parser::add_positional_option
*/
template <typename option_type, typename validator_type>
void add_positional_option(option_type & value,
Expand Down Expand Up @@ -371,49 +341,35 @@ class format_help_base : public format_base
}

/*!\brief Adds a print_section call to parser_set_up_calls.
* \param[in] title The title of the section of the help page.
* \copydetails seqan3::argument_parser::add_section
*/
void add_section(std::string const & title)
void add_section(std::string const & title, option_spec const spec)
rrahn marked this conversation as resolved.
Show resolved Hide resolved
{
parser_set_up_calls.push_back([this, title] ()
{
derived_t().print_section(title);
});
store_help_page_element([this, title] () { derived_t().print_section(title); }, spec);
}

/*!\brief Adds a print_subsection call to parser_set_up_calls.
* \param[in] title The title of the subsection of the help page.
* \copydetails seqan3::argument_parser::add_subsection
*/
void add_subsection(std::string const & title)
void add_subsection(std::string const & title, option_spec const spec)
{
parser_set_up_calls.push_back([this, title] ()
{
derived_t().print_subsection(title);
});
store_help_page_element([this, title] () { derived_t().print_subsection(title); }, spec);
}

/*!\brief Adds a print_line call to parser_set_up_calls.
* \param[in] text The line text to be printed to the help page.
* \param[in] line_is_paragraph True if you want a new line at the end.
* \copydetails seqan3::argument_parser::add_line
*/
void add_line(std::string const & text, bool line_is_paragraph)
void add_line(std::string const & text, bool is_paragraph, option_spec const spec)
{
parser_set_up_calls.push_back([this, text, line_is_paragraph] ()
{
derived_t().print_line(text, line_is_paragraph);
});
store_help_page_element([this, text, is_paragraph] () { derived_t().print_line(text, is_paragraph); }, spec);
}

/*!\brief Adds a seqan3::print_list_item call to parser_set_up_calls.
* \param[in] key The key of the key-value pair list item.
* \param[in] desc The key of the key-value pair list item.
* \copydetails seqan3::argument_parser::add_list_item
*/
void add_list_item(std::string const & key, std::string const & desc)
void add_list_item(std::string const & key, std::string const & desc, option_spec const spec)
{
parser_set_up_calls.push_back([this, key, desc] ()
{
derived_t().print_list_item(key, desc);
});
store_help_page_element([this, key, desc] () { derived_t().print_list_item(key, desc); }, spec);
}

/*!\brief Stores all meta information about the application
Expand Down Expand Up @@ -473,6 +429,23 @@ class format_help_base : public format_base
std::vector<std::string> command_names{};
//!\brief Whether to show advanced options or not.
bool show_advanced_options{true};

private:
/*!\brief Adds a function object to parser_set_up_calls **if** the annotation in `spec` does not prevent it.
* \param[in] printer The invokable that, if added to `parser_set_up_calls`, prints information to the help page.
* \param[in] spec The option specification deciding whether to add the information to the help page.
*
* \details
*
* If `spec` equals `seqan3::option_spec::HIDDEN`, the information is never added to the help page.
* If `spec` equals `seqan3::option_spec::ADVANCED`, the information is only added to the help page if
* the advanced help page has been queried on the command line (`show_advanced_options == true`).
*/
void store_help_page_element(std::function<void()> printer, option_spec const spec)
{
if (!(spec & option_spec::HIDDEN) && (!(spec & option_spec::ADVANCED) || show_advanced_options))
parser_set_up_calls.push_back(std::move(printer));
}
};

} // namespace seqan3::detail
48 changes: 13 additions & 35 deletions include/seqan3/argument_parser/detail/format_parse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,14 @@ class format_parse : public format_base
//!\}

/*!\brief Adds an seqan3::detail::get_option call to be evaluated later on.
*
* \tparam option_type The type of variable in which to store the given command line argument.
* \tparam validator_type The type of validator applied to the value after parsing.
*
* \param[out] value The variable in which to store the given command line argument.
* \param[in] short_id The short identifier for the option (e.g. 'i').
* \param[in] long_id The long identifier for the option (e.g. "integer").
* \param[in] spec Advanced option specification, see seqan3::option_spec.
* \param[in] validator The validator applied to the value after parsing (callable).
*
* \throws seqan3::design_error
* \copydetails seqan3::argument_parser::add_option
*/
template <typename option_type, typename validator_type>
void add_option(option_type & value,
char const short_id,
std::string const & long_id,
std::string const & /*desc*/,
option_spec const & spec,
std::string const & SEQAN3_DOXYGEN_ONLY(desc),
option_spec const spec,
validator_type && validator)
{
option_calls.push_back([this, &value, short_id, long_id, spec, validator]()
Expand All @@ -98,18 +88,13 @@ class format_parse : public format_base
}

/*!\brief Adds a get_flag call to be evaluated later on.
*
* \param[out] value The variable in which to store the given command line argument.
* \param[in] short_id The short identifier for the flag (e.g. 'i').
* \param[in] long_id The long identifier for the flag (e.g. "integer").
*
* \throws seqan3::design_error
* \copydetails seqan3::argument_parser::add_flag
*/
void add_flag(bool & value,
char const short_id,
std::string const & long_id,
std::string const & /*desc*/,
option_spec const & /*spec*/)
std::string const & SEQAN3_DOXYGEN_ONLY(desc),
option_spec const & SEQAN3_DOXYGEN_ONLY(spec))
{
flag_calls.push_back([this, &value, short_id, long_id]()
{
Expand All @@ -118,18 +103,11 @@ class format_parse : public format_base
}

/*!\brief Adds a get_positional_option call to be evaluated later on.
*
* \tparam option_type The type of variable in which to store the given command line argument.
* \tparam validator_type The type of validator applied to the value after parsing.
*
* \param[out] value The variable in which to store the given command line argument.
* \param[in] validator The validator applied to the value after parsing (callable).
*
* \throws seqan3::design_error
* \copydetails seqan3::argument_parser::add_positional_option
*/
template <typename option_type, typename validator_type>
void add_positional_option(option_type & value,
std::string const & /*desc*/,
std::string const & SEQAN3_DOXYGEN_ONLY(desc),
validator_type && validator)
{
positional_option_calls.push_back([this, &value, validator]()
Expand Down Expand Up @@ -164,10 +142,10 @@ class format_parse : public format_base

// functions are not needed for command line parsing but are part of the format interface.
//!\cond
void add_section(std::string const &) {}
void add_subsection(std::string const &) {}
void add_line(std::string const &, bool) {}
void add_list_item(std::string const &, std::string const &) {}
void add_section(std::string const &, option_spec const) {}
void add_subsection(std::string const &, option_spec const) {}
void add_line(std::string const &, bool, option_spec const) {}
void add_list_item(std::string const &, std::string const &, option_spec const) {}
//!\endcond

//!\brief Checks whether `id` is empty.
Expand Down Expand Up @@ -655,7 +633,7 @@ class format_parse : public format_base
void get_option(option_type & value,
char const short_id,
std::string const & long_id,
option_spec const & spec,
option_spec const spec,
validator_type && validator)
{
bool short_id_is_set{get_option_by_id(value, short_id)};
Expand Down
Loading