#include "UI/Text/TextMarkup.h" #include namespace { bool Hex(unsigned char value) { return (value >= '0' && value <= '9') || (value >= 'a' && value <= 'f') || (value >= 'A' && value <= 'F'); } bool Color(const char* text, const char* end) { if (*text != '^' || end - text < 6) { return false; } for (int index = 1; index <= 6; ++index) { if (!Hex(static_cast(text[index]))) { return false; } } return true; } } // OFFSET: 0x00A81A70 // FUNCTION: fn_16980 bool HasTextLinks(const std::string& text) { return text.find("") != std::string::npos || text.find("") != std::string::npos || text.find("") != std::string::npos || text.find("") != std::string::npos || text.find("") != std::string::npos || text.find("") != std::string::npos; } // OFFSET: 0x008791E0 // FUNCTION: fn_11214 std::string ExpandTextEscapes(std::string text) { auto position = text.find("\\n"); while (position != std::string::npos) { text.replace(position, 2, "\n"); position = text.find("\\n"); } position = text.find("\\r"); while (position != std::string::npos) { text.replace(position, 2, "\r"); position = text.find("\\r"); } return text; } // OFFSET: 0x00A7EDC0 // FUNCTION: fn_16961 std::string RemoveTextColors(const char* text, unsigned short codePage) { const char* end = text + std::char_traits::length(text); const char* current = text; std::string result; while (current < end) { const char* next = current; while (next < end && !Color(next, end)) { next = CharNextExA(codePage, next, 0); } result.append(current, next); if (next >= end) { break; } current = next + 7; } return result; } // OFFSET: 0x00A7F660 // FUNCTION: fn_16966 std::string DisplayTextTag(std::string text, const std::string& begin, const std::string& end) { auto position = text.find(begin); if (position == std::string::npos) { return text; } std::string result; do { if (position > 0) { result.append(text, 0, position); } const auto content = position + begin.size(); std::string tail = text.substr(content); const auto close = tail.find(end); if (close == std::string::npos) { position = content; } else { result.append(tail, 0, close); text = tail.substr(close + end.size()); position = text.find(begin); } } while (position != std::string::npos); result += text; return result; } // OFFSET: 0x00A7EF40 // FUNCTION: fn_16962 std::string RemoveTextLinkInfo(std::string text) { auto position = text.find(""); if (position == std::string::npos) { return text; } std::string result; do { if (position > 0) { result.append(text, 0, position); } const auto close = text.find(""); if (close != std::string::npos) { text = text.substr(close + 7); position = text.find(""); } } while (position != std::string::npos); result += text; return result; } // OFFSET: 0x00A7CAB0 // FUNCTION: fn_16950 void ExtractTextLinks(std::string text, const std::string& begin, const std::string& end, std::vector& links) { auto position = text.find(begin); if (position == std::string::npos) { return; } std::string prefix = RemoveTextLinkInfo(text.substr(0, position)); std::uint32_t offset = static_cast(prefix.size()); do { const auto content = position + begin.size(); std::string tail = text.substr(content); const auto close = tail.find(end); if (close == std::string::npos) { position = content; continue; } std::string display = tail.substr(0, close); std::string metadata; const auto info = display.find(""); if (info != std::string::npos) { display = tail.substr(0, info); metadata = tail.substr(info + 6); const auto infoEnd = metadata.find(""); if (infoEnd != std::string::npos) { metadata.resize(infoEnd); } } TextLink link; link.position = offset; link.display = display; link.metadata = metadata; links.push_back(std::move(link)); offset += static_cast(display.size()); text = tail.substr(close + end.size()); position = text.find(begin); if (position != std::string::npos) { prefix = RemoveTextLinkInfo(text.substr(0, position)); offset += static_cast(prefix.size()); } } while (position != std::string::npos); } // OFFSET: 0x00877650 // FUNCTION: fn_11210 void SplitTextLinkArguments(std::string text, std::vector& arguments) { if (text.empty()) { return; } auto comma = text.find(','); while (comma != std::string::npos) { arguments.push_back(text.substr(0, comma)); text = text.substr(comma + 1); comma = text.find(','); } arguments.push_back(text); }