From 59731e2a4c0b1a8c75a7f3d7598495141989204e Mon Sep 17 00:00:00 2001 From: Teemu Murtola Date: Wed, 20 May 2015 13:34:47 +0300 Subject: [PATCH] Include selection keyword details in user guide - Make 'gmx help -export rst' write out the detailed selection keyword help as subsections of the keywords topic. - Separate the titles from the help texts to make it possible to format the title separately. - Make synopsis formatting the same for each keyword details help topic. - Make HelpWriterContext not write leading empty lines to console output when the help text starts with a literal block. - Remove unnecessary stars from the keyword lists in the reStructuredText output. Some minor cleanup of the formatting could be done, but otherwise this closes #679. Change-Id: Id91ce3c01e9dd5f1c068498217dbc536a712c231 --- src/gromacs/onlinehelp/helpwritercontext.cpp | 4 ++ .../onlinehelp/tests/helpwritercontext.cpp | 13 ++++ ...textTest_FormatsLiteralTextAtBeginning.xml | 16 +++++ src/gromacs/selection/selhelp.cpp | 65 +++++++++++++++++-- src/gromacs/selection/selmethod.h | 13 +++- src/gromacs/selection/sm_compare.cpp | 4 +- src/gromacs/selection/sm_distance.cpp | 17 +++-- src/gromacs/selection/sm_insolidangle.cpp | 13 ++-- src/gromacs/selection/sm_keywords.cpp | 6 +- src/gromacs/selection/sm_merge.cpp | 12 ++-- src/gromacs/selection/sm_permute.cpp | 13 ++-- src/gromacs/selection/sm_position.cpp | 8 +-- src/gromacs/selection/sm_same.cpp | 14 ++-- src/gromacs/selection/sm_simple.cpp | 25 ++++--- 14 files changed, 166 insertions(+), 57 deletions(-) create mode 100644 src/gromacs/onlinehelp/tests/refdata/HelpWriterContextTest_FormatsLiteralTextAtBeginning.xml diff --git a/src/gromacs/onlinehelp/helpwritercontext.cpp b/src/gromacs/onlinehelp/helpwritercontext.cpp index 4c928e02ab..8d5a44903b 100644 --- a/src/gromacs/onlinehelp/helpwritercontext.cpp +++ b/src/gromacs/onlinehelp/helpwritercontext.cpp @@ -630,6 +630,10 @@ void HelpWriterContext::Impl::processMarkup(const std::string &text, bLiteral = true; if (paragraph.length() == 2) { + if (breakSize == 0) + { + nextBreakSize = 0; + } continue; } if (paragraph[paragraph.length() - 3] == ' ') diff --git a/src/gromacs/onlinehelp/tests/helpwritercontext.cpp b/src/gromacs/onlinehelp/tests/helpwritercontext.cpp index ed08fb84b0..4216fccf0b 100644 --- a/src/gromacs/onlinehelp/tests/helpwritercontext.cpp +++ b/src/gromacs/onlinehelp/tests/helpwritercontext.cpp @@ -155,6 +155,19 @@ TEST_F(HelpWriterContextTest, FormatsLiteralText) testFormatting(text); } +TEST_F(HelpWriterContextTest, FormatsLiteralTextAtBeginning) +{ + const char *const text[] = { + "::", + "", + " literal block", + " another line", + "", + "Normal paragraph" + }; + testFormatting(text); +} + TEST_F(HelpWriterContextTest, FormatsBulletList) { const char *const text[] = { diff --git a/src/gromacs/onlinehelp/tests/refdata/HelpWriterContextTest_FormatsLiteralTextAtBeginning.xml b/src/gromacs/onlinehelp/tests/refdata/HelpWriterContextTest_FormatsLiteralTextAtBeginning.xml new file mode 100644 index 0000000000..375cc6bf8e --- /dev/null +++ b/src/gromacs/onlinehelp/tests/refdata/HelpWriterContextTest_FormatsLiteralTextAtBeginning.xml @@ -0,0 +1,16 @@ + + + + + + diff --git a/src/gromacs/selection/selhelp.cpp b/src/gromacs/selection/selhelp.cpp index f51c0b5ff8..e521f1bc30 100644 --- a/src/gromacs/selection/selhelp.cpp +++ b/src/gromacs/selection/selhelp.cpp @@ -43,6 +43,7 @@ #include "selhelp.h" +#include #include #include #include @@ -53,6 +54,7 @@ #include "gromacs/onlinehelp/helpwritercontext.h" #include "gromacs/utility/exceptions.h" #include "gromacs/utility/file.h" +#include "gromacs/utility/gmxassert.h" #include "gromacs/utility/stringutil.h" #include "selmethod.h" @@ -495,7 +497,7 @@ class KeywordDetailsHelpTopic : public AbstractSimpleHelpTopic } virtual const char *title() const { - return NULL; + return method_.help.helpTitle; } protected: @@ -560,6 +562,11 @@ class KeywordsHelpTopic : public CompositeHelpTopic void printKeywordList(const HelpWriterContext &context, e_selvalue_t type, bool bModifiers) const; + /*! \brief + * Prints the detailed help for keywords for rst export. + */ + void writeKeywordSubTopics(const HelpWriterContext &context) const; + MethodList methods_; }; @@ -618,6 +625,8 @@ void KeywordsHelpTopic::writeHelp(const HelpWriterContext &context) const printKeywordList(context, POS_VALUE, true); printKeywordList(context, NO_VALUE, true); writeKeywordListEnd(context, NULL); + + writeKeywordSubTopics(context); } void KeywordsHelpTopic::writeKeywordListStart(const HelpWriterContext &context, @@ -655,11 +664,14 @@ void KeywordsHelpTopic::printKeywordList(const HelpWriterContext &context, for (iter = methods_.begin(); iter != methods_.end(); ++iter) { const gmx_ana_selmethod_t &method = *iter->second; - bool bIsModifier = (method.flags & SMETH_MODIFIER) != 0; + const bool bIsModifier + = (method.flags & SMETH_MODIFIER) != 0; if (method.type == type && bModifiers == bIsModifier) { - bool bHasHelp = (method.help.nlhelp > 0 && method.help.help != NULL); - file.writeString(formatString(" %c ", bHasHelp ? '*' : ' ')); + const bool bHasHelp = (method.help.nlhelp > 0 && method.help.help != NULL); + const bool bPrintStar + = bHasHelp && context.outputFormat() == eHelpOutputFormat_Console; + file.writeString(formatString(" %c ", bPrintStar ? '*' : ' ')); if (method.help.syntax != NULL) { file.writeLine(method.help.syntax); @@ -677,6 +689,51 @@ void KeywordsHelpTopic::printKeywordList(const HelpWriterContext &context, } } +void KeywordsHelpTopic::writeKeywordSubTopics(const HelpWriterContext &context) const +{ + if (context.outputFormat() != eHelpOutputFormat_Rst) + { + return; + } + std::set usedSymbols; + MethodList::const_iterator iter; + for (iter = methods_.begin(); iter != methods_.end(); ++iter) + { + const gmx_ana_selmethod_t &method = *iter->second; + const bool bHasHelp + = (method.help.nlhelp > 0 && method.help.help != NULL); + if (!bHasHelp || usedSymbols.count(iter->first) > 0) + { + continue; + } + + std::string title; + if (method.help.helpTitle != NULL) + { + title = method.help.helpTitle; + title.append(" - "); + } + title.append(iter->first); + MethodList::const_iterator mergeIter = iter; + for (++mergeIter; mergeIter != methods_.end(); ++mergeIter) + { + if (mergeIter->second->help.help == method.help.help) + { + title.append(", "); + title.append(mergeIter->first); + usedSymbols.insert(mergeIter->first); + } + } + + const HelpTopicInterface *subTopic = findSubTopic(iter->first.c_str()); + GMX_RELEASE_ASSERT(subTopic != NULL, "Keyword subtopic no longer exists"); + HelpWriterContext subContext(context); + subContext.enterSubSection(title); + subTopic->writeHelp(subContext); + context.writeTextBlock(""); + } +} + } // namespace //! \cond libapi */ diff --git a/src/gromacs/selection/selmethod.h b/src/gromacs/selection/selmethod.h index 8df079d3f1..d5142d6aae 100644 --- a/src/gromacs/selection/selmethod.h +++ b/src/gromacs/selection/selmethod.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -60,7 +60,7 @@ &init_frame_example, &evaluate_example, NULL, - {"example from POS_EXPR [cutoff REAL]", 0, NULL}, + {"example from POS_EXPR [cutoff REAL]", NULL, 0, NULL}, }; * \endcode * @@ -615,6 +615,13 @@ struct gmx_ana_selmethod_help_t * If NULL, the name of the method is used. */ const char *syntax; + /*! \brief + * Title for the help text in \p help. + * + * If NULL, the name of the method is used. + * Only used if `nlhelp > 0`. + */ + const char *helpTitle; /*! \brief * Number of strings in \p help. * @@ -627,7 +634,7 @@ struct gmx_ana_selmethod_help_t * If there is no help available in addition to \p syntax, this can be set * to NULL. */ - const char **help; + const char *const *help; }; /*! \internal diff --git a/src/gromacs/selection/sm_compare.cpp b/src/gromacs/selection/sm_compare.cpp index be899fd7e7..13c8483766 100644 --- a/src/gromacs/selection/sm_compare.cpp +++ b/src/gromacs/selection/sm_compare.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -158,7 +158,7 @@ gmx_ana_selmethod_t sm_compare = { NULL, &evaluate_compare, NULL, - {NULL, 0, NULL}, + {NULL, NULL, 0, NULL}, }; /*! \brief diff --git a/src/gromacs/selection/sm_distance.cpp b/src/gromacs/selection/sm_distance.cpp index 14b055c7fb..dda1b15567 100644 --- a/src/gromacs/selection/sm_distance.cpp +++ b/src/gromacs/selection/sm_distance.cpp @@ -153,10 +153,10 @@ static gmx_ana_selparam_t smparams_within[] = { {"of", {POS_VALUE, -1, {NULL}}, NULL, SPAR_DYNAMIC | SPAR_VARNUM}, }; -/** Help text for the distance selection methods. */ -static const char *help_distance[] = { - "DISTANCE-BASED SELECTION KEYWORDS", - "", +//! Help title for distance selection methods. +static const char helptitle_distance[] = "Selecting based on distance"; +//! Help text for distance selection methods. +static const char *const help_distance[] = { "::", "", " distance from POS [cutoff REAL]", @@ -188,7 +188,8 @@ gmx_ana_selmethod_t sm_distance = { &init_frame_common, NULL, &evaluate_distance, - {"distance from POS [cutoff REAL]", asize(help_distance), help_distance}, + {"distance from POS [cutoff REAL]", + helptitle_distance, asize(help_distance), help_distance}, }; /** Selection method data for the \p distance method. */ @@ -203,7 +204,8 @@ gmx_ana_selmethod_t sm_mindistance = { &init_frame_common, NULL, &evaluate_distance, - {"mindistance from POS_EXPR [cutoff REAL]", asize(help_distance), help_distance}, + {"mindistance from POS_EXPR [cutoff REAL]", + helptitle_distance, asize(help_distance), help_distance}, }; /** Selection method data for the \p within method. */ @@ -218,7 +220,8 @@ gmx_ana_selmethod_t sm_within = { &init_frame_common, NULL, &evaluate_within, - {"within REAL of POS_EXPR", asize(help_distance), help_distance}, + {"within REAL of POS_EXPR", + helptitle_distance, asize(help_distance), help_distance}, }; static void * diff --git a/src/gromacs/selection/sm_insolidangle.cpp b/src/gromacs/selection/sm_insolidangle.cpp index 9c163e097f..a9fd783704 100644 --- a/src/gromacs/selection/sm_insolidangle.cpp +++ b/src/gromacs/selection/sm_insolidangle.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -334,11 +334,11 @@ static gmx_ana_selparam_t smparams_insolidangle[] = { }; /** Help text for the \p insolidangle selection method. */ -static const char *help_insolidangle[] = { - "SELECTING ATOMS IN A SOLID ANGLE[PAR]", - - "[TT]insolidangle center POS span POS_EXPR [cutoff REAL][tt][PAR]", - +static const char *const help_insolidangle[] = { + "::", + "", + " insolidangle center POS span POS_EXPR [cutoff REAL]", + "", "This keyword selects atoms that are within [TT]REAL[tt] degrees", "(default=5) of any position in [TT]POS_EXPR[tt] as seen from [TT]POS[tt]", "a position expression that evaluates to a single position), i.e., atoms", @@ -365,6 +365,7 @@ gmx_ana_selmethod_t sm_insolidangle = { NULL, &evaluate_insolidangle, {"insolidangle center POS span POS_EXPR [cutoff REAL]", + "Selecting atoms in a solid angle", asize(help_insolidangle), help_insolidangle}, }; diff --git a/src/gromacs/selection/sm_keywords.cpp b/src/gromacs/selection/sm_keywords.cpp index ef063d7463..be69f1196d 100644 --- a/src/gromacs/selection/sm_keywords.cpp +++ b/src/gromacs/selection/sm_keywords.cpp @@ -303,7 +303,7 @@ gmx_ana_selmethod_t sm_keyword_int = { NULL, &evaluate_keyword_int, NULL, - {NULL, 0, NULL}, + {NULL, NULL, 0, NULL}, }; /** Selection method data for real keyword evaluation. */ @@ -318,7 +318,7 @@ gmx_ana_selmethod_t sm_keyword_real = { NULL, &evaluate_keyword_real, NULL, - {NULL, 0, NULL}, + {NULL, NULL, 0, NULL}, }; /** Selection method data for string keyword evaluation. */ @@ -333,7 +333,7 @@ gmx_ana_selmethod_t sm_keyword_str = { NULL, &evaluate_keyword_str, NULL, - {NULL, 0, NULL}, + {NULL, NULL, 0, NULL}, }; /*! \brief diff --git a/src/gromacs/selection/sm_merge.cpp b/src/gromacs/selection/sm_merge.cpp index 4b9a50c555..4e3e6d1a9f 100644 --- a/src/gromacs/selection/sm_merge.cpp +++ b/src/gromacs/selection/sm_merge.cpp @@ -120,10 +120,10 @@ static gmx_ana_selparam_t smparams_merge[] = { {"stride", {INT_VALUE, 1, {NULL}}, NULL, SPAR_OPTIONAL}, }; -/** Help text for the merging selection modifiers. */ -static const char *help_merge[] = { - "MERGING SELECTIONS[PAR]", - "", +//! Help title for the merging selection modifiers. +static const char helptitle_merge[] = "Merging selections"; +//! Help text for the merging selection modifiers. +static const char *const help_merge[] = { "::", "", " POSEXPR merge POSEXPR [stride INT]", @@ -160,7 +160,7 @@ gmx_ana_selmethod_t sm_merge = { NULL, NULL, &evaluate_merge, - {"merge POSEXPR", asize(help_merge), help_merge}, + {"merge POSEXPR", helptitle_merge, asize(help_merge), help_merge}, }; /** Selection method data for the \p plus modifier. */ @@ -175,7 +175,7 @@ gmx_ana_selmethod_t sm_plus = { NULL, NULL, &evaluate_plus, - {"plus POSEXPR", asize(help_merge), help_merge}, + {"plus POSEXPR", helptitle_merge, asize(help_merge), help_merge}, }; /*! diff --git a/src/gromacs/selection/sm_permute.cpp b/src/gromacs/selection/sm_permute.cpp index eb7467149f..a2c4117686 100644 --- a/src/gromacs/selection/sm_permute.cpp +++ b/src/gromacs/selection/sm_permute.cpp @@ -125,11 +125,11 @@ static gmx_ana_selparam_t smparams_permute[] = { }; /** Help text for the \p permute selection modifier. */ -static const char *help_permute[] = { - "PERMUTING SELECTIONS[PAR]", - - "[TT]permute P1 ... PN[tt][PAR]", - +static const char *const help_permute[] = { + "::", + "", + " permute P1 ... PN", + "", "By default, all selections are evaluated such that the atom indices are", "returned in ascending order. This can be changed by appending", "[TT]permute P1 P2 ... PN[tt] to an expression.", @@ -155,7 +155,8 @@ gmx_ana_selmethod_t sm_permute = { NULL, NULL, &evaluate_permute, - {"permute P1 ... PN", asize(help_permute), help_permute}, + {"POSEXPR permute P1 ... PN", + "Permuting selections", asize(help_permute), help_permute}, }; static void * diff --git a/src/gromacs/selection/sm_position.cpp b/src/gromacs/selection/sm_position.cpp index 3a92f82d69..fe85404536 100644 --- a/src/gromacs/selection/sm_position.cpp +++ b/src/gromacs/selection/sm_position.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -153,7 +153,7 @@ gmx_ana_selmethod_t sm_keyword_pos = { NULL, &evaluate_pos, NULL, - {NULL, 0, NULL}, + {NULL, NULL, 0, NULL}, }; /** Selection method data for the \p cog method. */ @@ -168,7 +168,7 @@ gmx_ana_selmethod_t sm_cog = { NULL, &evaluate_pos, NULL, - {"cog of ATOM_EXPR [pbc]", 0, NULL}, + {"cog of ATOM_EXPR [pbc]", NULL, 0, NULL}, }; /** Selection method data for the \p com method. */ @@ -183,7 +183,7 @@ gmx_ana_selmethod_t sm_com = { NULL, &evaluate_pos, NULL, - {"com of ATOM_EXPR [pbc]", 0, NULL}, + {"com of ATOM_EXPR [pbc]", NULL, 0, NULL}, }; /*! diff --git a/src/gromacs/selection/sm_same.cpp b/src/gromacs/selection/sm_same.cpp index 01450da98f..67e0629fc3 100644 --- a/src/gromacs/selection/sm_same.cpp +++ b/src/gromacs/selection/sm_same.cpp @@ -170,10 +170,11 @@ static gmx_ana_selparam_t smparams_same_str[] = { }; /** Help text for the \p same selection method. */ -static const char *help_same[] = { - "EXTENDING SELECTIONS[PAR]", - - "[TT]same KEYWORD as ATOM_EXPR[tt][PAR]", +static const char *const help_same[] = { + "::", + "", + " same KEYWORD as ATOM_EXPR", + "", "The keyword [TT]same[tt] can be used to select all atoms for which", "the given [TT]KEYWORD[tt] matches any of the atoms in [TT]ATOM_EXPR[tt].", @@ -192,7 +193,8 @@ gmx_ana_selmethod_t sm_same = { &init_frame_same_int, &evaluate_same_int, NULL, - {"same KEYWORD as ATOM_EXPR", asize(help_same), help_same}, + {"same KEYWORD as ATOM_EXPR", + "Extending selections", asize(help_same), help_same}, }; /*! \brief @@ -213,7 +215,7 @@ static gmx_ana_selmethod_t sm_same_str = { &init_frame_same_str, &evaluate_same_str, NULL, - {"same KEYWORD as ATOM_EXPR", asize(help_same), help_same}, + {NULL, NULL, 0, NULL}, }; static void * diff --git a/src/gromacs/selection/sm_simple.cpp b/src/gromacs/selection/sm_simple.cpp index b257effe74..b5ee784d5d 100644 --- a/src/gromacs/selection/sm_simple.cpp +++ b/src/gromacs/selection/sm_simple.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -171,14 +171,19 @@ static void evaluate_z(t_topology *top, t_trxframe *fr, t_pbc *pbc, gmx_ana_pos_t *pos, gmx_ana_selvalue_t *out, void *data); -/** Help text for atom name selection keywords. */ -static const char *help_atomname[] = { - "ATOM NAME SELECTION KEYWORDS[PAR]", - - "[TT]name[tt] [TT]pdbname[tt] [TT]atomname[tt] [TT]pdbatomname[tt][PAR]", - +//! Help title for atom name selection keywords. +static const char helptitle_atomname[] = "Selecting atoms by name"; +//! Help text for atom name selection keywords. +static const char *const help_atomname[] = { + "::", + "", + " name", + " pdbname", + " atomname", + " pdbatomname", + "", "These keywords select atoms by name. [TT]name[tt] selects atoms using", - "the Gromacs atom naming convention.", + "the GROMACS atom naming convention.", "For input formats other than PDB, the atom names are matched exactly", "as they appear in the input file. For PDB files, 4 character atom names", "that start with a digit are matched after moving the digit to the end", @@ -287,7 +292,7 @@ gmx_ana_selmethod_t sm_atomname = { NULL, &evaluate_atomname, NULL, - {NULL, asize(help_atomname), help_atomname} + {NULL, helptitle_atomname, asize(help_atomname), help_atomname} }; /** Selection method data for \p pdbatomname selection keyword. */ @@ -302,7 +307,7 @@ gmx_ana_selmethod_t sm_pdbatomname = { NULL, &evaluate_pdbatomname, NULL, - {NULL, asize(help_atomname), help_atomname} + {NULL, helptitle_atomname, asize(help_atomname), help_atomname} }; /** Selection method data for \p atomtype selection keyword. */ -- 2.22.0