#include <boost/scoped_ptr.hpp>
#include "gromacs/commandline/cmdlinehelpcontext.h"
-#include "gromacs/onlinehelp/helpformat.h"
#include "gromacs/onlinehelp/helpwritercontext.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/filenameoption.h"
//! Specifies the type of output that formatSelected() produces.
enum FilterType
{
- eSelectFileOptions,
+ eSelectInputFileOptions,
+ eSelectInputOutputFileOptions,
+ eSelectOutputFileOptions,
eSelectOtherOptions
};
{
return;
}
- if (option.isType<FileNameOptionInfo>())
+ const FileNameOptionInfo *const fileOption = option.toType<FileNameOptionInfo>();
+ if (fileOption != NULL && fileOption->isInputFile())
+ {
+ if (filterType_ == eSelectInputFileOptions)
+ {
+ formatter_->formatOption(option);
+ }
+ return;
+ }
+ if (fileOption != NULL && fileOption->isInputOutputFile())
+ {
+ if (filterType_ == eSelectInputOutputFileOptions)
+ {
+ formatter_->formatOption(option);
+ }
+ return;
+ }
+ if (fileOption != NULL && fileOption->isOutputFile())
{
- if (filterType_ == eSelectFileOptions)
+ if (filterType_ == eSelectOutputFileOptions)
{
formatter_->formatOption(option);
}
fileOptionFlagsAsString(const FileNameOptionInfo &option, bool bAbbrev)
{
std::string type;
- if (option.isInputOutputFile())
- {
- type = bAbbrev ? "In/Out" : "Input/Output";
- }
- else if (option.isInputFile())
- {
- type = "Input";
- }
- else if (option.isOutputFile())
- {
- type = "Output";
- }
if (!option.isRequired())
{
- type += bAbbrev ? ", Opt." : ", Optional";
+ type = bAbbrev ? "Opt." : "Optional";
}
if (option.isLibraryFile())
{
- type += bAbbrev ? ", Lib." : ", Library";
+ if (!type.empty())
+ {
+ type.append(", ");
+ }
+ type.append(bAbbrev ? "Lib." : "Library");
}
return type;
}
public:
//! Creates a helper object for formatting the synopsis.
explicit SynopsisFormatter(const HelpWriterContext &context)
- : context_(context), lineLength_(0), indent_(0), currentLength_(0)
+ : context_(context), bFormatted_(false), lineLength_(0), indent_(0),
+ currentLength_(0)
{
}
private:
const HelpWriterContext &context_;
+ bool bFormatted_;
int lineLength_;
int indent_;
int currentLength_;
file.writeString(name);
break;
case eHelpOutputFormat_Rst:
+ bFormatted_ = true;
lineLength_ = 74;
indent_ += 4;
- file.writeLine("::");
+ file.writeLine(".. parsed-literal::");
file.writeLine();
file.writeString(" ");
file.writeString(name);
{
std::string name, value;
formatOptionNameAndValue(option, &name, &value);
- std::string fullOptionText(" [-" + name);
+ int totalLength = name.length() + 4;
+ std::string fullOptionText
+ = formatString(" [%s-%s", bFormatted_ ? ":strong:`" : "", name.c_str());
if (!value.empty())
{
- fullOptionText.append(" ");
+ fullOptionText.append(bFormatted_ ? "` :emphasis:`" : " ");
fullOptionText.append(value);
+ totalLength += value.length() + 1;
}
- fullOptionText.append("]");
- const int totalLength = fullOptionText.size();
+ fullOptionText.append(bFormatted_ ? "`]" : "]");
File &file = context_.outputFile();
currentLength_ += totalLength;
const HelpWriterContext &context_;
const CommonFormatterData &common_;
- boost::scoped_ptr<TextTableFormatter> consoleFormatter_;
const char *title_;
const char *header_;
bool bDidOutput_;
: context_(context), common_(common),
title_(title), header_(NULL), bDidOutput_(false)
{
- if (context.outputFormat() == eHelpOutputFormat_Console)
- {
- consoleFormatter_.reset(new TextTableFormatter());
- consoleFormatter_->setFirstColumnIndent(1);
- consoleFormatter_->setFoldLastColumnToNextLine(4);
- consoleFormatter_->addColumn(NULL, 6, false);
- consoleFormatter_->addColumn(NULL, 8, false);
- consoleFormatter_->addColumn(NULL, 10, false);
- consoleFormatter_->addColumn(NULL, 50, true);
- }
}
void OptionsListFormatter::formatOption(const OptionInfo &option)
{
writeSectionStartIfNecessary();
- std::string name, value;
+ std::string name, value;
formatOptionNameAndValue(option, &name, &value);
- std::string defaultValue(defaultOptionValue(option));
- std::string info;
- if (!defaultValue.empty())
- {
- info = "(" + defaultValue + ")";
- }
+ std::string defaultValue(defaultOptionValue(option));
+ std::string info;
const FileNameOptionInfo *fileOption = option.toType<FileNameOptionInfo>();
if (fileOption != NULL)
{
const bool bAbbrev = (context_.outputFormat() == eHelpOutputFormat_Console);
- if (!info.empty())
- {
- info.append(" ");
- }
- info.append("(");
- info.append(fileOptionFlagsAsString(*fileOption, bAbbrev));
- info.append(")");
+ info = fileOptionFlagsAsString(*fileOption, bAbbrev);
}
std::string description(descriptionWithOptionDetails(common_, option));
- if (context_.outputFormat() == eHelpOutputFormat_Console)
- {
- consoleFormatter_->clear();
- consoleFormatter_->addColumnLine(0, "-" + name);
- consoleFormatter_->addColumnLine(1, value);
- if (!info.empty())
- {
- consoleFormatter_->addColumnLine(2, info);
- }
- consoleFormatter_->addColumnHelpTextBlock(3, context_, description);
- context_.outputFile().writeString(consoleFormatter_->formatRow());
- }
- else
- {
- if (!info.empty())
- {
- value.append(" ");
- value.append(info);
- }
- context_.writeOptionItem("-" + name, value, description);
- }
+ context_.writeOptionItem("-" + name, value, defaultValue, info, description);
}
//! \}
writerContext.writeTitle("Synopsis");
SynopsisFormatter synopsisFormatter(writerContext);
synopsisFormatter.start(context.moduleDisplayName());
- filter.formatSelected(OptionsFilter::eSelectFileOptions,
+ filter.formatSelected(OptionsFilter::eSelectInputFileOptions,
+ &synopsisFormatter, impl_->options_);
+ filter.formatSelected(OptionsFilter::eSelectInputOutputFileOptions,
+ &synopsisFormatter, impl_->options_);
+ filter.formatSelected(OptionsFilter::eSelectOutputFileOptions,
&synopsisFormatter, impl_->options_);
filter.formatSelected(OptionsFilter::eSelectOtherOptions,
&synopsisFormatter, impl_->options_);
}
CommonFormatterData common(impl_->timeUnit_.c_str());
OptionsListFormatter formatter(writerContext, common, "Options");
- formatter.startSection("Options to specify input and output files:[PAR]");
- filter.formatSelected(OptionsFilter::eSelectFileOptions,
+ formatter.startSection("Options to specify input files:");
+ filter.formatSelected(OptionsFilter::eSelectInputFileOptions,
+ &formatter, impl_->options_);
+ formatter.finishSection();
+ formatter.startSection("Options to specify input/output files:");
+ filter.formatSelected(OptionsFilter::eSelectInputOutputFileOptions,
+ &formatter, impl_->options_);
+ formatter.finishSection();
+ formatter.startSection("Options to specify output files:");
+ filter.formatSelected(OptionsFilter::eSelectOutputFileOptions,
&formatter, impl_->options_);
formatter.finishSection();
- formatter.startSection("Other options:[PAR]");
+ formatter.startSection("Other options:");
filter.formatSelected(OptionsFilter::eSelectOtherOptions,
&formatter, impl_->options_);
formatter.finishSection();
===========
Synopsis
--------
-::
+.. parsed-literal::
- test module [-int <int>]
+ test module [:strong:`-int` :emphasis:`<int>`]
Description
-----------
==========
Synopsis
--------
-::
+.. parsed-literal::
test other
Other options:
- -[no]h (no) Print help and quit
- -[no]quiet (no) Do not print common startup info or quotes
- -[no]version (no) Print extended version information and quit
- -[no]copyright (yes) Print copyright information on startup
- -nice <int> (19) Set the nicelevel (default depends on command)
- -[no]backup (yes) Write backups if output files exist
+ -[no]h (no)
+ Print help and quit
+ -[no]quiet (no)
+ Do not print common startup info or quotes
+ -[no]version (no)
+ Print extended version information and quit
+ -[no]copyright (yes)
+ Print copyright information on startup
+ -nice <int> (19)
+ Set the nicelevel (default depends on command)
+ -[no]backup (yes)
+ Write backups if output files exist
Additional help is available on the following topics:
commands List of available commands
OPTIONS
-Options to specify input and output files:
+Options to specify input files:
- -f [<.xtc/.trr/...>] (path/to/long/trajectory/name.xtc) (Input)
- File name option with a long value: xtc trr cpt gro g96 pdb tng
- -f2 [<.xtc/.trr/...>] (path/to/long/trajectory.xtc) (Input)
- File name option with a long value: xtc trr cpt gro g96 pdb tng
- -lib [<.xtc/.trr/...>] (path/to/long/trajectory/name.xtc) (Input, Opt., Lib.)
- File name option with a long value and type: xtc trr cpt gro g96 pdb tng
- -longfileopt [<.dat>] (deffile.dat) (Input, Opt.)
- File name option with a long name
- -longfileopt2 [<.dat>] (path/to/long/file/name.dat) (Input, Opt., Lib.)
- File name option with multiple long fields
+ -f [<.xtc/.trr/...>] (path/to/long/trajectory/name.xtc)
+ File name option with a long value: xtc trr cpt gro g96 pdb tng
+ -f2 [<.xtc/.trr/...>] (path/to/long/trajectory.xtc)
+ File name option with a long value: xtc trr cpt gro g96 pdb tng
+ -lib [<.xtc/.trr/...>] (path/to/long/trajectory/name.xtc) (Opt., Lib.)
+ File name option with a long value and type: xtc trr cpt gro g96
+ pdb tng
+ -longfileopt [<.dat>] (deffile.dat) (Opt.)
+ File name option with a long name
+ -longfileopt2 [<.dat>] (path/to/long/file/name.dat) (Opt., Lib.)
+ File name option with multiple long fields
]]></String>
</ReferenceData>
Other options:
- -[no]longboolean (yes) Boolean option with a long name
- -dvec <vector> (1.135 2.32 3.2132) Double vector option
- -string <string> (A very long string value that overflows even the description column Another very long string value that overflows even the description column)
- String option with very long values (may be less relevant with selections
- having their own option type)
+ -[no]longboolean (yes)
+ Boolean option with a long name
+ -dvec <vector> (1.135 2.32 3.2132)
+ Double vector option
+ -string <string> (A very long string value that overflows even the description column Another very long string value that overflows even the description column)
+ String option with very long values (may be less relevant with
+ selections having their own option type)
]]></String>
</ReferenceData>
Other options:
- -sub1 <int> Option in subsection 1
- -sub2 <int> Option in subsection 2
- -main <int> Option in main section
+ -sub1 <int>
+ Option in subsection 1
+ -sub2 <int>
+ Option in subsection 2
+ -main <int>
+ Option in main section
]]></String>
</ReferenceData>
OPTIONS
-Options to specify input and output files:
+Options to specify input files:
- -f [<.xtc/.trr/...>] (traj.xtc) (Input)
- Input file description: xtc trr cpt gro g96 pdb tng
- -mult [<.xtc/.trr/...> [...]] (traj.xtc) (Input, Opt.)
- Multiple file description: xtc trr cpt gro g96 pdb tng
- -lib [<.dat>] (libdata.dat) (Input, Opt., Lib.) Library file description
- -io [<.dat>] (inout.dat) (In/Out, Opt.) Input/Output file description
- -o <.xvg> (Output, Opt.) Output file description
+ -f [<.xtc/.trr/...>] (traj.xtc)
+ Input file description: xtc trr cpt gro g96 pdb tng
+ -mult [<.xtc/.trr/...> [...]] (traj.xtc) (Opt.)
+ Multiple file description: xtc trr cpt gro g96 pdb tng
+ -lib [<.dat>] (libdata.dat) (Opt., Lib.)
+ Library file description
+
+Options to specify input/output files:
+
+ -io [<.dat>] (inout.dat) (Opt.)
+ Input/Output file description
+
+Options to specify output files:
+
+ -o <.xvg> (Opt.)
+ Output file description
Other options:
- -[no]bool (yes) Boolean option
- -[no]hidden (yes) Hidden option
- -int <int> (2) Integer option
- -ivec <vector> (1 2 3) Integer vector option
- -double <real> (2.5) Double option
- -dvec <vector> (1.1 2.3 3.2) Double vector option
- -time <time> (10) Time option (ps)
- -string <string> (test) String option
- -enum <enum> (no) Enum option: no, opt1, opt2
+ -[no]bool (yes)
+ Boolean option
+ -[no]hidden (yes)
+ Hidden option
+ -int <int> (2)
+ Integer option
+ -ivec <vector> (1 2 3)
+ Integer vector option
+ -double <real> (2.5)
+ Double option
+ -dvec <vector> (1.1 2.3 3.2)
+ Double vector option
+ -time <time> (10)
+ Time option (ps)
+ -string <string> (test)
+ String option
+ -enum <enum> (no)
+ Enum option: no, opt1, opt2
]]></String>
</ReferenceData>
#include <string.h>
#include <time.h>
+#include <algorithm>
+
#ifdef HAVE_LIBMKL
#include <mkl.h>
#endif
sfree(tmpstr);
}
+static int centeringOffset(int width, int length)
+{
+ return std::max(width - length, 0) / 2;
+}
+
+static void printCentered(FILE *fp, int width, const char *text)
+{
+ const int offset = centeringOffset(width, std::strlen(text));
+ fprintf(fp, "%*s%s", offset, "", text);
+}
+
static void printCopyright(FILE *fp)
{
static const char * const Contributors[] = {
#define NLICENSE (int)asize(LicenseText)
#endif
- fprintf(fp, "GROMACS is written by:\n");
+ printCentered(fp, 78, "GROMACS is written by:");
+ fprintf(fp, "\n");
for (int i = 0; i < NCONTRIBUTORS; )
{
for (int j = 0; j < 4 && i < NCONTRIBUTORS; ++j, ++i)
{
- fprintf(fp, "%-18s ", Contributors[i]);
+ const int width = 18;
+ char buf[30];
+ const int offset = centeringOffset(width, strlen(Contributors[i]));
+ GMX_RELEASE_ASSERT(strlen(Contributors[i]) + offset < asize(buf),
+ "Formatting buffer is not long enough");
+ std::fill(buf, buf+width, ' ');
+ std::strcpy(buf+offset, Contributors[i]);
+ fprintf(fp, " %-*s", width, buf);
}
fprintf(fp, "\n");
}
- fprintf(fp, "and the project leaders:\n");
- fprintf(fp, "Mark Abraham, Berk Hess, Erik Lindahl, and David van der Spoel\n");
+ printCentered(fp, 78, "and the project leaders:");
fprintf(fp, "\n");
+ printCentered(fp, 78, "Mark Abraham, Berk Hess, Erik Lindahl, and David van der Spoel");
+ fprintf(fp, "\n\n");
for (int i = 0; i < NCR; ++i)
{
fprintf(fp, "%s\n", CopyrightText[i]);
{
fprintf(fp, "%sCreated by:%s\n", prefix, suffix);
}
+ // TODO: It would be nice to know here whether we are really running a
+ // Gromacs binary or some other binary that is calling Gromacs; we
+ // could then print "%s is part of GROMACS" or some alternative text.
+ std::string title
+ = formatString(":-) GROMACS - %s, %s%s (-:", name, gmx_version(), precisionString);
+ const int indent
+ = centeringOffset(78 - strlen(prefix) - strlen(suffix), title.length()) + 1;
+ fprintf(fp, "%s%*c%s%s\n", prefix, indent, ' ', title.c_str(), suffix);
+ fprintf(fp, "\n");
if (settings.bCopyright_)
{
GMX_RELEASE_ASSERT(prefix[0] == '\0' && suffix[0] == '\0',
"Prefix/suffix not supported with copyright");
+ printCopyright(fp);
+ fprintf(fp, "\n");
// This line is printed again after the copyright notice to make it
// appear together with all the other information, so that it is not
// necessary to read stuff above the copyright notice.
// The line above the copyright notice puts the copyright notice is
// context, though.
- // TODO: It would be nice to know here whether we are really running a
- // Gromacs binary or some other binary that is calling Gromacs; we
- // could then print "%s is part of GROMACS" or some alternative text.
- fprintf(fp, "%sGROMACS: %s, %s%s%s\n", prefix, name,
+ fprintf(fp, "%sGROMACS: %s, %s%s%s\n", prefix, name,
gmx_version(), precisionString, suffix);
- fprintf(fp, "\n");
- printCopyright(fp);
- fprintf(fp, "\n");
}
- fprintf(fp, "%sGROMACS: %s, %s%s%s\n", prefix, name,
- gmx_version(), precisionString, suffix);
const char *const binaryPath = programContext.fullBinaryPath();
if (!gmx::isNullOrEmpty(binaryPath))
{
#include <boost/shared_ptr.hpp>
+#include "gromacs/onlinehelp/helpformat.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/file.h"
#include "gromacs/utility/gmxassert.h"
*
* \ingroup module_onlinehelp
*/
- struct SharedState
+ class SharedState
{
- //! Initializes the state with the given parameters.
- SharedState(File *file, HelpOutputFormat format,
- const HelpLinks *links)
- : file_(*file), format_(format), links_(links)
- {
- }
-
- //! Output file to which the help is written.
- File &file_;
- //! Output format for the help output.
- HelpOutputFormat format_;
- //! Links to use.
- const HelpLinks *links_;
+ public:
+ //! Initializes the state with the given parameters.
+ SharedState(File *file, HelpOutputFormat format,
+ const HelpLinks *links)
+ : file_(*file), format_(format), links_(links)
+ {
+ }
+
+ /*! \brief
+ * Returns a formatter for formatting options lists for console
+ * output.
+ *
+ * The formatter is lazily initialized on first access.
+ */
+ TextTableFormatter &consoleOptionsFormatter() const
+ {
+ GMX_RELEASE_ASSERT(format_ == eHelpOutputFormat_Console,
+ "Accessing console formatter for non-console output");
+ if (!consoleOptionsFormatter_)
+ {
+ consoleOptionsFormatter_.reset(new TextTableFormatter());
+ consoleOptionsFormatter_->setFirstColumnIndent(1);
+ consoleOptionsFormatter_->addColumn(NULL, 7, false);
+ consoleOptionsFormatter_->addColumn(NULL, 18, false);
+ consoleOptionsFormatter_->addColumn(NULL, 16, false);
+ consoleOptionsFormatter_->addColumn(NULL, 28, false);
+ }
+ return *consoleOptionsFormatter_;
+ }
+
+ //! Output file to which the help is written.
+ File &file_;
+ //! Output format for the help output.
+ HelpOutputFormat format_;
+ //! Links to use.
+ const HelpLinks *links_;
+
+ private:
+ //! Formatter for console output options.
+ mutable boost::scoped_ptr<TextTableFormatter> consoleOptionsFormatter_;
};
struct ReplaceItem
}
void HelpWriterContext::writeOptionItem(const std::string &name,
- const std::string &args,
+ const std::string &value,
+ const std::string &defaultValue,
+ const std::string &info,
const std::string &description) const
{
File &file = outputFile();
switch (outputFormat())
{
case eHelpOutputFormat_Console:
- // TODO: Generalize this when there is need for it; the current,
- // special implementation is in CommandLineHelpWriter.
- GMX_THROW(NotImplementedError("Option item formatting for console output not implemented"));
+ {
+ TextTableFormatter &formatter(impl_->state_->consoleOptionsFormatter());
+ formatter.clear();
+ formatter.addColumnLine(0, name);
+ formatter.addColumnLine(1, value);
+ if (!defaultValue.empty())
+ {
+ formatter.addColumnLine(2, "(" + defaultValue + ")");
+ }
+ if (!info.empty())
+ {
+ formatter.addColumnLine(3, "(" + info + ")");
+ }
+ TextLineWrapperSettings settings;
+ settings.setIndent(11);
+ settings.setLineLength(78);
+ std::string formattedDescription
+ = substituteMarkupAndWrapToString(settings, description);
+ file.writeLine(formatter.formatRow());
+ file.writeLine(formattedDescription);
break;
+ }
case eHelpOutputFormat_Rst:
{
+ std::string args(value);
+ if (!defaultValue.empty())
+ {
+ args.append(" (");
+ args.append(defaultValue);
+ args.append(")");
+ }
+ if (!info.empty())
+ {
+ args.append(" (");
+ args.append(info);
+ args.append(")");
+ }
file.writeLine(formatString("``%s`` %s", name.c_str(), args.c_str()));
TextLineWrapperSettings settings;
settings.setIndent(4);
* Writes an entry for a single option into the output.
*
* \param[in] name Name of the option.
- * \param[in] args Placeholder for values and other information about
- * the option (placed after \p name).
+ * \param[in] value Placeholder for option value.
+ * \param[in] defaultValue Default value for the option.
+ * \param[in] info Additional (brief) info/attributes for the
+ * option.
* \param[in] description Full description of the option.
*/
- void writeOptionItem(const std::string &name, const std::string &args,
- const std::string &description) const;
+ void writeOptionItem(
+ const std::string &name, const std::string &value,
+ const std::string &defaultValue, const std::string &info,
+ const std::string &description) const;
/*! \brief
* Finishes writing a list of options.
*