SNode.C
Loading...
Searching...
No Matches
CLI::HelpFormatter Class Reference

#include <Formatter.h>

Inheritance diagram for CLI::HelpFormatter:
Collaboration diagram for CLI::HelpFormatter:

Public Member Functions

 HelpFormatter ()
 ~HelpFormatter () override

Private Member Functions

std::string make_group (std::string group, bool is_positional, std::vector< const Option * > opts) const override
std::string make_description (const App *app) const override
std::string make_usage (const App *app, std::string name) const override
std::string make_footer (const App *app) const override
std::string make_subcommands (const App *app, AppFormatMode mode) const override
std::string make_subcommand (const App *sub) const override
std::string make_expanded (const App *sub, AppFormatMode mode) const override
std::string make_option_opts (const Option *opt) const override

Detailed Description

Definition at line 88 of file Formatter.h.

Constructor & Destructor Documentation

◆ HelpFormatter()

CLI::HelpFormatter::HelpFormatter ( )
inline

Definition at line 92 of file Formatter.h.

92 {
93 label("SUBCOMMAND", "INSTANCE");
94 label("SUBCOMMANDS", "INSTANCES");
95 label("PERSISTENT", "");
96 label("Persistent Options", "Options (persistent)");
97 label("Nonpersistent Options", "Options (nonpersistent)");
98 label("Usage", "\nUsage");
99 label("bool:{true,false}", "{true,false}");
100 label(":{true,false)", "{true,false}");
101 label(":{standard,active,complete,required}", "{standard,active,complete,required}");
102 label(":{standard,exact,expanded}", "{standard,exact,expanded}");
103 column_width(7);
104 }

◆ ~HelpFormatter()

CLI::HelpFormatter::~HelpFormatter ( )
override

Definition at line 193 of file Formatter.cpp.

193 {
194 }

Member Function Documentation

◆ make_description()

CLI11_INLINE std::string CLI::HelpFormatter::make_description ( const App * app) const
overrideprivate

Definition at line 208 of file Formatter.cpp.

208 {
209 std::string desc = app->get_description();
210 auto min_options = app->get_require_option_min();
211 auto max_options = app->get_require_option_max();
212 // ############## Next line changed (if statement removed)
213 if ((max_options == min_options) && (min_options > 0)) {
214 if (min_options == 1) {
215 desc += " \n[Exactly 1 of the following options is required]";
216 } else {
217 desc += " \n[Exactly " + std::to_string(min_options) + " options from the following list are required]";
218 }
219 } else if (max_options > 0) {
220 if (min_options > 0) {
221 desc += " \n[Between " + std::to_string(min_options) + " and " + std::to_string(max_options) +
222 " of the follow options are required]";
223 } else {
224 desc += " \n[At most " + std::to_string(max_options) + " of the following options are allowed]";
225 }
226 } else if (min_options > 0) {
227 desc += " \n[At least " + std::to_string(min_options) + " of the following options are required]";
228 }
229 return (!desc.empty()) ? desc + "\n" : std::string{};
230 }

Referenced by make_expanded().

Here is the caller graph for this function:

◆ make_expanded()

CLI11_INLINE std::string CLI::HelpFormatter::make_expanded ( const App * sub,
AppFormatMode mode ) const
overrideprivate

Definition at line 398 of file Formatter.cpp.

398 {
399 std::stringstream out;
400 // ########## Next lines changed
401 const Option* disabledOpt = sub->get_option_no_throw("--disabled");
402 out << sub->get_display_name(true) + " [OPTIONS]" + (!sub->get_subcommands({}).empty() ? " [SECTIONS]" : "") +
403 ((disabledOpt != nullptr ? disabledOpt->as<bool>() : false) ? " " + get_label("DISABLED")
404 : (sub->get_required() ? " " + get_label("REQUIRED") : ""))
405 << "\n";
406
407 detail::streamOutAsParagraph(out, make_description(sub), description_paragraph_width_, ""); // Format description as paragraph
408
409 if (sub->get_name().empty() && !sub->get_aliases().empty()) {
410 detail::format_aliases(out, sub->get_aliases(), column_width_ + 2);
411 }
412 out << make_positionals(sub);
413 out << make_groups(sub, mode);
414 out << make_subcommands(sub, mode);
415
416 // Drop blank spaces
417 std::string tmp = out.str();
418 tmp.pop_back();
419
420 // Indent all but the first line (the name)
421 return detail::find_and_replace(tmp, "\n", "\n ") + "\n";
422 }
std::string make_description(const App *app) const override
std::string make_subcommands(const App *app, AppFormatMode mode) const override

References make_description(), and make_subcommands().

Referenced by make_subcommands().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_footer()

CLI11_INLINE std::string CLI::HelpFormatter::make_footer ( const App * app) const
overrideprivate

Definition at line 294 of file Formatter.cpp.

294 {
295 const std::string footer = app->get_footer();
296 if (footer.empty()) {
297 return std::string{"\n"};
298 }
299 return '\n' + footer + "\n\n";
300 }

◆ make_group()

CLI11_INLINE std::string CLI::HelpFormatter::make_group ( std::string group,
bool is_positional,
std::vector< const Option * > opts ) const
overrideprivate

Definition at line 196 of file Formatter.cpp.

196 {
197 std::stringstream out;
198
199 // ############## Next line changed
200 out << "\n" << group << ":\n";
201 for (const Option* opt : opts) {
202 out << make_option(opt, is_positional);
203 }
204
205 return out.str();
206 }

◆ make_option_opts()

CLI11_INLINE std::string CLI::HelpFormatter::make_option_opts ( const Option * opt) const
overrideprivate

Definition at line 424 of file Formatter.cpp.

424 {
425 std::stringstream out;
426
427 if (!opt->get_option_text().empty()) {
428 out << " " << opt->get_option_text();
429 } else {
430 if (opt->get_type_size() != 0) {
431 if (!opt->get_type_name().empty()) {
432 // ########## Next line changed
433 out << ((opt->get_items_expected_max() == 0) ? "=" : " ") << get_label(opt->get_type_name());
434 }
435 if (!opt->get_default_str().empty()) {
436 out << " [" << opt->get_default_str() << "]";
437 }
438 try {
439 if (opt->count() > 0 && opt->get_default_str() != opt->as<std::string>()) {
440 out << " {";
441 std::string completeResult;
442 for (const auto& result : opt->reduced_results()) {
443 completeResult += (!result.empty() ? result : "\"\"") + " ";
444 }
445 completeResult.pop_back();
446 out << completeResult << "}";
447 }
448 } catch (CLI::ParseError& e) {
449 out << " <[" << Color::Code::FG_RED << e.get_name() << Color::Code::FG_DEFAULT << "] " << e.what() << ">";
450 }
451 if (opt->get_expected_max() == detail::expected_max_vector_size) {
452 out << " ... ";
453 } else if (opt->get_expected_min() > 1) {
454 out << " x " << opt->get_expected();
455 }
456 if (opt->get_required() && !get_label("REQUIRED").empty()) {
457 out << " " << get_label("REQUIRED");
458 }
459 if (opt->get_configurable() && !get_label("PERSISTENT").empty()) {
460 out << " " << get_label("PERSISTENT");
461 }
462 }
463 if (!opt->get_envname().empty()) {
464 out << " (" << get_label("Env") << ":" << opt->get_envname() << ") ";
465 }
466 if (!opt->get_needs().empty()) {
467 out << " " << get_label("Needs") << ":";
468 for (const Option* op : opt->get_needs()) {
469 out << " " << op->get_name();
470 }
471 }
472 if (!opt->get_excludes().empty()) {
473 out << " " << get_label("Excludes") << ":";
474 for (const Option* op : opt->get_excludes()) {
475 out << " " << op->get_name();
476 }
477 }
478 }
479 return out.str();
480 }
@ FG_DEFAULT
Definition Logger.h:58

References Color::FG_DEFAULT, and Color::FG_RED.

◆ make_subcommand()

CLI11_INLINE std::string CLI::HelpFormatter::make_subcommand ( const App * sub) const
overrideprivate

Definition at line 378 of file Formatter.cpp.

378 {
379 std::stringstream out;
380 const std::string name = " " + sub->get_display_name(true) + (sub->get_required() ? " " + get_label("REQUIRED") : "");
381
382 out << std::setw(static_cast<int>(column_width_)) << std::left << name;
383 const std::string desc = sub->get_description();
384 if (!desc.empty()) {
385 bool skipFirstLinePrefix = true;
386 if (out.str().length() >= column_width_) {
387 out << '\n';
388 skipFirstLinePrefix = false;
389 }
390 detail::streamOutAsParagraph(out, desc, right_column_width_, std::string(column_width_, ' '), skipFirstLinePrefix);
391 }
392
393 out << '\n';
394
395 return out.str();
396 }

Referenced by make_subcommands().

Here is the caller graph for this function:

◆ make_subcommands()

CLI11_INLINE std::string CLI::HelpFormatter::make_subcommands ( const App * app,
AppFormatMode mode ) const
overrideprivate

Definition at line 302 of file Formatter.cpp.

302 {
303 std::stringstream out;
304
305 const std::vector<const App*> subcommands = app->get_subcommands([](const App* subc) {
306 if (subc->get_group() == "Instances") {
307 if (subc->get_option("--disabled")->as<bool>()) {
308 const_cast<CLI::App*>(subc)->group(subc->get_group() + " (disabled)");
309 }
310 }
311 return !subc->get_disabled() && !subc->get_name().empty();
312 });
313
314 // Make a list in alphabetic order of the groups seen
315 std::set<std::string> subcmd_groups_seen;
316 for (const App* com : subcommands) {
317 if (com->get_name().empty()) {
318 if (!com->get_group().empty()) {
319 out << make_expanded(com, mode);
320 }
321 continue;
322 }
323 std::string group_key = com->get_group();
324 if (!group_key.empty() &&
325 std::find_if(subcmd_groups_seen.begin(), subcmd_groups_seen.end(), [&group_key](const std::string& a) {
326 return detail::to_lower(a) == detail::to_lower(group_key);
327 }) == subcmd_groups_seen.end()) {
328 subcmd_groups_seen.insert(group_key);
329 }
330 }
331
332 // For each group, filter out and print subcommands
333 const Option* disabledOpt = app->get_option_no_throw("--disabled");
334 bool disabled = false;
335 if (disabledOpt != nullptr) {
336 disabled = disabledOpt->as<bool>();
337 }
338
339 if (!disabled) {
340 for (const std::string& group : subcmd_groups_seen) {
341 out << "\n" << group << ":\n";
342 const std::vector<const App*> subcommands_group = app->get_subcommands([&group](const App* sub_app) {
343 return detail::to_lower(sub_app->get_group()) == detail::to_lower(group) && !sub_app->get_disabled() &&
344 !sub_app->get_name().empty();
345 });
346 for (const App* new_com : subcommands_group) {
347 if (new_com->get_name().empty()) {
348 continue;
349 }
350 if (mode != AppFormatMode::All) {
351 out << make_subcommand(new_com);
352 } else {
353 out << new_com->help(disabledOpt != nullptr && (app->get_help_ptr()->as<std::string>() == "exact" ||
354 app->get_help_ptr()->as<std::string>() == "expanded")
355 ? new_com
356 : nullptr,
357 new_com->get_name(),
358 AppFormatMode::Sub);
359 out << "\n";
360 }
361 }
362 }
363 }
364
365 // ########## Next line(s) changed
366
367 std::string tmp = out.str();
368 if (mode == AppFormatMode::All && !tmp.empty()) {
369 tmp.pop_back();
370 }
371
372 out.str(tmp);
373 out.clear();
374
375 return out.str();
376 }
std::string make_subcommand(const App *sub) const override
std::string make_expanded(const App *sub, AppFormatMode mode) const override

References make_expanded(), and make_subcommand().

Referenced by make_expanded().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_usage()

CLI11_INLINE std::string CLI::HelpFormatter::make_usage ( const App * app,
std::string name ) const
overrideprivate

Definition at line 232 of file Formatter.cpp.

232 {
233 const std::string usage = app->get_usage();
234 if (!usage.empty()) {
235 return usage + "\n";
236 }
237
238 std::stringstream out;
239
240 out << get_label("Usage") << ":" << (name.empty() ? "" : " ") << name;
241
242 // Print an Options badge if any options exist
243 const std::vector<const Option*> non_pos_options = app->get_options([](const Option* opt) {
244 return opt->nonpositional();
245 });
246 if (!non_pos_options.empty()) {
247 out << " [" << get_label("OPTIONS") << "]";
248 }
249
250 // Positionals need to be listed here
251 std::vector<const Option*> positionals = app->get_options([](const Option* opt) {
252 return opt->get_positional();
253 });
254
255 // Print out positionals if any are left
256 if (!positionals.empty()) {
257 // Convert to help names
258 std::vector<std::string> positional_names(positionals.size());
259 std::transform(positionals.begin(), positionals.end(), positional_names.begin(), [this](const Option* opt) {
260 return make_option_usage(opt);
261 });
262
263 out << " " << detail::join(positional_names, " ");
264 }
265
266 // Add a marker if subcommands are expected or optional
267 if (!app->get_subcommands([](const App* subc) {
268 return !subc->get_disabled() && !subc->get_name().empty();
269 })
270 .empty()) {
271 // ############## Next line changed
272 out << " ["
273 << get_label(app->get_subcommands([](const CLI::App* subc) {
274 return ((!subc->get_disabled()) && (!subc->get_name().empty()) /*&& subc->get_required()*/);
275 }).size() <= 1
276 ? "SUBCOMMAND"
277 : "SUBCOMMANDS")
278 << " [--help]"
279 << "]";
280 }
281
282 const Option* disabledOpt = app->get_option_no_throw("--disabled");
283 if (disabledOpt != nullptr ? disabledOpt->as<bool>() : false) {
284 out << " " << get_label("DISABLED");
285 } else if (app->get_required()) {
286 out << " " << get_label("REQUIRED");
287 }
288
289 out << std::endl;
290
291 return out.str();
292 }

The documentation for this class was generated from the following files: