diff --git a/extensions/extrawindow.cpp b/extensions/extrawindow.cpp index cdf96f3..dd57edd 100644 --- a/extensions/extrawindow.cpp +++ b/extensions/extrawindow.cpp @@ -197,7 +197,7 @@ public: void AddSentence(QString sentence) { if (sentence.size() > maxSentenceSize) sentence = SENTENCE_TOO_BIG; - if (!showOriginal) sentence = sentence.section("\n----\n", sentence.count("\n----\n") / 2 + 1); + if (!showOriginal && sentence.count(u8"\x200b \n")) sentence = sentence.split(u8"\x200b \n")[1]; sanitize(sentence); sentence.chop(std::distance(std::remove(sentence.begin(), sentence.end(), QChar::Tabulation), sentence.end())); sentenceHistory.push_back(sentence); diff --git a/extensions/network.h b/extensions/network.h index 49bd945..d2610ca 100644 --- a/extensions/network.h +++ b/extensions/network.h @@ -33,43 +33,6 @@ std::string Escape(const std::string& text); namespace JSON { - inline std::wstring UTF(int charCode) - { - return { (wchar_t)charCode }; - } - - template - std::pair, int> Unescape(std::basic_string_view text) - { - std::basic_string unescaped; - int i = 0; - for (; i < text.size(); ++i) - { - auto ch = text[i]; - if (ch == '"') return { unescaped, i + 1 }; - if (ch == '\\') - { - ch = text[i + 1]; - if (ch == 'u' && isxdigit(text[i + 2]) && isxdigit(text[i + 3]) && isxdigit(text[i + 4]) && isxdigit(text[i + 5])) - { - char charCode[] = { text[i + 2], text[i + 3], text[i + 4], text[i + 5], 0 }; - unescaped += UTF(strtol(charCode, nullptr, 16)); - i += 5; - continue; - } - for (auto [original, value] : Array{ { 'b', '\b' }, {'f', '\f'}, {'n', '\n'}, {'r', '\r'}, {'t', '\t'} }) if (ch == original) - { - unescaped.push_back(value); - goto replaced; - } - unescaped.push_back(ch); - replaced: i += 1; - } - else unescaped.push_back(ch); - } - return { unescaped, i }; - } - template std::basic_string Escape(std::basic_string text) { @@ -93,6 +56,44 @@ namespace JSON return text; } + template struct UTF {}; + template <> struct UTF + { + inline static std::wstring FromCodepoint(int codepoint) { return { (wchar_t)codepoint }; } // TODO: surrogate pairs + }; + + template + std::pair, int> Unescape(std::basic_string_view text) + { + std::basic_string unescaped; + int i = 0; + for (; i < text.size(); ++i) + { + auto ch = text[i]; + if (ch == '"') return { unescaped, i + 1 }; + if (ch == '\\') + { + ch = text[i + 1]; + if (ch == 'u' && isxdigit(text[i + 2]) && isxdigit(text[i + 3]) && isxdigit(text[i + 4]) && isxdigit(text[i + 5])) + { + char charCode[] = { text[i + 2], text[i + 3], text[i + 4], text[i + 5], 0 }; + unescaped += UTF::FromCodepoint(strtol(charCode, nullptr, 16)); + i += 5; + continue; + } + for (auto [original, value] : Array{ { 'b', '\b' }, {'f', '\f'}, {'n', '\n'}, {'r', '\r'}, {'t', '\t'} }) if (ch == original) + { + unescaped.push_back(value); + goto replaced; + } + unescaped.push_back(ch); + replaced: i += 1; + } + else unescaped.push_back(ch); + } + return { unescaped, i }; + } + template struct Value : private std::variant, std::vector>, std::unordered_map, Value>> { @@ -119,10 +120,10 @@ namespace JSON } }; - template + template Value Parse(std::basic_string_view text, int64_t& i, int depth) { - if (depth > 25) return {}; + if (depth > maxDepth) return {}; C ch; auto SkipWhitespace = [&] { @@ -169,7 +170,7 @@ namespace JSON i += 1; if (SkipWhitespace()) return {}; if (ch == ']') return i += 1, Value(array); - if (!array.emplace_back(Parse(text, i, depth + 1))) return {}; + if (!array.emplace_back(Parse(text, i, depth + 1))) return {}; if (SkipWhitespace()) return {}; if (ch == ']') return i += 1, Value(array); if (ch != ',') return {}; @@ -188,7 +189,7 @@ namespace JSON auto key = ExtractString(); if (SkipWhitespace() || ch != ':') return {}; i += 1; - if (!(object[std::move(key)] = Parse(text, i, depth + 1))) return {}; + if (!(object[std::move(key)] = Parse(text, i, depth + 1))) return {}; if (SkipWhitespace()) return {}; if (ch == '}') return i += 1, Value(object); if (ch != ',') return {}; diff --git a/extensions/translatewrapper.cpp b/extensions/translatewrapper.cpp index 97778e9..dd4613d 100644 --- a/extensions/translatewrapper.cpp +++ b/extensions/translatewrapper.cpp @@ -161,7 +161,7 @@ bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo) if (cache && translationCache->size() > savedSize + 50) SaveCache(); for (int i = 0; i < translation.size(); ++i) if (translation[i] == '\r' && translation[i + 1] == '\n') translation[i] = 0x200b; // for some reason \r appears as newline - no need to double - if (!translation.empty()) (sentence += L"\n----\n") += translation; + if (!translation.empty()) (sentence += L"\x200b \n") += translation; return true; }