File: Languages.h

package info (click to toggle)
vcmi 1.6.5%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 32,060 kB
  • sloc: cpp: 238,971; python: 265; sh: 224; xml: 157; ansic: 78; objc: 61; makefile: 49
file content (163 lines) | stat: -rw-r--r-- 5,493 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * Languages.h, part of VCMI engine
 *
 * Authors: listed in file AUTHORS in main folder
 *
 * License: GNU General Public License v2.0 or later
 * Full text of license available in license.txt file, in main folder
 *
 */
#pragma once

namespace Languages
{

enum class EPluralForms
{
	NONE,
	VI_1, // Single plural form, (Vietnamese)
	EN_2, // Two forms, singular used for one only (English)
	FR_2, // Two forms, singular used for zero and one (French)
	UK_3, // Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4] (Ukrainian)
	CZ_3, // Three forms, special cases for 1 and 2, 3, 4 (Czech)
	PL_3, // Three forms, special case for one and some numbers ending in 2, 3, or 4 (Polish)
};

enum class ELanguages
{
	CZECH,
	CHINESE,
	ENGLISH,
	FINNISH,
	FRENCH,
	GERMAN,
	HUNGARIAN,
	ITALIAN,
	KOREAN,
	POLISH,
	PORTUGUESE,
	RUSSIAN,
	SPANISH,
	SWEDISH,
	TURKISH,
	UKRAINIAN,
	VIETNAMESE,

	COUNT
};

struct Options
{
	/// string identifier (ascii, lower-case), e.g. "english"
	std::string identifier;

	/// human-readable name of language in English
	std::string nameEnglish;

	/// human-readable name of language in its own language
	std::string nameNative;

	/// encoding that is used by H3 for this language
	std::string encoding;

	/// primary IETF language tag
	std::string tagIETF;

	/// ISO 639-2 (B) language code
	std::string tagISO2;

	/// DateTime format
	std::string dateTimeFormat;

	/// Ruleset for plural forms in this language
	EPluralForms pluralForms = EPluralForms::NONE;
};

inline const auto & getLanguageList()
{
	static const std::array<Options, 17> languages
	{ {
		{ "czech",       "Czech",       "Čeština",    "CP1250", "cs", "cze", "%d.%m.%Y %H:%M", EPluralForms::CZ_3 },
		{ "chinese",     "Chinese",     "简体中文",       "GBK",    "zh", "chi", "%Y-%m-%d %H:%M", EPluralForms::VI_1 }, // Note: actually Simplified Chinese
		{ "english",     "English",     "English",    "CP1252", "en", "eng", "%Y-%m-%d %H:%M", EPluralForms::EN_2 }, // English uses international date/time format here
		{ "finnish",     "Finnish",     "Suomi",      "CP1252", "fi", "fin", "%d.%m.%Y %H:%M", EPluralForms::EN_2, },
		{ "french",      "French",      "Français",   "CP1252", "fr", "fre", "%d/%m/%Y %H:%M", EPluralForms::FR_2, },
		{ "german",      "German",      "Deutsch",    "CP1252", "de", "ger", "%d.%m.%Y %H:%M", EPluralForms::EN_2, },
		{ "hungarian",   "Hungarian",   "Magyar",     "CP1250", "hu", "hun", "%Y. %m. %d. %H:%M", EPluralForms::EN_2 },
		{ "italian",     "Italian",     "Italiano",   "CP1250", "it", "ita", "%d/%m/%Y %H:%M", EPluralForms::EN_2 },
		{ "korean",      "Korean",      "한국어",        "CP949",  "ko", "kor", "%Y-%m-%d %H:%M", EPluralForms::VI_1 },
		{ "polish",      "Polish",      "Polski",     "CP1250", "pl", "pol", "%d.%m.%Y %H:%M", EPluralForms::PL_3 },
		{ "portuguese",  "Portuguese",  "Português",  "CP1252", "pt", "por", "%d/%m/%Y %H:%M", EPluralForms::EN_2 }, // Note: actually Brazilian Portuguese
		{ "russian",     "Russian",     "Русский",    "CP1251", "ru", "rus", "%d.%m.%Y %H:%M", EPluralForms::UK_3 },
		{ "spanish",     "Spanish",     "Español",    "CP1252", "es", "spa", "%d/%m/%Y %H:%M", EPluralForms::EN_2 },
		{ "swedish",     "Swedish",     "Svenska",    "CP1252", "sv", "swe", "%Y-%m-%d %H:%M", EPluralForms::EN_2 },
		{ "turkish",     "Turkish",     "Türkçe",     "CP1254", "tr", "tur", "%d.%m.%Y %H:%M", EPluralForms::EN_2 },
		{ "ukrainian",   "Ukrainian",   "Українська", "CP1251", "uk", "ukr", "%d.%m.%Y %H:%M", EPluralForms::UK_3 },
		{ "vietnamese",  "Vietnamese",  "Tiếng Việt", "UTF-8",  "vi", "vie", "%d/%m/%Y %H:%M", EPluralForms::VI_1 }, // Fan translation uses special encoding
	} };
	static_assert(languages.size() == static_cast<size_t>(ELanguages::COUNT), "Languages array is missing a value!");

	return languages;
}

inline const Options & getLanguageOptions(ELanguages language)
{
	return getLanguageList().at(static_cast<size_t>(language));
}

inline const Options & getLanguageOptions(const std::string & language)
{
	for(const auto & entry : getLanguageList())
		if(entry.identifier == language)
			return entry;

	throw std::out_of_range("Language " + language + " does not exists!");
}

template<typename Numeric>
inline constexpr int getPluralFormIndex(EPluralForms form, Numeric value)
{
	// Based on https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
	switch(form)
	{
		case EPluralForms::NONE:
		case EPluralForms::VI_1:
			return 0;
		case EPluralForms::EN_2:
			if (value == 1)
				return 1;
			return 2;
		case EPluralForms::FR_2:
			if (value == 1 || value == 0)
				return 1;
			return 2;
		case EPluralForms::UK_3:
			if (value % 10 == 1 && value % 100 != 11)
				return 1;
			if (value%10>=2 && value%10<=4 && (value%100<10 || value%100>=20))
				return 2;
			return 0;
		case EPluralForms::CZ_3:
			if (value == 1)
				return 1;
			if (value>=2 && value<=4)
				return 2;
			return 0;
		case EPluralForms::PL_3:
			if (value == 1)
				return 1;
			if (value%10>=2 && value%10<=4 && (value%100<10 || value%100>=20))
				return 2;
			return 0;
	}
	throw std::runtime_error("Invalid plural form enumeration received!");
}

template<typename Numeric>
inline std::string getPluralFormTextID(std::string languageName, Numeric value, std::string textID)
{
	int formIndex = getPluralFormIndex(getLanguageOptions(languageName).pluralForms, value);
	return textID + '.' + std::to_string(formIndex);
}

}