// _____ _ _____ // |_ _|____ _| ||_ _|_ __ // | |/ _ \ \/ / __|| | \ \ / / // | | __/> <| |_ | | \ V / // |_|\___/_/\_\\__||_| \_/ // Author: Love Billenius // License: GPL-3 #include "stringutil.hpp" #include #include #include namespace string_utils { bool isAllWhitespace(const std::string &str) { return std::ranges::all_of(str, [](const unsigned char c) -> bool { return std::isspace(c); }); } void removeTrailingWhitespace(std::string &str) { auto shouldRemoveTrailingWhitespace = [&str]() -> bool { std::size_t last_newline = str.find_last_of('\n'); if (last_newline == std::string::npos) return isAllWhitespace(str); const std::string last_line = str.substr(last_newline + 1); return isAllWhitespace(last_line); }; while (shouldRemoveTrailingWhitespace()) { const std::size_t last_newline = str.find_last_of('\n'); if (last_newline == std::string::npos) { if (isAllWhitespace(str)) str.clear(); break; } str.erase(last_newline); } } void removeTabs(std::string &str) { std::erase(str, '\t'); } void limitConsecutiveWhitespace(std::string &str, const uint_fast8_t maxWhitespace) { std::istringstream stream(str); std::string line; std::ostringstream processedStream; uint_fast8_t whitespaceRow = 0; bool hasAddedRealTextJet = false; while (std::getline(stream, line)) { const bool onlySpace = isAllWhitespace(line); if (!hasAddedRealTextJet) { if (onlySpace) continue; // Skip leading empty lines hasAddedRealTextJet = true; } else if (onlySpace) { whitespaceRow++; } else { whitespaceRow = 0; } if (whitespaceRow > maxWhitespace) continue; // Skip lines exceeding maxWhitespace processedStream << line << "\n"; } str = processedStream.str(); } }