summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Src/Util.cpp4
-rw-r--r--Src/Util.h4
-rw-r--r--Src/main.cpp86
-rw-r--r--Test/ConditionalReplaceButKeepSigns.cpp26
4 files changed, 83 insertions, 37 deletions
diff --git a/Src/Util.cpp b/Src/Util.cpp
index c084018..9965098 100644
--- a/Src/Util.cpp
+++ b/Src/Util.cpp
@@ -7,7 +7,7 @@ std::string Util::ConditionalReplaceButKeepSigns(
const std::string& str,
std::string find,
const std::string& sub,
- const std::function<bool(const std::string&, const std::size_t)>& onlyIf
+ const std::function<bool(const std::string&, const std::string&, const std::size_t)>& onlyIf
)
{
@@ -29,7 +29,7 @@ std::string Util::ConditionalReplaceButKeepSigns(
if (foundInText_lower == find)
{
// Ask the callback if we should replace this one
- if (onlyIf(foundInText, i))
+ if (onlyIf(str, foundInText, i))
{
// Here we've found our occurrence...
// We have three possible cases:
diff --git a/Src/Util.h b/Src/Util.h
index 11faa61..6b4064b 100644
--- a/Src/Util.h
+++ b/Src/Util.h
@@ -17,8 +17,8 @@ public:
const std::string& str,
std::string find,
const std::string& sub,
- const std::function<bool(const std::string&, const std::size_t)>& onlyIf =
- [](const std::string &, const std::size_t) { return true; } // Default is: replace always
+ const std::function<bool(const std::string&, const std::string&, const std::size_t)>& onlyIf =
+ [](auto, auto, auto) { return true; } // Default is: replace always
);
};
diff --git a/Src/main.cpp b/Src/main.cpp
index 0ebeb5d..26e9fdb 100644
--- a/Src/main.cpp
+++ b/Src/main.cpp
@@ -7,6 +7,30 @@
#include <random>
#include "Util.h"
+// This validator will only replace findings, if they are a complete word, and not just part of a word.
+auto ValidatorFindingIsCompleteWord(const std::string& original, const std::string& finding, const std::size_t index) -> bool {
+ // Quick-accept: Original-string length matches finding-string length
+ if (original.length() == finding.length())
+ return true;
+
+ bool lastCharBreaksWord = true; // Default is true, because this value stays in case there is no last/next char.
+ bool nextCharBreaksWord = true; // In this case, "no character" would imply the word to be broken.
+
+ // Assign surrounding chars, if possible
+ if (index > 0)
+ lastCharBreaksWord = !CharTools::IsLetter(original[index - 1]);
+ if (index + finding.length() < original.length())
+ nextCharBreaksWord = !CharTools::IsLetter(original[index + finding.length()]);
+
+ // If both the last and the next character are word-breaking, replace.
+ if (lastCharBreaksWord && nextCharBreaksWord)
+ return true;
+ // Else: don't
+ else
+ return false;
+}
+
+
//! Will make a boring string look sooper dooper kawaii and cute :3
std::string MakeUwu(std::string boringString) {
// Easy ones first
@@ -20,30 +44,34 @@ std::string MakeUwu(std::string boringString) {
boringString = Util::ConditionalReplaceButKeepSigns(boringString, "up", "uwp");
// Let's do some language adjustments
- boringString = Util::ConditionalReplaceButKeepSigns(boringString, "twank you", "you're twe best <3333 xoxo");
- boringString = Util::ConditionalReplaceButKeepSigns(boringString, "good", "sooper dooper");
- boringString = Util::ConditionalReplaceButKeepSigns(boringString, "suwper", "sooper dooper");
- boringString = Util::ConditionalReplaceButKeepSigns(boringString, "well", "sooper dooper");
- boringString = Util::ConditionalReplaceButKeepSigns(boringString, "emacs", "vim");
- boringString = Util::ConditionalReplaceButKeepSigns(boringString, "twanks", "you're twe best :33 xoxo");
- boringString = Util::ConditionalReplaceButKeepSigns(boringString, "hello", "hiiiiiii");
- boringString = Util::ConditionalReplaceButKeepSigns(boringString, "dear", "hiiiiiii");
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "twank you", "you're twe best <3333 xoxo", ValidatorFindingIsCompleteWord);
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "good", "sooper dooper", ValidatorFindingIsCompleteWord);
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "suwper", "sooper dooper", ValidatorFindingIsCompleteWord);
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "well", "sooper dooper", ValidatorFindingIsCompleteWord);
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "emacs", "vim", ValidatorFindingIsCompleteWord);
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "twanks", "you're twe best :33 xoxo", ValidatorFindingIsCompleteWord);
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "hello", "hiiiiiii", ValidatorFindingIsCompleteWord);
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "dear", "hiiiiiii", ValidatorFindingIsCompleteWord);
+
+ // Let's extend some phonetics
boringString = Util::ConditionalReplaceButKeepSigns(boringString, "hi", "hiiiiiii");
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "ay", "aaay");
+ boringString = Util::ConditionalReplaceButKeepSigns(boringString, "ey", "eeey");
// Replace N with Ny, but only if succeeded by a vowel, and not (preceded by an o and succeeded by an "e{nonletter}"): "one" has such a niche pronunciation...
boringString = Util::ConditionalReplaceButKeepSigns(
boringString,
"n",
"ny",
- [boringString](const std::string &found, int index) {
+ [](const std::string& original, const std::string& finding, const std::size_t index) {
// Jävla this is one clustered piece of shitcode
// Don't replace, if we are on the last char
- if (index + found.length() == boringString.length())
+ if (index + finding.length() == original.length())
return false;
- const char nextChar = CharTools::MakeLower(boringString[index + found.length()]);
- const char lastChar = CharTools::MakeLower(boringString[index - 1]);
+ const char nextChar = CharTools::MakeLower(original[index + finding.length()]);
+ const char lastChar = CharTools::MakeLower(original[index - 1]);
// Apply the complex "one\b"-rule:
// (don't replace if 'n' is preceded by 'o' and succeeded by 'e', which is succeeded by a word break)
@@ -52,12 +80,12 @@ std::string MakeUwu(std::string boringString) {
char nextNextChar;
// How much length is left including `nextChar`?
- const std::size_t sizeLeft = boringString.length() - (index + found.length());
+ const std::size_t sizeLeft = original.length() - (index + finding.length());
// We have room to pick the nextNext char...
if (sizeLeft > 1)
{
- nextNextChar = CharTools::MakeLower(boringString[index + found.length() + 1]);
+ nextNextChar = CharTools::MakeLower(original[index + finding.length() + 1]);
nextNextCharIsNotLetter = !CharTools::IsLetter(nextNextChar);
}
@@ -83,17 +111,17 @@ std::string MakeUwu(std::string boringString) {
boringString,
"r",
"w",
- [boringString](const std::string &found, const std::size_t index) {
+ [](const std::string& original, const std::string& finding, const std::size_t index) {
// Don't replace, if we are on the last char
- if (index + found.length() == boringString.length())
+ if (index + finding.length() == original.length())
return false;
// Don't replace if we're at index 0
if (index == 0)
return false;
- const char nextChar = CharTools::MakeLower(boringString[index + found.length()]);
- const char lastChar = CharTools::MakeLower(boringString[index - 1]);
+ const char nextChar = CharTools::MakeLower(original[index + finding.length()]);
+ const char lastChar = CharTools::MakeLower(original[index - 1]);
// Is this a non-vowel?
if (!CharTools::IsVowel(nextChar))
@@ -113,17 +141,17 @@ std::string MakeUwu(std::string boringString) {
boringString,
"l",
"w",
- [boringString](const std::string &found, int index) {
+ [](const std::string& original, const std::string& finding, const std::size_t index) {
// Our segment has to be at least two characters long
- if (boringString.length() < found.length() + 2)
+ if (original.length() < finding.length() + 2)
return false;
// Don't replace if we're at index o
if (index == 0)
return false;
- const char lastChar = CharTools::MakeLower(boringString[index - 1]);
- const char nextChar = CharTools::MakeLower(boringString[index + found.length()]);
+ const char lastChar = CharTools::MakeLower(original[index - 1]);
+ const char nextChar = CharTools::MakeLower(original[index + finding.length()]);
// Don't replace if the last char is not a letter
if (!CharTools::IsLetter(lastChar))
@@ -138,12 +166,12 @@ std::string MakeUwu(std::string boringString) {
boringString,
"ll",
"ww",
- [boringString](const std::string &found, int index) {
+ [](const std::string& original, const std::string& finding, const std::size_t index) {
// Don't replace, if we are on the last char
- if (index + found.length() == boringString.length())
+ if (index + finding.length() == original.length())
return false;
- const char nextChar = CharTools::MakeLower(boringString[index + found.length()]);
+ const char nextChar = CharTools::MakeLower(original[index + finding.length()]);
return CharTools::IsVowel(nextChar);
}
@@ -154,16 +182,16 @@ std::string MakeUwu(std::string boringString) {
boringString,
"er",
"a",
- [boringString](const std::string &found, int index) {
+ [](const std::string& original, const std::string& finding, const std::size_t index) {
// Replace if we're at the end of this line/segment
- if (index + found.length() == boringString.length())
+ if (index + finding.length() == original.length())
return true;
// Fetch the next char
- const char nextChar = CharTools::MakeLower(boringString[index + found.length()]);
+ const char nextChar = CharTools::MakeLower(original[index + finding.length()]);
// Replace if the next char is not a letter
- return CharTools::IsLetter(nextChar) == false;
+ return !CharTools::IsLetter(nextChar);
}
);
diff --git a/Test/ConditionalReplaceButKeepSigns.cpp b/Test/ConditionalReplaceButKeepSigns.cpp
index 1994528..99c3bcb 100644
--- a/Test/ConditionalReplaceButKeepSigns.cpp
+++ b/Test/ConditionalReplaceButKeepSigns.cpp
@@ -97,7 +97,7 @@ TEST_CASE(__FILE__"/RejectingAllReplacementsChangesNothing", "[]")
in,
"e",
"hello",
- [](auto, auto){ return false; } // Reject all replacements
+ [](auto, auto, auto){ return false; } // Reject all replacements
);
// Verify
@@ -116,7 +116,7 @@ TEST_CASE(__FILE__"/Callback_Index_Matches", "[]")
in,
"banana",
"hello",
- [](const std::string& finding, const std::size_t index) -> bool {
+ [](const std::string& original, const std::string& finding, const std::size_t index) -> bool {
REQUIRE(index == 7);
return true;
}
@@ -135,7 +135,7 @@ TEST_CASE(__FILE__"/Callback_Finding_Matches", "[]")
in,
"banana",
"hello",
- [](const std::string& finding, const std::size_t index) -> bool {
+ [](const std::string& original, const std::string& finding, const std::size_t index) -> bool {
REQUIRE(finding == "BANAna");
return true;
}
@@ -157,7 +157,7 @@ TEST_CASE(__FILE__"/Callback_Conditional_Rejecting_Works", "[]")
in,
"ding",
"dong",
- [ptrCounter](const std::string& finding, const std::size_t index) -> bool {
+ [ptrCounter](const std::string& original, const std::string& finding, const std::size_t index) -> bool {
return (++*ptrCounter) % 2;
}
);
@@ -183,3 +183,21 @@ TEST_CASE(__FILE__"/ReplaceSymbols", "[]")
// Verify
REQUIRE(result == expected);
}
+
+// The callback ALWAYS receives the same, identical 'original string' value on each call, without any replacements made to it.
+TEST_CASE(__FILE__"/Original-value_on_callback_is_correct", "[]")
+{
+ // Setup
+ const std::string in = "I felt happy because I saw the others were happy and because I knew I should feel happy, but I wasn't really happy.”";
+
+ // Exercise & Verify
+ const std::string result = Util::ConditionalReplaceButKeepSigns(
+ in,
+ "happy",
+ "",
+ [in](const std::string& original, const std::string& finding, const std::size_t index) -> bool {
+ REQUIRE(original == in);
+ return true;
+ }
+ );
+}