diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-07-22 22:31:04 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-07-22 22:31:04 +1000 |
commit | cb19eef701b5c9e27d0464795fffcf8a4d795a21 (patch) | |
tree | 5cfbdf49ebd7ac9539891eea850e244887d4c355 /source/core/StarText.cpp | |
parent | 4fbd67daccfa69df6988bdf17c67ee3d5f3049c5 (diff) |
Add character swapping (no GUI yet)
Diffstat (limited to 'source/core/StarText.cpp')
-rw-r--r-- | source/core/StarText.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/source/core/StarText.cpp b/source/core/StarText.cpp new file mode 100644 index 0000000..11fca27 --- /dev/null +++ b/source/core/StarText.cpp @@ -0,0 +1,89 @@ +#include "StarText.hpp" + +#include <regex> + +namespace Star { + +namespace Text { + static auto stripEscapeRegex = std::regex(strf("\\{:c}[^;]*{:c}", CmdEsc, EndEsc)); + String stripEscapeCodes(String const& s) { + return std::regex_replace(s.utf8(), stripEscapeRegex, ""); + } + + static std::string escapeChars = strf("{:c}{:c}", CmdEsc, StartEsc); + + bool processText(StringView text, TextCallback textFunc, CommandsCallback commandsFunc, bool includeCommandSides) { + std::string_view escChars(escapeChars); + + std::string_view str = text.utf8(); + while (true) { + size_t escape = str.find_first_of(escChars); + if (escape != NPos) { + escape = str.find_first_not_of(escChars, escape) - 1; // jump to the last ^ + + size_t end = str.find_first_of(EndEsc, escape); + if (end != NPos) { + if (escape && !textFunc(str.substr(0, escape))) + return false; + if (commandsFunc) { + StringView commands = includeCommandSides + ? str.substr(escape, end - escape + 1) + : str.substr(escape + 1, end - escape - 1); + if (!commands.empty() && !commandsFunc(commands)) + return false; + } + str = str.substr(end + 1); + continue; + } + } + + if (!str.empty()) + return textFunc(str); + + return true; + } + } + + // The below two functions aren't used anymore, not bothering with StringView for them + String preprocessEscapeCodes(String const& s) { + bool escape = false; + std::string result = s.utf8(); + + size_t escapeStartIdx = 0; + for (size_t i = 0; i < result.size(); i++) { + auto& c = result[i]; + if (isEscapeCode(c)) { + escape = true; + escapeStartIdx = i; + } + if ((c <= SpecialCharLimit) && !(c == StartEsc)) + escape = false; + if ((c == EndEsc) && escape) + result[escapeStartIdx] = StartEsc; + } + return {result}; + } + + String extractCodes(String const& s) { + bool escape = false; + StringList result; + String escapeCode; + for (auto c : preprocessEscapeCodes(s)) { + if (c == StartEsc) + escape = true; + if (c == EndEsc) { + escape = false; + for (auto command : escapeCode.split(',')) + result.append(command); + escapeCode = ""; + } + if (escape && (c != StartEsc)) + escapeCode.append(c); + } + if (!result.size()) + return ""; + return "^" + result.join(",") + ";"; + } +} + +}
\ No newline at end of file |