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 ( )

Definition at line 193 of file Formatter.cpp.

193 {
194 label("SUBCOMMAND", "SECTION");
195 label("SUBCOMMANDS", "SECTIONS");
196 label("PERSISTENT", "");
197 label("Persistent Options", "Options (persistent)");
198 label("Nonpersistent Options", "Options (nonpersistent)");
199 label("Usage", "\nUsage");
200 label("BOOL:{true,false}", "{true,false}");
201 label("bool:{true,false}", "{true,false}");
202 label("TRISTAT:{true,false,default}", "{true,false,default}");
203 label("MODE:{standard,active,complete,required}", "{standard,active,complete,required}");
204 label("MODE:{standard,exact,expanded}", "{standard,exact,expanded}");
205 label("MODE:{standard,exact}", "{standard,exact}");
206
207 column_width(7);
208 }

◆ ~HelpFormatter()

CLI::HelpFormatter::~HelpFormatter ( )
override

Definition at line 210 of file Formatter.cpp.

210 {
211 }

Member Function Documentation

◆ make_description()

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

Definition at line 225 of file Formatter.cpp.

225 {
226 std::string desc = app->get_description();
227 auto min_options = app->get_require_option_min();
228 auto max_options = app->get_require_option_max();
229 // ############## Next line changed (if statement removed)
230 if ((max_options == min_options) && (min_options > 0)) {
231 if (min_options == 1) {
232 desc += " \n[Exactly 1 of the following options is required]";
233 } else {
234 desc += " \n[Exactly " + std::to_string(min_options) + " options from the following list are required]";
235 }
236 } else if (max_options > 0) {
237 if (min_options > 0) {
238 desc += " \n[Between " + std::to_string(min_options) + " and " + std::to_string(max_options) +
239 " of the follow options are required]";
240 } else {
241 desc += " \n[At most " + std::to_string(max_options) + " of the following options are allowed]";
242 }
243 } else if (min_options > 0) {
244 desc += " \n[At least " + std::to_string(min_options) + " of the following options are required]";
245 }
246 return (!desc.empty()) ? desc + "\n" : std::string{};
247 }

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 415 of file Formatter.cpp.

415 {
416 std::stringstream out;
417 // ########## Next lines changed
418 const Option* disabledOpt = sub->get_option_no_throw("--disabled");
419 out << sub->get_display_name(true) + " [OPTIONS]" + (!sub->get_subcommands({}).empty() ? " [SECTIONS]" : "") +
420 ((disabledOpt != nullptr ? disabledOpt->as<bool>() : false) ? " " + get_label("DISABLED")
421 : (sub->get_required() ? " " + get_label("REQUIRED") : ""))
422 << "\n";
423
424 detail::streamOutAsParagraph(out, make_description(sub), description_paragraph_width_, ""); // Format description as paragraph
425
426 if (sub->get_name().empty() && !sub->get_aliases().empty()) {
427 detail::format_aliases(out, sub->get_aliases(), column_width_ + 2);
428 }
429 out << make_positionals(sub);
430 out << make_groups(sub, mode);
431 out << make_subcommands(sub, mode);
432
433 // Drop blank spaces
434 std::string tmp = out.str();
435 tmp.pop_back();
436
437 // Indent all but the first line (the name)
438 return detail::find_and_replace(tmp, "\n", "\n ") + "\n";
439 }
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 311 of file Formatter.cpp.

311 {
312 const std::string footer = app->get_footer();
313 if (footer.empty()) {
314 return std::string{"\n"};
315 }
316 return '\n' + footer + "\n\n";
317 }

◆ 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 213 of file Formatter.cpp.

213 {
214 std::stringstream out;
215
216 // ############## Next line changed
217 out << "\n" << group << ":\n";
218 for (const Option* opt : opts) {
219 out << make_option(opt, is_positional);
220 }
221
222 return out.str();
223 }

◆ make_option_opts()

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

Definition at line 441 of file Formatter.cpp.

441 {
442 std::stringstream out;
443
444 if (!opt->get_option_text().empty()) {
445 out << " " << opt->get_option_text();
446 } else {
447 if (opt->get_type_size() != 0) {
448 if (!opt->get_type_name().empty()) {
449 // ########## Next line changed
450 out << ((opt->get_items_expected_max() == 0) ? "=" : " ") << get_label(opt->get_type_name());
451 }
452 if (!opt->get_default_str().empty()) {
453 out << " [" << opt->get_default_str() << "]";
454 }
455 try {
456 if (opt->count() > 0 && opt->get_default_str() != opt->as<std::string>()) {
457 out << " {";
458 std::string completeResult;
459 for (const auto& result : opt->reduced_results()) {
460 completeResult += (!result.empty() ? result : "\"\"") + " ";
461 }
462 completeResult.pop_back();
463 out << completeResult << "}";
464 }
465 } catch (CLI::ParseError& e) {
466 out << " <[" << Color::Code::FG_RED << e.get_name() << Color::Code::FG_DEFAULT << "] " << e.what() << ">";
467 }
468 if (opt->get_expected_max() == detail::expected_max_vector_size) {
469 out << " ... ";
470 } else if (opt->get_expected_min() > 1) {
471 out << " x " << opt->get_expected();
472 }
473 if (opt->get_required() && !get_label("REQUIRED").empty()) {
474 out << " " << get_label("REQUIRED");
475 }
476 if (opt->get_configurable() && !get_label("PERSISTENT").empty()) {
477 out << " " << get_label("PERSISTENT");
478 }
479 }
480 if (!opt->get_envname().empty()) {
481 out << " (" << get_label("Env") << ":" << opt->get_envname() << ") ";
482 }
483 if (!opt->get_needs().empty()) {
484 out << " " << get_label("Needs") << ":";
485 for (const Option* op : opt->get_needs()) {
486 out << " " << op->get_name();
487 }
488 }
489 if (!opt->get_excludes().empty()) {
490 out << " " << get_label("Excludes") << ":";
491 for (const Option* op : opt->get_excludes()) {
492 out << " " << op->get_name();
493 }
494 }
495 }
496 return out.str();
497 }
@ 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 395 of file Formatter.cpp.

395 {
396 std::stringstream out;
397 const std::string name = " " + sub->get_display_name(true) + (sub->get_required() ? " " + get_label("REQUIRED") : "");
398
399 out << std::setw(static_cast<int>(column_width_)) << std::left << name;
400 const std::string desc = sub->get_description();
401 if (!desc.empty()) {
402 bool skipFirstLinePrefix = true;
403 if (out.str().length() >= column_width_) {
404 out << '\n';
405 skipFirstLinePrefix = false;
406 }
407 detail::streamOutAsParagraph(out, desc, right_column_width_, std::string(column_width_, ' '), skipFirstLinePrefix);
408 }
409
410 out << '\n';
411
412 return out.str();
413 }

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 319 of file Formatter.cpp.

319 {
320 std::stringstream out;
321
322 const std::vector<const App*> subcommands = app->get_subcommands([](const App* subc) {
323 if (subc->get_group() == "Instances") {
324 if (subc->get_option("--disabled")->as<bool>()) {
325 const_cast<CLI::App*>(subc)->group(subc->get_group() + " (disabled)");
326 }
327 }
328 return !subc->get_disabled() && !subc->get_name().empty();
329 });
330
331 // Make a list in alphabetic order of the groups seen
332 std::set<std::string> subcmd_groups_seen;
333 for (const App* com : subcommands) {
334 if (com->get_name().empty()) {
335 if (!com->get_group().empty()) {
336 out << make_expanded(com, mode);
337 }
338 continue;
339 }
340 std::string group_key = com->get_group();
341 if (!group_key.empty() &&
342 std::find_if(subcmd_groups_seen.begin(), subcmd_groups_seen.end(), [&group_key](const std::string& a) {
343 return detail::to_lower(a) == detail::to_lower(group_key);
344 }) == subcmd_groups_seen.end()) {
345 subcmd_groups_seen.insert(group_key);
346 }
347 }
348
349 // For each group, filter out and print subcommands
350 const Option* disabledOpt = app->get_option_no_throw("--disabled");
351 bool disabled = false;
352 if (disabledOpt != nullptr) {
353 disabled = disabledOpt->as<bool>();
354 }
355
356 if (!disabled) {
357 for (const std::string& group : subcmd_groups_seen) {
358 out << "\n" << group << ":\n";
359 const std::vector<const App*> subcommands_group = app->get_subcommands([&group](const App* sub_app) {
360 return detail::to_lower(sub_app->get_group()) == detail::to_lower(group) && !sub_app->get_disabled() &&
361 !sub_app->get_name().empty();
362 });
363 for (const App* new_com : subcommands_group) {
364 if (new_com->get_name().empty()) {
365 continue;
366 }
367 if (mode != AppFormatMode::All) {
368 out << make_subcommand(new_com);
369 } else {
370 out << new_com->help(disabledOpt != nullptr && (app->get_help_ptr()->as<std::string>() == "exact" ||
371 app->get_help_ptr()->as<std::string>() == "expanded")
372 ? new_com
373 : nullptr,
374 new_com->get_name(),
375 AppFormatMode::Sub);
376 out << "\n";
377 }
378 }
379 }
380 }
381
382 // ########## Next line(s) changed
383
384 std::string tmp = out.str();
385 if (mode == AppFormatMode::All && !tmp.empty()) {
386 tmp.pop_back();
387 }
388
389 out.str(tmp);
390 out.clear();
391
392 return out.str();
393 }
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 249 of file Formatter.cpp.

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

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