string.cpp (2651B)
1 /* ReaPack: Package manager for REAPER 2 * Copyright (C) 2015-2025 Christian Fillion 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "string.hpp" 19 20 #include <boost/algorithm/string/replace.hpp> 21 #include <boost/algorithm/string/trim.hpp> 22 #include <cstdarg> 23 #include <regex> 24 #include <sstream> 25 26 std::string String::format(const char *fmt, ...) 27 { 28 va_list args; 29 30 va_start(args, fmt); 31 const int size = vsnprintf(nullptr, 0, fmt, args); 32 va_end(args); 33 34 std::string buf(size, 0); 35 36 va_start(args, fmt); 37 vsnprintf(&buf[0], size + 1, fmt, args); 38 va_end(args); 39 40 return buf; 41 } 42 43 std::string String::indent(const std::string &text) 44 { 45 std::string output; 46 std::istringstream input(text); 47 std::string line; 48 bool first = true; 49 50 while(getline(input, line, '\n')) { 51 if(first) 52 first = false; 53 else 54 output += "\r\n"; 55 56 boost::algorithm::trim(line); 57 58 if(line.empty()) 59 continue; 60 61 output += "\x20\x20"; 62 output += line; 63 } 64 65 return output; 66 } 67 68 std::string String::stripRtf(const std::string &rtf) 69 { 70 static const std::regex rtfRules( 71 // passthrough for later replacement to \n 72 R"((\\line |\\par\}))" "|" 73 R"(\\line(\n)\s*)" "|" 74 75 // preserve literal braces 76 R"(\\([\{\}]))" "|" 77 78 // hidden groups (strip contents) 79 R"(\{\\(?:f\d+|fonttbl|colortbl)[^\{\}]+\})" "|" 80 81 // formatting tags and groups (keep contents) 82 R"(\\\w+\s?|\{|\})" "|" 83 84 // newlines and indentation 85 R"(\s*\n\s*)" 86 ); 87 88 std::string text = std::regex_replace(rtf, rtfRules, "$1$2$3"); 89 boost::algorithm::replace_all(text, "\\line ", "\n"); 90 boost::algorithm::replace_all(text, "\\par}", "\n\n"); 91 boost::algorithm::trim(text); 92 93 return text; 94 } 95 96 void String::ImplDetail::imbueStream(std::ostream &stream) 97 { 98 class NumPunct : public std::numpunct<char> 99 { 100 protected: 101 char do_thousands_sep() const override { return ','; } 102 std::string do_grouping() const override { return "\3"; } 103 }; 104 105 stream.imbue(std::locale(std::locale::classic(), new NumPunct)); 106 }