2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
37 * Implements gmx::CommandLineHelpModule.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
40 * \ingroup module_commandline
42 #include "gromacs/commandline/cmdlinehelpmodule.h"
47 #include <boost/scoped_ptr.hpp>
49 #include "gromacs/commandline/cmdlinehelpcontext.h"
50 #include "gromacs/commandline/cmdlinehelpwriter.h"
51 #include "gromacs/commandline/cmdlineparser.h"
52 #include "gromacs/commandline/shellcompletions.h"
53 #include "gromacs/onlinehelp/helpformat.h"
54 #include "gromacs/onlinehelp/helpmanager.h"
55 #include "gromacs/onlinehelp/helptopic.h"
56 #include "gromacs/onlinehelp/helpwritercontext.h"
57 #include "gromacs/options/basicoptions.h"
58 #include "gromacs/options/options.h"
59 #include "gromacs/utility/baseversion.h"
60 #include "gromacs/utility/exceptions.h"
61 #include "gromacs/utility/file.h"
62 #include "gromacs/utility/gmxassert.h"
63 #include "gromacs/utility/programcontext.h"
64 #include "gromacs/utility/stringutil.h"
71 class HelpExportInterface;
75 /********************************************************************
76 * CommandLineHelpModuleImpl declaration
79 class CommandLineHelpModuleImpl
82 CommandLineHelpModuleImpl(const ProgramContextInterface &programContext,
83 const std::string &binaryName,
84 const CommandLineModuleMap &modules,
85 const CommandLineModuleGroupList &groups);
87 void exportHelp(HelpExportInterface *exporter) const;
89 boost::scoped_ptr<RootHelpTopic> rootTopic_;
90 const ProgramContextInterface &programContext_;
91 std::string binaryName_;
92 const CommandLineModuleMap &modules_;
93 const CommandLineModuleGroupList &groups_;
95 CommandLineHelpContext *context_;
96 const CommandLineModuleInterface *moduleOverride_;
99 File *outputOverride_;
101 GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModuleImpl);
107 /********************************************************************
113 static const char name[];
114 static const char title[];
115 static const char *const text[];
118 // The first two are not used.
119 const char RootHelpText::name[] = "";
120 const char RootHelpText::title[] = "";
121 const char *const RootHelpText::text[] = { "" };
124 * Help topic that forms the root of the help tree for the help subcommand.
126 * \ingroup module_commandline
128 class RootHelpTopic : public CompositeHelpTopic<RootHelpText>
132 * Creates a root help topic.
136 explicit RootHelpTopic(const std::string &binaryName)
137 : binaryName_(binaryName)
141 virtual void writeHelp(const HelpWriterContext &context) const;
144 std::string binaryName_;
146 GMX_DISALLOW_COPY_AND_ASSIGN(RootHelpTopic);
149 void RootHelpTopic::writeHelp(const HelpWriterContext &context) const
151 if (context.outputFormat() != eHelpOutputFormat_Console)
153 // TODO: Implement once the situation with Redmine issue #969 is more
155 GMX_THROW(NotImplementedError(
156 "Root help is not implemented for this output format"));
159 CommandLineCommonOptionsHolder optionsHolder;
160 CommandLineHelpContext cmdlineContext(context);
161 optionsHolder.initOptions();
162 cmdlineContext.setModuleDisplayName(binaryName_);
163 // TODO: Add <command> [<args>] into the synopsis.
164 // TODO: Propagate the -hidden option here.
165 CommandLineHelpWriter(*optionsHolder.options())
166 .writeHelp(cmdlineContext);
168 // TODO: Consider printing a list of "core" commands. Would require someone
169 // to determine such a set...
170 writeSubTopicList(context,
171 "Additional help is available on the following topics:");
172 context.writeTextBlock(
173 "To access the help, use '[PROGRAM] help <topic>'.[BR]"
174 "For help on a command, use '[PROGRAM] help <command>'.");
177 /********************************************************************
182 * Help topic for listing the commands.
184 * \ingroup module_commandline
186 class CommandsHelpTopic : public HelpTopicInterface
190 * Creates a command list help topic.
192 * \param[in] helpModule Help module to get module information from.
196 explicit CommandsHelpTopic(const CommandLineHelpModuleImpl &helpModule)
197 : helpModule_(helpModule)
201 virtual const char *name() const { return "commands"; }
202 virtual const char *title() const { return "List of available commands"; }
203 virtual bool hasSubTopics() const { return false; }
204 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
209 virtual void writeHelp(const HelpWriterContext &context) const;
212 const CommandLineHelpModuleImpl &helpModule_;
214 GMX_DISALLOW_COPY_AND_ASSIGN(CommandsHelpTopic);
217 void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const
219 if (context.outputFormat() != eHelpOutputFormat_Console)
221 GMX_THROW(NotImplementedError(
222 "Module list is not implemented for this output format"));
224 int maxNameLength = 0;
225 const CommandLineModuleMap &modules = helpModule_.modules_;
226 CommandLineModuleMap::const_iterator module;
227 for (module = modules.begin(); module != modules.end(); ++module)
229 int nameLength = static_cast<int>(module->first.length());
230 if (module->second->shortDescription() != NULL
231 && nameLength > maxNameLength)
233 maxNameLength = nameLength;
236 context.writeTextBlock(
237 "Usage: [PROGRAM] [<options>] <command> [<args>][PAR]"
238 "Available commands:");
239 File &file = context.outputFile();
240 TextTableFormatter formatter;
241 formatter.addColumn(NULL, maxNameLength + 1, false);
242 formatter.addColumn(NULL, 72 - maxNameLength, true);
243 formatter.setFirstColumnIndent(4);
244 for (module = modules.begin(); module != modules.end(); ++module)
246 const char *name = module->first.c_str();
247 const char *description = module->second->shortDescription();
248 if (description != NULL)
251 formatter.addColumnLine(0, name);
252 formatter.addColumnLine(1, description);
253 file.writeString(formatter.formatRow());
256 context.writeTextBlock(
257 "For help on a command, use '[PROGRAM] help <command>'.");
260 /********************************************************************
265 * Help topic wrapper for a command-line module.
267 * This class implements HelpTopicInterface such that it wraps a
268 * CommandLineModuleInterface, allowing subcommand "help <command>"
269 * to produce the help for "<command>".
271 * \ingroup module_commandline
273 class ModuleHelpTopic : public HelpTopicInterface
276 //! Constructs a help topic for a specific module.
277 ModuleHelpTopic(const CommandLineModuleInterface &module,
278 const CommandLineHelpModuleImpl &helpModule)
279 : module_(module), helpModule_(helpModule)
283 virtual const char *name() const { return module_.name(); }
284 virtual const char *title() const { return NULL; }
285 virtual bool hasSubTopics() const { return false; }
286 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
290 virtual void writeHelp(const HelpWriterContext &context) const;
293 const CommandLineModuleInterface &module_;
294 const CommandLineHelpModuleImpl &helpModule_;
296 GMX_DISALLOW_COPY_AND_ASSIGN(ModuleHelpTopic);
299 void ModuleHelpTopic::writeHelp(const HelpWriterContext & /*context*/) const
301 CommandLineHelpContext context(*helpModule_.context_);
302 const char *const program = helpModule_.binaryName_.c_str();
303 context.setModuleDisplayName(formatString("%s %s", program, module_.name()));
304 module_.writeHelp(context);
307 /********************************************************************
308 * HelpExportInterface
312 * Callbacks for exporting help information for command-line modules.
314 * \ingroup module_commandline
316 class HelpExportInterface
319 //! Shorthand for a list of modules contained in a group.
320 typedef CommandLineModuleGroupData::ModuleList ModuleGroupContents;
322 virtual ~HelpExportInterface() {};
325 * Called once before exporting individual modules.
327 * Can, e.g., open shared output files (e.g., if the output is written
328 * into a single file, or if a separate index is required) and write
331 virtual void startModuleExport() = 0;
333 * Called to export the help for each module.
335 * \param[in] module Module for which the help should be exported.
336 * \param[in] tag Unique tag for the module (gmx-something).
337 * \param[in] displayName Display name for the module (gmx something).
339 virtual void exportModuleHelp(
340 const CommandLineModuleInterface &module,
341 const std::string &tag,
342 const std::string &displayName) = 0;
344 * Called after all modules have been exported.
346 * Can close files opened in startModuleExport(), write footers to them
349 virtual void finishModuleExport() = 0;
352 * Called once before exporting module groups.
354 * Can, e.g., open a single output file for listing all the groups.
356 virtual void startModuleGroupExport() = 0;
358 * Called to export the help for each module group.
360 * \param[in] title Title for the group.
361 * \param[in] modules List of modules in the group.
363 virtual void exportModuleGroup(const char *title,
364 const ModuleGroupContents &modules) = 0;
366 * Called after all module groups have been exported.
368 * Can close files opened in startModuleGroupExport(), write footers to them
371 virtual void finishModuleGroupExport() = 0;
375 * Adds hyperlinks to modules within this binary.
377 * \param[in,out] links Links are added here.
378 * \param[in] helpModule Help module to get module information from.
379 * \throws std::bad_alloc if out of memory.
381 * Initializes a HelpLinks object with links to modules defined in
384 * \ingroup module_commandline
386 void initProgramLinks(HelpLinks *links, const CommandLineHelpModuleImpl &helpModule)
388 const char *const program = helpModule.binaryName_.c_str();
389 CommandLineModuleMap::const_iterator module;
390 for (module = helpModule.modules_.begin();
391 module != helpModule.modules_.end();
394 if (module->second->shortDescription() != NULL)
396 std::string linkName("[gmx-" + module->first + "]");
397 std::string targetName(
398 formatString("%s-%s", program, module->first.c_str()));
399 std::string displayName(
400 formatString("[TT]%s %s[tt]", program, module->first.c_str()));
401 links->addLink(linkName, targetName, displayName);
406 /********************************************************************
411 * Implements export for man pages.
413 * \ingroup module_commandline
415 class HelpExportMan : public HelpExportInterface
418 //! Initializes man page exporter.
419 explicit HelpExportMan(const CommandLineHelpModuleImpl &helpModule)
420 : links_(eHelpOutputFormat_Man)
422 initProgramLinks(&links_, helpModule);
425 virtual void startModuleExport() {}
426 virtual void exportModuleHelp(
427 const CommandLineModuleInterface &module,
428 const std::string &tag,
429 const std::string &displayName);
430 virtual void finishModuleExport() {}
432 virtual void startModuleGroupExport();
433 virtual void exportModuleGroup(const char *title,
434 const ModuleGroupContents &modules);
435 virtual void finishModuleGroupExport();
439 boost::scoped_ptr<File> man7File_;
440 std::string man7Footer_;
443 void HelpExportMan::exportModuleHelp(
444 const CommandLineModuleInterface &module,
445 const std::string &tag,
446 const std::string &displayName)
448 File file("man1/" + tag + ".1", "w");
450 // TODO: It would be nice to remove the VERSION prefix from the version
451 // string to make it shorter.
452 file.writeLine(formatString(".TH %s 1 \"\" \"%s\" \"GROMACS Manual\"\n",
453 tag.c_str(), gmx_version()));
454 file.writeLine(".SH NAME");
455 file.writeLine(formatString("%s - %s", tag.c_str(),
456 module.shortDescription()));
459 CommandLineHelpContext context(&file, eHelpOutputFormat_Man, &links_);
460 context.setModuleDisplayName(displayName);
461 module.writeHelp(context);
463 file.writeLine(".SH SEE ALSO");
464 file.writeLine(".BR gromacs(7)");
466 file.writeLine("More information about \\fBGROMACS\\fR is available at <\\fIhttp://www.gromacs.org/\\fR>.");
469 void HelpExportMan::startModuleGroupExport()
471 const char *const programListPlaceholder = "@PROGMANPAGES@";
473 const std::string man7Template = gmx::File::readToString("man7/gromacs.7.in");
474 const size_t index = man7Template.find(programListPlaceholder);
475 GMX_RELEASE_ASSERT(index != std::string::npos,
476 "gromacs.7.in must contain a @PROGMANPAGES@ line");
477 std::string header = man7Template.substr(0, index);
478 man7Footer_ = man7Template.substr(index + std::strlen(programListPlaceholder));
479 header = replaceAll(header, "@VERSION@", gmx_version());
480 man7File_.reset(new File("man7/gromacs.7", "w"));
481 man7File_->writeLine(header);
484 void HelpExportMan::exportModuleGroup(const char *title,
485 const ModuleGroupContents &modules)
487 man7File_->writeLine(formatString(".Sh \"%s\"", title));
488 man7File_->writeLine(formatString(".IX Subsection \"%s\"", title));
489 man7File_->writeLine(".Vb");
490 man7File_->writeLine(".ta 16n");
492 ModuleGroupContents::const_iterator module;
493 for (module = modules.begin(); module != modules.end(); ++module)
495 const std::string &tag(module->first);
496 man7File_->writeLine(formatString("\\& %s\t%s",
497 tag.c_str(), module->second));
500 man7File_->writeLine(".Ve");
503 void HelpExportMan::finishModuleGroupExport()
505 man7File_->writeLine(man7Footer_);
509 /********************************************************************
514 * Implements export for HTML help.
516 * \ingroup module_commandline
518 class HelpExportHtml : public HelpExportInterface
521 //! Initializes HTML exporter.
522 explicit HelpExportHtml(const CommandLineHelpModuleImpl &helpModule);
524 virtual void startModuleExport();
525 virtual void exportModuleHelp(
526 const CommandLineModuleInterface &module,
527 const std::string &tag,
528 const std::string &displayName);
529 virtual void finishModuleExport();
531 virtual void startModuleGroupExport();
532 virtual void exportModuleGroup(const char *title,
533 const ModuleGroupContents &modules);
534 virtual void finishModuleGroupExport();
537 void setupHeaderAndFooter();
539 void writeHtmlHeader(File *file, const std::string &title) const;
540 void writeHtmlFooter(File *file) const;
543 boost::scoped_ptr<File> indexFile_;
548 HelpExportHtml::HelpExportHtml(const CommandLineHelpModuleImpl &helpModule)
549 : links_(eHelpOutputFormat_Html)
551 File linksFile("links.dat", "r");
553 while (linksFile.readLine(&line))
555 links_.addLink(line, "../online/" + line, line);
558 initProgramLinks(&links_, helpModule);
559 setupHeaderAndFooter();
562 void HelpExportHtml::setupHeaderAndFooter()
564 header_ = gmx::File::readToString("header.html.in");
565 header_ = replaceAll(header_, "@VERSION@", gmx_version());
566 gmx::File::writeFileFromString("header.html", header_);
567 header_ = replaceAll(header_, "@ROOTPATH@", "../");
568 footer_ = gmx::File::readToString("footer.html");
571 void HelpExportHtml::startModuleExport()
573 indexFile_.reset(new File("final/programs/byname.html", "w"));
574 writeHtmlHeader(indexFile_.get(), "GROMACS Programs by Name");
575 indexFile_->writeLine("<H3>GROMACS Programs Alphabetically</H3>");
578 void HelpExportHtml::exportModuleHelp(
579 const CommandLineModuleInterface &module,
580 const std::string &tag,
581 const std::string &displayName)
583 File file("final/programs/" + tag + ".html", "w");
584 writeHtmlHeader(&file, displayName);
586 CommandLineHelpContext context(&file, eHelpOutputFormat_Html, &links_);
587 context.setModuleDisplayName(displayName);
588 module.writeHelp(context);
590 writeHtmlFooter(&file);
593 indexFile_->writeLine(formatString("<a href=\"%s.html\">%s</a> - %s<br>",
594 tag.c_str(), displayName.c_str(),
595 module.shortDescription()));
598 void HelpExportHtml::finishModuleExport()
600 writeHtmlFooter(indexFile_.get());
604 void HelpExportHtml::startModuleGroupExport()
606 indexFile_.reset(new File("final/programs/bytopic.html", "w"));
607 writeHtmlHeader(indexFile_.get(), "GROMACS Programs by Topic");
608 indexFile_->writeLine("<H3>GROMACS Programs by Topic</H3>");
611 void HelpExportHtml::exportModuleGroup(const char *title,
612 const ModuleGroupContents &modules)
614 indexFile_->writeLine(formatString("<H4>%s</H4>", title));
616 ModuleGroupContents::const_iterator module;
617 for (module = modules.begin(); module != modules.end(); ++module)
619 const std::string &tag(module->first);
620 std::string displayName(tag);
621 // TODO: This does not work if the binary name would contain a dash,
622 // but that is not currently the case.
623 size_t dashPos = displayName.find('-');
624 GMX_RELEASE_ASSERT(dashPos != std::string::npos,
625 "There should always be at least one dash in the tag");
626 displayName[dashPos] = ' ';
627 indexFile_->writeLine(formatString("<a href=\"%s.html\">%s</a> - %s<br>",
628 tag.c_str(), displayName.c_str(),
633 void HelpExportHtml::finishModuleGroupExport()
635 writeHtmlFooter(indexFile_.get());
639 void HelpExportHtml::writeHtmlHeader(File *file, const std::string &title) const
641 file->writeLine(replaceAll(header_, "@TITLE@", title));
644 void HelpExportHtml::writeHtmlFooter(File *file) const
646 file->writeLine(footer_);
649 /********************************************************************
650 * HelpExportCompletion
654 * Implements export for command-line completion.
656 * \ingroup module_commandline
658 class HelpExportCompletion : public HelpExportInterface
661 //! Initializes completion exporter.
662 explicit HelpExportCompletion(const CommandLineHelpModuleImpl &helpModule);
664 virtual void startModuleExport();
665 virtual void exportModuleHelp(
666 const CommandLineModuleInterface &module,
667 const std::string &tag,
668 const std::string &displayName);
669 virtual void finishModuleExport();
671 virtual void startModuleGroupExport() {}
672 virtual void exportModuleGroup(const char * /*title*/,
673 const ModuleGroupContents & /*modules*/) {}
674 virtual void finishModuleGroupExport() {}
677 ShellCompletionWriter bashWriter_;
678 std::vector<std::string> modules_;
681 HelpExportCompletion::HelpExportCompletion(
682 const CommandLineHelpModuleImpl &helpModule)
683 : bashWriter_(helpModule.binaryName_, eShellCompletionFormat_Bash)
687 void HelpExportCompletion::startModuleExport()
689 bashWriter_.startCompletions();
692 void HelpExportCompletion::exportModuleHelp(
693 const CommandLineModuleInterface &module,
694 const std::string & /*tag*/,
695 const std::string & /*displayName*/)
697 modules_.push_back(module.name());
699 CommandLineHelpContext context(&bashWriter_);
700 // We use the display name to pass the name of the module to the
701 // completion writer.
702 context.setModuleDisplayName(module.name());
703 module.writeHelp(context);
707 void HelpExportCompletion::finishModuleExport()
709 CommandLineCommonOptionsHolder optionsHolder;
710 optionsHolder.initOptions();
711 bashWriter_.writeWrapperCompletions(modules_, *optionsHolder.options());
712 bashWriter_.finishCompletions();
717 /********************************************************************
718 * CommandLineHelpModuleImpl implementation
720 CommandLineHelpModuleImpl::CommandLineHelpModuleImpl(
721 const ProgramContextInterface &programContext,
722 const std::string &binaryName,
723 const CommandLineModuleMap &modules,
724 const CommandLineModuleGroupList &groups)
725 : rootTopic_(new RootHelpTopic(binaryName)), programContext_(programContext),
726 binaryName_(binaryName), modules_(modules), groups_(groups),
727 context_(NULL), moduleOverride_(NULL), bHidden_(false),
728 outputOverride_(NULL)
732 void CommandLineHelpModuleImpl::exportHelp(HelpExportInterface *exporter) const
734 // TODO: Would be nicer to have the file names supplied by the build system
735 // and/or export a list of files from here.
736 const char *const program = binaryName_.c_str();
738 exporter->startModuleExport();
739 CommandLineModuleMap::const_iterator module;
740 for (module = modules_.begin(); module != modules_.end(); ++module)
742 if (module->second->shortDescription() != NULL)
744 const char *const moduleName = module->first.c_str();
745 std::string tag(formatString("%s-%s", program, moduleName));
746 std::string displayName(formatString("%s %s", program, moduleName));
747 exporter->exportModuleHelp(*module->second, tag, displayName);
750 exporter->finishModuleExport();
752 exporter->startModuleGroupExport();
753 CommandLineModuleGroupList::const_iterator group;
754 for (group = groups_.begin(); group != groups_.end(); ++group)
756 exporter->exportModuleGroup((*group)->title(), (*group)->modules());
758 exporter->finishModuleGroupExport();
761 /********************************************************************
762 * CommandLineHelpModule
765 CommandLineHelpModule::CommandLineHelpModule(
766 const ProgramContextInterface &programContext,
767 const std::string &binaryName,
768 const CommandLineModuleMap &modules,
769 const CommandLineModuleGroupList &groups)
770 : impl_(new Impl(programContext, binaryName, modules, groups))
774 CommandLineHelpModule::~CommandLineHelpModule()
778 HelpTopicPointer CommandLineHelpModule::createModuleHelpTopic(
779 const CommandLineModuleInterface &module) const
781 return HelpTopicPointer(new ModuleHelpTopic(module, *impl_));
784 void CommandLineHelpModule::addTopic(HelpTopicPointer topic)
786 impl_->rootTopic_->addSubTopic(move(topic));
789 void CommandLineHelpModule::setShowHidden(bool bHidden)
791 impl_->bHidden_ = bHidden;
794 void CommandLineHelpModule::setModuleOverride(
795 const CommandLineModuleInterface &module)
797 impl_->moduleOverride_ = &module;
800 void CommandLineHelpModule::setOutputRedirect(File *output)
802 impl_->outputOverride_ = output;
805 int CommandLineHelpModule::run(int argc, char *argv[])
807 // Add internal topics lazily here.
808 addTopic(HelpTopicPointer(new CommandsHelpTopic(*impl_)));
810 const char *const exportFormats[] = { "man", "html", "completion" };
811 std::string exportFormat;
812 Options options(NULL, NULL);
813 options.addOption(StringOption("export").store(&exportFormat)
814 .enumValue(exportFormats));
815 CommandLineParser(&options).parse(&argc, argv);
816 if (!exportFormat.empty())
818 boost::scoped_ptr<HelpExportInterface> exporter;
819 if (exportFormat == "man")
821 exporter.reset(new HelpExportMan(*impl_));
823 else if (exportFormat == "html")
825 exporter.reset(new HelpExportHtml(*impl_));
827 else if (exportFormat == "completion")
829 exporter.reset(new HelpExportCompletion(*impl_));
833 GMX_THROW(NotImplementedError("This help format is not implemented"));
835 impl_->exportHelp(exporter.get());
839 File *outputFile = &File::standardOutput();
840 if (impl_->outputOverride_ != NULL)
842 outputFile = impl_->outputOverride_;
844 HelpLinks links(eHelpOutputFormat_Console);
845 initProgramLinks(&links, *impl_);
846 boost::scoped_ptr<CommandLineHelpContext> context(
847 new CommandLineHelpContext(outputFile,
848 eHelpOutputFormat_Console, &links));
849 context->setShowHidden(impl_->bHidden_);
850 if (impl_->moduleOverride_ != NULL)
852 context->setModuleDisplayName(impl_->programContext_.displayName());
853 impl_->moduleOverride_->writeHelp(*context);
856 impl_->context_ = context.get();
858 HelpManager helpManager(*impl_->rootTopic_, context->writerContext());
861 for (int i = 1; i < argc; ++i)
863 helpManager.enterTopic(argv[i]);
866 catch (const InvalidInputError &ex)
868 fprintf(stderr, "%s\n", ex.what());
871 helpManager.writeCurrentTopic();
875 void CommandLineHelpModule::writeHelp(const CommandLineHelpContext &context) const
877 const HelpWriterContext &writerContext = context.writerContext();
879 if (writerContext.outputFormat() != eHelpOutputFormat_Console)
883 writerContext.writeTextBlock(
884 "Usage: [PROGRAM] help [<command>|<topic> [<subtopic> [...]]]");
885 // TODO: More information.