allow to use multiple locale directories

remove config options:
- locale_dir
- locale_dir_default

add a config option:
- locale_dirs - a list of directories with locale files (translations)

We start reading locale from the first directory and files with the same name
in each directory are concatenated.
This commit is contained in:
2026-06-21 23:36:29 +02:00
parent d35854691c
commit b82a36142c
5 changed files with 101 additions and 107 deletions
+1 -2
View File
@@ -266,8 +266,7 @@ void Config::AssignValues()
html_filter_orphans_mode_str = Text(L"html_filter_orphans_mode_str", L"nbsp");
html_filter_nofilter_tag = Text(L"html_filter_nofilter_tag", L"nofilter");
locale_dir = Text(L"locale_dir");
locale_dir_default = Text(L"locale_dir_default");
ListText(L"locale_dirs", locale_dirs);
locale_max_id = Size(L"locale_max_id", 100);
locale_default_id = Size(L"locale_default_id", 0);
ListText(L"locale_files", locale_files);
+7 -6
View File
@@ -592,14 +592,15 @@ public:
// default: /usr/local/bin/convert
std::wstring convert_cmd;
// directory with locale files
std::wstring locale_dir;
// directory with default locale files (those from winix)
std::wstring locale_dir_default;
// directories with locale files
// we start reading locale from the first directory
// and files with the same name in each directory are concatenated
std::vector<std::wstring> locale_dirs;
// locale files (e.g. "en", "pl")
// default: only one item: en
// default: "en"
// a locale file should define winix_locale_id integer parameter
// and it should be smaller or equal to locale_max_id
std::vector<std::wstring> locale_files;
// a maximum value of a locale identifier
+71 -81
View File
@@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2021, Tomasz Sowa
/*
* Copyright (c) 2010-2026, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,13 +49,18 @@ Locale::Locale()
}
void Locale::SetDirectories(const std::vector<std::wstring> & dirs)
{
directories = dirs;
}
void Locale::SetLocaleFiles(const std::vector<std::wstring> & files)
{
locale_files = files;
}
void Locale::SetLocaleMaxId(size_t max_id)
{
if( max_id > 1000 )
@@ -72,8 +77,6 @@ void Locale::SetLocaleMaxId(size_t max_id)
}
bool Locale::HasLanguage(size_t lang_id)
{
if( lang_id < locale_indices.size() )
@@ -83,34 +86,38 @@ return false;
}
void Locale::ReadFile(const char * dir, const char * dir_def, const char * file)
void Locale::ReadFile(const std::wstring & file)
{
bool read = false;
temp_space.clear();
if( dir_def && ReadFile(dir_def, file) )
read = true;
if( dir && ReadFile(dir, file) )
read = true;
for(const std::wstring & dir : directories)
{
if( ReadFile(dir, file) )
read = true;
}
if( read )
{
AddLocale(file);
}
else
{
log << log1 << "Locale: can't open locale's file: " << file << logend;
}
temp_space.clear();
}
bool Locale::ReadFile(const char * dir, const char * file)
bool Locale::ReadFile(const std::wstring & dir, const std::wstring & file)
{
bool read = false;
bool read = false;
file_name = dir;
pt::wide_to_utf8(dir, file_name);
file_name += '/';
file_name += file;
pt::wide_to_utf8(file, file_name, false);
pt::SpaceParser::Status status = loc_parser.parse_space_file(file_name, temp_space, false);
@@ -125,23 +132,24 @@ bool read = false;
log << log1 << "Locale: syntax error in: " << file_name << " in line: " << loc_parser.get_last_parsed_line() << logend;
}
return read;
file_name.clear();
return read;
}
void Locale::AddLocale(const char * file)
void Locale::AddLocale(const std::wstring & file)
{
std::wstring * id_str = temp_space.get_wstr(L"winix_locale_id");
if( !id_str )
{
log << log1 << "Locale: winix_locale_id field should be defined in locale file: "
<< file << " (skipping)" << logend;
log << log1 << "Locale: winix_locale_id field should be defined in a locale file: "
<< file << " (skipping this file)" << logend;
return;
}
size_t id = (size_t)Tol(*id_str);
size_t id = (size_t)pt::to_ul(*id_str);
if( id >= locale_indices.size() )
{
@@ -155,32 +163,35 @@ void Locale::AddLocale(const char * file)
void Locale::ReadSubstTable(const char * dir, const char * dir_def)
void Locale::ReadSubstTable()
{
bool read = false;
bool read = false;
temp_space.clear();
subst_url.clear();
subst_smalllet.clear();
subst_capitallet.clear();
subst_sort.clear();
if( dir_def && ReadSubstTable(dir_def) )
read = true;
if( dir && ReadSubstTable(dir) )
read = true;
for(const std::wstring & dir : directories)
{
if( ReadSubstTable(dir) )
read = true;
}
if( !read )
log << log1 << "Locale: can't open file for characters substitution" << logend;
{
log << log1 << "Locale: can't open a file for characters substitution" << logend;
}
temp_space.clear();
}
bool Locale::ReadSubstTable(const char * dir)
bool Locale::ReadSubstTable(const std::wstring & dir)
{
bool read = false;
bool read = false;
file_name = dir;
pt::wide_to_utf8(dir, file_name);
file_name += '/';
file_name += "substitute";
@@ -199,7 +210,8 @@ bool read = false;
log << log3 << "Locale: read characters substitution tables from: " << file_name << logend;
}
return read;
file_name.clear();
return read;
}
@@ -254,58 +266,36 @@ void Locale::CreateSubstSortVector(std::vector<SubstItem> & vect, std::vector<st
}
void Locale::Read(const char * dir, const char * dir_def)
void Locale::ReadLocales()
{
for(size_t & index : locale_indices)
index = size_t(-1);
for(const std::wstring & file : locale_files)
{
ReadFile(file);
}
ReadSubstTable();
}
void Locale::Clear()
{
directories.clear();
locale_files.clear();
locale_indices.clear();
locale_tab.clear();
default_lang = 0;
current_lang = 0;
for(size_t i=0 ; i<locale_indices.size() ; ++i)
locale_indices[i] = size_t(-1);
for(size_t i=0 ; i<locale_files.size() ; ++i)
{
pt::wide_to_utf8(locale_files[i], locale_filea);
ReadFile(dir, dir_def, locale_filea.c_str());
}
ReadSubstTable(dir, dir_def);
subst_url.clear();
subst_smalllet.clear();
subst_capitallet.clear();
subst_sort.clear();
}
void Locale::Read(const std::string & dir, const std::string & dir_def)
{
if( dir_def.empty() )
Read(dir.c_str());
else
Read(dir.c_str(), dir_def.c_str());
}
void Locale::Read(const wchar_t * dir, const wchar_t * dir_def)
{
pt::wide_to_utf8(dir, adir1);
if( !dir_def )
{
Read(adir1.c_str());
}
else
{
pt::wide_to_utf8(dir_def, adir2);
Read(adir1.c_str(), adir2.c_str());
}
}
void Locale::Read(const std::wstring & dir, const std::wstring & dir_def)
{
if( dir_def.empty() )
Read(dir.c_str());
else
Read(dir.c_str(), dir_def.c_str());
}
void Locale::SetCurLang(size_t lang_id)
{
+18 -15
View File
@@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2010-2018, Tomasz Sowa
/*
* Copyright (c) 2010-2026, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -53,8 +53,11 @@ public:
Locale();
// locale directories
void SetDirectories(const std::vector<std::wstring> & dirs);
// locale files
// those files will be reading from directories specified in Read() method
// those files will be reading from directories specified above
// default one item: en
void SetLocaleFiles(const std::vector<std::wstring> & files);
@@ -73,11 +76,11 @@ public:
size_t GetDefLang() const;
// reading locales
// you should call SetLocaleFiles() beforehand
void Read(const char * dir, const char * dir_def = 0);
void Read(const std::string & dir, const std::string & dir_def);
void Read(const wchar_t * dir, const wchar_t * dir_def = 0);
void Read(const std::wstring & dir, const std::wstring & dir_def);
// you should call SetDirectories(), SetLocaleFiles() and SetLocaleMaxId() beforehand
void ReadLocales();
// clear directories, files and read translations
void Clear();
// returns true if a language with lang_id exists
bool HasLanguage(size_t lang_id);
@@ -208,11 +211,11 @@ private:
bool operator<(const SubstItem & arg) const { return from < arg.from; }
};
void AddLocale(const char * file);
void ReadFile(const char * dir, const char * dir_def, const char * file);
bool ReadFile(const char * dir, const char * file);
void ReadSubstTable(const char * dir, const char * dir_def);
bool ReadSubstTable(const char * dir);
void AddLocale(const std::wstring & file);
void ReadFile(const std::wstring & file);
bool ReadFile(const std::wstring & dir, const std::wstring & file);
void ReadSubstTable();
bool ReadSubstTable(const std::wstring & dir);
void CreateSubstVector(std::vector<SubstItem> & vect, const std::wstring & tab1, const std::wstring & tab2);
void CreateSubstSortVector(std::vector<SubstItem> & vect, std::vector<std::wstring> & tab);
size_t SubstFindIndex(const std::vector<SubstItem> & vect, wchar_t val);
@@ -221,6 +224,8 @@ private:
bool GetListInLanguage(const std::wstring & key, size_t lang_id, std::vector<std::wstring> & list) const;
bool IsListInLanguage(const std::wstring & key, size_t lang_id) const;
// directories
std::vector<std::wstring> directories;
// locale files
std::vector<std::wstring> locale_files;
@@ -252,11 +257,9 @@ private:
pt::Space temp_space;
pt::SpaceParser loc_parser;
std::string locale_filea;
std::string file_name;
std::wstring key_str;
const std::wstring empty; // used when returning a non existing key from loc_tab (or in LangToFileName)
std::string adir1, adir2;
std::wstring pattern_value;
};
+4 -3
View File
@@ -4,8 +4,8 @@
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2008-2024, Tomasz Sowa
/*
* Copyright (c) 2008-2026, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -678,10 +678,11 @@ void Templates::CreateFunctions()
void Templates::ReadLocale()
{
TemplatesFunctions::locale.SetDirectories(config->locale_dirs);
TemplatesFunctions::locale.SetLocaleFiles(config->locale_files);
TemplatesFunctions::locale.SetLocaleMaxId(config->locale_max_id);
TemplatesFunctions::locale.SetDefLang(config->locale_default_id);
TemplatesFunctions::locale.Read(config->locale_dir, config->locale_dir_default);
TemplatesFunctions::locale.ReadLocales();
log << log3 << "Templates: there are " << TemplatesFunctions::locale.Size() << " locales" << logend;
}