summaryrefslogtreecommitdiffstats
path: root/src/rttt/text.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rttt/text.hpp')
-rw-r--r--src/rttt/text.hpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/rttt/text.hpp b/src/rttt/text.hpp
new file mode 100644
index 0000000..fb59b55
--- /dev/null
+++ b/src/rttt/text.hpp
@@ -0,0 +1,101 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "rttt.hpp"
+
+namespace rttt {
+namespace text {
+// TODO: should work with constexpr, but might need newer g++/clang++
+inline std::vector<std::string> split(std::string_view strv,
+ std::string_view delims = " ",
+ size_t no_pieces = 0) {
+ std::vector<std::string> output;
+ size_t first = 0;
+
+ while (first < strv.size()) {
+ const auto second = strv.find_first_of(delims, first);
+
+ if (first != second)
+ output.emplace_back(strv.substr(first, second - first));
+
+ if (second == std::string_view::npos) {
+ break;
+ } else if (no_pieces > 0 && output.size() >= no_pieces - 1) {
+ output.emplace_back(strv.substr(second + 1, strv.size()));
+ break;
+ }
+
+ first = second + 1;
+ }
+
+ return output;
+}
+
+std::vector<std::string> wrap_single_line(const std::string &line,
+ size_t width) {
+ std::vector<std::string> output;
+
+ // Check for carriage return. Would be nice if this was not explicitely needed
+ if (line.empty() || line == "\n") {
+ output.push_back("");
+ return output;
+ }
+
+ std::istringstream str(line);
+ std::ostringstream new_line;
+
+ std::string word;
+ // Length of the new_line
+ size_t s = 0;
+ while (!str.eof()) {
+ str >> word;
+ if (s + word.size() + 1 >= width) {
+ // Break long words (when there is enough white space left)
+ if (word.size() >= std::min(std::size_t{20}, width) && width > s + 7) {
+ auto n = width - s - 2;
+ std::string w1 = " " + word.substr(0, n) + "-";
+ std::string w2 = word.substr(n, word.size());
+ new_line << w1;
+ word = w2;
+ }
+ output.push_back(new_line.str());
+ new_line = std::ostringstream();
+ s = 0;
+ } else if (new_line.tellp() != 0) {
+ new_line << " ";
+ ++s;
+ }
+ new_line << word;
+ s += word.size();
+ word.clear();
+ }
+ output.push_back(new_line.str());
+ return output;
+}
+
+std::vector<std::string> wrap(std::string_view text, size_t width) {
+ auto lines = rttt::text::split(text, "\n");
+ std::vector<std::string> output;
+ output.reserve(lines.size());
+
+ for (auto &line : lines) {
+ auto v = wrap_single_line(line, width);
+ output.insert(output.end(), v.begin(), v.end());
+ }
+ return output;
+}
+
+inline std::string time_since_string(uint64_t t) {
+ auto delta = rttt::current_time() - t;
+ if (delta < 60)
+ return std::to_string(delta) + " seconds";
+ if (delta < 3600)
+ return std::to_string(delta / 60) + " minutes";
+ if (delta < 24 * 3600)
+ return std::to_string(delta / 3600) + " hours";
+ return std::to_string(delta / 24 / 3600) + " days";
+}
+} // namespace text
+} // namespace rttt