yum-mirror/UwwwuPP
A rehost of leonetienne's UwwwuPP, a simple text filter to uwu-ify English text.
git clone https://git.yummers.dev/yum-mirror/UwwwuPP
b172ec9
master
1#include "Util.h" 2#include <CharTools.h> 3#include <StringTools.h> 4#include <sstream> 5 6std::string Util ::ConditionalReplaceButKeepSigns ( 7const std::string & str , 8 std::string find , 9const std::string & sub , 10const std::function < bool (const std::string & ,const std::string & ,const std::size_t )>& onlyIf 11) 12{ 13 14// Quick accepts-and rejects 15if (str .length ()== 0 ) 16return "" ; 17else if (find .length ()== 0 ) 18return str ; 19 20 std::stringstream ss ; 21 22// Better safe than sorry 23find = StringTools ::Lower (find ); 24 25for (std::size_t i = 0 ;i < str .length ();i ++ ) 26 { 27const std::string foundInText = str .substr (i ,find .length ()); 28const std::string foundInText_lower = StringTools ::Lower (foundInText ); 29if (foundInText_lower == find ) 30 { 31// Ask the callback if we should replace this one 32if (onlyIf (str ,foundInText ,i )) 33 { 34// Here we've found our occurrence... 35// We have three possible cases: 36// 1: len(find) == len(sub), in this case we want to sync capitalization by index. 37// 2: len(find) < len(sub), in this case we sync by index, BUT... 38// 3: len(find) > len(sub): sync capitalization by index 39 40// We want to sync capitalization by index 41// This accounts for both cases: 1 and 3 42if (foundInText .length () >=sub .length ()) 43 { 44for (std::size_t j = 0 ;j < sub .length ();j ++ ) 45 { 46const char cf = foundInText [j ]; 47const char cs = sub [j ]; 48 49ss <<CharTools ::CopySign (cf ,cs ); 50 } 51 } 52 53// in this case we sync by index, BUT... 54else if (foundInText .length ()< sub .length ()) 55 { 56char followingCharsSign = 0 ; 57bool doHaveFollowingChar = false; 58// Do we even have a following char? 59if (str .length () >=i + foundInText .length ()+ 1 ) 60 { 61const char followingChar = str [i + foundInText .length ()]; 62 63// Is it a letter? 64if (CharTools ::IsLetter (followingChar )) 65 { 66// Copy its sign 67followingCharsSign = followingChar ; 68doHaveFollowingChar = true; 69 } 70 } 71 72 73char lastCharCharSign = 0 ; 74for (std::size_t j = 0 ;j < sub .length ();j ++ ) 75 { 76const char cs = sub [j ]; 77 78// Do we still have chars of 'find' left? 79if (j < foundInText .length ()) 80 { 81// Yes: Just copy the sign as is, and update the last sign seen 82const char cf = foundInText [j ]; 83lastCharCharSign = cf ; 84ss <<CharTools ::CopySign (cf ,cs ); 85 } 86else 87 { 88// No: Use the last sign seen, or the sign of the following char (the following char within the same word-boundary) (Important for replacing vocals within a word) 89const char charSignToUse = doHaveFollowingChar ?followingCharsSign :lastCharCharSign ; 90ss <<CharTools ::CopySign (charSignToUse ,cs ); 91 } 92 } 93 } 94 } 95else 96 { 97// We do not have an occurrence... just insert the subsection found as is (next iteration will start behind it) 98ss <<foundInText ; 99 } 100 101// Advance i accordingly 102i += foundInText .length ()- 1 ; 103 } 104else 105 { 106// We do not have an occurrence... just insert the char as is 107ss <<str [i ]; 108 } 109 } 110 111return ss .str (); 112}