From 4b8e38970a9f49bbb1c0e482776fe95cc4224d99 Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Tue, 12 Apr 2016 21:23:15 +0200 Subject: [PATCH] Added hanging indent to help output to make it more readable --- src/NiceCmdLineOutput.cpp | 8 ++------ src/TablePrinter.cpp | 2 +- src/stringTools.cpp | 17 ++++++++++------- src/stringTools.h | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/NiceCmdLineOutput.cpp b/src/NiceCmdLineOutput.cpp index 86567ba..44de9c2 100644 --- a/src/NiceCmdLineOutput.cpp +++ b/src/NiceCmdLineOutput.cpp @@ -68,10 +68,6 @@ void NiceCmdLineOutput::printShortUsage(CmdLineInterface& cli, std::ostream& out outStream << shortUsage << endl; } -string wrapLongID(const string& s) { - return std::regex_replace(s, std::regex(", "), ",\n"); -} - void NiceCmdLineOutput::printLongUsage(CmdLineInterface& cli, std::ostream& outStream) const { TablePrinter tablePrinter(&outStream, { 20, 56 }); @@ -83,7 +79,7 @@ void NiceCmdLineOutput::printLongUsage(CmdLineInterface& cli, std::ostream& outS if (arg != xorArgGroup[0]) outStream << "-- or --" << endl; - tablePrinter.printRow({ wrapLongID(arg->longID()), arg->getDescription() }); + tablePrinter.printRow({ arg->longID(), arg->getDescription() }); } outStream << endl; } @@ -93,6 +89,6 @@ void NiceCmdLineOutput::printLongUsage(CmdLineInterface& cli, std::ostream& outS for (auto arg : argList) { if (xorHandler.contains(arg)) continue; - tablePrinter.printRow({ wrapLongID(arg->longID()), arg->getDescription() }); + tablePrinter.printRow({ arg->longID(), arg->getDescription() }); } } \ No newline at end of file diff --git a/src/TablePrinter.cpp b/src/TablePrinter.cpp index 1f8b80f..bb2c4d4 100644 --- a/src/TablePrinter.cpp +++ b/src/TablePrinter.cpp @@ -33,7 +33,7 @@ void TablePrinter::printRow(initializer_list columns) const { { int columnIndex = 0; for (const string& column : columns) { - vector lines = wrapString(column, columnWidths[columnIndex]); + vector lines = wrapString(column, columnWidths[columnIndex], 2); if (lines.size() > lineCount) lineCount = lines.size(); strings[columnIndex] = move(lines); diff --git a/src/stringTools.cpp b/src/stringTools.cpp index f3eb098..73a6e3d 100644 --- a/src/stringTools.cpp +++ b/src/stringTools.cpp @@ -25,8 +25,10 @@ vector splitIntoLines(const string& s) { return lines; } -vector wrapSingleLineString(const string& s, int lineLength) { +vector wrapSingleLineString(const string& s, int lineLength, int hangingIndent) { if (lineLength <= 0) throw std::invalid_argument("lineLength must be > 0."); + if (hangingIndent < 0) throw std::invalid_argument("hangingIndent must be >= 0."); + if (hangingIndent >= lineLength) throw std::invalid_argument("hangingIndent must be < lineLength."); if (s.find('\t') != std::string::npos) throw std::invalid_argument("s must not contain tabs."); if (s.find('\n') != std::string::npos) throw std::invalid_argument("s must not contain line breaks."); @@ -37,13 +39,14 @@ vector wrapSingleLineString(const string& s, int lineLength) { auto end = p + s.size(); // Iterate over input string while (p <= end) { - // If we're at a word boundary: update safeLineEnd - if (p == end || *p == ' ') { + // If we're at a word boundary: update lineEnd + if (p == end || *p == ' ' || *p == '|') { lineEnd = p; } // If we've hit lineLength or the end of the string: add a new result line - if (p == end || p - lineBegin == lineLength) { + int currentIndent = lines.empty() ? 0 : hangingIndent; + if (p == end || p - lineBegin == lineLength - currentIndent) { if (lineEnd == lineBegin) { // The line contains a single word, which is too long. Split mid-word. lineEnd = p; @@ -52,7 +55,7 @@ vector wrapSingleLineString(const string& s, int lineLength) { // Add trimmed line to list string line(lineBegin, lineEnd); boost::algorithm::trim_right(line); - lines.push_back(line); + lines.push_back(string(currentIndent, ' ') + line); // Resume after the last line, skipping spaces p = lineEnd; @@ -66,10 +69,10 @@ vector wrapSingleLineString(const string& s, int lineLength) { return lines; } -vector wrapString(const string& s, int lineLength) { +vector wrapString(const string& s, int lineLength, int hangingIndent) { vector lines; for (string paragraph : splitIntoLines(s)) { - auto paragraphLines = wrapSingleLineString(paragraph, lineLength); + auto paragraphLines = wrapSingleLineString(paragraph, lineLength, hangingIndent); copy(paragraphLines.cbegin(), paragraphLines.cend(), back_inserter(lines)); } diff --git a/src/stringTools.h b/src/stringTools.h index 646ef5e..522cc9e 100644 --- a/src/stringTools.h +++ b/src/stringTools.h @@ -5,6 +5,6 @@ std::vector splitIntoLines(const std::string& s); -std::vector wrapSingleLineString(const std::string& s, int lineLength); +std::vector wrapSingleLineString(const std::string& s, int lineLength, int hangingIndent = 0); -std::vector wrapString(const std::string& s, int lineLength); +std::vector wrapString(const std::string& s, int lineLength, int hangingIndent = 0);