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 CommandLineHelpModuleImpl &helpModule)
137 : helpModule_(helpModule)
141 virtual void writeHelp(const HelpWriterContext &context) const;
144 const CommandLineHelpModuleImpl &helpModule_;
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(*helpModule_.context_);
161 cmdlineContext.setModuleDisplayName(helpModule_.binaryName_);
162 optionsHolder.initOptions();
163 // TODO: Add <command> [<args>] into the synopsis.
164 CommandLineHelpWriter(*optionsHolder.options())
165 .writeHelp(cmdlineContext);
167 // TODO: Consider printing a list of "core" commands. Would require someone
168 // to determine such a set...
169 writeSubTopicList(context,
170 "Additional help is available on the following topics:");
171 context.writeTextBlock(
172 "To access the help, use '[PROGRAM] help <topic>'.[BR]"
173 "For help on a command, use '[PROGRAM] help <command>'.");
176 /********************************************************************
181 * Help topic for listing the commands.
183 * \ingroup module_commandline
185 class CommandsHelpTopic : public HelpTopicInterface
189 * Creates a command list help topic.
191 * \param[in] helpModule Help module to get module information from.
195 explicit CommandsHelpTopic(const CommandLineHelpModuleImpl &helpModule)
196 : helpModule_(helpModule)
200 virtual const char *name() const { return "commands"; }
201 virtual const char *title() const { return "List of available commands"; }
202 virtual bool hasSubTopics() const { return false; }
203 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
208 virtual void writeHelp(const HelpWriterContext &context) const;
211 const CommandLineHelpModuleImpl &helpModule_;
213 GMX_DISALLOW_COPY_AND_ASSIGN(CommandsHelpTopic);
216 void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const
218 if (context.outputFormat() != eHelpOutputFormat_Console)
220 GMX_THROW(NotImplementedError(
221 "Module list is not implemented for this output format"));
223 int maxNameLength = 0;
224 const CommandLineModuleMap &modules = helpModule_.modules_;
225 CommandLineModuleMap::const_iterator module;
226 for (module = modules.begin(); module != modules.end(); ++module)
228 int nameLength = static_cast<int>(module->first.length());
229 if (module->second->shortDescription() != NULL
230 && nameLength > maxNameLength)
232 maxNameLength = nameLength;
235 context.writeTextBlock(
236 "Usage: [PROGRAM] [<options>] <command> [<args>][PAR]"
237 "Available commands:");
238 File &file = context.outputFile();
239 TextTableFormatter formatter;
240 formatter.addColumn(NULL, maxNameLength + 1, false);
241 formatter.addColumn(NULL, 72 - maxNameLength, true);
242 formatter.setFirstColumnIndent(4);
243 for (module = modules.begin(); module != modules.end(); ++module)
245 const char *name = module->first.c_str();
246 const char *description = module->second->shortDescription();
247 if (description != NULL)
250 formatter.addColumnLine(0, name);
251 formatter.addColumnLine(1, description);
252 file.writeString(formatter.formatRow());
255 context.writeTextBlock(
256 "For help on a command, use '[PROGRAM] help <command>'.");
259 /********************************************************************
264 * Help topic wrapper for a command-line module.
266 * This class implements HelpTopicInterface such that it wraps a
267 * CommandLineModuleInterface, allowing subcommand "help <command>"
268 * to produce the help for "<command>".
270 * \ingroup module_commandline
272 class ModuleHelpTopic : public HelpTopicInterface
275 //! Constructs a help topic for a specific module.
276 ModuleHelpTopic(const CommandLineModuleInterface &module,
277 const CommandLineHelpModuleImpl &helpModule)
278 : module_(module), helpModule_(helpModule)
282 virtual const char *name() const { return module_.name(); }
283 virtual const char *title() const { return NULL; }
284 virtual bool hasSubTopics() const { return false; }
285 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
289 virtual void writeHelp(const HelpWriterContext &context) const;
292 const CommandLineModuleInterface &module_;
293 const CommandLineHelpModuleImpl &helpModule_;
295 GMX_DISALLOW_COPY_AND_ASSIGN(ModuleHelpTopic);
298 void ModuleHelpTopic::writeHelp(const HelpWriterContext & /*context*/) const
300 CommandLineHelpContext context(*helpModule_.context_);
301 const char *const program = helpModule_.binaryName_.c_str();
302 context.setModuleDisplayName(formatString("%s %s", program, module_.name()));
303 module_.writeHelp(context);
306 /********************************************************************
307 * HelpExportInterface
311 * Callbacks for exporting help information for command-line modules.
313 * \ingroup module_commandline
315 class HelpExportInterface
318 //! Shorthand for a list of modules contained in a group.
319 typedef CommandLineModuleGroupData::ModuleList ModuleGroupContents;
321 virtual ~HelpExportInterface() {};
324 * Called once before exporting individual modules.
326 * Can, e.g., open shared output files (e.g., if the output is written
327 * into a single file, or if a separate index is required) and write
330 virtual void startModuleExport() = 0;
332 * Called to export the help for each module.
334 * \param[in] module Module for which the help should be exported.
335 * \param[in] tag Unique tag for the module (gmx-something).
336 * \param[in] displayName Display name for the module (gmx something).
338 virtual void exportModuleHelp(
339 const CommandLineModuleInterface &module,
340 const std::string &tag,
341 const std::string &displayName) = 0;
343 * Called after all modules have been exported.
345 * Can close files opened in startModuleExport(), write footers to them
348 virtual void finishModuleExport() = 0;
351 * Called once before exporting module groups.
353 * Can, e.g., open a single output file for listing all the groups.
355 virtual void startModuleGroupExport() = 0;
357 * Called to export the help for each module group.
359 * \param[in] title Title for the group.
360 * \param[in] modules List of modules in the group.
362 virtual void exportModuleGroup(const char *title,
363 const ModuleGroupContents &modules) = 0;
365 * Called after all module groups have been exported.
367 * Can close files opened in startModuleGroupExport(), write footers to them
370 virtual void finishModuleGroupExport() = 0;
374 * Adds hyperlinks to modules within this binary.
376 * \param[in,out] links Links are added here.
377 * \param[in] helpModule Help module to get module information from.
378 * \throws std::bad_alloc if out of memory.
380 * Initializes a HelpLinks object with links to modules defined in
383 * \ingroup module_commandline
385 void initProgramLinks(HelpLinks *links, const CommandLineHelpModuleImpl &helpModule)
387 const char *const program = helpModule.binaryName_.c_str();
388 CommandLineModuleMap::const_iterator module;
389 for (module = helpModule.modules_.begin();
390 module != helpModule.modules_.end();
393 if (module->second->shortDescription() != NULL)
395 std::string linkName("[gmx-" + module->first + "]");
396 std::string targetName(
397 formatString("%s-%s", program, module->first.c_str()));
398 std::string displayName(
399 formatString("[TT]%s %s[tt]", program, module->first.c_str()));
400 links->addLink(linkName, targetName, displayName);
405 /********************************************************************
410 * Implements export for man pages.
412 * \ingroup module_commandline
414 class HelpExportMan : public HelpExportInterface
417 //! Initializes man page exporter.
418 explicit HelpExportMan(const CommandLineHelpModuleImpl &helpModule)
419 : links_(eHelpOutputFormat_Man)
421 initProgramLinks(&links_, helpModule);
424 virtual void startModuleExport() {}
425 virtual void exportModuleHelp(
426 const CommandLineModuleInterface &module,
427 const std::string &tag,
428 const std::string &displayName);
429 virtual void finishModuleExport() {}
431 virtual void startModuleGroupExport();
432 virtual void exportModuleGroup(const char *title,
433 const ModuleGroupContents &modules);
434 virtual void finishModuleGroupExport();
438 boost::scoped_ptr<File> man7File_;
439 std::string man7Footer_;
442 void HelpExportMan::exportModuleHelp(
443 const CommandLineModuleInterface &module,
444 const std::string &tag,
445 const std::string &displayName)
447 File file("man1/" + tag + ".1", "w");
449 // TODO: It would be nice to remove the VERSION prefix from the version
450 // string to make it shorter.
451 file.writeLine(formatString(".TH %s 1 \"\" \"%s\" \"GROMACS Manual\"\n",
452 tag.c_str(), gmx_version()));
453 file.writeLine(".SH NAME");
454 file.writeLine(formatString("%s - %s", tag.c_str(),
455 module.shortDescription()));
458 CommandLineHelpContext context(&file, eHelpOutputFormat_Man, &links_);
459 context.setModuleDisplayName(displayName);
460 module.writeHelp(context);
462 file.writeLine(".SH SEE ALSO");
463 file.writeLine(".BR gromacs(7)");
465 file.writeLine("More information about \\fBGROMACS\\fR is available at <\\fIhttp://www.gromacs.org/\\fR>.");
468 void HelpExportMan::startModuleGroupExport()
470 const char *const programListPlaceholder = "@PROGMANPAGES@";
472 const std::string man7Template = gmx::File::readToString("man7/gromacs.7.in");
473 const size_t index = man7Template.find(programListPlaceholder);
474 GMX_RELEASE_ASSERT(index != std::string::npos,
475 "gromacs.7.in must contain a @PROGMANPAGES@ line");
476 std::string header = man7Template.substr(0, index);
477 man7Footer_ = man7Template.substr(index + std::strlen(programListPlaceholder));
478 header = replaceAll(header, "@VERSION@", gmx_version());
479 man7File_.reset(new File("man7/gromacs.7", "w"));
480 man7File_->writeLine(header);
483 void HelpExportMan::exportModuleGroup(const char *title,
484 const ModuleGroupContents &modules)
486 man7File_->writeLine(formatString(".Sh \"%s\"", title));
487 man7File_->writeLine(formatString(".IX Subsection \"%s\"", title));
488 man7File_->writeLine(".Vb");
489 man7File_->writeLine(".ta 16n");
491 ModuleGroupContents::const_iterator module;
492 for (module = modules.begin(); module != modules.end(); ++module)
494 const std::string &tag(module->first);
495 man7File_->writeLine(formatString("\\& %s\t%s",
496 tag.c_str(), module->second));
499 man7File_->writeLine(".Ve");
502 void HelpExportMan::finishModuleGroupExport()
504 man7File_->writeLine(man7Footer_);
508 /********************************************************************
513 * Implements export for HTML help.
515 * \ingroup module_commandline
517 class HelpExportHtml : public HelpExportInterface
520 //! Initializes HTML exporter.
521 explicit HelpExportHtml(const CommandLineHelpModuleImpl &helpModule);
523 virtual void startModuleExport();
524 virtual void exportModuleHelp(
525 const CommandLineModuleInterface &module,
526 const std::string &tag,
527 const std::string &displayName);
528 virtual void finishModuleExport();
530 virtual void startModuleGroupExport();
531 virtual void exportModuleGroup(const char *title,
532 const ModuleGroupContents &modules);
533 virtual void finishModuleGroupExport();
536 void setupHeaderAndFooter();
538 void writeHtmlHeader(File *file, const std::string &title) const;
539 void writeHtmlFooter(File *file) const;
542 boost::scoped_ptr<File> indexFile_;
547 HelpExportHtml::HelpExportHtml(const CommandLineHelpModuleImpl &helpModule)
548 : links_(eHelpOutputFormat_Html)
550 File linksFile("links.dat", "r");
552 while (linksFile.readLine(&line))
554 links_.addLink(line, "../online/" + line, line);
557 initProgramLinks(&links_, helpModule);
558 setupHeaderAndFooter();
561 void HelpExportHtml::setupHeaderAndFooter()
563 header_ = gmx::File::readToString("header.html.in");
564 header_ = replaceAll(header_, "@VERSION@", gmx_version());
565 gmx::File::writeFileFromString("header.html", header_);
566 header_ = replaceAll(header_, "@ROOTPATH@", "../");
567 footer_ = gmx::File::readToString("footer.html");
570 void HelpExportHtml::startModuleExport()
572 indexFile_.reset(new File("final/programs/byname.html", "w"));
573 writeHtmlHeader(indexFile_.get(), "GROMACS Programs by Name");
574 indexFile_->writeLine("<H3>GROMACS Programs Alphabetically</H3>");
577 void HelpExportHtml::exportModuleHelp(
578 const CommandLineModuleInterface &module,
579 const std::string &tag,
580 const std::string &displayName)
582 File file("final/programs/" + tag + ".html", "w");
583 writeHtmlHeader(&file, displayName);
585 CommandLineHelpContext context(&file, eHelpOutputFormat_Html, &links_);
586 context.setModuleDisplayName(displayName);
587 module.writeHelp(context);
589 writeHtmlFooter(&file);
592 indexFile_->writeLine(formatString("<a href=\"%s.html\">%s</a> - %s<br>",
593 tag.c_str(), displayName.c_str(),
594 module.shortDescription()));
597 void HelpExportHtml::finishModuleExport()
599 writeHtmlFooter(indexFile_.get());
603 void HelpExportHtml::startModuleGroupExport()
605 indexFile_.reset(new File("final/programs/bytopic.html", "w"));
606 writeHtmlHeader(indexFile_.get(), "GROMACS Programs by Topic");
607 indexFile_->writeLine("<H3>GROMACS Programs by Topic</H3>");
610 void HelpExportHtml::exportModuleGroup(const char *title,
611 const ModuleGroupContents &modules)
613 indexFile_->writeLine(formatString("<H4>%s</H4>", title));
615 ModuleGroupContents::const_iterator module;
616 for (module = modules.begin(); module != modules.end(); ++module)
618 const std::string &tag(module->first);
619 std::string displayName(tag);
620 // TODO: This does not work if the binary name would contain a dash,
621 // but that is not currently the case.
622 size_t dashPos = displayName.find('-');
623 GMX_RELEASE_ASSERT(dashPos != std::string::npos,
624 "There should always be at least one dash in the tag");
625 displayName[dashPos] = ' ';
626 indexFile_->writeLine(formatString("<a href=\"%s.html\">%s</a> - %s<br>",
627 tag.c_str(), displayName.c_str(),
632 void HelpExportHtml::finishModuleGroupExport()
634 writeHtmlFooter(indexFile_.get());
638 void HelpExportHtml::writeHtmlHeader(File *file, const std::string &title) const
640 file->writeLine(replaceAll(header_, "@TITLE@", title));
643 void HelpExportHtml::writeHtmlFooter(File *file) const
645 file->writeLine(footer_);
648 /********************************************************************
649 * HelpExportCompletion
653 * Implements export for command-line completion.
655 * \ingroup module_commandline
657 class HelpExportCompletion : public HelpExportInterface
660 //! Initializes completion exporter.
661 explicit HelpExportCompletion(const CommandLineHelpModuleImpl &helpModule);
663 virtual void startModuleExport();
664 virtual void exportModuleHelp(
665 const CommandLineModuleInterface &module,
666 const std::string &tag,
667 const std::string &displayName);
668 virtual void finishModuleExport();
670 virtual void startModuleGroupExport() {}
671 virtual void exportModuleGroup(const char * /*title*/,
672 const ModuleGroupContents & /*modules*/) {}
673 virtual void finishModuleGroupExport() {}
676 ShellCompletionWriter bashWriter_;
677 std::vector<std::string> modules_;
680 HelpExportCompletion::HelpExportCompletion(
681 const CommandLineHelpModuleImpl &helpModule)
682 : bashWriter_(helpModule.binaryName_, eShellCompletionFormat_Bash)
686 void HelpExportCompletion::startModuleExport()
688 bashWriter_.startCompletions();
691 void HelpExportCompletion::exportModuleHelp(
692 const CommandLineModuleInterface &module,
693 const std::string & /*tag*/,
694 const std::string & /*displayName*/)
696 modules_.push_back(module.name());
698 CommandLineHelpContext context(&bashWriter_);
699 // We use the display name to pass the name of the module to the
700 // completion writer.
701 context.setModuleDisplayName(module.name());
702 module.writeHelp(context);
706 void HelpExportCompletion::finishModuleExport()
708 CommandLineCommonOptionsHolder optionsHolder;
709 optionsHolder.initOptions();
710 bashWriter_.writeWrapperCompletions(modules_, *optionsHolder.options());
711 bashWriter_.finishCompletions();
716 /********************************************************************
717 * CommandLineHelpModuleImpl implementation
719 CommandLineHelpModuleImpl::CommandLineHelpModuleImpl(
720 const ProgramContextInterface &programContext,
721 const std::string &binaryName,
722 const CommandLineModuleMap &modules,
723 const CommandLineModuleGroupList &groups)
724 : rootTopic_(new RootHelpTopic(*this)), programContext_(programContext),
725 binaryName_(binaryName), modules_(modules), groups_(groups),
726 context_(NULL), moduleOverride_(NULL), bHidden_(false),
727 outputOverride_(NULL)
731 void CommandLineHelpModuleImpl::exportHelp(HelpExportInterface *exporter) const
733 // TODO: Would be nicer to have the file names supplied by the build system
734 // and/or export a list of files from here.
735 const char *const program = binaryName_.c_str();
737 exporter->startModuleExport();
738 CommandLineModuleMap::const_iterator module;
739 for (module = modules_.begin(); module != modules_.end(); ++module)
741 if (module->second->shortDescription() != NULL)
743 const char *const moduleName = module->first.c_str();
744 std::string tag(formatString("%s-%s", program, moduleName));
745 std::string displayName(formatString("%s %s", program, moduleName));
746 exporter->exportModuleHelp(*module->second, tag, displayName);
749 exporter->finishModuleExport();
751 exporter->startModuleGroupExport();
752 CommandLineModuleGroupList::const_iterator group;
753 for (group = groups_.begin(); group != groups_.end(); ++group)
755 exporter->exportModuleGroup((*group)->title(), (*group)->modules());
757 exporter->finishModuleGroupExport();
760 /********************************************************************
761 * CommandLineHelpModule
764 CommandLineHelpModule::CommandLineHelpModule(
765 const ProgramContextInterface &programContext,
766 const std::string &binaryName,
767 const CommandLineModuleMap &modules,
768 const CommandLineModuleGroupList &groups)
769 : impl_(new Impl(programContext, binaryName, modules, groups))
773 CommandLineHelpModule::~CommandLineHelpModule()
777 HelpTopicPointer CommandLineHelpModule::createModuleHelpTopic(
778 const CommandLineModuleInterface &module) const
780 return HelpTopicPointer(new ModuleHelpTopic(module, *impl_));
783 void CommandLineHelpModule::addTopic(HelpTopicPointer topic)
785 impl_->rootTopic_->addSubTopic(move(topic));
788 void CommandLineHelpModule::setShowHidden(bool bHidden)
790 impl_->bHidden_ = bHidden;
793 void CommandLineHelpModule::setModuleOverride(
794 const CommandLineModuleInterface &module)
796 impl_->moduleOverride_ = &module;
799 void CommandLineHelpModule::setOutputRedirect(File *output)
801 impl_->outputOverride_ = output;
804 int CommandLineHelpModule::run(int argc, char *argv[])
806 // Add internal topics lazily here.
807 addTopic(HelpTopicPointer(new CommandsHelpTopic(*impl_)));
809 const char *const exportFormats[] = { "man", "html", "completion" };
810 std::string exportFormat;
811 Options options(NULL, NULL);
812 options.addOption(StringOption("export").store(&exportFormat)
813 .enumValue(exportFormats));
814 CommandLineParser(&options).parse(&argc, argv);
815 if (!exportFormat.empty())
817 boost::scoped_ptr<HelpExportInterface> exporter;
818 if (exportFormat == "man")
820 exporter.reset(new HelpExportMan(*impl_));
822 else if (exportFormat == "html")
824 exporter.reset(new HelpExportHtml(*impl_));
826 else if (exportFormat == "completion")
828 exporter.reset(new HelpExportCompletion(*impl_));
832 GMX_THROW(NotImplementedError("This help format is not implemented"));
834 impl_->exportHelp(exporter.get());
838 File *outputFile = &File::standardOutput();
839 if (impl_->outputOverride_ != NULL)
841 outputFile = impl_->outputOverride_;
843 HelpLinks links(eHelpOutputFormat_Console);
844 initProgramLinks(&links, *impl_);
845 boost::scoped_ptr<CommandLineHelpContext> context(
846 new CommandLineHelpContext(outputFile,
847 eHelpOutputFormat_Console, &links));
848 context->setShowHidden(impl_->bHidden_);
849 if (impl_->moduleOverride_ != NULL)
851 context->setModuleDisplayName(impl_->programContext_.displayName());
852 impl_->moduleOverride_->writeHelp(*context);
855 impl_->context_ = context.get();
857 HelpManager helpManager(*impl_->rootTopic_, context->writerContext());
860 for (int i = 1; i < argc; ++i)
862 helpManager.enterTopic(argv[i]);
865 catch (const InvalidInputError &ex)
867 fprintf(stderr, "%s\n", ex.what());
870 helpManager.writeCurrentTopic();
874 void CommandLineHelpModule::writeHelp(const CommandLineHelpContext &context) const
876 const HelpWriterContext &writerContext = context.writerContext();
878 if (writerContext.outputFormat() != eHelpOutputFormat_Console)
882 writerContext.writeTextBlock(
883 "Usage: [PROGRAM] help [<command>|<topic> [<subtopic> [...]]]");
884 // TODO: More information.