* \author Teemu Murtola <teemu.murtola@gmail.com>
* \ingroup module_commandline
*/
+#include "gmxpre.h"
+
#include "cmdlinehelpwriter.h"
+#include <cstring>
+
+#include <algorithm>
#include <string>
#include <boost/scoped_ptr.hpp>
#include "gromacs/commandline/cmdlinehelpcontext.h"
-#include "gromacs/commandline/shellcompletions.h"
#include "gromacs/onlinehelp/helpformat.h"
#include "gromacs/onlinehelp/helpwritercontext.h"
#include "gromacs/options/basicoptions.h"
#include "gromacs/options/options.h"
#include "gromacs/options/optionsvisitor.h"
#include "gromacs/options/timeunitmanager.h"
+#include "gromacs/utility/arrayref.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/file.h"
#include "gromacs/utility/stringutil.h"
+#include "shellcompletions.h"
+
namespace gmx
{
return description;
}
+/********************************************************************
+ * OptionsSynopsisFormatter
+ */
+
+/*! \brief
+ * Formatter implementation for synopsis.
+ */
+class SynopsisFormatter : public OptionsFormatterInterface
+{
+ public:
+ //! Creates a helper object for formatting the synopsis.
+ explicit SynopsisFormatter(const HelpWriterContext &context)
+ : context_(context), lineLength_(0), indent_(0), currentLength_(0)
+ {
+ }
+
+ //! Starts formatting the synopsis.
+ void start(const char *name);
+ //! Finishes formatting the synopsis.
+ void finish();
+
+ virtual void formatOption(const OptionInfo &option);
+
+ private:
+ const HelpWriterContext &context_;
+ int lineLength_;
+ int indent_;
+ int currentLength_;
+
+ GMX_DISALLOW_COPY_AND_ASSIGN(SynopsisFormatter);
+};
+
+void SynopsisFormatter::start(const char *name)
+{
+ currentLength_ = std::strlen(name) + 1;
+ indent_ = std::min(currentLength_, 13);
+ File &file = context_.outputFile();
+ switch (context_.outputFormat())
+ {
+ case eHelpOutputFormat_Console:
+ lineLength_ = 78;
+ file.writeString(name);
+ break;
+ case eHelpOutputFormat_Man:
+ lineLength_ = 70;
+ file.writeString(name);
+ break;
+ case eHelpOutputFormat_Html:
+ lineLength_ = 78;
+ file.writeLine("<pre>");
+ file.writeString(name);
+ break;
+ default:
+ GMX_THROW(NotImplementedError("Synopsis formatting not implemented for this output format"));
+ }
+}
+
+void SynopsisFormatter::finish()
+{
+ File &file = context_.outputFile();
+ file.writeLine();
+ if (context_.outputFormat() == eHelpOutputFormat_Html)
+ {
+ file.writeLine("</pre>");
+ }
+ file.writeLine();
+}
+
+void SynopsisFormatter::formatOption(const OptionInfo &option)
+{
+ std::string name, value;
+ formatOptionNameAndValue(option, &name, &value);
+ std::string fullOptionText(" [-" + name);
+ if (!value.empty())
+ {
+ fullOptionText.append(" ");
+ fullOptionText.append(value);
+ }
+ fullOptionText.append("]");
+ const int totalLength = fullOptionText.size();
+
+ if (context_.outputFormat() == eHelpOutputFormat_Html)
+ {
+ value = replaceAll(value, "<", "<");
+ value = replaceAll(value, ">", ">");
+ }
+
+ File &file = context_.outputFile();
+ currentLength_ += totalLength;
+ if (currentLength_ >= lineLength_)
+ {
+ file.writeString(formatString("\n%*c", indent_ - 1, ' '));
+ currentLength_ = indent_ - 1 + totalLength;
+ }
+ file.writeString(fullOptionText);
+}
+
/********************************************************************
* OptionsListFormatter
*/
//! Creates a helper object for formatting options.
OptionsListFormatter(const HelpWriterContext &context,
const CommonFormatterData &common,
- bool bConsole);
+ const char *title);
//! Initiates a new section in the options list.
- void startSection(const char *title)
+ void startSection(const char *header)
{
- title_ = title;
+ header_ = header;
bDidOutput_ = false;
}
//! Finishes a section in the options list.
private:
void writeSectionStartIfNecessary()
{
+ if (title_ != NULL)
+ {
+ context_.writeTitle(title_);
+ title_ = NULL;
+ }
if (!bDidOutput_)
{
- if (title_ != NULL)
+ if (header_ != NULL)
{
- context_.writeTitle(title_);
+ context_.writeTextBlock(header_);
}
context_.writeOptionListStart();
}
const CommonFormatterData &common_;
boost::scoped_ptr<TextTableFormatter> consoleFormatter_;
const char *title_;
+ const char *header_;
bool bDidOutput_;
GMX_DISALLOW_COPY_AND_ASSIGN(OptionsListFormatter);
OptionsListFormatter::OptionsListFormatter(
const HelpWriterContext &context,
const CommonFormatterData &common,
- bool bConsole)
- : context_(context), common_(common), title_(NULL), bDidOutput_(false)
+ const char *title)
+ : context_(context), common_(common),
+ title_(title), header_(NULL), bDidOutput_(false)
{
- if (bConsole)
+ if (context.outputFormat() == eHelpOutputFormat_Console)
{
consoleFormatter_.reset(new TextTableFormatter());
consoleFormatter_->setFirstColumnIndent(1);
//! Sets the Options object to use for generating help.
explicit Impl(const Options &options);
+ //! Format the list of known issues.
+ void formatBugs(const HelpWriterContext &context);
+
//! Options object to use for generating help.
- const Options &options_;
+ const Options &options_;
+ //! List of bugs/knows issues.
+ ConstArrayRef<const char *> bugs_;
//! Time unit to show in descriptions.
- std::string timeUnit_;
+ std::string timeUnit_;
//! Whether to write descriptions to output.
- bool bShowDescriptions_;
+ bool bShowDescriptions_;
};
CommandLineHelpWriter::Impl::Impl(const Options &options)
{
}
+void CommandLineHelpWriter::Impl::formatBugs(const HelpWriterContext &context)
+{
+ if (bugs_.empty())
+ {
+ return;
+ }
+ context.writeTitle("Known Issues");
+ if (context.outputFormat() != eHelpOutputFormat_Console)
+ {
+ context.writeTextBlock("[UL]");
+ }
+ ConstArrayRef<const char *>::const_iterator i;
+ for (i = bugs_.begin(); i != bugs_.end(); ++i)
+ {
+ const char *const bug = *i;
+ // TODO: The context should be able to do this also for console output, but
+ // that requires a lot more elaborate parser for the markup.
+ if (context.outputFormat() == eHelpOutputFormat_Console)
+ {
+ TextLineWrapperSettings settings;
+ settings.setIndent(2);
+ settings.setFirstLineIndent(0);
+ settings.setLineLength(78);
+ context.outputFile().writeLine(
+ context.substituteMarkupAndWrapToString(
+ settings, formatString("* %s", bug)));
+ }
+ else
+ {
+ context.writeTextBlock(formatString("[LI]%s", bug));
+ }
+ }
+ if (context.outputFormat() != eHelpOutputFormat_Console)
+ {
+ context.writeTextBlock("[ul]");
+ }
+}
+
+
/********************************************************************
* CommandLineHelpWriter
*/
{
}
-CommandLineHelpWriter &CommandLineHelpWriter::setShowDescriptions(bool bSet)
+CommandLineHelpWriter &
+CommandLineHelpWriter::setShowDescriptions(bool bSet)
{
impl_->bShowDescriptions_ = bSet;
return *this;
}
-CommandLineHelpWriter &CommandLineHelpWriter::setTimeUnitString(const char *timeUnit)
+CommandLineHelpWriter &
+CommandLineHelpWriter::setTimeUnitString(const char *timeUnit)
{
impl_->timeUnit_ = timeUnit;
return *this;
}
+CommandLineHelpWriter &
+CommandLineHelpWriter::setKnownIssues(const ConstArrayRef<const char *> &bugs)
+{
+ impl_->bugs_ = bugs;
+ return *this;
+}
+
void CommandLineHelpWriter::writeHelp(const CommandLineHelpContext &context)
{
if (context.isCompletionExport())
return;
}
const HelpWriterContext &writerContext = context.writerContext();
- const bool bConsole
- = (writerContext.outputFormat() == eHelpOutputFormat_Console);
OptionsFilter filter;
filter.setShowHidden(context.showHidden());
- File &file = writerContext.outputFile();
- if (!bConsole)
{
- // TODO: Write a proper synopsis, with all the options.
writerContext.writeTitle("Synopsis");
- writerContext.writeTextBlock(context.moduleDisplayName());
- file.writeLine("\n\n");
+ SynopsisFormatter synopsisFormatter(writerContext);
+ synopsisFormatter.start(context.moduleDisplayName());
+ filter.formatSelected(OptionsFilter::eSelectFileOptions,
+ &synopsisFormatter, impl_->options_);
+ filter.formatSelected(OptionsFilter::eSelectOtherOptions,
+ &synopsisFormatter, impl_->options_);
+ synopsisFormatter.finish();
}
if (impl_->bShowDescriptions_)
descriptionFormatter.format(impl_->options_, "Description");
}
CommonFormatterData common(impl_->timeUnit_.c_str());
- OptionsListFormatter formatter(writerContext, common, bConsole);
- formatter.startSection("File Options");
+ OptionsListFormatter formatter(writerContext, common, "Options");
+ formatter.startSection("Options to specify input and output files:[PAR]");
filter.formatSelected(OptionsFilter::eSelectFileOptions,
&formatter, impl_->options_);
formatter.finishSection();
- formatter.startSection("Options");
+ formatter.startSection("Other options:[PAR]");
filter.formatSelected(OptionsFilter::eSelectOtherOptions,
&formatter, impl_->options_);
formatter.finishSection();
+
+ impl_->formatBugs(writerContext);
}
} // namespace gmx