diff options
Diffstat (limited to 'src/translation.cpp')
-rw-r--r-- | src/translation.cpp | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/src/translation.cpp b/src/translation.cpp new file mode 100644 index 000000000..e8582f328 --- /dev/null +++ b/src/translation.cpp @@ -0,0 +1,146 @@ +/* +Minetest +Copyright (C) 2017 Nore, Nathanaƫl Courant <nore@mesecons.net> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "translation.h" +#include "log.h" +#include "util/string.h" + +static Translations main_translations; +Translations *g_translations = &main_translations; + +Translations::~Translations() +{ + clear(); +} + +void Translations::clear() +{ + m_translations.clear(); +} + +const std::wstring &Translations::getTranslation( + const std::wstring &textdomain, const std::wstring &s) +{ + std::wstring key = textdomain + L"|" + s; + try { + return m_translations.at(key); + } catch (std::out_of_range) { + warningstream << "Translations: can't find translation for string \"" + << wide_to_utf8(s) << "\" in textdomain \"" + << wide_to_utf8(textdomain) << "\"" << std::endl; + // Silence that warning in the future + m_translations[key] = s; + return s; + } +} + +void Translations::loadTranslation(const std::string &data) +{ + std::istringstream is(data); + std::wstring textdomain; + std::string line; + + while (is.good()) { + std::getline(is, line); + if (str_starts_with(line, "# textdomain:")) { + textdomain = utf8_to_wide(trim(str_split(line, ':')[1])); + } + if (line.empty() || line[0] == '#') + continue; + + std::wstring wline = utf8_to_wide(line); + if (wline.empty()) + continue; + + // Read line + // '=' marks the key-value pair, but may be escaped by an '@'. + // '\n' may also be escaped by '@'. + // All other escapes are preserved. + + size_t i = 0; + std::wostringstream word1, word2; + while (i < wline.length() && wline[i] != L'=') { + if (wline[i] == L'@') { + if (i + 1 < wline.length()) { + if (wline[i + 1] == L'=') { + word1.put(L'='); + } else { + word1.put(L'@'); + word1.put(wline[i + 1]); + } + i += 2; + } else { + // End of line, go to the next one. + word1.put(L'\n'); + if (!is.good()) { + break; + } + i = 0; + std::getline(is, line); + wline = utf8_to_wide(line); + } + } else { + word1.put(wline[i]); + i++; + } + } + + if (i == wline.length()) { + errorstream << "Malformed translation line \"" << line << "\"" + << std::endl; + continue; + } + i++; + + while (i < wline.length()) { + if (wline[i] == L'@') { + if (i + 1 < wline.length()) { + if (wline[i + 1] == L'=') { + word2.put(L'='); + } else { + word2.put(L'@'); + word2.put(wline[i + 1]); + } + i += 2; + } else { + // End of line, go to the next one. + word2.put(L'\n'); + if (!is.good()) { + break; + } + i = 0; + std::getline(is, line); + wline = utf8_to_wide(line); + } + } else { + word2.put(wline[i]); + i++; + } + } + + std::wstring oword1 = word1.str(), oword2 = word2.str(); + if (oword2.empty()) { + oword2 = oword1; + errorstream << "Ignoring empty translation for \"" + << wide_to_utf8(oword1) << "\"" << std::endl; + } + + m_translations[textdomain + L"|" + oword1] = oword2; + } +}
\ No newline at end of file |