-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rewrite localization; use .po and .pot files
- Loading branch information
Showing
30 changed files
with
560 additions
and
311 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[scheme] | ||
processor = cage-asset-processor texts | ||
index = 2 | ||
|
||
[multilingual] | ||
display = multilingual | ||
type = bool | ||
default = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
#include "processor.h" | ||
|
||
#include <cage-core/texts.h> | ||
|
||
namespace | ||
{ | ||
LanguageCode extractLanguage(const String &pth) | ||
{ | ||
// eg. pth = dir/gui.en_US.po | ||
const String n = pathExtractFilenameNoExtension(pth); // -> gui.en_US | ||
const String l = subString(pathExtractExtension(n), 1, m); // -> en_US | ||
// eg. inputFile = dir/gui.pot | ||
const String p = pathExtractFilenameNoExtension(inputFile); // -> gui | ||
if (p + "." + l == n) | ||
return l; | ||
return ""; | ||
} | ||
|
||
void parsePO(Holder<File> f, const LanguageCode &lang, Texts *txt) | ||
{ | ||
String id, str, l; | ||
|
||
const auto "es = [](const String &s) -> String | ||
{ | ||
if (s.length() >= 2 && s[0] == '\"' && s[s.length() - 1] == '\"') | ||
return subString(s, 1, s.length() - 2); | ||
return s; | ||
}; | ||
|
||
const auto &add = [&]() | ||
{ | ||
if (!id.empty() && !str.empty()) | ||
txt->set(quotes(id), quotes(str), lang); | ||
else if (!id.empty() || !str.empty()) | ||
{ | ||
CAGE_LOG(SeverityEnum::Note, "assetProcessor", id); | ||
CAGE_LOG(SeverityEnum::Note, "assetProcessor", str); | ||
CAGE_THROW_ERROR(Exception, "missing msgstr or msgid"); | ||
} | ||
id = str = ""; | ||
}; | ||
|
||
while (f->readLine(l)) | ||
{ | ||
l = trim(l); | ||
if (l.empty()) | ||
add(); | ||
else if (l[0] != '#') | ||
{ | ||
const String p = l; | ||
String k = split(l, "\t "); | ||
k = toLower(k); | ||
if (k == "msgid") | ||
{ | ||
if (!id.empty()) | ||
{ | ||
CAGE_LOG(SeverityEnum::Note, "assetProcessor", id); | ||
CAGE_LOG(SeverityEnum::Note, "assetProcessor", p); | ||
CAGE_THROW_ERROR(Exception, "multiple msgid"); | ||
} | ||
id = l; | ||
} | ||
else if (k == "msgstr") | ||
{ | ||
if (!str.empty()) | ||
{ | ||
CAGE_LOG(SeverityEnum::Note, "assetProcessor", id); | ||
CAGE_LOG(SeverityEnum::Note, "assetProcessor", p); | ||
CAGE_THROW_ERROR(Exception, "multiple msgstr"); | ||
} | ||
str = l; | ||
} | ||
else | ||
{ | ||
CAGE_LOG(SeverityEnum::Note, "assetProcessor", p); | ||
CAGE_THROW_ERROR(Exception, "unknown command"); | ||
} | ||
} | ||
} | ||
add(); | ||
} | ||
} | ||
|
||
void processTexts() | ||
{ | ||
writeLine(String("use=") + inputFile); | ||
|
||
{ | ||
const String ext = pathExtractExtension(inputFile); | ||
if (ext != ".pot" && ext != ".po") | ||
CAGE_THROW_ERROR(Exception, "input file must have .pot or .po extension"); | ||
} | ||
|
||
Holder<Texts> txt = newTexts(); | ||
|
||
if (toBool(properties("multilingual"))) | ||
{ | ||
{ // validate template file | ||
CAGE_LOG(SeverityEnum::Info, "assetProcessor", "validating template"); | ||
Holder<Texts> tmp = newTexts(); | ||
parsePO(readFile(inputFileName), "", +tmp); | ||
} | ||
|
||
for (const String &pth : pathListDirectory(pathExtractDirectory(inputFileName))) | ||
{ | ||
if (!pathIsFile(pth)) | ||
continue; | ||
if (pathExtractExtension(pth) != ".po") | ||
continue; | ||
const LanguageCode lang = extractLanguage(pth); | ||
if (lang.empty()) | ||
continue; | ||
writeLine(String("use=") + pathToRel(pth, inputDirectory)); | ||
CAGE_LOG(SeverityEnum::Info, "assetProcessor", Stringizer() + "loading language: " + lang); | ||
parsePO(readFile(pth), lang, +txt); | ||
} | ||
} | ||
else | ||
{ | ||
parsePO(readFile(inputFileName), "", +txt); | ||
} | ||
|
||
{ | ||
const auto l = txt->allLanguages(); | ||
if (l.empty()) | ||
CAGE_THROW_ERROR(Exception, "loaded no languages"); | ||
for (const String &n : l) | ||
CAGE_LOG(SeverityEnum::Info, "language", n); | ||
} | ||
{ | ||
const auto l = txt->allNames(); | ||
if (l.empty()) | ||
CAGE_THROW_ERROR(Exception, "loaded no texts"); | ||
for (const String &n : l) | ||
CAGE_LOG(SeverityEnum::Info, "name", n); | ||
} | ||
|
||
Holder<PointerRange<char>> buff = txt->exportBuffer(); | ||
CAGE_LOG(SeverityEnum::Info, "assetProcessor", Stringizer() + "buffer size (before compression): " + buff.size()); | ||
Holder<PointerRange<char>> comp = compress(buff); | ||
CAGE_LOG(SeverityEnum::Info, "assetProcessor", Stringizer() + "buffer size (after compression): " + comp.size()); | ||
|
||
AssetHeader h = initializeAssetHeader(); | ||
h.originalSize = buff.size(); | ||
h.compressedSize = comp.size(); | ||
Holder<File> f = writeFile(outputFileName); | ||
f->write(bufferView(h)); | ||
f->write(comp); | ||
f->close(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef guard_texts_h_B436B597745C461DAA266CE6FBBE10D1 | ||
#define guard_texts_h_B436B597745C461DAA266CE6FBBE10D1 | ||
|
||
#include <cage-core/core.h> | ||
|
||
namespace cage | ||
{ | ||
using LanguageCode = detail::StringBase<10>; | ||
|
||
class CAGE_CORE_API Texts : private Immovable | ||
{ | ||
public: | ||
void clear(); | ||
Holder<Texts> copy() const; | ||
|
||
void importBuffer(PointerRange<const char> buffer); | ||
Holder<PointerRange<char>> exportBuffer() const; | ||
|
||
void set(uint32 id, const String &text, const LanguageCode &language); | ||
uint32 set(const String &name, const String &text, const LanguageCode &language); | ||
|
||
Holder<PointerRange<LanguageCode>> allLanguages() const; | ||
Holder<PointerRange<String>> allNames() const; | ||
Holder<PointerRange<uint32>> allIds() const; | ||
|
||
// returns empty string if not found | ||
String get(uint32 id, const LanguageCode &language) const; | ||
}; | ||
|
||
CAGE_CORE_API Holder<Texts> newTexts(); | ||
|
||
CAGE_CORE_API AssetScheme genAssetSchemeTexts(); | ||
constexpr uint32 AssetSchemeIndexTexts = 2; | ||
|
||
CAGE_CORE_API void textsSetLanguages(PointerRange<const LanguageCode> languages); | ||
CAGE_CORE_API void textsSetLanguages(const String &languages); // list of languages separated by ; | ||
CAGE_CORE_API void textsAdd(const Texts *txt); | ||
CAGE_CORE_API void textsRemove(const Texts *txt); | ||
CAGE_CORE_API String textsGet(uint32 id, String params = ""); | ||
|
||
CAGE_CORE_API String textFormat(String format, const String ¶ms); | ||
} | ||
|
||
#endif // guard_texts_h_B436B597745C461DAA266CE6FBBE10D1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.