Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarText.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-07-22 22:31:04 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-07-22 22:31:04 +1000
commitcb19eef701b5c9e27d0464795fffcf8a4d795a21 (patch)
tree5cfbdf49ebd7ac9539891eea850e244887d4c355 /source/core/StarText.cpp
parent4fbd67daccfa69df6988bdf17c67ee3d5f3049c5 (diff)
Add character swapping (no GUI yet)
Diffstat (limited to 'source/core/StarText.cpp')
-rw-r--r--source/core/StarText.cpp89
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