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/fileredirector.h"
64 #include "gromacs/utility/gmxassert.h"
65 #include "gromacs/utility/programcontext.h"
66 #include "gromacs/utility/stringutil.h"
67 #include "gromacs/utility/textreader.h"
68 #include "gromacs/utility/textwriter.h"
70 #include "shellcompletions.h"
77 class HelpExportInterface;
81 /********************************************************************
82 * CommandLineHelpModuleImpl declaration
85 class CommandLineHelpModuleImpl
88 CommandLineHelpModuleImpl(const ProgramContextInterface &programContext,
89 const std::string &binaryName,
90 const CommandLineModuleMap &modules,
91 const CommandLineModuleGroupList &groups);
93 void exportHelp(HelpExportInterface *exporter);
95 boost::scoped_ptr<RootHelpTopic> rootTopic_;
96 const ProgramContextInterface &programContext_;
97 std::string binaryName_;
98 const CommandLineModuleMap &modules_;
99 const CommandLineModuleGroupList &groups_;
101 CommandLineHelpContext *context_;
102 const CommandLineModuleInterface *moduleOverride_;
105 FileOutputRedirectorInterface *outputRedirector_;
107 GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModuleImpl);
113 /********************************************************************
114 * HelpExportInterface
118 * Callbacks for exporting help information for command-line modules.
120 * \ingroup module_commandline
122 class HelpExportInterface
125 //! Shorthand for a list of modules contained in a group.
126 typedef CommandLineModuleGroupData::ModuleList ModuleGroupContents;
128 virtual ~HelpExportInterface() {};
131 * Called once before exporting individual modules.
133 * Can, e.g., open shared output files (e.g., if the output is written
134 * into a single file, or if a separate index is required) and write
137 virtual void startModuleExport() = 0;
139 * Called to export the help for each module.
141 * \param[in] module Module for which the help should be exported.
142 * \param[in] tag Unique tag for the module (gmx-something).
143 * \param[in] displayName Display name for the module (gmx something).
145 virtual void exportModuleHelp(
146 const CommandLineModuleInterface &module,
147 const std::string &tag,
148 const std::string &displayName) = 0;
150 * Called after all modules have been exported.
152 * Can close files opened in startModuleExport(), write footers to them
155 virtual void finishModuleExport() = 0;
158 * Called once before exporting module groups.
160 * Can, e.g., open a single output file for listing all the groups.
162 virtual void startModuleGroupExport() = 0;
164 * Called to export the help for each module group.
166 * \param[in] title Title for the group.
167 * \param[in] modules List of modules in the group.
169 virtual void exportModuleGroup(const char *title,
170 const ModuleGroupContents &modules) = 0;
172 * Called after all module groups have been exported.
174 * Can close files opened in startModuleGroupExport(), write footers to them
177 virtual void finishModuleGroupExport() = 0;
180 * Called to export the help for a top-level topic.
182 * \param[in] topic Topic to export.
184 virtual void exportTopic(const HelpTopicInterface &topic) = 0;
187 /********************************************************************
193 static const char title[];
194 static const char *const text[];
197 // These are used for the gmx.1 man page.
198 // TODO: Do not hardcode them here, but pass them from the outside to make this
199 // code more generic.
200 const char RootHelpText::title[] = "molecular dynamics simulation suite";
201 const char *const RootHelpText::text[] = {
202 "|Gromacs| is a full-featured suite of programs to perform molecular",
203 "dynamics simulations, i.e., to simulate the behavior of systems with",
204 "hundreds to millions of particles using Newtonian equations of motion.",
205 "It is primarily used for research on proteins, lipids, and polymers, but",
206 "can be applied to a wide variety of chemical and biological research",
211 * Help topic that forms the root of the help tree for the help subcommand.
213 * \ingroup module_commandline
215 class RootHelpTopic : public AbstractCompositeHelpTopic
219 * Creates a root help topic.
223 explicit RootHelpTopic(const CommandLineHelpModuleImpl &helpModule)
224 : helpModule_(helpModule)
228 virtual const char *name() const { return helpModule_.binaryName_.c_str(); }
229 virtual const char *title() const { return title_.c_str(); }
231 //! Adds a top-level topic and optionally marks it as exported.
232 void addTopic(HelpTopicPointer topic, bool bExported)
236 exportedTopics_.push_back(topic->name());
238 addSubTopic(move(topic));
240 //! Exports all the top-level topics with the given exporter.
241 void exportHelp(HelpExportInterface *exporter);
243 virtual void writeHelp(const HelpWriterContext &context) const;
246 // unused because of the writeHelp() override
247 virtual std::string helpText() const { return ""; }
249 const CommandLineHelpModuleImpl &helpModule_;
251 std::vector<std::string> exportedTopics_;
253 GMX_DISALLOW_COPY_AND_ASSIGN(RootHelpTopic);
256 void RootHelpTopic::exportHelp(HelpExportInterface *exporter)
258 std::vector<std::string>::const_iterator topicName;
259 for (topicName = exportedTopics_.begin();
260 topicName != exportedTopics_.end();
263 const HelpTopicInterface *topic = findSubTopic(topicName->c_str());
264 GMX_RELEASE_ASSERT(topic != NULL, "Exported help topic no longer found");
265 exporter->exportTopic(*topic);
267 // For now, the title is only set for the export to make it not appear in
268 // console output, which makes things consistent for 'gmx help' and
269 // 'gmx help <command>'.
270 title_ = RootHelpText::title;
271 exporter->exportTopic(*this);
274 void RootHelpTopic::writeHelp(const HelpWriterContext &context) const
277 CommandLineCommonOptionsHolder optionsHolder;
278 boost::scoped_ptr<CommandLineHelpContext> cmdlineContext;
279 if (helpModule_.context_ != NULL)
281 cmdlineContext.reset(new CommandLineHelpContext(*helpModule_.context_));
285 cmdlineContext.reset(new CommandLineHelpContext(context));
287 cmdlineContext->setModuleDisplayName(helpModule_.binaryName_);
288 optionsHolder.initOptions();
289 Options &options = *optionsHolder.options();
290 options.setDescription(RootHelpText::text);
291 // TODO: Add <command> [<args>] into the synopsis.
292 CommandLineHelpWriter(options)
293 .setShowDescriptions(context.outputFormat() != eHelpOutputFormat_Console)
294 .writeHelp(*cmdlineContext);
296 if (context.outputFormat() == eHelpOutputFormat_Console)
298 // TODO: Consider printing a list of "core" commands. Would require someone
299 // to determine such a set...
300 writeSubTopicList(context,
301 "Additional help is available on the following topics:");
302 context.writeTextBlock("To access the help, use '[PROGRAM] help <topic>'.");
303 context.writeTextBlock("For help on a command, use '[PROGRAM] help <command>'.");
307 // TODO: This should not really end up on the HTML page.
308 context.writeTitle(formatString("%s commands", helpModule_.binaryName_.c_str()));
309 context.writeTextBlock(
310 "The following commands are available. Please refer to their "
311 "individual man pages or [TT][PROGRAM] help <command>[tt] "
312 "for further details.");
313 context.writeTextBlock("");
314 context.writeTextBlock(".. include:: /fragments/bytopic-man.rst");
318 /********************************************************************
323 * Help topic for listing the commands.
325 * \ingroup module_commandline
327 class CommandsHelpTopic : public HelpTopicInterface
331 * Creates a command list help topic.
333 * \param[in] helpModule Help module to get module information from.
337 explicit CommandsHelpTopic(const CommandLineHelpModuleImpl &helpModule)
338 : helpModule_(helpModule)
342 virtual const char *name() const { return "commands"; }
343 virtual const char *title() const { return "List of available commands"; }
344 virtual bool hasSubTopics() const { return false; }
345 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
350 virtual void writeHelp(const HelpWriterContext &context) const;
353 const CommandLineHelpModuleImpl &helpModule_;
355 GMX_DISALLOW_COPY_AND_ASSIGN(CommandsHelpTopic);
358 void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const
360 if (context.outputFormat() != eHelpOutputFormat_Console)
362 GMX_THROW(NotImplementedError(
363 "Module list is not implemented for this output format"));
365 int maxNameLength = 0;
366 const CommandLineModuleMap &modules = helpModule_.modules_;
367 CommandLineModuleMap::const_iterator module;
368 for (module = modules.begin(); module != modules.end(); ++module)
370 int nameLength = static_cast<int>(module->first.length());
371 if (module->second->shortDescription() != NULL
372 && nameLength > maxNameLength)
374 maxNameLength = nameLength;
377 context.writeTextBlock(
378 "Usage: [PROGRAM] [<options>] <command> [<args>][PAR]"
379 "Available commands:");
380 TextWriter &file = context.outputFile();
381 TextTableFormatter formatter;
382 formatter.addColumn(NULL, maxNameLength + 1, false);
383 formatter.addColumn(NULL, 72 - maxNameLength, true);
384 formatter.setFirstColumnIndent(4);
385 for (module = modules.begin(); module != modules.end(); ++module)
387 const char *name = module->first.c_str();
388 const char *description = module->second->shortDescription();
389 if (description != NULL)
392 formatter.addColumnLine(0, name);
393 formatter.addColumnLine(1, description);
394 file.writeString(formatter.formatRow());
397 context.writeTextBlock(
398 "For help on a command, use '[PROGRAM] help <command>'.");
401 /********************************************************************
406 * Help topic wrapper for a command-line module.
408 * This class implements HelpTopicInterface such that it wraps a
409 * CommandLineModuleInterface, allowing subcommand "help <command>"
410 * to produce the help for "<command>".
412 * \ingroup module_commandline
414 class ModuleHelpTopic : public HelpTopicInterface
417 //! Constructs a help topic for a specific module.
418 ModuleHelpTopic(const CommandLineModuleInterface &module,
419 const CommandLineHelpModuleImpl &helpModule)
420 : module_(module), helpModule_(helpModule)
424 virtual const char *name() const { return module_.name(); }
425 virtual const char *title() const { return NULL; }
426 virtual bool hasSubTopics() const { return false; }
427 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
431 virtual void writeHelp(const HelpWriterContext &context) const;
434 const CommandLineModuleInterface &module_;
435 const CommandLineHelpModuleImpl &helpModule_;
437 GMX_DISALLOW_COPY_AND_ASSIGN(ModuleHelpTopic);
440 void ModuleHelpTopic::writeHelp(const HelpWriterContext & /*context*/) const
442 CommandLineHelpContext context(*helpModule_.context_);
443 const char *const program = helpModule_.binaryName_.c_str();
444 context.setModuleDisplayName(formatString("%s %s", program, module_.name()));
445 module_.writeHelp(context);
448 /********************************************************************
449 * HelpExportReStructuredText
453 * Adds hyperlinks to modules within this binary.
455 * \param[in,out] links Links are added here.
456 * \param[in] helpModule Help module to get module information from.
457 * \throws std::bad_alloc if out of memory.
459 * Initializes a HelpLinks object with links to modules defined in
462 * \ingroup module_commandline
464 void initProgramLinks(HelpLinks *links, const CommandLineHelpModuleImpl &helpModule)
466 const char *const program = helpModule.binaryName_.c_str();
467 CommandLineModuleMap::const_iterator module;
468 for (module = helpModule.modules_.begin();
469 module != helpModule.modules_.end();
472 if (module->second->shortDescription() != NULL)
474 std::string linkName("[gmx-" + module->first + "]");
475 const char *name = module->first.c_str();
476 std::string reference(
477 formatString(":doc:`%s %s <%s-%s>`", program, name, program, name));
478 std::string displayName(
479 formatString("[TT]%s %s[tt]", program, name));
480 links->addLink(linkName, reference, displayName);
486 * Implements export for web pages as reStructuredText.
488 * \ingroup module_commandline
490 class HelpExportReStructuredText : public HelpExportInterface
493 //! Initializes reST exporter.
494 explicit HelpExportReStructuredText(
495 const CommandLineHelpModuleImpl &helpModule);
497 virtual void startModuleExport();
498 virtual void exportModuleHelp(
499 const CommandLineModuleInterface &module,
500 const std::string &tag,
501 const std::string &displayName);
502 virtual void finishModuleExport();
504 virtual void startModuleGroupExport();
505 virtual void exportModuleGroup(const char *title,
506 const ModuleGroupContents &modules);
507 virtual void finishModuleGroupExport();
509 virtual void exportTopic(const HelpTopicInterface &topic);
512 FileOutputRedirectorInterface *outputRedirector_;
513 const std::string &binaryName_;
515 boost::scoped_ptr<TextWriter> indexFile_;
516 boost::scoped_ptr<TextWriter> manPagesFile_;
519 HelpExportReStructuredText::HelpExportReStructuredText(
520 const CommandLineHelpModuleImpl &helpModule)
521 : outputRedirector_(helpModule.outputRedirector_),
522 binaryName_(helpModule.binaryName_),
523 links_(eHelpOutputFormat_Rst)
525 TextReader linksFile("links.dat");
527 while (linksFile.readLineTrimmed(&line))
529 links_.addLink("[REF]." + line + "[ref]",
530 formatString(":ref:`.%s <%s>`", line.c_str(), line.c_str()),
532 links_.addLink("[REF]" + line + "[ref]", formatString(":ref:`%s`", line.c_str()), line);
535 initProgramLinks(&links_, helpModule);
538 void HelpExportReStructuredText::startModuleExport()
542 outputRedirector_->openTextOutputFile("fragments/byname.rst")));
543 indexFile_->writeLine(formatString("* :doc:`%s </onlinehelp/%s>` - %s",
544 binaryName_.c_str(), binaryName_.c_str(),
545 RootHelpText::title));
548 outputRedirector_->openTextOutputFile("conf-man.py")));
549 manPagesFile_->writeLine("man_pages = [");
552 void HelpExportReStructuredText::exportModuleHelp(
553 const CommandLineModuleInterface &module,
554 const std::string &tag,
555 const std::string &displayName)
557 // TODO: Ideally, the file would only be touched if it really changes.
558 // This would make Sphinx reruns much faster.
559 TextOutputStreamPointer file
560 = outputRedirector_->openTextOutputFile("onlinehelp/" + tag + ".rst");
561 TextWriter writer(file);
562 writer.writeLine(formatString(".. _%s:", displayName.c_str()));
563 if (0 == displayName.compare(binaryName_ + " mdrun"))
565 // Make an extra link target for the convenience of
566 // MPI-specific documentation
567 writer.writeLine(".. _mdrun_mpi:");
571 CommandLineHelpContext context(file.get(), eHelpOutputFormat_Rst, &links_, binaryName_);
572 context.enterSubSection(displayName);
573 context.setModuleDisplayName(displayName);
574 module.writeHelp(context);
577 writer.writeLine(".. only:: man");
579 writer.writeLine(" See also");
580 writer.writeLine(" --------");
582 writer.writeLine(formatString(" :manpage:`%s(1)`", binaryName_.c_str()));
584 writer.writeLine(" More information about |Gromacs| is available at <http://www.gromacs.org/>.");
587 indexFile_->writeLine(formatString("* :doc:`%s </onlinehelp/%s>` - %s",
588 displayName.c_str(), tag.c_str(),
589 module.shortDescription()));
590 manPagesFile_->writeLine(
591 formatString(" ('onlinehelp/%s', '%s', \"%s\", '', 1),",
592 tag.c_str(), tag.c_str(), module.shortDescription()));
595 void HelpExportReStructuredText::finishModuleExport()
600 manPagesFile_->writeLine(
601 formatString(" ('onlinehelp/%s', '%s', '%s', '', 1)",
602 binaryName_.c_str(), binaryName_.c_str(),
603 RootHelpText::title));
604 manPagesFile_->writeLine("]");
605 manPagesFile_->close();
606 manPagesFile_.reset();
609 void HelpExportReStructuredText::startModuleGroupExport()
613 outputRedirector_->openTextOutputFile("fragments/bytopic.rst")));
616 outputRedirector_->openTextOutputFile("fragments/bytopic-man.rst")));
619 void HelpExportReStructuredText::exportModuleGroup(
621 const ModuleGroupContents &modules)
623 indexFile_->writeLine(title);
624 indexFile_->writeLine(std::string(std::strlen(title), '^'));
625 manPagesFile_->writeLine(title);
626 manPagesFile_->writeLine(std::string(std::strlen(title), '^'));
628 ModuleGroupContents::const_iterator module;
629 for (module = modules.begin(); module != modules.end(); ++module)
631 const std::string &tag(module->first);
632 std::string displayName(tag);
633 // TODO: This does not work if the binary name would contain a dash,
634 // but that is not currently the case.
635 const size_t dashPos = displayName.find('-');
636 GMX_RELEASE_ASSERT(dashPos != std::string::npos,
637 "There should always be at least one dash in the tag");
638 displayName[dashPos] = ' ';
639 indexFile_->writeLine(formatString(":doc:`%s </onlinehelp/%s>`\n %s",
640 displayName.c_str(), tag.c_str(),
642 manPagesFile_->writeLine(formatString(":manpage:`%s(1)`\n %s",
646 indexFile_->writeLine();
647 manPagesFile_->writeLine();
650 void HelpExportReStructuredText::finishModuleGroupExport()
654 manPagesFile_->close();
655 manPagesFile_.reset();
658 void HelpExportReStructuredText::exportTopic(const HelpTopicInterface &topic)
660 const std::string path("onlinehelp/" + std::string(topic.name()) + ".rst");
661 TextOutputStreamPointer file(outputRedirector_->openTextOutputFile(path));
662 CommandLineHelpContext context(file.get(), eHelpOutputFormat_Rst, &links_,
664 HelpManager manager(topic, context.writerContext());
665 manager.writeCurrentTopic();
669 /********************************************************************
670 * HelpExportCompletion
674 * Implements export for command-line completion.
676 * \ingroup module_commandline
678 class HelpExportCompletion : public HelpExportInterface
681 //! Initializes completion exporter.
682 explicit HelpExportCompletion(const CommandLineHelpModuleImpl &helpModule);
684 virtual void startModuleExport();
685 virtual void exportModuleHelp(
686 const CommandLineModuleInterface &module,
687 const std::string &tag,
688 const std::string &displayName);
689 virtual void finishModuleExport();
691 virtual void startModuleGroupExport() {}
692 virtual void exportModuleGroup(const char * /*title*/,
693 const ModuleGroupContents & /*modules*/) {}
694 virtual void finishModuleGroupExport() {}
696 virtual void exportTopic(const HelpTopicInterface & /*topic*/) {}
699 ShellCompletionWriter bashWriter_;
700 std::vector<std::string> modules_;
703 HelpExportCompletion::HelpExportCompletion(
704 const CommandLineHelpModuleImpl &helpModule)
705 : bashWriter_(helpModule.binaryName_, eShellCompletionFormat_Bash)
709 void HelpExportCompletion::startModuleExport()
711 bashWriter_.startCompletions();
714 void HelpExportCompletion::exportModuleHelp(
715 const CommandLineModuleInterface &module,
716 const std::string & /*tag*/,
717 const std::string & /*displayName*/)
719 modules_.push_back(module.name());
721 CommandLineHelpContext context(&bashWriter_);
722 // We use the display name to pass the name of the module to the
723 // completion writer.
724 context.setModuleDisplayName(module.name());
725 module.writeHelp(context);
729 void HelpExportCompletion::finishModuleExport()
731 CommandLineCommonOptionsHolder optionsHolder;
732 optionsHolder.initOptions();
733 bashWriter_.writeWrapperCompletions(modules_, *optionsHolder.options());
734 bashWriter_.finishCompletions();
739 /********************************************************************
740 * CommandLineHelpModuleImpl implementation
743 CommandLineHelpModuleImpl::CommandLineHelpModuleImpl(
744 const ProgramContextInterface &programContext,
745 const std::string &binaryName,
746 const CommandLineModuleMap &modules,
747 const CommandLineModuleGroupList &groups)
748 : rootTopic_(new RootHelpTopic(*this)), programContext_(programContext),
749 binaryName_(binaryName), modules_(modules), groups_(groups),
750 context_(NULL), moduleOverride_(NULL), bHidden_(false),
751 outputRedirector_(&defaultFileOutputRedirector())
755 void CommandLineHelpModuleImpl::exportHelp(HelpExportInterface *exporter)
757 // TODO: Would be nicer to have the file names supplied by the build system
758 // and/or export a list of files from here.
759 const char *const program = binaryName_.c_str();
761 exporter->startModuleExport();
762 CommandLineModuleMap::const_iterator module;
763 for (module = modules_.begin(); module != modules_.end(); ++module)
765 if (module->second->shortDescription() != NULL)
767 const char *const moduleName = module->first.c_str();
768 std::string tag(formatString("%s-%s", program, moduleName));
769 std::string displayName(formatString("%s %s", program, moduleName));
770 exporter->exportModuleHelp(*module->second, tag, displayName);
773 exporter->finishModuleExport();
775 exporter->startModuleGroupExport();
776 CommandLineModuleGroupList::const_iterator group;
777 for (group = groups_.begin(); group != groups_.end(); ++group)
779 exporter->exportModuleGroup((*group)->title(), (*group)->modules());
781 exporter->finishModuleGroupExport();
783 rootTopic_->exportHelp(exporter);
786 /********************************************************************
787 * CommandLineHelpModule
790 CommandLineHelpModule::CommandLineHelpModule(
791 const ProgramContextInterface &programContext,
792 const std::string &binaryName,
793 const CommandLineModuleMap &modules,
794 const CommandLineModuleGroupList &groups)
795 : impl_(new Impl(programContext, binaryName, modules, groups))
799 CommandLineHelpModule::~CommandLineHelpModule()
803 HelpTopicPointer CommandLineHelpModule::createModuleHelpTopic(
804 const CommandLineModuleInterface &module) const
806 return HelpTopicPointer(new ModuleHelpTopic(module, *impl_));
809 void CommandLineHelpModule::addTopic(HelpTopicPointer topic, bool bExported)
811 impl_->rootTopic_->addTopic(move(topic), bExported);
814 void CommandLineHelpModule::setShowHidden(bool bHidden)
816 impl_->bHidden_ = bHidden;
819 void CommandLineHelpModule::setModuleOverride(
820 const CommandLineModuleInterface &module)
822 impl_->moduleOverride_ = &module;
825 void CommandLineHelpModule::setOutputRedirector(
826 FileOutputRedirectorInterface *output)
828 impl_->outputRedirector_ = output;
831 int CommandLineHelpModule::run(int argc, char *argv[])
833 // Add internal topics lazily here.
834 addTopic(HelpTopicPointer(new CommandsHelpTopic(*impl_)), false);
836 const char *const exportFormats[] = { "rst", "completion" };
837 std::string exportFormat;
838 Options options(NULL, NULL);
839 options.addOption(StringOption("export").store(&exportFormat)
840 .enumValue(exportFormats));
841 CommandLineParser(&options).parse(&argc, argv);
842 if (!exportFormat.empty())
844 boost::scoped_ptr<HelpExportInterface> exporter;
845 if (exportFormat == "rst")
847 exporter.reset(new HelpExportReStructuredText(*impl_));
849 else if (exportFormat == "completion")
851 exporter.reset(new HelpExportCompletion(*impl_));
855 GMX_THROW(NotImplementedError("This help format is not implemented"));
857 impl_->exportHelp(exporter.get());
861 TextOutputStream &outputFile = impl_->outputRedirector_->standardOutput();
862 HelpLinks links(eHelpOutputFormat_Console);
863 initProgramLinks(&links, *impl_);
864 CommandLineHelpContext context(&outputFile, eHelpOutputFormat_Console, &links,
866 context.setShowHidden(impl_->bHidden_);
867 if (impl_->moduleOverride_ != NULL)
869 context.setModuleDisplayName(impl_->programContext_.displayName());
870 impl_->moduleOverride_->writeHelp(context);
873 impl_->context_ = &context;
875 HelpManager helpManager(*impl_->rootTopic_, context.writerContext());
878 for (int i = 1; i < argc; ++i)
880 helpManager.enterTopic(argv[i]);
883 catch (const InvalidInputError &ex)
885 fprintf(stderr, "%s\n", ex.what());
888 helpManager.writeCurrentTopic();
892 void CommandLineHelpModule::writeHelp(const CommandLineHelpContext &context) const
894 const HelpWriterContext &writerContext = context.writerContext();
896 if (writerContext.outputFormat() != eHelpOutputFormat_Console)
900 writerContext.writeTextBlock(
901 "Usage: [PROGRAM] help [<command>|<topic> [<subtopic> [...]]]");
902 // TODO: More information.