#include <utility>
#include "gromacs/commandline/cmdlinemodule.h"
+#include "gromacs/onlinehelp/helpformat.h"
#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/programinfo.h"
maxNameLength = nameLength;
}
}
+ TextTableFormatter formatter;
+ formatter.addColumn(NULL, maxNameLength + 1, false);
+ formatter.addColumn(NULL, 72 - maxNameLength, true);
+ formatter.setFirstColumnIndent(4);
fprintf(stderr, "The following commands are available:\n");
for (module = modules_.begin(); module != modules_.end(); ++module)
{
const char *name = module->first.c_str();
const char *description = module->second->shortDescription();
- fprintf(stderr, " %*s %s\n", -maxNameLength, name, description);
+ formatter.clear();
+ formatter.addColumnLine(0, name);
+ formatter.addColumnLine(1, description);
+ fprintf(stderr, "%s", formatter.formatRow().c_str());
}
}
//! Container for column data.
ColumnList columns_;
+ //! Indentation before the first column.
+ int firstColumnIndent_;
//! If true, no output has yet been produced.
bool bFirstRow_;
+ //! If true, a header will be printed before the first row.
+ bool bPrintHeader_;
};
TextTableFormatter::Impl::Impl()
- : bFirstRow_(true)
+ : firstColumnIndent_(0), bFirstRow_(true), bPrintHeader_(false)
{
}
void TextTableFormatter::addColumn(const char *title, int width, bool bWrap)
{
+ if (title != NULL && title[0] != '\0')
+ {
+ impl_->bPrintHeader_ = true;
+ }
impl_->columns_.push_back(Impl::ColumnData(title, width, bWrap));
}
+void TextTableFormatter::setFirstColumnIndent(int indent)
+{
+ GMX_RELEASE_ASSERT(indent >= 0, "Negative indentation not allowed");
+ impl_->firstColumnIndent_ = indent;
+}
+
bool TextTableFormatter::didOutput() const
{
return !impl_->bFirstRow_;
std::string result;
Impl::ColumnList::const_iterator column;
// Print a header if this is the first line.
- if (impl_->bFirstRow_)
+ if (impl_->bPrintHeader_ && impl_->bFirstRow_)
{
size_t totalWidth = 0;
+ result.append(impl_->firstColumnIndent_, ' ');
for (column = impl_->columns_.begin();
column != impl_->columns_.end();
++column)
result.append(title);
}
result.append("\n");
+ result.append(impl_->firstColumnIndent_, ' ');
result.append(totalWidth, '-');
result.append("\n");
}
lineResult.append(value);
currentWidth += column->width();
}
+ result.append(impl_->firstColumnIndent_, ' ');
result.append(lineResult);
result.append("\n");
}
* responsibility to check that overflows are avoided or are acceptable).
*
* Column definitions are first set with addColumn().
- * To format a fow, first call clear(). Then call addColumnLine() to add text
+ * To format a row, first call clear(). Then call addColumnLine() to add text
* to each column (can be called multiple times on a single column to add
* multiple lines), and possibly setColumnFirstLineOffset() to adjust the line
* from which the column output should start. Finally, call formatRow() to
* The length of \p title must not exceed \p width.
*/
void addColumn(const char *title, int width, bool bWrap);
+ /*! \brief
+ * Sets amount on indentation before the first column.
+ *
+ * \param[in] indent Number of spaces to use for indenting.
+ *
+ * Does not throw.
+ */
+ void setFirstColumnIndent(int indent);
/*! \brief
* Whether formatRow() has been successfully called.
* addColumnLine() and setColumnFirstLineOffset().
*
* If this is the first line to be formatted, a header is also added to
- * the beginning of the returned string.
+ * the beginning of the returned string if any column has a title.
*
* The return value always terminates with a newline.
*
class TextTableFormatterTest : public gmx::test::StringTestBase
{
public:
- TextTableFormatterTest();
+ void setupStandardColumns();
gmx::TextTableFormatter formatter_;
};
-TextTableFormatterTest::TextTableFormatterTest()
+void TextTableFormatterTest::setupStandardColumns()
{
formatter_.addColumn("Col1", 4, false);
formatter_.addColumn("Col2", 4, false);
TEST_F(TextTableFormatterTest, HandlesBasicCase)
{
+ setupStandardColumns();
+ formatter_.clear();
+ formatter_.addColumnLine(0, "foo");
+ formatter_.addColumnLine(1, "bar");
+ formatter_.addColumnLine(2, g_wrapText);
+ formatter_.addColumnLine(3, g_wrapText2);
+ checkText(formatter_.formatRow(), "FormattedTable");
+}
+
+TEST_F(TextTableFormatterTest, HandlesEmptyColumnTitles)
+{
+ formatter_.addColumn(NULL, 4, false);
+ formatter_.addColumn("", 4, false);
+ formatter_.addColumn(NULL, 14, true);
+ formatter_.addColumn("", 14, true);
+
+ formatter_.clear();
+ formatter_.addColumnLine(0, "foo");
+ formatter_.addColumnLine(1, "bar");
+ formatter_.addColumnLine(2, g_wrapText);
+ formatter_.addColumnLine(3, g_wrapText2);
+ checkText(formatter_.formatRow(), "FormattedTable");
+}
+
+TEST_F(TextTableFormatterTest, HandlesIndentation)
+{
+ setupStandardColumns();
+ formatter_.setFirstColumnIndent(4);
formatter_.clear();
formatter_.addColumnLine(0, "foo");
formatter_.addColumnLine(1, "bar");
TEST_F(TextTableFormatterTest, HandlesOverflowingLines)
{
+ setupStandardColumns();
formatter_.clear();
formatter_.addColumnLine(0, "foobar");
formatter_.addColumnLine(1, "barfoo");
TEST_F(TextTableFormatterTest, HandlesEmptyColumns)
{
+ setupStandardColumns();
formatter_.clear();
formatter_.addColumnLine(0, "foo");
formatter_.addColumnLine(1, "bar");
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="FormattedTable"><![CDATA[
+foo bar A quick brown A quick brown
+ fox jumps over fox jumps
+ the lazy dog over the lazy
+ dog
+]]></String>
+</ReferenceData>
--- /dev/null
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="referencedata.xsl"?>
+<ReferenceData>
+ <String Name="FormattedTable"><![CDATA[
+ Col1 Col2 Col3Wrap Col4Wrap
+ ---------------------------------------
+ foo bar A quick brown A quick brown
+ fox jumps over fox jumps
+ the lazy dog over the lazy
+ dog
+]]></String>
+</ReferenceData>