Add listing of programs by topic to HTML output.
authorTeemu Murtola <teemu.murtola@gmail.com>
Tue, 8 Oct 2013 18:34:40 +0000 (21:34 +0300)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Sat, 16 Nov 2013 22:31:54 +0000 (23:31 +0100)
Now the HTML-exported help contains also a list of programs by topic,
similar to what used to be generated from programs.txt.  Removed the
mkhtml script, since it is now fully replaced by the mechanism in the
wrapper binary.

The same mechanism could also be used to replace the gromacs.7 man page,
but in its current form, it contains so much boilerplate code that I
didn't want to copy-paste that all into the source file.  And it could
also be used to make the output of 'gmx help' more structured.

Related to #685, #969, and #1242.

Change-Id: I6c2efe10c53f10f7fde90b3386ddea7fbea34b89

admin/mkhtml [deleted file]
share/html/online.html
src/gromacs/commandline/cmdlinemodulemanager.cpp
src/gromacs/commandline/cmdlinemodulemanager.h
src/gromacs/trajectoryanalysis/modules.cpp
src/programs/gmx/legacymodules.cpp

diff --git a/admin/mkhtml b/admin/mkhtml
deleted file mode 100755 (executable)
index 30a245a..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/bin/csh -f
-
-if ( $#argv < 2 ) then
-  echo "Error: provide the binary directory as first argument,"
-  echo "and the location of programs.txt as the second."
-  echo "A html subdirectory will be created in the current dir."
-  exit
-endif
-
-set GMXBINDIR   = $1
-set PROGFILE   = $2
-
-set dir = $cwd
-
-set VER                = 4.6.4
-set MANDIR     = online
-set HTML       = $cwd/html
-set HTMLOL     = $HTML/$MANDIR
-set HTMLIDX    = $HTML/$MANDIR.html
-
-set GENERAL    = "getting_started:Getting_Started flow:Flow_Chart files:File_Formats mdp_opt:mdp_options"
-
-cd $GMXBINDIR
-set PROGRAMS = [a-z]*
-cd $dir
-
-echo ""
-echo "Generating table of contents in $HTMLIDX"
-echo "-------------------------------------------"
-
-if ( ! -d $HTML ) mkdir $HTML
-if ( ! -d $HTMLOL ) mkdir $HTMLOL
-
-if ( -f $HTMLIDX ) \rm $HTMLIDX
-touch $HTMLIDX
-
-cat > $HTMLIDX << EOD
-<HTML>
-<HEAD>
-<TITLE>GROMACS $VER Online Reference </TITLE>
-</HEAD>
-<LINK rel=stylesheet href="online/style.css" type="text/css">
-<BODY text="#000000" bgcolor="#FFFFFF" link="#0000FF" vlink="#990000" alink="#FF0000">
-
-<table WIDTH="98%" NOSAVE NOBORDER >
-<TR><TD WIDTH=400>
-<TABLE WIDTH=400 NOBORDER>
-<TD WIDTH=116>
-<a href="http://www.gromacs.org/">
-<img SRC="images/gmxlogo_small.jpg" BORDER=0 height=133 width=116></a></td>
-<td ALIGN=LEFT VALIGN=TOP WIDTH=280>
-<br><br>
-<h2>
-GROMACS $VER<br>
-Online Reference</h2>
-</td>
-</TABLE></TD>
-<td ALIGN=RIGHT VALIGN=BOTTOM WIDTH="*" NOSAVE>
-<B>VERSION $VER</B></td>
-</tr>
-</table>
-
-<hr>
-
-<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=10>
-<TR>
-<TD VALIGN=top WIDTH="25%">
-<h3>General</h3>
-EOD
-foreach i ( $GENERAL )
-  set file = `echo $i | cut -d: -f1`
-  set desc = `echo $i | cut -d: -f2 | sed 's/_/ /g'`
-  echo "<A HREF="\""$MANDIR/"$file".html"\"">"$desc"</a>" >> $HTMLIDX
-  echo "<br><br>" >> $HTMLIDX
-end
-cat >> $HTMLIDX <<EOD
-<A HREF="http://www.gromacs.org/Documentation/FAQs">FAQ</a>
-<br>
-</TD>
-<TD VALIGN=top WIDTH=75%>
-<h3>Programs</h3>
-<multicol cols=5> 
-<A HREF="$MANDIR/options.html">Options</a>
-<br>
-EOD
-foreach program ( $PROGRAMS )
-  if ( ( -x $GMXBINDIR/$program ) && ( $program != "my_dssp" ) && ( $program != "GMXRC" ) && ( $program != "completion.csh" ) && ( $program != "completion.zsh" ) && ( $program != "average" ) && ( $program != "completion.bash" ) && ( $program != "demux.pl" ) && ( $program != "xplor2gmx.pl" ) ) then  
-    echo "<br><a href="$MANDIR/$program.html">$program</a>" >> $HTMLIDX
-  endif
-end
-cat >> $HTMLIDX << EOD
-</multicol>
-</TD>
-</TR>
-</TABLE>
-<HR>
-<h3>Programs by Topic</h3>
-<multicol cols=3>
-EOD
-awk -F '|' -v mandir=$MANDIR '{\
-  if (NF) {\
-    if ( $1 == "HEAD" ) {\
-      hnr++;\
-      printf("<A HREF=\"#HNR%d\">%s</A><br>\n",hnr,$2);\
-    }\
-  }\
-}' $PROGFILE >> $HTMLIDX
-echo "</multicol> " >> $HTMLIDX
-awk -F '|' -v mandir=$MANDIR '{\
-  if (NF) {\
-    if ( $1 == "HEAD" ) {\
-      hnr++;\
-      printf("\n<A NAME=\"HNR%d\">\n",hnr);\
-      printf("<TABLE CELLSPACING=1>\n<TR><TD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n");\
-      printf("<TR><TD COLSPAN=2><b>%s</b>\n",$2);\
-    } else if ( $1 == "END" ) {\
-      printf("</TABLE>\n");\
-    } else {\
-      printf("<TR><TD><A HREF=\"%s/%s.html\">%s</A></TD><TD>%s</TD>\n",mandir,$1,$1,$2);\
-    }\
-  }\
-}' $PROGFILE >> $HTMLIDX
-cat >> $HTMLIDX <<EOD
-<p>
-<hr>
-<div ALIGN=RIGHT>
-<font size="-1"><a href="http://www.gromacs.org">http://www.gromacs.org</a></font><br>
-</body>
-</html>
-EOD
-
-echo "Generating html manual for GROMACS programs"
-echo "-------------------------------------------"
-
-cd $dir
-
-setenv GMX_MAXBACKUP -1
-foreach program ( $PROGRAMS )
-  if ( ( -x $GMXBINDIR/$program ) && ( $program != "my_dssp" ) && ( $program != "GMXRC" ) && ( $program != "completion.csh" ) && ( $program != "completion.zsh" ) && ( $program != "average" ) && ( $program != "completion.bash" ) && ( $program != "demux.pl" ) ) then
-    echo -n "$program "
-    cd $HTMLOL
-    $GMXBINDIR/$program -quiet -man html >& /dev/null
-    cd ..
-    endif
-  endif
-end
-echo
-
-#last line
index 1d4b5f016256c9b78b0147bd7debaedc784eec2a..143c588bfe88cf88cfee48c7f93cef46a5727267 100644 (file)
@@ -46,6 +46,8 @@ Sat 19 Jan 2013</B></td>
 <A HREF="online/options.html">Options</a>
 <br><br>
 <a href="programs/byname.html">All Programs Alphabetically</a>
+<br><br>
+<a href="programs/bytopic.html">Programs by Topic</a>
 </TD>
 </TR>
 </TABLE>
index 3486a1e48cd0379371e43fb9f330a1d9ecea7379..d4524aa6d8e0f3ba910e2ec344b64d9b2ba4a843 100644 (file)
 #include "gromacs/utility/init.h"
 #include "gromacs/utility/programinfo.h"
 #include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/uniqueptr.h"
 
 namespace gmx
 {
 
 //! Container type for mapping module names to module objects.
 typedef std::map<std::string, CommandLineModulePointer> CommandLineModuleMap;
+//! Smart pointer type for managing a CommandLineModuleGroup.
+typedef gmx_unique_ptr<internal::CommandLineModuleGroupData>::type
+    CommandLineModuleGroupDataPointer;
+//! Container type for keeping a list of module groups.
+typedef std::vector<CommandLineModuleGroupDataPointer>
+    CommandLineModuleGroupList;
 
 class CommandLineHelpModule;
 
+namespace internal
+{
+
+/*! \internal
+ * \brief
+ * Internal data for a CommandLineModuleManager module group.
+ *
+ * This class contains the state of a module group.  CommandLineModuleGroup
+ * provides the public interface to construct/alter the state, and
+ * CommandLineModuleManager and its associated classes use it for help output.
+ *
+ * \ingroup module_commandline
+ */
+class CommandLineModuleGroupData
+{
+    public:
+        /*! \brief
+         * Shorthand for a list of modules contained in the group.
+         *
+         * The first element in the contained pair contains the tag
+         * (gmx-something) of the module, and the second element contains the
+         * description.  The second element is never NULL.
+         */
+        typedef std::vector<std::pair<std::string, const char *> > ModuleList;
+
+        /*! \brief
+         * Constructs an empty module group.
+         *
+         * \param[in] modules  List of all modules
+         *     (used for checking and default descriptions).
+         * \param[in] title    Title of the group.
+         *
+         * Does not throw.
+         */
+        CommandLineModuleGroupData(const CommandLineModuleMap &modules,
+                                   const char                 *title)
+            : allModules_(modules), title_(title)
+        {
+        }
+
+        //! Returns the title for the group.
+        const char *title() const { return title_; }
+        //! Returns the list of modules in the group.
+        const ModuleList &modules() const { return modules_; }
+
+        /*! \brief
+         * Adds a module to the group.
+         *
+         * \param[in] name        Name of the module.
+         * \param[in] description Description of the module in this group.
+         * \throws    std::bad_alloc if out of memory.
+         *
+         * If \p description is NULL, the description returned by the module is
+         * used.
+         */
+        void addModule(const char *name, const char *description)
+        {
+            CommandLineModuleMap::const_iterator moduleIter = allModules_.find(name);
+            GMX_RELEASE_ASSERT(moduleIter != allModules_.end(),
+                               "Non-existent module added to a group");
+            if (description == NULL)
+            {
+                description = moduleIter->second->shortDescription();
+                GMX_RELEASE_ASSERT(description != NULL,
+                                   "Module without a description added to a group");
+            }
+            const char *const program =
+                ProgramInfo::getInstance().invariantProgramName().c_str();
+            std::string       tag(formatString("%s-%s", program, name));
+            modules_.push_back(std::make_pair(tag, description));
+        }
+
+    private:
+        const CommandLineModuleMap &allModules_;
+        const char                 *title_;
+        ModuleList                  modules_;
+
+        GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineModuleGroupData);
+};
+
+}   // namespace internal
+
 namespace
 {
 
@@ -244,6 +333,10 @@ class ModuleHelpTopic : public HelpTopicInterface
 class HelpExportInterface
 {
     public:
+        //! Shorthand for a list of modules contained in a group.
+        typedef internal::CommandLineModuleGroupData::ModuleList
+            ModuleGroupContents;
+
         virtual ~HelpExportInterface() {};
 
         /*! \brief
@@ -269,6 +362,28 @@ class HelpExportInterface
          * etc.
          */
         virtual void finishModuleExport() = 0;
+
+        /*! \brief
+         * Called once before exporting module groups.
+         *
+         * Can, e.g., open a single output file for listing all the groups.
+         */
+        virtual void startModuleGroupExport() = 0;
+        /*! \brief
+         * Called to export the help for each module group.
+         *
+         * \param[in] title    Title for the group.
+         * \param[in] modules  List of modules in the group.
+         */
+        virtual void exportModuleGroup(const char                *title,
+                                       const ModuleGroupContents &modules) = 0;
+        /*! \brief
+         * Called after all module groups have been exported.
+         *
+         * Can close files opened in startModuleGroupExport(), write footers to them
+         * etc.
+         */
+        virtual void finishModuleGroupExport() = 0;
 };
 
 /********************************************************************
@@ -287,6 +402,14 @@ class HelpExportMan : public HelpExportInterface
         virtual void exportModuleHelp(const std::string                &tag,
                                       const CommandLineModuleInterface &module);
         virtual void finishModuleExport() {}
+
+        virtual void startModuleGroupExport() {}
+        virtual void exportModuleGroup(const char                * /*title*/,
+                                       const ModuleGroupContents & /*modules*/) {}
+        virtual void finishModuleGroupExport() {}
+
+    private:
+        boost::scoped_ptr<File> indexFile_;
 };
 
 void HelpExportMan::exportModuleHelp(const std::string                &tag,
@@ -335,11 +458,16 @@ class HelpExportHtml : public HelpExportInterface
                                       const CommandLineModuleInterface &module);
         virtual void finishModuleExport();
 
+        virtual void startModuleGroupExport();
+        virtual void exportModuleGroup(const char                *title,
+                                       const ModuleGroupContents &modules);
+        virtual void finishModuleGroupExport();
+
     private:
         void writeHtmlHeader(File *file, const std::string &title) const;
         void writeHtmlFooter(File *file) const;
 
-        boost::scoped_ptr<File>  byNameFile_;
+        boost::scoped_ptr<File>  indexFile_;
         HelpLinks                links_;
 };
 
@@ -360,9 +488,9 @@ HelpExportHtml::HelpExportHtml()
 
 void HelpExportHtml::startModuleExport()
 {
-    byNameFile_.reset(new File("byname.html", "w"));
-    writeHtmlHeader(byNameFile_.get(), "GROMACS Programs by Name");
-    byNameFile_->writeLine("<H3>GROMACS Programs Alphabetically</H3>");
+    indexFile_.reset(new File("byname.html", "w"));
+    writeHtmlHeader(indexFile_.get(), "GROMACS Programs by Name");
+    indexFile_->writeLine("<H3>GROMACS Programs Alphabetically</H3>");
 }
 
 void HelpExportHtml::exportModuleHelp(const std::string                &tag,
@@ -381,15 +509,45 @@ void HelpExportHtml::exportModuleHelp(const std::string                &tag,
     writeHtmlFooter(&file);
     file.close();
 
-    byNameFile_->writeLine(formatString("<a href=\"%s.html\">%s</a> - %s<br>",
-                                        tag.c_str(), displayName.c_str(),
-                                        module.shortDescription()));
+    indexFile_->writeLine(formatString("<a href=\"%s.html\">%s</a> - %s<br>",
+                                       tag.c_str(), displayName.c_str(),
+                                       module.shortDescription()));
 }
 
 void HelpExportHtml::finishModuleExport()
 {
-    writeHtmlFooter(byNameFile_.get());
-    byNameFile_->close();
+    writeHtmlFooter(indexFile_.get());
+    indexFile_->close();
+}
+
+void HelpExportHtml::startModuleGroupExport()
+{
+    indexFile_.reset(new File("bytopic.html", "w"));
+    writeHtmlHeader(indexFile_.get(), "GROMACS Programs by Topic");
+    indexFile_->writeLine("<H3>GROMACS Programs by Topic</H3>");
+}
+
+void HelpExportHtml::exportModuleGroup(const char                *title,
+                                       const ModuleGroupContents &modules)
+{
+    indexFile_->writeLine(formatString("<H4>%s</H4>", title));
+
+    ModuleGroupContents::const_iterator module;
+    for (module = modules.begin(); module != modules.end(); ++module)
+    {
+        const std::string     &tag(module->first);
+        std::string            displayName(tag);
+        std::replace(displayName.begin(), displayName.end(), '-', ' ');
+        indexFile_->writeLine(formatString("<a href=\"%s.html\">%s</a> - %s<br>",
+                                           tag.c_str(), displayName.c_str(),
+                                           module->second));
+    }
+}
+
+void HelpExportHtml::finishModuleGroupExport()
+{
+    writeHtmlFooter(indexFile_.get());
+    indexFile_->close();
 }
 
 void HelpExportHtml::writeHtmlHeader(File *file, const std::string &title) const
@@ -451,9 +609,11 @@ class CommandLineHelpModule : public CommandLineModuleInterface
          * Creates a command-line help module.
          *
          * \param[in] modules  List of modules for to use for module listings.
+         * \param[in] groups   List of module groups.
          * \throws    std::bad_alloc if out of memory.
          */
-        explicit CommandLineHelpModule(const CommandLineModuleMap &modules);
+        CommandLineHelpModule(const CommandLineModuleMap       &modules,
+                              const CommandLineModuleGroupList &groups);
 
         /*! \brief
          * Adds a top-level help topic.
@@ -495,6 +655,7 @@ class CommandLineHelpModule : public CommandLineModuleInterface
 
         boost::scoped_ptr<RootHelpTopic>  rootTopic_;
         const CommandLineModuleMap       &modules_;
+        const CommandLineModuleGroupList &groups_;
 
         CommandLineHelpContext           *context_;
         const CommandLineModuleInterface *moduleOverride_;
@@ -503,8 +664,10 @@ class CommandLineHelpModule : public CommandLineModuleInterface
         GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModule);
 };
 
-CommandLineHelpModule::CommandLineHelpModule(const CommandLineModuleMap &modules)
-    : rootTopic_(new RootHelpTopic(modules)), modules_(modules),
+CommandLineHelpModule::CommandLineHelpModule(
+        const CommandLineModuleMap       &modules,
+        const CommandLineModuleGroupList &groups)
+    : rootTopic_(new RootHelpTopic(modules)), modules_(modules), groups_(groups),
       context_(NULL), moduleOverride_(NULL), bHidden_(false)
 {
 }
@@ -601,6 +764,14 @@ void CommandLineHelpModule::exportHelp(HelpExportInterface *exporter) const
         }
     }
     exporter->finishModuleExport();
+
+    exporter->startModuleGroupExport();
+    CommandLineModuleGroupList::const_iterator group;
+    for (group = groups_.begin(); group != groups_.end(); ++group)
+    {
+        exporter->exportModuleGroup((*group)->title(), (*group)->modules());
+    }
+    exporter->finishModuleGroupExport();
 }
 
 namespace
@@ -788,6 +959,14 @@ class CommandLineModuleManager::Impl
          * Owns the contained modules.
          */
         CommandLineModuleMap         modules_;
+        /*! \brief
+         * List of groupings for modules for help output.
+         *
+         * Owns the contained module group data objects.
+         * CommandLineModuleGroup objects point to the data objects contained
+         * here.
+         */
+        CommandLineModuleGroupList   moduleGroups_;
         //! Information about the currently running program.
         ProgramInfo                 &programInfo_;
         /*! \brief
@@ -831,7 +1010,7 @@ void CommandLineModuleManager::Impl::ensureHelpModuleExists()
 {
     if (helpModule_ == NULL)
     {
-        helpModule_ = new CommandLineHelpModule(modules_);
+        helpModule_ = new CommandLineHelpModule(modules_, moduleGroups_);
         addModule(CommandLineModulePointer(helpModule_));
     }
 }
@@ -994,6 +1173,15 @@ void CommandLineModuleManager::addModuleCMain(
     addModule(move(module));
 }
 
+CommandLineModuleGroup CommandLineModuleManager::addModuleGroup(
+        const char *title)
+{
+    CommandLineModuleGroupDataPointer group(
+            new internal::CommandLineModuleGroupData(impl_->modules_, title));
+    impl_->moduleGroups_.push_back(move(group));
+    return CommandLineModuleGroup(impl_->moduleGroups_.back().get());
+}
+
 void CommandLineModuleManager::addHelpTopic(HelpTopicPointer topic)
 {
     impl_->ensureHelpModuleExists();
@@ -1068,4 +1256,19 @@ int CommandLineModuleManager::runAsMainCMain(
     return runAsMainSingleModule(argc, argv, &module);
 }
 
+/********************************************************************
+ * CommandLineModuleGroup
+ */
+
+void CommandLineModuleGroup::addModule(const char *name)
+{
+    impl_->addModule(name, NULL);
+}
+
+void CommandLineModuleGroup::addModuleWithDescription(const char *name,
+                                                      const char *description)
+{
+    impl_->addModule(name, description);
+}
+
 } // namespace gmx
index c6dcbdcfe9f8b777097ffec6e224aeb7d54fc132..6324616f607dc73b384f97dd94847854b91471d3 100644 (file)
@@ -50,6 +50,7 @@
 namespace gmx
 {
 
+class CommandLineModuleGroup;
 class CommandLineModuleInterface;
 class ProgramInfo;
 
@@ -57,6 +58,11 @@ class ProgramInfo;
 typedef gmx_unique_ptr<CommandLineModuleInterface>::type
     CommandLineModulePointer;
 
+namespace internal
+{
+class CommandLineModuleGroupData;
+}   // namespace internal
+
 /*! \brief
  * Implements a wrapper command-line interface for multiple modules.
  *
@@ -235,7 +241,20 @@ class CommandLineModuleManager
         }
 
         /*! \brief
-         * Make given help topic available through the manager's help module.
+         * Adds a group for modules to use in help output.
+         *
+         * \param[in] title  Short title for the group.
+         * \returns   Handle that can be used to add modules to the group.
+         * \throws    std::bad_alloc if out of memory.
+         *
+         * Creates a group that is used to structure the list of all modules in
+         * help output.  Modules are added to the group using the returned
+         * object.
+         */
+        CommandLineModuleGroup addModuleGroup(const char *title);
+
+        /*! \brief
+         * Makes given help topic available through the manager's help module.
          *
          * \param[in]  topic  Help topic to add.
          * \throws     std::bad_alloc if out of memory.
@@ -265,6 +284,58 @@ class CommandLineModuleManager
         PrivateImplPointer<Impl> impl_;
 };
 
+/*! \brief
+ * Handle to add content to a group added with
+ * CommandLineModuleManager::addModuleGroup().
+ *
+ * This class only provides a public interface to construct a module group for
+ * CommandLineModuleManager, and has semantics similar to a pointer: copies all
+ * point to the same group.  The actual state of the group is maintained in an
+ * internal implementation class.
+ *
+ * \inpublicapi
+ * \ingroup module_commandline
+ */
+class CommandLineModuleGroup
+{
+    public:
+        /*! \cond internal */
+        //! Shorthand for the implementation type that holds all the data.
+        typedef internal::CommandLineModuleGroupData Impl;
+
+        //! Creates a new group (only called by CommandLineModuleManager).
+        explicit CommandLineModuleGroup(Impl *impl) : impl_(impl) {}
+        //! \endcond
+
+        /*! \brief
+         * Adds a module to this group.
+         *
+         * \param[in] name  Name of the module.
+         * \throws    std::bad_alloc if out of memory.
+         *
+         * This works as addModuleWithDescription(), but uses the short
+         * description of the module itself as the description.
+         *
+         * \see addModuleWithDescription()
+         */
+        void addModule(const char *name);
+        /*! \brief
+         * Adds a module to this group with a custom description.
+         *
+         * \param[in] name        Name of the module.
+         * \param[in] description Description of the module in this group.
+         * \throws    std::bad_alloc if out of memory.
+         *
+         * \p name must name a module added into the CommandLineModuleManager.
+         * It is possible to add the same module into multiple groups.
+         */
+        void addModuleWithDescription(const char *name, const char *description);
+
+    private:
+        //! Pointer to the data owned by CommandLineModuleManager.
+        Impl                     *impl_;
+};
+
 } // namespace gmx
 
 #endif
index c45421b4d4aa3d2402e9177b68fd5a7067ba2289..d5d16c124a3c29a14d8b0d7e18f01d36b6be260a 100644 (file)
@@ -41,6 +41,7 @@
  */
 #include "gromacs/trajectoryanalysis/modules.h"
 
+#include "gromacs/commandline/cmdlinemodulemanager.h"
 #include "gromacs/trajectoryanalysis/cmdlinerunner.h"
 
 #include "modules/angle.h"
@@ -67,11 +68,13 @@ namespace
  * \ingroup module_trajectoryanalysis
  */
 template <class ModuleInfo>
-void registerModule(CommandLineModuleManager *manager)
+void registerModule(CommandLineModuleManager *manager,
+                    CommandLineModuleGroup    group)
 {
     TrajectoryAnalysisCommandLineRunner::registerModule(
             manager, ModuleInfo::name, ModuleInfo::shortDescription,
             &ModuleInfo::create);
+    group.addModule(ModuleInfo::name);
 }
 
 }   // namespace
@@ -79,10 +82,11 @@ void registerModule(CommandLineModuleManager *manager)
 void registerTrajectoryAnalysisModules(CommandLineModuleManager *manager)
 {
     using namespace gmx::analysismodules;
-    registerModule<AngleInfo>(manager);
-    registerModule<DistanceInfo>(manager);
-    registerModule<FreeVolumeInfo>(manager);
-    registerModule<SelectInfo>(manager);
+    CommandLineModuleGroup group = manager->addModuleGroup("Trajectory analysis");
+    registerModule<AngleInfo>(manager, group);
+    registerModule<DistanceInfo>(manager, group);
+    registerModule<FreeVolumeInfo>(manager, group);
+    registerModule<SelectInfo>(manager, group);
 }
 
 } // namespace gmx
index 9e8ddc0165485a495a94534ded3ace0b7f19b985..f45fb20abefe0f827c2f7ca271c4e85af7d79a0f 100644 (file)
@@ -222,7 +222,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager)
     registerModule(manager, &gmx_covar, "covar",
                    "Calculate and diagonalize the covariance matrix");
     registerModule(manager, &gmx_current, "current",
-                   "Calculate dielectric constants and charge autocorrelation function");
+                   "Calculate dielectric constants and current autocorrelation function");
     registerModule(manager, &gmx_density, "density",
                    "Calculate the density of the system");
     registerModule(manager, &gmx_densmap, "densmap",
@@ -305,11 +305,11 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager)
     registerModule(manager, &gmx_saltbr, "saltbr",
                    "Compute salt bridges");
     registerModule(manager, &gmx_sans, "sans",
-                   "Compute the small angle neutron scattering spectra");
+                   "Compute small angle neutron scattering spectra");
     registerModule(manager, &gmx_sas, "sas",
                    "Compute solvent accessible surface area");
     registerModule(manager, &gmx_saxs, "saxs",
-                   "Calculates SAXS structure factors based on Cromer's method");
+                   "Compute small angle X-ray scattering spectra");
     registerModule(manager, &gmx_sham, "sham",
                    "Compute free energies or other histograms from histograms");
     registerModule(manager, &gmx_sigeps, "sigeps",
@@ -327,7 +327,7 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager)
     registerModule(manager, &gmx_tune_pme, "tune_pme",
                    "Time mdrun as a function of PME nodes to optimize settings");
     registerModule(manager, &gmx_vanhove, "vanhove",
-                   "Compute Van Hove correlation functions");
+                   "Compute Van Hove displacement and correlation functions");
     registerModule(manager, &gmx_velacc, "velacc",
                    "Calculate velocity autocorrelation functions");
     registerModule(manager, &gmx_wham, "wham",
@@ -337,7 +337,182 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager)
     registerModule(manager, &gmx_view, "view",
                    "View a trajectory on an X-Windows terminal");
 
-    // TODO: Also include binaries from other directories than src/tools/:
-    //        "mdrun|finds a potential energy minimum and calculates the Hessian");
-    //        "mdrun|with -rerun (re)calculates energies for trajectory frames");
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Generating topologies and coordinates");
+        group.addModuleWithDescription("editconf", "Edit the box and write subgroups");
+        group.addModule("protonate");
+        group.addModule("x2top");
+        group.addModule("genbox");
+        group.addModule("genconf");
+        group.addModule("genion");
+        group.addModule("genrestr");
+        group.addModule("pdb2gmx");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Running a simulation");
+        group.addModule("grompp");
+        group.addModule("mdrun");
+        group.addModule("tpbconv");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Viewing trajectories");
+        group.addModule("nmtraj");
+        group.addModule("view");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Processing energies");
+        group.addModule("enemat");
+        group.addModule("energy");
+        group.addModuleWithDescription("mdrun", "(Re)calculate energies for trajectory frames with -rerun");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Converting files");
+        group.addModule("editconf");
+        group.addModule("eneconv");
+        group.addModule("sigeps");
+        group.addModule("trjcat");
+        group.addModule("trjconv");
+        group.addModule("xpm2ps");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Tools");
+        group.addModule("analyze");
+        group.addModule("dyndom");
+        group.addModule("filter");
+        group.addModule("lie");
+        group.addModule("morph");
+        group.addModule("pme_error");
+        group.addModule("sham");
+        group.addModule("spatial");
+        group.addModule("traj");
+        group.addModule("tune_pme");
+        group.addModule("wham");
+        group.addModule("check");
+        group.addModule("dump");
+        group.addModule("make_ndx");
+        group.addModule("mk_angndx");
+        group.addModule("trjorder");
+        group.addModule("xpm2ps");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Distances between structures");
+        group.addModule("cluster");
+        group.addModule("confrms");
+        group.addModule("rms");
+        group.addModule("rmsf");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Distances in structures over time");
+        group.addModule("mindist");
+        group.addModule("mdmat");
+        group.addModule("polystat");
+        group.addModule("rmsdist");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Mass distribution properties over time");
+        group.addModule("gyrate");
+        group.addModule("msd");
+        group.addModule("polystat");
+        group.addModule("rdf");
+        group.addModule("rotacf");
+        group.addModule("rotmat");
+        group.addModule("sans");
+        group.addModule("saxs");
+        group.addModule("traj");
+        group.addModule("vanhove");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Analyzing bonded interactions");
+        group.addModule("angle");
+        group.addModule("mk_angndx");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Structural properties");
+        group.addModule("anadock");
+        group.addModule("bundle");
+        group.addModule("clustsize");
+        group.addModule("disre");
+        group.addModule("hbond");
+        group.addModule("order");
+        group.addModule("principal");
+        group.addModule("rdf");
+        group.addModule("saltbr");
+        group.addModule("sas");
+        group.addModule("sorient");
+        group.addModule("spol");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Kinetic properties");
+        group.addModule("bar");
+        group.addModule("current");
+        group.addModule("dos");
+        group.addModule("dyecoupl");
+        group.addModule("kinetics");
+        group.addModule("principal");
+        group.addModule("tcaf");
+        group.addModule("traj");
+        group.addModule("vanhove");
+        group.addModule("velacc");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Electrostatic properties");
+        group.addModule("current");
+        group.addModule("dielectric");
+        group.addModule("dipoles");
+        group.addModule("potential");
+        group.addModule("spol");
+        group.addModule("genion");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Protein-specific analysis");
+        group.addModule("do_dssp");
+        group.addModule("chi");
+        group.addModule("helix");
+        group.addModule("helixorient");
+        group.addModule("rama");
+        group.addModule("wheel");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Interfaces");
+        group.addModule("bundle");
+        group.addModule("density");
+        group.addModule("densmap");
+        group.addModule("densorder");
+        group.addModule("h2order");
+        group.addModule("hydorder");
+        group.addModule("order");
+        group.addModule("potential");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Covariance analysis");
+        group.addModuleWithDescription("anaeig", "Analyze the eigenvectors");
+        group.addModule("covar");
+        group.addModule("make_edi");
+    }
+    {
+        gmx::CommandLineModuleGroup group =
+            manager->addModuleGroup("Normal modes");
+        group.addModuleWithDescription("anaeig", "Analyze the normal modes");
+        group.addModule("nmeig");
+        group.addModule("nmtraj");
+        group.addModule("nmens");
+        group.addModule("grompp");
+        group.addModuleWithDescription("mdrun", "Find a potential energy minimum and calculate the Hessian");
+    }
 }