From 55e4008925ee5af3a07ca3225ed73d2414423a0d Mon Sep 17 00:00:00 2001 From: Tim Siegel Date: Thu, 21 Apr 2022 16:58:53 -0400 Subject: [PATCH] MiscUtils: teach word_wrap() to optionally preserve whitespace --- library/MiscUtils.cpp | 58 +++++++++++++++++++++++++++---------- library/include/MiscUtils.h | 3 +- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/library/MiscUtils.cpp b/library/MiscUtils.cpp index 56af85afe..6ab63d5eb 100644 --- a/library/MiscUtils.cpp +++ b/library/MiscUtils.cpp @@ -168,32 +168,58 @@ std::string to_search_normalized(const std::string &str) return result; } -bool word_wrap(std::vector *out, const std::string &str, size_t line_length) + +bool word_wrap(std::vector *out, const std::string &str, + size_t line_length, bool collapse_whitespace) { - out->clear(); - std::istringstream input(str); - std::string out_line; - std::string word; - if (input >> word) + if (line_length == 0) + line_length = SIZE_MAX; + + std::string line; + size_t break_pos = 0; + + for (auto &c : str) { - out_line += word; - // size_t remaining = line_length - std::min(line_length, word.length()); - while (input >> word) + if (c == '\n') + { + out->push_back(line); + line.clear(); + break_pos = 0; + continue; + } + + if (isspace(c)) { - if (out_line.length() + word.length() + 1 <= line_length) + if (break_pos == line.length() && collapse_whitespace) + continue; + + line.push_back(collapse_whitespace ? ' ' : c); + break_pos = line.length(); + } + else { + line.push_back(c); + } + + if (line.length() > line_length) + { + if (break_pos > 0) { - out_line += ' '; - out_line += word; + // Break before last space, and skip that space + out->push_back(line.substr(0, break_pos - 1)); } else { - out->push_back(out_line); - out_line = word; + // Single word is too long, just break it + out->push_back(line.substr(0, line_length)); + break_pos = line_length; } + line = line.substr(break_pos); + break_pos = 0; } - if (out_line.length()) - out->push_back(out_line); } + if (line.length()) + out->push_back(line); + return true; } diff --git a/library/include/MiscUtils.h b/library/include/MiscUtils.h index 7a5f050a2..764b11413 100644 --- a/library/include/MiscUtils.h +++ b/library/include/MiscUtils.h @@ -391,7 +391,8 @@ DFHACK_EXPORT std::string to_search_normalized(const std::string &str); DFHACK_EXPORT bool word_wrap(std::vector *out, const std::string &str, - size_t line_length = 80); + size_t line_length = 80, + bool collapse_whitespace = false); inline bool bits_match(unsigned required, unsigned ok, unsigned mask) {