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/baseversion.h"
61 #include "gromacs/utility/exceptions.h"
62 #include "gromacs/utility/file.h"
63 #include "gromacs/utility/gmxassert.h"
64 #include "gromacs/utility/programcontext.h"
65 #include "gromacs/utility/stringutil.h"
67 #include "shellcompletions.h"
74 class HelpExportInterface;
78 /********************************************************************
79 * CommandLineHelpModuleImpl declaration
82 class CommandLineHelpModuleImpl
85 CommandLineHelpModuleImpl(const ProgramContextInterface &programContext,
86 const std::string &binaryName,
87 const CommandLineModuleMap &modules,
88 const CommandLineModuleGroupList &groups);
90 void exportHelp(HelpExportInterface *exporter) const;
92 boost::scoped_ptr<RootHelpTopic> rootTopic_;
93 const ProgramContextInterface &programContext_;
94 std::string binaryName_;
95 const CommandLineModuleMap &modules_;
96 const CommandLineModuleGroupList &groups_;
98 CommandLineHelpContext *context_;
99 const CommandLineModuleInterface *moduleOverride_;
102 File *outputOverride_;
104 GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModuleImpl);
110 /********************************************************************
116 static const char name[];
117 static const char title[];
118 static const char *const text[];
121 // The first two are not used.
122 const char RootHelpText::name[] = "";
123 const char RootHelpText::title[] = "";
124 const char *const RootHelpText::text[] = { "" };
127 * Help topic that forms the root of the help tree for the help subcommand.
129 * \ingroup module_commandline
131 class RootHelpTopic : public CompositeHelpTopic<RootHelpText>
135 * Creates a root help topic.
139 explicit RootHelpTopic(const CommandLineHelpModuleImpl &helpModule)
140 : helpModule_(helpModule)
144 virtual void writeHelp(const HelpWriterContext &context) const;
147 const CommandLineHelpModuleImpl &helpModule_;
149 GMX_DISALLOW_COPY_AND_ASSIGN(RootHelpTopic);
152 void RootHelpTopic::writeHelp(const HelpWriterContext &context) const
154 if (context.outputFormat() != eHelpOutputFormat_Console)
156 // TODO: Implement once the situation with Redmine issue #969 is more
158 GMX_THROW(NotImplementedError(
159 "Root help is not implemented for this output format"));
162 CommandLineCommonOptionsHolder optionsHolder;
163 CommandLineHelpContext cmdlineContext(*helpModule_.context_);
164 cmdlineContext.setModuleDisplayName(helpModule_.binaryName_);
165 optionsHolder.initOptions();
166 // TODO: Add <command> [<args>] into the synopsis.
167 CommandLineHelpWriter(*optionsHolder.options())
168 .writeHelp(cmdlineContext);
170 // TODO: Consider printing a list of "core" commands. Would require someone
171 // to determine such a set...
172 writeSubTopicList(context,
173 "Additional help is available on the following topics:");
174 context.writeTextBlock(
175 "To access the help, use '[PROGRAM] help <topic>'.[BR]"
176 "For help on a command, use '[PROGRAM] help <command>'.");
179 /********************************************************************
184 * Help topic for listing the commands.
186 * \ingroup module_commandline
188 class CommandsHelpTopic : public HelpTopicInterface
192 * Creates a command list help topic.
194 * \param[in] helpModule Help module to get module information from.
198 explicit CommandsHelpTopic(const CommandLineHelpModuleImpl &helpModule)
199 : helpModule_(helpModule)
203 virtual const char *name() const { return "commands"; }
204 virtual const char *title() const { return "List of available commands"; }
205 virtual bool hasSubTopics() const { return false; }
206 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
211 virtual void writeHelp(const HelpWriterContext &context) const;
214 const CommandLineHelpModuleImpl &helpModule_;
216 GMX_DISALLOW_COPY_AND_ASSIGN(CommandsHelpTopic);
219 void CommandsHelpTopic::writeHelp(const HelpWriterContext &context) const
221 if (context.outputFormat() != eHelpOutputFormat_Console)
223 GMX_THROW(NotImplementedError(
224 "Module list is not implemented for this output format"));
226 int maxNameLength = 0;
227 const CommandLineModuleMap &modules = helpModule_.modules_;
228 CommandLineModuleMap::const_iterator module;
229 for (module = modules.begin(); module != modules.end(); ++module)
231 int nameLength = static_cast<int>(module->first.length());
232 if (module->second->shortDescription() != NULL
233 && nameLength > maxNameLength)
235 maxNameLength = nameLength;
238 context.writeTextBlock(
239 "Usage: [PROGRAM] [<options>] <command> [<args>][PAR]"
240 "Available commands:");
241 File &file = context.outputFile();
242 TextTableFormatter formatter;
243 formatter.addColumn(NULL, maxNameLength + 1, false);
244 formatter.addColumn(NULL, 72 - maxNameLength, true);
245 formatter.setFirstColumnIndent(4);
246 for (module = modules.begin(); module != modules.end(); ++module)
248 const char *name = module->first.c_str();
249 const char *description = module->second->shortDescription();
250 if (description != NULL)
253 formatter.addColumnLine(0, name);
254 formatter.addColumnLine(1, description);
255 file.writeString(formatter.formatRow());
258 context.writeTextBlock(
259 "For help on a command, use '[PROGRAM] help <command>'.");
262 /********************************************************************
267 * Help topic wrapper for a command-line module.
269 * This class implements HelpTopicInterface such that it wraps a
270 * CommandLineModuleInterface, allowing subcommand "help <command>"
271 * to produce the help for "<command>".
273 * \ingroup module_commandline
275 class ModuleHelpTopic : public HelpTopicInterface
278 //! Constructs a help topic for a specific module.
279 ModuleHelpTopic(const CommandLineModuleInterface &module,
280 const CommandLineHelpModuleImpl &helpModule)
281 : module_(module), helpModule_(helpModule)
285 virtual const char *name() const { return module_.name(); }
286 virtual const char *title() const { return NULL; }
287 virtual bool hasSubTopics() const { return false; }
288 virtual const HelpTopicInterface *findSubTopic(const char * /*name*/) const
292 virtual void writeHelp(const HelpWriterContext &context) const;
295 const CommandLineModuleInterface &module_;
296 const CommandLineHelpModuleImpl &helpModule_;
298 GMX_DISALLOW_COPY_AND_ASSIGN(ModuleHelpTopic);
301 void ModuleHelpTopic::writeHelp(const HelpWriterContext & /*context*/) const
303 CommandLineHelpContext context(*helpModule_.context_);
304 const char *const program = helpModule_.binaryName_.c_str();
305 context.setModuleDisplayName(formatString("%s %s", program, module_.name()));
306 module_.writeHelp(context);
309 /********************************************************************
310 * HelpExportInterface
314 * Callbacks for exporting help information for command-line modules.
316 * \ingroup module_commandline
318 class HelpExportInterface
321 //! Shorthand for a list of modules contained in a group.
322 typedef CommandLineModuleGroupData::ModuleList ModuleGroupContents;
324 virtual ~HelpExportInterface() {};
327 * Called once before exporting individual modules.
329 * Can, e.g., open shared output files (e.g., if the output is written
330 * into a single file, or if a separate index is required) and write
333 virtual void startModuleExport() = 0;
335 * Called to export the help for each module.
337 * \param[in] module Module for which the help should be exported.
338 * \param[in] tag Unique tag for the module (gmx-something).
339 * \param[in] displayName Display name for the module (gmx something).
341 virtual void exportModuleHelp(
342 const CommandLineModuleInterface &module,
343 const std::string &tag,
344 const std::string &displayName) = 0;
346 * Called after all modules have been exported.
348 * Can close files opened in startModuleExport(), write footers to them
351 virtual void finishModuleExport() = 0;
354 * Called once before exporting module groups.
356 * Can, e.g., open a single output file for listing all the groups.
358 virtual void startModuleGroupExport() = 0;
360 * Called to export the help for each module group.
362 * \param[in] title Title for the group.
363 * \param[in] modules List of modules in the group.
365 virtual void exportModuleGroup(const char *title,
366 const ModuleGroupContents &modules) = 0;
368 * Called after all module groups have been exported.
370 * Can close files opened in startModuleGroupExport(), write footers to them
373 virtual void finishModuleGroupExport() = 0;
377 * Adds hyperlinks to modules within this binary.
379 * \param[in,out] links Links are added here.
380 * \param[in] helpModule Help module to get module information from.
381 * \throws std::bad_alloc if out of memory.
383 * Initializes a HelpLinks object with links to modules defined in
386 * \ingroup module_commandline
388 void initProgramLinks(HelpLinks *links, const CommandLineHelpModuleImpl &helpModule)
390 const char *const program = helpModule.binaryName_.c_str();
391 CommandLineModuleMap::const_iterator module;
392 for (module = helpModule.modules_.begin();
393 module != helpModule.modules_.end();
396 if (module->second->shortDescription() != NULL)
398 std::string linkName("[gmx-" + module->first + "]");
399 std::string targetName(
400 formatString("%s-%s", program, module->first.c_str()));
401 std::string displayName(
402 formatString("[TT]%s %s[tt]", program, module->first.c_str()));
403 links->addLink(linkName, targetName, displayName);
408 /********************************************************************
413 * Implements export for man pages.
415 * \ingroup module_commandline
417 class HelpExportMan : public HelpExportInterface
420 //! Initializes man page exporter.
421 explicit HelpExportMan(const CommandLineHelpModuleImpl &helpModule)
422 : links_(eHelpOutputFormat_Man)
424 initProgramLinks(&links_, helpModule);
427 virtual void startModuleExport() {}
428 virtual void exportModuleHelp(
429 const CommandLineModuleInterface &module,
430 const std::string &tag,
431 const std::string &displayName);
432 virtual void finishModuleExport() {}
434 virtual void startModuleGroupExport();
435 virtual void exportModuleGroup(const char *title,
436 const ModuleGroupContents &modules);
437 virtual void finishModuleGroupExport();
441 boost::scoped_ptr<File> man7File_;
442 std::string man7Footer_;
445 void HelpExportMan::exportModuleHelp(
446 const CommandLineModuleInterface &module,
447 const std::string &tag,
448 const std::string &displayName)
450 File file("man1/" + tag + ".1", "w");
452 // TODO: It would be nice to remove the VERSION prefix from the version
453 // string to make it shorter.
454 file.writeLine(formatString(".TH %s 1 \"\" \"%s\" \"GROMACS Manual\"\n",
455 tag.c_str(), gmx_version()));
456 file.writeLine(".SH NAME");
457 file.writeLine(formatString("%s - %s", tag.c_str(),
458 module.shortDescription()));
461 CommandLineHelpContext context(&file, eHelpOutputFormat_Man, &links_);
462 context.setModuleDisplayName(displayName);
463 module.writeHelp(context);
465 file.writeLine(".SH SEE ALSO");
466 file.writeLine(".BR gromacs(7)");
468 file.writeLine("More information about \\fBGROMACS\\fR is available at <\\fIhttp://www.gromacs.org/\\fR>.");
471 void HelpExportMan::startModuleGroupExport()
473 const char *const programListPlaceholder = "@PROGMANPAGES@";
475 const std::string man7Template = gmx::File::readToString("man7/gromacs.7.in");
476 const size_t index = man7Template.find(programListPlaceholder);
477 GMX_RELEASE_ASSERT(index != std::string::npos,
478 "gromacs.7.in must contain a @PROGMANPAGES@ line");
479 std::string header = man7Template.substr(0, index);
480 man7Footer_ = man7Template.substr(index + std::strlen(programListPlaceholder));
481 header = replaceAll(header, "@VERSION@", gmx_version());
482 man7File_.reset(new File("man7/gromacs.7", "w"));
483 man7File_->writeLine(header);
486 void HelpExportMan::exportModuleGroup(const char *title,
487 const ModuleGroupContents &modules)
489 man7File_->writeLine(formatString(".Sh \"%s\"", title));
490 man7File_->writeLine(formatString(".IX Subsection \"%s\"", title));
491 man7File_->writeLine(".Vb");
492 man7File_->writeLine(".ta 16n");
494 ModuleGroupContents::const_iterator module;
495 for (module = modules.begin(); module != modules.end(); ++module)
497 const std::string &tag(module->first);
498 man7File_->writeLine(formatString("\\& %s\t%s",
499 tag.c_str(), module->second));
502 man7File_->writeLine(".Ve");
505 void HelpExportMan::finishModuleGroupExport()
507 man7File_->writeLine(man7Footer_);
511 /********************************************************************
517 * Implements export for HTML help.
519 * This whole class can go once docs/old-html/ no longer requires header.html
522 * \ingroup module_commandline
524 class HelpExportHtml : public HelpExportInterface
527 //! Initializes HTML exporter.
530 virtual void startModuleExport() {}
531 virtual void exportModuleHelp(
532 const CommandLineModuleInterface & /*module*/,
533 const std::string & /*tag*/,
534 const std::string & /*displayName*/) {}
535 virtual void finishModuleExport() {}
537 virtual void startModuleGroupExport() {}
538 virtual void exportModuleGroup(const char * /*title*/,
539 const ModuleGroupContents & /*modules*/) {}
540 virtual void finishModuleGroupExport() {}
543 HelpExportHtml::HelpExportHtml()
545 std::string header = gmx::File::readToString("header.html.in");
546 header = replaceAll(header, "@VERSION@", gmx_version());
547 gmx::File::writeFileFromString("header.html", header);
550 /********************************************************************
551 * HelpExportReStructuredText
555 * Implements export for web pages as reStructuredText.
557 * \ingroup module_commandline
559 class HelpExportReStructuredText : public HelpExportInterface
562 //! Initializes reST exporter.
563 explicit HelpExportReStructuredText(
564 const CommandLineHelpModuleImpl &helpModule);
566 virtual void startModuleExport();
567 virtual void exportModuleHelp(
568 const CommandLineModuleInterface &module,
569 const std::string &tag,
570 const std::string &displayName);
571 virtual void finishModuleExport();
573 virtual void startModuleGroupExport();
574 virtual void exportModuleGroup(const char *title,
575 const ModuleGroupContents &modules);
576 virtual void finishModuleGroupExport();
580 boost::scoped_ptr<File> indexFile_;
583 HelpExportReStructuredText::HelpExportReStructuredText(
584 const CommandLineHelpModuleImpl &helpModule)
585 : links_(eHelpOutputFormat_Rst)
587 #if 0 // TODO: Investigate how these links can be made to work again.
588 File linksFile("links.dat", "r");
590 while (linksFile.readLine(&line))
592 links_.addLink(line, "../online/" + line, line);
596 initProgramLinks(&links_, helpModule);
599 void HelpExportReStructuredText::startModuleExport()
601 indexFile_.reset(new File("programs/byname.rst", "w"));
602 indexFile_->writeLine("Tools by Name");
603 indexFile_->writeLine("=============");
606 void HelpExportReStructuredText::exportModuleHelp(
607 const CommandLineModuleInterface &module,
608 const std::string &tag,
609 const std::string &displayName)
611 // TODO: Ideally, the file would only be touched if it really changes.
612 // This would make Sphinx reruns much faster.
613 File file("programs/" + tag + ".rst", "w");
614 file.writeLine(formatString(".. _%s:", displayName.c_str()));
616 file.writeLine(displayName);
617 file.writeLine(std::string(displayName.length(), '='));
618 CommandLineHelpContext context(&file, eHelpOutputFormat_Rst, &links_);
619 context.setModuleDisplayName(displayName);
620 module.writeHelp(context);
623 indexFile_->writeLine(formatString("* :doc:`%s <%s>` - %s",
624 displayName.c_str(), tag.c_str(),
625 module.shortDescription()));
628 void HelpExportReStructuredText::finishModuleExport()
634 void HelpExportReStructuredText::startModuleGroupExport()
636 indexFile_.reset(new File("programs/bytopic.rst", "w"));
637 indexFile_->writeLine("Tools by Topic");
638 indexFile_->writeLine("==============");
641 void HelpExportReStructuredText::exportModuleGroup(
643 const ModuleGroupContents &modules)
645 indexFile_->writeLine(title);
646 indexFile_->writeLine(std::string(std::strlen(title), '-'));
648 ModuleGroupContents::const_iterator module;
649 for (module = modules.begin(); module != modules.end(); ++module)
651 const std::string &tag(module->first);
652 std::string displayName(tag);
653 // TODO: This does not work if the binary name would contain a dash,
654 // but that is not currently the case.
655 const size_t dashPos = displayName.find('-');
656 GMX_RELEASE_ASSERT(dashPos != std::string::npos,
657 "There should always be at least one dash in the tag");
658 displayName[dashPos] = ' ';
659 indexFile_->writeLine(formatString("| :doc:`%s <%s>` - %s",
660 displayName.c_str(), tag.c_str(),
663 indexFile_->writeLine();
666 void HelpExportReStructuredText::finishModuleGroupExport()
672 /********************************************************************
673 * HelpExportCompletion
677 * Implements export for command-line completion.
679 * \ingroup module_commandline
681 class HelpExportCompletion : public HelpExportInterface
684 //! Initializes completion exporter.
685 explicit HelpExportCompletion(const CommandLineHelpModuleImpl &helpModule);
687 virtual void startModuleExport();
688 virtual void exportModuleHelp(
689 const CommandLineModuleInterface &module,
690 const std::string &tag,
691 const std::string &displayName);
692 virtual void finishModuleExport();
694 virtual void startModuleGroupExport() {}
695 virtual void exportModuleGroup(const char * /*title*/,
696 const ModuleGroupContents & /*modules*/) {}
697 virtual void finishModuleGroupExport() {}
700 ShellCompletionWriter bashWriter_;
701 std::vector<std::string> modules_;
704 HelpExportCompletion::HelpExportCompletion(
705 const CommandLineHelpModuleImpl &helpModule)
706 : bashWriter_(helpModule.binaryName_, eShellCompletionFormat_Bash)
710 void HelpExportCompletion::startModuleExport()
712 bashWriter_.startCompletions();
715 void HelpExportCompletion::exportModuleHelp(
716 const CommandLineModuleInterface &module,
717 const std::string & /*tag*/,
718 const std::string & /*displayName*/)
720 modules_.push_back(module.name());
722 CommandLineHelpContext context(&bashWriter_);
723 // We use the display name to pass the name of the module to the
724 // completion writer.
725 context.setModuleDisplayName(module.name());
726 module.writeHelp(context);
730 void HelpExportCompletion::finishModuleExport()
732 CommandLineCommonOptionsHolder optionsHolder;
733 optionsHolder.initOptions();
734 bashWriter_.writeWrapperCompletions(modules_, *optionsHolder.options());
735 bashWriter_.finishCompletions();
740 /********************************************************************
741 * 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 outputOverride_(NULL)
755 void CommandLineHelpModuleImpl::exportHelp(HelpExportInterface *exporter) const
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();
784 /********************************************************************
785 * CommandLineHelpModule
788 CommandLineHelpModule::CommandLineHelpModule(
789 const ProgramContextInterface &programContext,
790 const std::string &binaryName,
791 const CommandLineModuleMap &modules,
792 const CommandLineModuleGroupList &groups)
793 : impl_(new Impl(programContext, binaryName, modules, groups))
797 CommandLineHelpModule::~CommandLineHelpModule()
801 HelpTopicPointer CommandLineHelpModule::createModuleHelpTopic(
802 const CommandLineModuleInterface &module) const
804 return HelpTopicPointer(new ModuleHelpTopic(module, *impl_));
807 void CommandLineHelpModule::addTopic(HelpTopicPointer topic)
809 impl_->rootTopic_->addSubTopic(move(topic));
812 void CommandLineHelpModule::setShowHidden(bool bHidden)
814 impl_->bHidden_ = bHidden;
817 void CommandLineHelpModule::setModuleOverride(
818 const CommandLineModuleInterface &module)
820 impl_->moduleOverride_ = &module;
823 void CommandLineHelpModule::setOutputRedirect(File *output)
825 impl_->outputOverride_ = output;
828 int CommandLineHelpModule::run(int argc, char *argv[])
830 // Add internal topics lazily here.
831 addTopic(HelpTopicPointer(new CommandsHelpTopic(*impl_)));
833 const char *const exportFormats[] = { "man", "html", "rst", "completion" };
834 std::string exportFormat;
835 Options options(NULL, NULL);
836 options.addOption(StringOption("export").store(&exportFormat)
837 .enumValue(exportFormats));
838 CommandLineParser(&options).parse(&argc, argv);
839 if (!exportFormat.empty())
841 boost::scoped_ptr<HelpExportInterface> exporter;
842 if (exportFormat == "man")
844 exporter.reset(new HelpExportMan(*impl_));
846 else if (exportFormat == "html")
848 exporter.reset(new HelpExportHtml());
850 else if (exportFormat == "rst")
852 exporter.reset(new HelpExportReStructuredText(*impl_));
854 else if (exportFormat == "completion")
856 exporter.reset(new HelpExportCompletion(*impl_));
860 GMX_THROW(NotImplementedError("This help format is not implemented"));
862 impl_->exportHelp(exporter.get());
866 File *outputFile = &File::standardOutput();
867 if (impl_->outputOverride_ != NULL)
869 outputFile = impl_->outputOverride_;
871 HelpLinks links(eHelpOutputFormat_Console);
872 initProgramLinks(&links, *impl_);
873 boost::scoped_ptr<CommandLineHelpContext> context(
874 new CommandLineHelpContext(outputFile,
875 eHelpOutputFormat_Console, &links));
876 context->setShowHidden(impl_->bHidden_);
877 if (impl_->moduleOverride_ != NULL)
879 context->setModuleDisplayName(impl_->programContext_.displayName());
880 impl_->moduleOverride_->writeHelp(*context);
883 impl_->context_ = context.get();
885 HelpManager helpManager(*impl_->rootTopic_, context->writerContext());
888 for (int i = 1; i < argc; ++i)
890 helpManager.enterTopic(argv[i]);
893 catch (const InvalidInputError &ex)
895 fprintf(stderr, "%s\n", ex.what());
898 helpManager.writeCurrentTopic();
902 void CommandLineHelpModule::writeHelp(const CommandLineHelpContext &context) const
904 const HelpWriterContext &writerContext = context.writerContext();
906 if (writerContext.outputFormat() != eHelpOutputFormat_Console)
910 writerContext.writeTextBlock(
911 "Usage: [PROGRAM] help [<command>|<topic> [<subtopic> [...]]]");
912 // TODO: More information.