2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2012,2013,2014,2015, 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
44 #include "cmdlinehelpmodule.h"
49 #include <boost/scoped_ptr.hpp>
51 #include "gromacs/commandline/cmdlinehelpcontext.h"
52 #include "gromacs/commandline/cmdlinehelpwriter.h"
53 #include "gromacs/commandline/cmdlineparser.h"
54 #include "gromacs/onlinehelp/helpformat.h"
55 #include "gromacs/onlinehelp/helpmanager.h"
56 #include "gromacs/onlinehelp/helptopic.h"
57 #include "gromacs/onlinehelp/helpwritercontext.h"
58 #include "gromacs/options/basicoptions.h"
59 #include "gromacs/options/options.h"
60 #include "gromacs/utility/arrayref.h"
61 #include "gromacs/utility/baseversion.h"
62 #include "gromacs/utility/exceptions.h"
63 #include "gromacs/utility/file.h"
64 #include "gromacs/utility/fileredirector.h"
65 #include "gromacs/utility/gmxassert.h"
66 #include "gromacs/utility/programcontext.h"
67 #include "gromacs/utility/stringutil.h"
69 #include "shellcompletions.h"
76 class HelpExportInterface;
80 /********************************************************************
81 * CommandLineHelpModuleImpl declaration
84 class CommandLineHelpModuleImpl
87 CommandLineHelpModuleImpl(const ProgramContextInterface &programContext,
88 const std::string &binaryName,
89 const CommandLineModuleMap &modules,
90 const CommandLineModuleGroupList &groups);
92 void exportHelp(HelpExportInterface *exporter);
94 boost::scoped_ptr<RootHelpTopic> rootTopic_;
95 const ProgramContextInterface &programContext_;
96 std::string binaryName_;
97 const CommandLineModuleMap &modules_;
98 const CommandLineModuleGroupList &groups_;
100 CommandLineHelpContext *context_;
101 const CommandLineModuleInterface *moduleOverride_;
104 FileOutputRedirectorInterface *outputRedirector_;
106 GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModuleImpl);
112 /********************************************************************
113 * HelpExportInterface
117 * Callbacks for exporting help information for command-line modules.
119 * \ingroup module_commandline
121 class HelpExportInterface
124 //! Shorthand for a list of modules contained in a group.
125 typedef CommandLineModuleGroupData::ModuleList ModuleGroupContents;
127 virtual ~HelpExportInterface() {};
130 * Called once before exporting individual modules.
132 * Can, e.g., open shared output files (e.g., if the output is written
133 * into a single file, or if a separate index is required) and write
136 virtual void startModuleExport() = 0;
138 * Called to export the help for each module.
140 * \param[in] module Module for which the help should be exported.
141 * \param[in] tag Unique tag for the module (gmx-something).
142 * \param[in] displayName Display name for the module (gmx something).
144 virtual void exportModuleHelp(
145 const CommandLineModuleInterface &module,
146 const std::string &tag,
147 const std::string &displayName) = 0;
149 * Called after all modules have been exported.
151 * Can close files opened in startModuleExport(), write footers to them
154 virtual void finishModuleExport() = 0;
157 * Called once before exporting module groups.
159 * Can, e.g., open a single output file for listing all the groups.
161 virtual void startModuleGroupExport() = 0;
163 * Called to export the help for each module group.
165 * \param[in] title Title for the group.
166 * \param[in] modules List of modules in the group.
168 virtual void exportModuleGroup(const char *title,
169 const ModuleGroupContents &modules) = 0;
171 * Called after all module groups have been exported.
173 * Can close files opened in startModuleGroupExport(), write footers to them
176 virtual void finishModuleGroupExport() = 0;
179 * Called to export the help for a top-level topic.
181 * \param[in] topic Topic to export.
183 virtual void exportTopic(const HelpTopicInterface &topic) = 0;
186 /********************************************************************
192 static const char title[];
193 static const char *const text[];
196 // These are used for the gmx.1 man page.
197 // TODO: Do not hardcode them here, but pass them from the outside to make this
198 // code more generic.
199 const char RootHelpText::title[] = "molecular dynamics simulation suite";
200 const char *const RootHelpText::text[] = {
201 "|Gromacs| is a full-featured suite of programs to perform molecular",
202 "dynamics simulations, i.e., to simulate the behavior of systems with",
203 "hundreds to millions of particles using Newtonian equations of motion.",
204 "It is primarily used for research on proteins, lipids, and polymers, but",
205 "can be applied to a wide variety of chemical and biological research",
210 * Help topic that forms the root of the help tree for the help subcommand.
212 * \ingroup module_commandline
214 class RootHelpTopic : public AbstractCompositeHelpTopic
218 * Creates a root help topic.
222 explicit RootHelpTopic(const CommandLineHelpModuleImpl &helpModule)
223 : helpModule_(helpModule)
227 virtual const char *name() const { return helpModule_.binaryName_.c_str(); }
228 virtual const char *title() const { return title_.c_str(); }
230 //! Adds a top-level topic and optionally marks it as exported.
231 void addTopic(HelpTopicPointer topic, bool bExported)
235 exportedTopics_.push_back(topic->name());
237 addSubTopic(move(topic));
239 //! Exports all the top-level topics with the given exporter.
240 void exportHelp(HelpExportInterface *exporter);
242 virtual void writeHelp(const HelpWriterContext &context) const;
245 // unused because of the writeHelp() override
246 virtual std::string helpText() const { return ""; }
248 const CommandLineHelpModuleImpl &helpModule_;
250 std::vector<std::string> exportedTopics_;
252 GMX_DISALLOW_COPY_AND_ASSIGN(RootHelpTopic);
255 void RootHelpTopic::exportHelp(HelpExportInterface *exporter)
257 std::vector<std::string>::const_iterator topicName;
258 for (topicName = exportedTopics_.begin();
259 topicName != exportedTopics_.end();
262 const HelpTopicInterface *topic = findSubTopic(topicName->c_str());
263 GMX_RELEASE_ASSERT(topic != NULL, "Exported help topic no longer found");
264 exporter->exportTopic(*topic);
266 // For now, the title is only set for the export to make it not appear in
267 // console output, which makes things consistent for 'gmx help' and
268 // 'gmx help <command>'.
269 title_ = RootHelpText::title;
270 exporter->exportTopic(*this);
273 void RootHelpTopic::writeHelp(const HelpWriterContext &context) const
276 CommandLineCommonOptionsHolder optionsHolder;
277 boost::scoped_ptr<CommandLineHelpContext> cmdlineContext;
278 if (helpModule_.context_ != NULL)
280 cmdlineContext.reset(new CommandLineHelpContext(*helpModule_.context_));
284 cmdlineContext.reset(new CommandLineHelpContext(context));
286 cmdlineContext->setModuleDisplayName(helpModule_.binaryName_);
287 optionsHolder.initOptions();
288 Options &options = *optionsHolder.options();
289 options.setDescription(RootHelpText::text);
290 // TODO: Add <command> [<args>] into the synopsis.
291 CommandLineHelpWriter(options)
292 .setShowDescriptions(context.outputFormat() != eHelpOutputFormat_Console)
293 .writeHelp(*cmdlineContext);
295 if (context.outputFormat() == eHelpOutputFormat_Console)
297 // TODO: Consider printing a list of "core" commands. Would require someone
298 // to determine such a set...
299 writeSubTopicList(context,
300 "Additional help is available on the following topics:");
301 context.writeTextBlock("To access the help, use '[PROGRAM] help <topic>'.");
302 context.writeTextBlock("For help on a command, use '[PROGRAM] help <command>'.");
306 // TODO: This should not really end up on the HTML page.
307 context.writeTitle(formatString("%s commands", helpModule_.binaryName_.c_str()));
308 context.writeTextBlock(
309 "The following commands are available. Please refer to their "
310 "individual man pages or [TT][PROGRAM] help <command>[tt] "
311 "for further details.");
312 context.writeTextBlock("");
313 context.writeTextBlock(".. include:: /fragments/bytopic-man.rst");
317 /********************************************************************
322 * Help topic for listing the commands.
324 * \ingroup module_commandline
326 class CommandsHelpTopic : public HelpTopicInterface
330 * Creates a command list help topic.
332 * \param[in] helpModule Help module to get module information from.
336 explicit CommandsHelpTopic(const CommandLineHelpModuleImpl &helpModule)
337 : helpModule_(helpModule)
341 virtual const char *name() const { return "commands"; }
342 virtual const char *title() const { return "List of available commands"; }
343 virtual bool hasSubTopics() const { return false; }
344 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
349 virtual void writeHelp(const HelpWriterContext &context) const;
352 const CommandLineHelpModuleImpl &helpModule_;
354 GMX_DISALLOW_COPY_AND_ASSIGN(CommandsHelpTopic);
357 void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const
359 if (context.outputFormat() != eHelpOutputFormat_Console)
361 GMX_THROW(NotImplementedError(
362 "Module list is not implemented for this output format"));
364 int maxNameLength = 0;
365 const CommandLineModuleMap &modules = helpModule_.modules_;
366 CommandLineModuleMap::const_iterator module;
367 for (module = modules.begin(); module != modules.end(); ++module)
369 int nameLength = static_cast<int>(module->first.length());
370 if (module->second->shortDescription() != NULL
371 && nameLength > maxNameLength)
373 maxNameLength = nameLength;
376 context.writeTextBlock(
377 "Usage: [PROGRAM] [<options>] <command> [<args>][PAR]"
378 "Available commands:");
379 File &file = context.outputFile();
380 TextTableFormatter formatter;
381 formatter.addColumn(NULL, maxNameLength + 1, false);
382 formatter.addColumn(NULL, 72 - maxNameLength, true);
383 formatter.setFirstColumnIndent(4);
384 for (module = modules.begin(); module != modules.end(); ++module)
386 const char *name = module->first.c_str();
387 const char *description = module->second->shortDescription();
388 if (description != NULL)
391 formatter.addColumnLine(0, name);
392 formatter.addColumnLine(1, description);
393 file.writeString(formatter.formatRow());
396 context.writeTextBlock(
397 "For help on a command, use '[PROGRAM] help <command>'.");
400 /********************************************************************
405 * Help topic wrapper for a command-line module.
407 * This class implements HelpTopicInterface such that it wraps a
408 * CommandLineModuleInterface, allowing subcommand "help <command>"
409 * to produce the help for "<command>".
411 * \ingroup module_commandline
413 class ModuleHelpTopic : public HelpTopicInterface
416 //! Constructs a help topic for a specific module.
417 ModuleHelpTopic(const CommandLineModuleInterface &module,
418 const CommandLineHelpModuleImpl &helpModule)
419 : module_(module), helpModule_(helpModule)
423 virtual const char *name() const { return module_.name(); }
424 virtual const char *title() const { return NULL; }
425 virtual bool hasSubTopics() const { return false; }
426 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
430 virtual void writeHelp(const HelpWriterContext &context) const;
433 const CommandLineModuleInterface &module_;
434 const CommandLineHelpModuleImpl &helpModule_;
436 GMX_DISALLOW_COPY_AND_ASSIGN(ModuleHelpTopic);
439 void ModuleHelpTopic::writeHelp(const HelpWriterContext & /*context*/) const
441 CommandLineHelpContext context(*helpModule_.context_);
442 const char *const program = helpModule_.binaryName_.c_str();
443 context.setModuleDisplayName(formatString("%s %s", program, module_.name()));
444 module_.writeHelp(context);
447 /********************************************************************
448 * HelpExportReStructuredText
452 * Adds hyperlinks to modules within this binary.
454 * \param[in,out] links Links are added here.
455 * \param[in] helpModule Help module to get module information from.
456 * \throws std::bad_alloc if out of memory.
458 * Initializes a HelpLinks object with links to modules defined in
461 * \ingroup module_commandline
463 void initProgramLinks(HelpLinks *links, const CommandLineHelpModuleImpl &helpModule)
465 const char *const program = helpModule.binaryName_.c_str();
466 CommandLineModuleMap::const_iterator module;
467 for (module = helpModule.modules_.begin();
468 module != helpModule.modules_.end();
471 if (module->second->shortDescription() != NULL)
473 std::string linkName("[gmx-" + module->first + "]");
474 const char *name = module->first.c_str();
475 std::string reference(
476 formatString(":doc:`%s %s <%s-%s>`", program, name, program, name));
477 std::string displayName(
478 formatString("[TT]%s %s[tt]", program, name));
479 links->addLink(linkName, reference, displayName);
485 * Implements export for web pages as reStructuredText.
487 * \ingroup module_commandline
489 class HelpExportReStructuredText : public HelpExportInterface
492 //! Initializes reST exporter.
493 explicit HelpExportReStructuredText(
494 const CommandLineHelpModuleImpl &helpModule);
496 virtual void startModuleExport();
497 virtual void exportModuleHelp(
498 const CommandLineModuleInterface &module,
499 const std::string &tag,
500 const std::string &displayName);
501 virtual void finishModuleExport();
503 virtual void startModuleGroupExport();
504 virtual void exportModuleGroup(const char *title,
505 const ModuleGroupContents &modules);
506 virtual void finishModuleGroupExport();
508 virtual void exportTopic(const HelpTopicInterface &topic);
511 FileOutputRedirectorInterface *outputRedirector_;
512 const std::string &binaryName_;
514 boost::scoped_ptr<File> indexFile_;
515 boost::scoped_ptr<File> manPagesFile_;
518 HelpExportReStructuredText::HelpExportReStructuredText(
519 const CommandLineHelpModuleImpl &helpModule)
520 : outputRedirector_(helpModule.outputRedirector_),
521 binaryName_(helpModule.binaryName_),
522 links_(eHelpOutputFormat_Rst)
524 File linksFile("links.dat", "r");
526 while (linksFile.readLine(&line))
528 links_.addLink("[REF]." + line + "[ref]",
529 formatString(":ref:`.%s <%s>`", line.c_str(), line.c_str()),
531 links_.addLink("[REF]" + line + "[ref]", formatString(":ref:`%s`", line.c_str()), line);
534 initProgramLinks(&links_, helpModule);
537 void HelpExportReStructuredText::startModuleExport()
540 new File(outputRedirector_->openFileForWriting("fragments/byname.rst")));
541 indexFile_->writeLine(formatString("* :doc:`%s </onlinehelp/%s>` - %s",
542 binaryName_.c_str(), binaryName_.c_str(),
543 RootHelpText::title));
545 new File(outputRedirector_->openFileForWriting("conf-man.py")));
546 manPagesFile_->writeLine("man_pages = [");
549 void HelpExportReStructuredText::exportModuleHelp(
550 const CommandLineModuleInterface &module,
551 const std::string &tag,
552 const std::string &displayName)
554 // TODO: Ideally, the file would only be touched if it really changes.
555 // This would make Sphinx reruns much faster.
556 File file(outputRedirector_->openFileForWriting("onlinehelp/" + tag + ".rst"));
557 file.writeLine(formatString(".. _%s:", displayName.c_str()));
558 if (0 == displayName.compare(binaryName_ + " mdrun"))
560 // Make an extra link target for the convenience of
561 // MPI-specific documentation
562 file.writeLine(".. _mdrun_mpi:");
566 CommandLineHelpContext context(&file, eHelpOutputFormat_Rst, &links_, binaryName_);
567 context.enterSubSection(displayName);
568 context.setModuleDisplayName(displayName);
569 module.writeHelp(context);
572 file.writeLine(".. only:: man");
574 file.writeLine(" See also");
575 file.writeLine(" --------");
577 file.writeLine(formatString(" :manpage:`%s(1)`", binaryName_.c_str()));
579 file.writeLine(" More information about |Gromacs| is available at <http://www.gromacs.org/>.");
582 indexFile_->writeLine(formatString("* :doc:`%s </onlinehelp/%s>` - %s",
583 displayName.c_str(), tag.c_str(),
584 module.shortDescription()));
585 manPagesFile_->writeLine(
586 formatString(" ('onlinehelp/%s', '%s', \"%s\", '', 1),",
587 tag.c_str(), tag.c_str(), module.shortDescription()));
590 void HelpExportReStructuredText::finishModuleExport()
595 manPagesFile_->writeLine(
596 formatString(" ('onlinehelp/%s', '%s', '%s', '', 1)",
597 binaryName_.c_str(), binaryName_.c_str(),
598 RootHelpText::title));
599 manPagesFile_->writeLine("]");
600 manPagesFile_->close();
601 manPagesFile_.reset();
604 void HelpExportReStructuredText::startModuleGroupExport()
607 new File(outputRedirector_->openFileForWriting("fragments/bytopic.rst")));
609 new File(outputRedirector_->openFileForWriting("fragments/bytopic-man.rst")));
612 void HelpExportReStructuredText::exportModuleGroup(
614 const ModuleGroupContents &modules)
616 indexFile_->writeLine(title);
617 indexFile_->writeLine(std::string(std::strlen(title), '^'));
618 manPagesFile_->writeLine(title);
619 manPagesFile_->writeLine(std::string(std::strlen(title), '^'));
621 ModuleGroupContents::const_iterator module;
622 for (module = modules.begin(); module != modules.end(); ++module)
624 const std::string &tag(module->first);
625 std::string displayName(tag);
626 // TODO: This does not work if the binary name would contain a dash,
627 // but that is not currently the case.
628 const size_t dashPos = displayName.find('-');
629 GMX_RELEASE_ASSERT(dashPos != std::string::npos,
630 "There should always be at least one dash in the tag");
631 displayName[dashPos] = ' ';
632 indexFile_->writeLine(formatString(":doc:`%s </onlinehelp/%s>`\n %s",
633 displayName.c_str(), tag.c_str(),
635 manPagesFile_->writeLine(formatString(":manpage:`%s(1)`\n %s",
639 indexFile_->writeLine();
640 manPagesFile_->writeLine();
643 void HelpExportReStructuredText::finishModuleGroupExport()
647 manPagesFile_->close();
648 manPagesFile_.reset();
651 void HelpExportReStructuredText::exportTopic(const HelpTopicInterface &topic)
653 const std::string path("onlinehelp/" + std::string(topic.name()) + ".rst");
654 File file(outputRedirector_->openFileForWriting(path));
655 CommandLineHelpContext context(&file, eHelpOutputFormat_Rst, &links_,
657 HelpManager manager(topic, context.writerContext());
658 manager.writeCurrentTopic();
661 /********************************************************************
662 * HelpExportCompletion
666 * Implements export for command-line completion.
668 * \ingroup module_commandline
670 class HelpExportCompletion : public HelpExportInterface
673 //! Initializes completion exporter.
674 explicit HelpExportCompletion(const CommandLineHelpModuleImpl &helpModule);
676 virtual void startModuleExport();
677 virtual void exportModuleHelp(
678 const CommandLineModuleInterface &module,
679 const std::string &tag,
680 const std::string &displayName);
681 virtual void finishModuleExport();
683 virtual void startModuleGroupExport() {}
684 virtual void exportModuleGroup(const char * /*title*/,
685 const ModuleGroupContents & /*modules*/) {}
686 virtual void finishModuleGroupExport() {}
688 virtual void exportTopic(const HelpTopicInterface & /*topic*/) {}
691 ShellCompletionWriter bashWriter_;
692 std::vector<std::string> modules_;
695 HelpExportCompletion::HelpExportCompletion(
696 const CommandLineHelpModuleImpl &helpModule)
697 : bashWriter_(helpModule.binaryName_, eShellCompletionFormat_Bash)
701 void HelpExportCompletion::startModuleExport()
703 bashWriter_.startCompletions();
706 void HelpExportCompletion::exportModuleHelp(
707 const CommandLineModuleInterface &module,
708 const std::string & /*tag*/,
709 const std::string & /*displayName*/)
711 modules_.push_back(module.name());
713 CommandLineHelpContext context(&bashWriter_);
714 // We use the display name to pass the name of the module to the
715 // completion writer.
716 context.setModuleDisplayName(module.name());
717 module.writeHelp(context);
721 void HelpExportCompletion::finishModuleExport()
723 CommandLineCommonOptionsHolder optionsHolder;
724 optionsHolder.initOptions();
725 bashWriter_.writeWrapperCompletions(modules_, *optionsHolder.options());
726 bashWriter_.finishCompletions();
731 /********************************************************************
732 * CommandLineHelpModuleImpl implementation
735 CommandLineHelpModuleImpl::CommandLineHelpModuleImpl(
736 const ProgramContextInterface &programContext,
737 const std::string &binaryName,
738 const CommandLineModuleMap &modules,
739 const CommandLineModuleGroupList &groups)
740 : rootTopic_(new RootHelpTopic(*this)), programContext_(programContext),
741 binaryName_(binaryName), modules_(modules), groups_(groups),
742 context_(NULL), moduleOverride_(NULL), bHidden_(false),
743 outputRedirector_(&defaultFileOutputRedirector())
747 void CommandLineHelpModuleImpl::exportHelp(HelpExportInterface *exporter)
749 // TODO: Would be nicer to have the file names supplied by the build system
750 // and/or export a list of files from here.
751 const char *const program = binaryName_.c_str();
753 exporter->startModuleExport();
754 CommandLineModuleMap::const_iterator module;
755 for (module = modules_.begin(); module != modules_.end(); ++module)
757 if (module->second->shortDescription() != NULL)
759 const char *const moduleName = module->first.c_str();
760 std::string tag(formatString("%s-%s", program, moduleName));
761 std::string displayName(formatString("%s %s", program, moduleName));
762 exporter->exportModuleHelp(*module->second, tag, displayName);
765 exporter->finishModuleExport();
767 exporter->startModuleGroupExport();
768 CommandLineModuleGroupList::const_iterator group;
769 for (group = groups_.begin(); group != groups_.end(); ++group)
771 exporter->exportModuleGroup((*group)->title(), (*group)->modules());
773 exporter->finishModuleGroupExport();
775 rootTopic_->exportHelp(exporter);
778 /********************************************************************
779 * CommandLineHelpModule
782 CommandLineHelpModule::CommandLineHelpModule(
783 const ProgramContextInterface &programContext,
784 const std::string &binaryName,
785 const CommandLineModuleMap &modules,
786 const CommandLineModuleGroupList &groups)
787 : impl_(new Impl(programContext, binaryName, modules, groups))
791 CommandLineHelpModule::~CommandLineHelpModule()
795 HelpTopicPointer CommandLineHelpModule::createModuleHelpTopic(
796 const CommandLineModuleInterface &module) const
798 return HelpTopicPointer(new ModuleHelpTopic(module, *impl_));
801 void CommandLineHelpModule::addTopic(HelpTopicPointer topic, bool bExported)
803 impl_->rootTopic_->addTopic(move(topic), bExported);
806 void CommandLineHelpModule::setShowHidden(bool bHidden)
808 impl_->bHidden_ = bHidden;
811 void CommandLineHelpModule::setModuleOverride(
812 const CommandLineModuleInterface &module)
814 impl_->moduleOverride_ = &module;
817 void CommandLineHelpModule::setOutputRedirector(
818 FileOutputRedirectorInterface *output)
820 impl_->outputRedirector_ = output;
823 int CommandLineHelpModule::run(int argc, char *argv[])
825 // Add internal topics lazily here.
826 addTopic(HelpTopicPointer(new CommandsHelpTopic(*impl_)), false);
828 const char *const exportFormats[] = { "rst", "completion" };
829 std::string exportFormat;
830 Options options(NULL, NULL);
831 options.addOption(StringOption("export").store(&exportFormat)
832 .enumValue(exportFormats));
833 CommandLineParser(&options).parse(&argc, argv);
834 if (!exportFormat.empty())
836 boost::scoped_ptr<HelpExportInterface> exporter;
837 if (exportFormat == "rst")
839 exporter.reset(new HelpExportReStructuredText(*impl_));
841 else if (exportFormat == "completion")
843 exporter.reset(new HelpExportCompletion(*impl_));
847 GMX_THROW(NotImplementedError("This help format is not implemented"));
849 impl_->exportHelp(exporter.get());
853 File &outputFile = impl_->outputRedirector_->standardOutput();
854 HelpLinks links(eHelpOutputFormat_Console);
855 initProgramLinks(&links, *impl_);
856 CommandLineHelpContext context(&outputFile, eHelpOutputFormat_Console, &links,
858 context.setShowHidden(impl_->bHidden_);
859 if (impl_->moduleOverride_ != NULL)
861 context.setModuleDisplayName(impl_->programContext_.displayName());
862 impl_->moduleOverride_->writeHelp(context);
865 impl_->context_ = &context;
867 HelpManager helpManager(*impl_->rootTopic_, context.writerContext());
870 for (int i = 1; i < argc; ++i)
872 helpManager.enterTopic(argv[i]);
875 catch (const InvalidInputError &ex)
877 fprintf(stderr, "%s\n", ex.what());
880 helpManager.writeCurrentTopic();
884 void CommandLineHelpModule::writeHelp(const CommandLineHelpContext &context) const
886 const HelpWriterContext &writerContext = context.writerContext();
888 if (writerContext.outputFormat() != eHelpOutputFormat_Console)
892 writerContext.writeTextBlock(
893 "Usage: [PROGRAM] help [<command>|<topic> [<subtopic> [...]]]");
894 // TODO: More information.