mirror of https://github.com/kiwix/libkiwix.git
commit
c2042c3be8
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2022 Veloman Yunkan <veloman.yunkan@gmail.com>
|
* Copyright 2024 Veloman Yunkan <veloman.yunkan@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -17,29 +17,15 @@
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef KIWIX_SERVER_I18N
|
#ifndef KIWIX_I18N
|
||||||
#define KIWIX_SERVER_I18N
|
#define KIWIX_I18N
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <mustache.hpp>
|
|
||||||
|
|
||||||
namespace kiwix
|
namespace kiwix
|
||||||
{
|
{
|
||||||
|
|
||||||
struct I18nString {
|
|
||||||
const char* const key;
|
|
||||||
const char* const value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct I18nStringTable {
|
|
||||||
const char* const lang;
|
|
||||||
const size_t entryCount;
|
|
||||||
const I18nString* const entries;
|
|
||||||
|
|
||||||
const char* get(const std::string& key) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string getTranslatedString(const std::string& lang, const std::string& key);
|
std::string getTranslatedString(const std::string& lang, const std::string& key);
|
||||||
|
|
||||||
namespace i18n
|
namespace i18n
|
||||||
|
@ -70,28 +56,6 @@ private:
|
||||||
const std::string m_lang;
|
const std::string m_lang;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GetTranslatedStringWithMsgId
|
|
||||||
{
|
|
||||||
typedef kainjow::mustache::basic_data<std::string> MustacheString;
|
|
||||||
typedef std::pair<std::string, MustacheString> MsgIdAndTranslation;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit GetTranslatedStringWithMsgId(const std::string& lang) : m_lang(lang) {}
|
|
||||||
|
|
||||||
MsgIdAndTranslation operator()(const std::string& key) const
|
|
||||||
{
|
|
||||||
return {key, getTranslatedString(m_lang, key)};
|
|
||||||
}
|
|
||||||
|
|
||||||
MsgIdAndTranslation operator()(const std::string& key, const Parameters& params) const
|
|
||||||
{
|
|
||||||
return {key, expandParameterizedString(m_lang, key, params)};
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const std::string m_lang;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace i18n
|
} // namespace i18n
|
||||||
|
|
||||||
class ParameterizedMessage
|
class ParameterizedMessage
|
||||||
|
@ -121,18 +85,8 @@ inline ParameterizedMessage nonParameterizedMessage(const std::string& msgId)
|
||||||
return ParameterizedMessage(msgId, noParams);
|
return ParameterizedMessage(msgId, noParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LangPreference
|
std::string translateBookCategory(const std::string& lang, const std::string& category);
|
||||||
{
|
|
||||||
const std::string lang;
|
|
||||||
const float preference;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<LangPreference> UserLangPreferences;
|
|
||||||
|
|
||||||
UserLangPreferences parseUserLanguagePreferences(const std::string& s);
|
|
||||||
|
|
||||||
std::string selectMostSuitableLanguage(const UserLangPreferences& prefs);
|
|
||||||
|
|
||||||
} // namespace kiwix
|
} // namespace kiwix
|
||||||
|
|
||||||
#endif // KIWIX_SERVER_I18N
|
#endif // KIWIX_I18N
|
|
@ -10,7 +10,8 @@ headers = [
|
||||||
'kiwixserve.h',
|
'kiwixserve.h',
|
||||||
'name_mapper.h',
|
'name_mapper.h',
|
||||||
'tools.h',
|
'tools.h',
|
||||||
'version.h'
|
'version.h',
|
||||||
|
'i18n.h'
|
||||||
]
|
]
|
||||||
|
|
||||||
install_headers(headers, subdir:'kiwix')
|
install_headers(headers, subdir:'kiwix')
|
||||||
|
|
|
@ -61,7 +61,7 @@ lang_table_entry_cxx_template = '''
|
||||||
|
|
||||||
cxxfile_template = '''// This file is automatically generated. Do not modify it.
|
cxxfile_template = '''// This file is automatically generated. Do not modify it.
|
||||||
|
|
||||||
#include "server/i18n.h"
|
#include "server/i18n_utils.h"
|
||||||
|
|
||||||
namespace kiwix {
|
namespace kiwix {
|
||||||
namespace i18n {
|
namespace i18n {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "tools/otherTools.h"
|
#include "tools/otherTools.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "tools/regexTools.h"
|
#include "tools/regexTools.h"
|
||||||
#include "server/i18n.h"
|
#include "server/i18n_utils.h"
|
||||||
|
|
||||||
namespace kiwix
|
namespace kiwix
|
||||||
{
|
{
|
||||||
|
@ -77,7 +77,7 @@ std::string HTMLDumper::dumpPlainHTML(kiwix::Filter filter) const
|
||||||
const auto tags = bookObj.getTags();
|
const auto tags = bookObj.getTags();
|
||||||
const auto downloadAvailable = (bookObj.getUrl() != "");
|
const auto downloadAvailable = (bookObj.getUrl() != "");
|
||||||
std::string faviconAttr = "style=background-image:url(" + bookIconUrl + ")";
|
std::string faviconAttr = "style=background-image:url(" + bookIconUrl + ")";
|
||||||
|
|
||||||
booksData.push_back(kainjow::mustache::object{
|
booksData.push_back(kainjow::mustache::object{
|
||||||
{"id", contentId},
|
{"id", contentId},
|
||||||
{"title", bookTitle},
|
{"title", bookTitle},
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "libkiwix-resources.h"
|
#include "libkiwix-resources.h"
|
||||||
#include "tools/stringTools.h"
|
#include "tools/stringTools.h"
|
||||||
|
|
||||||
#include "server/i18n.h"
|
#include "server/i18n_utils.h"
|
||||||
|
|
||||||
namespace kiwix
|
namespace kiwix
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n_utils.h"
|
||||||
|
|
||||||
#include "tools/otherTools.h"
|
#include "tools/otherTools.h"
|
||||||
|
|
||||||
|
@ -193,4 +193,13 @@ std::string selectMostSuitableLanguage(const UserLangPreferences& prefs)
|
||||||
return bestLangSoFar;
|
return bestLangSoFar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string translateBookCategory(const std::string& lang, const std::string& category)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return getTranslatedString(lang, "book-category." + category);
|
||||||
|
} catch (...) {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace kiwix
|
} // namespace kiwix
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Veloman Yunkan <veloman.yunkan@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KIWIX_SERVER_I18N_UTILS
|
||||||
|
#define KIWIX_SERVER_I18N_UTILS
|
||||||
|
|
||||||
|
#include "i18n.h"
|
||||||
|
#include <mustache.hpp>
|
||||||
|
|
||||||
|
namespace kiwix
|
||||||
|
{
|
||||||
|
|
||||||
|
struct I18nString {
|
||||||
|
const char* const key;
|
||||||
|
const char* const value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct I18nStringTable {
|
||||||
|
const char* const lang;
|
||||||
|
const size_t entryCount;
|
||||||
|
const I18nString* const entries;
|
||||||
|
|
||||||
|
const char* get(const std::string& key) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace i18n
|
||||||
|
{
|
||||||
|
|
||||||
|
class GetTranslatedStringWithMsgId
|
||||||
|
{
|
||||||
|
typedef kainjow::mustache::basic_data<std::string> MustacheString;
|
||||||
|
typedef std::pair<std::string, MustacheString> MsgIdAndTranslation;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit GetTranslatedStringWithMsgId(const std::string& lang) : m_lang(lang) {}
|
||||||
|
|
||||||
|
MsgIdAndTranslation operator()(const std::string& key) const
|
||||||
|
{
|
||||||
|
return {key, getTranslatedString(m_lang, key)};
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgIdAndTranslation operator()(const std::string& key, const Parameters& params) const
|
||||||
|
{
|
||||||
|
return {key, expandParameterizedString(m_lang, key, params)};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string m_lang;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace i18n
|
||||||
|
|
||||||
|
struct LangPreference
|
||||||
|
{
|
||||||
|
const std::string lang;
|
||||||
|
const float preference;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<LangPreference> UserLangPreferences;
|
||||||
|
|
||||||
|
UserLangPreferences parseUserLanguagePreferences(const std::string& s);
|
||||||
|
|
||||||
|
std::string selectMostSuitableLanguage(const UserLangPreferences& prefs);
|
||||||
|
|
||||||
|
} // namespace kiwix
|
||||||
|
|
||||||
|
#endif // KIWIX_SERVER_I18N_UTILS
|
|
@ -54,7 +54,7 @@ extern "C" {
|
||||||
#include "search_renderer.h"
|
#include "search_renderer.h"
|
||||||
#include "opds_dumper.h"
|
#include "opds_dumper.h"
|
||||||
#include "html_dumper.h"
|
#include "html_dumper.h"
|
||||||
#include "i18n.h"
|
#include "i18n_utils.h"
|
||||||
|
|
||||||
#include <zim/uuid.h>
|
#include <zim/uuid.h>
|
||||||
#include <zim/error.h>
|
#include <zim/error.h>
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
#include "tools/stringTools.h"
|
#include "tools/stringTools.h"
|
||||||
#include "i18n.h"
|
#include "i18n_utils.h"
|
||||||
|
|
||||||
namespace kiwix {
|
namespace kiwix {
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <mustache.hpp>
|
#include <mustache.hpp>
|
||||||
#include "byte_range.h"
|
#include "byte_range.h"
|
||||||
#include "etag.h"
|
#include "etag.h"
|
||||||
#include "i18n.h"
|
#include "i18n_utils.h"
|
||||||
|
|
||||||
#include <zim/item.h>
|
#include <zim/item.h>
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "tools/stringTools.h"
|
#include "tools/stringTools.h"
|
||||||
#include "server/i18n.h"
|
#include "server/i18n_utils.h"
|
||||||
#include "libkiwix-resources.h"
|
#include "libkiwix-resources.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
|
@ -60,4 +60,22 @@
|
||||||
, "preview-book": "Preview"
|
, "preview-book": "Preview"
|
||||||
, "non-translated-text": "{{MSG}}"
|
, "non-translated-text": "{{MSG}}"
|
||||||
, "unknown-error": "Unknown error"
|
, "unknown-error": "Unknown error"
|
||||||
|
, "book-category.gutenberg": "Gutenberg"
|
||||||
|
, "book-category.iFixit": "iFixit"
|
||||||
|
, "book-category.mooc": "MOOC"
|
||||||
|
, "book-category.phet": "Phet"
|
||||||
|
, "book-category.stack_exchange": "Stack Exchange"
|
||||||
|
, "book-category.ted": "Ted"
|
||||||
|
, "book-category.vikidia": "Vikidia"
|
||||||
|
, "book-category.wikibooks": "Wikibooks"
|
||||||
|
, "book-category.wikihow": "wikiHow"
|
||||||
|
, "book-category.wikinews": "Wikinews"
|
||||||
|
, "book-category.wikipedia": "Wikipedia"
|
||||||
|
, "book-category.wikiquote": "Wikiquote"
|
||||||
|
, "book-category.wikisource": "Wikisource"
|
||||||
|
, "book-category.wikispecies": "Wikispecies"
|
||||||
|
, "book-category.wikiversity": "Wikiversity"
|
||||||
|
, "book-category.wikivoyage": "Wikivoyage"
|
||||||
|
, "book-category.wiktionary": "Wiktionary"
|
||||||
|
, "book-category.other": "Other"
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,5 +62,23 @@
|
||||||
"download-links-title": "Title for no-js download page",
|
"download-links-title": "Title for no-js download page",
|
||||||
"preview-book": "Tooltip of book-tile leading to the book",
|
"preview-book": "Tooltip of book-tile leading to the book",
|
||||||
"non-translated-text": "{{ignored}}\nUsed to display text that is generated at runtime and cannot be translated. Nothing to translate about this one.",
|
"non-translated-text": "{{ignored}}\nUsed to display text that is generated at runtime and cannot be translated. Nothing to translate about this one.",
|
||||||
"unknown-error": "Unknown error"
|
"unknown-error": "Unknown error",
|
||||||
|
"book-category.gutenberg": "Name for the category of books from the Gutenberg project",
|
||||||
|
"book-category.iFixit": "Name for the category of iFixit books",
|
||||||
|
"book-category.mooc": "Name for the category of MOOC books",
|
||||||
|
"book-category.phet": "Name for the category of Phet books",
|
||||||
|
"book-category.stack_exchange": "Name for the category of books from the Stack Exchange network books",
|
||||||
|
"book-category.ted": "Name for the category of Ted books",
|
||||||
|
"book-category.vikidia": "Name for the category of Vikidia books",
|
||||||
|
"book-category.wikibooks": "Name for the category of Wikibooks books books",
|
||||||
|
"book-category.wikihow": "Name for the category of wikiHow books",
|
||||||
|
"book-category.wikinews": "Name for the category of Wikinews books",
|
||||||
|
"book-category.wikipedia": "Name for the category of Wikipedia books",
|
||||||
|
"book-category.wikiquote": "Name for the category of Wikiquote books",
|
||||||
|
"book-category.wikisource": "Name for the category of Wikisource books",
|
||||||
|
"book-category.wikispecies": "Name for the category of Wikispecies books",
|
||||||
|
"book-category.wikiversity": "Name for the category of Wikiversity books",
|
||||||
|
"book-category.wikivoyage": "Name for the category of Wikivoyage books",
|
||||||
|
"book-category.wiktionary": "Name for the category of Wiktionary books",
|
||||||
|
"book-category.other": "Books not belonging to any special category are listed under this one"
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,4 +47,22 @@
|
||||||
, "empty-search-results-page-header": "[I18N TESTING] No results were found for <b>\"{{{SEARCH_PATTERN}}}\"</b>"
|
, "empty-search-results-page-header": "[I18N TESTING] No results were found for <b>\"{{{SEARCH_PATTERN}}}\"</b>"
|
||||||
, "search-result-book-info": "from [I18N TESTING] {{BOOK_TITLE}}"
|
, "search-result-book-info": "from [I18N TESTING] {{BOOK_TITLE}}"
|
||||||
, "word-count": "{{COUNT}} [I18N TESTING] words"
|
, "word-count": "{{COUNT}} [I18N TESTING] words"
|
||||||
|
, "book-category.gutenberg": "[I18N] Gutenberg [TESTING]"
|
||||||
|
, "book-category.iFixit": "[I18N] iFixit [TESTING]"
|
||||||
|
, "book-category.mooc": "[I18N] MOOC [TESTING]"
|
||||||
|
, "book-category.phet": "[I18N] Phet [TESTING]"
|
||||||
|
, "book-category.stack_exchange": "[I18N] Stack Exchange [TESTING]"
|
||||||
|
, "book-category.ted": "[I18N] Ted [TESTING]"
|
||||||
|
, "book-category.vikidia": "[I18N] Vikidia [TESTING]"
|
||||||
|
, "book-category.wikibooks": "[I18N] Wikibooks [TESTING]"
|
||||||
|
, "book-category.wikihow": "[I18N] wikiHow [TESTING]"
|
||||||
|
, "book-category.wikinews": "[I18N] Wikinews [TESTING]"
|
||||||
|
, "book-category.wikipedia": "[I18N] Wikipedia [TESTING]"
|
||||||
|
, "book-category.wikiquote": "[I18N] Wikiquote [TESTING]"
|
||||||
|
, "book-category.wikisource": "[I18N] Wikisource [TESTING]"
|
||||||
|
, "book-category.wikispecies": "[I18N] Wikispecies [TESTING]"
|
||||||
|
, "book-category.wikiversity": "[I18N] Wikiversity [TESTING]"
|
||||||
|
, "book-category.wikivoyage": "[I18N] Wikivoyage [TESTING]"
|
||||||
|
, "book-category.wiktionary": "[I18N] Wiktionary [TESTING]"
|
||||||
|
, "book-category.other": "[I18N] Other [TESTING]"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "../src/server/i18n.h"
|
#include "../src/server/i18n_utils.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
using namespace kiwix;
|
using namespace kiwix;
|
||||||
|
@ -48,3 +48,17 @@ TEST(ParameterizedMessage, messagesWithParameters)
|
||||||
EXPECT_EQ(msg.getText("test"), "Filter [I18N] by [TESTING] tag \"\"");
|
EXPECT_EQ(msg.getText("test"), "Filter [I18N] by [TESTING] tag \"\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(I18n, translateBookCategory)
|
||||||
|
{
|
||||||
|
|
||||||
|
EXPECT_EQ(translateBookCategory("en", "ted"), "Ted");
|
||||||
|
EXPECT_EQ(translateBookCategory("test", "ted"), "[I18N] Ted [TESTING]");
|
||||||
|
|
||||||
|
EXPECT_EQ(translateBookCategory("en", "stack_exchange"), "Stack Exchange");
|
||||||
|
EXPECT_EQ(translateBookCategory("test", "stack_exchange"), "[I18N] Stack Exchange [TESTING]");
|
||||||
|
|
||||||
|
// unknown categories are simply not translated
|
||||||
|
EXPECT_EQ(translateBookCategory("en", "Qwerty"), "Qwerty");
|
||||||
|
EXPECT_EQ(translateBookCategory("test", "Qwerty"), "Qwerty");
|
||||||
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "../src/tools/otherTools.h"
|
#include "../src/tools/otherTools.h"
|
||||||
#include "zim/suggestion_iterator.h"
|
#include "zim/suggestion_iterator.h"
|
||||||
#include "../src/server/i18n.h"
|
#include "../src/server/i18n_utils.h"
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue