#pragma once // Distributed under the 3-Clause BSD License. See accompanying // file LICENSE or https://github.com/CLIUtils/CLI11 for details. #include #include #include "CLI/StringTools.hpp" namespace CLI { class Option; class App; /// This enum signifies what situation the option is beig printed in. /// /// This is passed in as part of the built in formatter in App; it is /// possible that a custom App formatter could avoid using it, however. enum class OptionFormatMode { Usage, //< In the program usage line Positional, //< In the positionals Optional //< In the normal optionals }; /// This enum signifies the type of help requested /// /// This is passed in by App; all user classes must accept this as /// the second argument. enum class AppFormatMode { Normal, //< The normal, detailed help All, //< A fully expanded help Sub, //< Used when printed as part of expanded subcommand }; /// This is an example formatter (and also the default formatter) /// For option help. class OptionFormatter { protected: /// @name Options ///@{ /// @brief The required help printout labels (user changeable) /// Values are REQUIRED, NEEDS, EXCLUDES std::map labels_{{"REQUIRED", "(REQUIRED)"}}; /// The width of the first column size_t column_width_{30}; ///@} /// @name Basic ///@{ public: OptionFormatter() = default; OptionFormatter(const OptionFormatter &) = default; OptionFormatter(OptionFormatter &&) = default; ///@} /// @name Setters ///@{ /// Set the "REQUIRED" label void label(std::string key, std::string val) { labels_[key] = val; } /// Set the column width void column_width(size_t val) { column_width_ = val; } ///@} /// @name Getters ///@{ /// Get the current value of a name (REQUIRED, etc.) std::string get_label(std::string key) const { if(labels_.find(key) == labels_.end()) return key; else return labels_.at(key); } /// Get the current column width size_t get_column_width() const { return column_width_; } ///@} /// @name Overridables ///@{ /// @brief This is the name part of an option, Default: left column virtual std::string make_name(const Option *, OptionFormatMode) const; /// @brief This is the options part of the name, Default: combined into left column virtual std::string make_opts(const Option *) const; /// @brief This is the description. Default: Right column, on new line if left column too large virtual std::string make_desc(const Option *) const; /// @brief This is used to print the name on the USAGE line (by App formatter) virtual std::string make_usage(const Option *opt) const; /// @brief This is the standard help combiner that does the "default" thing. virtual std::string operator()(const Option *opt, OptionFormatMode mode) const { std::stringstream out; if(mode == OptionFormatMode::Usage) out << make_usage(opt); else detail::format_help(out, make_name(opt, mode) + make_opts(opt), make_desc(opt), column_width_); return out.str(); } ///@} }; class AppFormatter { /// @name Options ///@{ /// The width of the first column size_t column_width_{30}; /// @brief The required help printout labels (user changeable) /// Values are Needs, Excludes, etc. std::map labels_; ///@} /// @name Basic ///@{ public: AppFormatter() = default; AppFormatter(const AppFormatter &) = default; AppFormatter(AppFormatter &&) = default; ///@} /// @name Setters ///@{ /// Set the "REQUIRED" label void label(std::string key, std::string val) { labels_[key] = val; } /// Set the column width void column_width(size_t val) { column_width_ = val; } ///@} /// @name Getters ///@{ /// Get the current value of a name (REQUIRED, etc.) std::string get_label(std::string key) const { if(labels_.find(key) == labels_.end()) return key; else return labels_.at(key); } /// Get the current column width size_t get_column_width() const { return column_width_; } /// @name Overridables ///@{ /// This prints out a group of options virtual std::string make_group(std::string group, std::vector opts, OptionFormatMode mode) const; /// This prints out all the groups of options virtual std::string make_groups(const App *app, AppFormatMode mode) const; /// This prints out all the subcommands virtual std::string make_subcommands(const App *app, AppFormatMode mode) const; /// This prints out a subcommand virtual std::string make_subcommand(const App *sub) const; /// This prints out a subcommand in help-all virtual std::string make_expanded(const App *sub) const; /// This prints out all the groups of options virtual std::string make_footer(const App *app) const; /// This displays the description line virtual std::string make_description(const App *app) const; /// This displays the usage line virtual std::string make_usage(const App *app, std::string name) const; /// This puts everything together virtual std::string operator()(const App *, std::string, AppFormatMode) const; ///@} }; } // namespace CLI