fix: wrap long language comment in gen_i18n.py output
This commit is contained in:
+2
-1
@@ -408,7 +408,8 @@ inline const char* const* getStringArray(Language lang) {
|
|||||||
constexpr uint8_t getLanguageCount() { return static_cast<uint8_t>(Language::_COUNT); }
|
constexpr uint8_t getLanguageCount() { return static_cast<uint8_t>(Language::_COUNT); }
|
||||||
|
|
||||||
// Sorted language indices by code (auto-generated by gen_i18n.py)
|
// Sorted language indices by code (auto-generated by gen_i18n.py)
|
||||||
// Order: English, Беларуская, Català, Čeština, Dansk, Deutsch, Español, Suomi, Français, Italiano, Қазақша, Nederlands, Polski, Português (Brasil), Română, Русский, Svenska, Türkçe, Українська
|
// Order: English,
|
||||||
|
// Беларуская, Català, Čeština, Dansk, Deutsch, Español, Suomi, Français, Italiano, Қазақша, Nederlands, Polski, Português (Brasil), Română, Русский, Svenska, Türkçe, Українська
|
||||||
constexpr uint8_t SORTED_LANGUAGE_INDICES[] = {0, 11, 9, 4, 15, 3, 1, 14, 2, 12, 18, 16, 13, 5, 8, 6, 7, 17, 10};
|
constexpr uint8_t SORTED_LANGUAGE_INDICES[] = {0, 11, 9, 4, 15, 3, 1, 14, 2, 12, 18, 16, 13, 5, 8, 6, 7, 17, 10};
|
||||||
|
|
||||||
static_assert(sizeof(SORTED_LANGUAGE_INDICES) / sizeof(SORTED_LANGUAGE_INDICES[0]) == getLanguageCount(),
|
static_assert(sizeof(SORTED_LANGUAGE_INDICES) / sizeof(SORTED_LANGUAGE_INDICES[0]) == getLanguageCount(),
|
||||||
|
|||||||
+59
-34
@@ -33,6 +33,7 @@ from typing import List, Dict, Tuple
|
|||||||
# YAML file reading (simple key: "value" format, no PyYAML dependency)
|
# YAML file reading (simple key: "value" format, no PyYAML dependency)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
def _unescape_yaml_value(raw: str, filepath: str = "", line_num: int = 0) -> str:
|
def _unescape_yaml_value(raw: str, filepath: str = "", line_num: int = 0) -> str:
|
||||||
"""
|
"""
|
||||||
Process escape sequences in a YAML value string.
|
Process escape sequences in a YAML value string.
|
||||||
@@ -51,9 +52,7 @@ def _unescape_yaml_value(raw: str, filepath: str = "", line_num: int = 0) -> str
|
|||||||
elif nxt == "n":
|
elif nxt == "n":
|
||||||
result.append("\n")
|
result.append("\n")
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(f"{filepath}:{line_num}: unknown escape '\\{nxt}'")
|
||||||
f"{filepath}:{line_num}: unknown escape '\\{nxt}'"
|
|
||||||
)
|
|
||||||
i += 2
|
i += 2
|
||||||
else:
|
else:
|
||||||
result.append(raw[i])
|
result.append(raw[i])
|
||||||
@@ -103,6 +102,7 @@ def parse_yaml_file(filepath: str) -> Dict[str, str]:
|
|||||||
# Load all languages from a directory of YAML files
|
# Load all languages from a directory of YAML files
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
def load_translations(
|
def load_translations(
|
||||||
translations_dir: str,
|
translations_dir: str,
|
||||||
) -> Tuple[List[str], List[str], List[str], Dict[str, List[str]]]:
|
) -> Tuple[List[str], List[str], List[str], Dict[str, List[str]]]:
|
||||||
@@ -207,23 +207,37 @@ def load_translations(
|
|||||||
|
|
||||||
LANG_ABBREVIATIONS = {
|
LANG_ABBREVIATIONS = {
|
||||||
"english": "EN",
|
"english": "EN",
|
||||||
"español": "ES", "espanol": "ES",
|
"español": "ES",
|
||||||
|
"espanol": "ES",
|
||||||
"italiano": "IT",
|
"italiano": "IT",
|
||||||
"svenska": "SV",
|
"svenska": "SV",
|
||||||
"français": "FR", "francais": "FR",
|
"français": "FR",
|
||||||
"deutsch": "DE", "german": "DE",
|
"francais": "FR",
|
||||||
|
"deutsch": "DE",
|
||||||
|
"german": "DE",
|
||||||
"polski": "PL",
|
"polski": "PL",
|
||||||
"português": "PT", "portugues": "PT", "português (brasil)": "PO",
|
"português": "PT",
|
||||||
"中文": "ZH", "chinese": "ZH",
|
"portugues": "PT",
|
||||||
"日本語": "JA", "japanese": "JA",
|
"português (brasil)": "PO",
|
||||||
"한국어": "KO", "korean": "KO",
|
"中文": "ZH",
|
||||||
"русский": "RU", "russian": "RU",
|
"chinese": "ZH",
|
||||||
"العربية": "AR", "arabic": "AR",
|
"日本語": "JA",
|
||||||
"עברית": "HE", "hebrew": "HE",
|
"japanese": "JA",
|
||||||
"فارسی": "FA", "persian": "FA",
|
"한국어": "KO",
|
||||||
|
"korean": "KO",
|
||||||
|
"русский": "RU",
|
||||||
|
"russian": "RU",
|
||||||
|
"العربية": "AR",
|
||||||
|
"arabic": "AR",
|
||||||
|
"עברית": "HE",
|
||||||
|
"hebrew": "HE",
|
||||||
|
"فارسی": "FA",
|
||||||
|
"persian": "FA",
|
||||||
"čeština": "CS",
|
"čeština": "CS",
|
||||||
"türkçe": "TR", "turkish": "TR",
|
"türkçe": "TR",
|
||||||
"Қазақша": "KK", "kazakh": "KK",
|
"turkish": "TR",
|
||||||
|
"Қазақша": "KK",
|
||||||
|
"kazakh": "KK",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -267,12 +281,12 @@ def escape_cpp_string(s: str) -> List[str]:
|
|||||||
|
|
||||||
if ch == "\\" and i + 1 < len(s):
|
if ch == "\\" and i + 1 < len(s):
|
||||||
nxt = s[i + 1]
|
nxt = s[i + 1]
|
||||||
if nxt in "ntr\"\\":
|
if nxt in 'ntr"\\':
|
||||||
current.append(ch + nxt)
|
current.append(ch + nxt)
|
||||||
i += 2
|
i += 2
|
||||||
elif nxt == "x" and i + 3 < len(s):
|
elif nxt == "x" and i + 3 < len(s):
|
||||||
current.append(s[i : i + 4])
|
current.append(s[i : i + 4])
|
||||||
_flush() # segment break after hex
|
_flush() # segment break after hex
|
||||||
i += 4
|
i += 4
|
||||||
else:
|
else:
|
||||||
current.append("\\\\")
|
current.append("\\\\")
|
||||||
@@ -286,7 +300,7 @@ def escape_cpp_string(s: str) -> List[str]:
|
|||||||
else:
|
else:
|
||||||
for byte in ch.encode("utf-8"):
|
for byte in ch.encode("utf-8"):
|
||||||
current.append(f"\\x{byte:02X}")
|
current.append(f"\\x{byte:02X}")
|
||||||
_flush() # segment break after hex
|
_flush() # segment break after hex
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# Flush remaining content
|
# Flush remaining content
|
||||||
@@ -321,11 +335,11 @@ def format_cpp_string_literal(segments: List[str], indent: str = " ") -> List
|
|||||||
last_space = -1
|
last_space = -1
|
||||||
idx = 0
|
idx = 0
|
||||||
while idx <= MAX_CONTENT_LEN and idx < len(current):
|
while idx <= MAX_CONTENT_LEN and idx < len(current):
|
||||||
if current[idx] == ' ':
|
if current[idx] == " ":
|
||||||
last_space = idx
|
last_space = idx
|
||||||
|
|
||||||
# Handle escapes to step correctly
|
# Handle escapes to step correctly
|
||||||
if current[idx] == '\\':
|
if current[idx] == "\\":
|
||||||
idx += 2
|
idx += 2
|
||||||
else:
|
else:
|
||||||
idx += 1
|
idx += 1
|
||||||
@@ -340,7 +354,7 @@ def format_cpp_string_literal(segments: List[str], indent: str = " ") -> List
|
|||||||
# No space, forced break at MAX_CONTENT_LEN (or slightly less)
|
# No space, forced break at MAX_CONTENT_LEN (or slightly less)
|
||||||
cut_at = MAX_CONTENT_LEN
|
cut_at = MAX_CONTENT_LEN
|
||||||
# Don't cut in the middle of an escape sequence
|
# Don't cut in the middle of an escape sequence
|
||||||
if current[cut_at - 1] == '\\':
|
if current[cut_at - 1] == "\\":
|
||||||
cut_at -= 1
|
cut_at -= 1
|
||||||
|
|
||||||
lines.append(f'{indent}"{current[:cut_at]}"')
|
lines.append(f'{indent}"{current[:cut_at]}"')
|
||||||
@@ -356,6 +370,7 @@ def format_cpp_string_literal(segments: List[str], indent: str = " ") -> List
|
|||||||
# Character-set computation
|
# Character-set computation
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
def compute_character_set(translations: Dict[str, List[str]], lang_index: int) -> str:
|
def compute_character_set(translations: Dict[str, List[str]], lang_index: int) -> str:
|
||||||
"""Return a sorted string of every unique character used in a language."""
|
"""Return a sorted string of every unique character used in a language."""
|
||||||
chars = set()
|
chars = set()
|
||||||
@@ -369,6 +384,7 @@ def compute_character_set(translations: Dict[str, List[str]], lang_index: int) -
|
|||||||
# Code generators
|
# Code generators
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
def generate_keys_header(
|
def generate_keys_header(
|
||||||
languages: List[str],
|
languages: List[str],
|
||||||
language_names: List[str],
|
language_names: List[str],
|
||||||
@@ -451,9 +467,15 @@ def generate_keys_header(
|
|||||||
key=lambda i: languages[i],
|
key=lambda i: languages[i],
|
||||||
)
|
)
|
||||||
sorted_indices = [english_idx] + rest
|
sorted_indices = [english_idx] + rest
|
||||||
comment_names = ", ".join(language_names[i] for i in sorted_indices)
|
names = [language_names[i] for i in sorted_indices]
|
||||||
|
comment_names = ", ".join(names)
|
||||||
lines.append("// Sorted language indices by code (auto-generated by gen_i18n.py)")
|
lines.append("// Sorted language indices by code (auto-generated by gen_i18n.py)")
|
||||||
lines.append(f"// Order: {comment_names}")
|
if len(f"// Order: {comment_names}") <= 100:
|
||||||
|
lines.append(f"// Order: {comment_names}")
|
||||||
|
else:
|
||||||
|
lines.append("// Order: " + names[0] + ",")
|
||||||
|
rest_line = ", ".join(names[1:])
|
||||||
|
lines.append("// " + rest_line)
|
||||||
lines.append(
|
lines.append(
|
||||||
"constexpr uint8_t SORTED_LANGUAGE_INDICES[] = {"
|
"constexpr uint8_t SORTED_LANGUAGE_INDICES[] = {"
|
||||||
f"{', '.join(str(i) for i in sorted_indices)}"
|
f"{', '.join(str(i) for i in sorted_indices)}"
|
||||||
@@ -463,9 +485,7 @@ def generate_keys_header(
|
|||||||
lines.append(
|
lines.append(
|
||||||
"static_assert(sizeof(SORTED_LANGUAGE_INDICES) / sizeof(SORTED_LANGUAGE_INDICES[0]) == getLanguageCount(),"
|
"static_assert(sizeof(SORTED_LANGUAGE_INDICES) / sizeof(SORTED_LANGUAGE_INDICES[0]) == getLanguageCount(),"
|
||||||
)
|
)
|
||||||
lines.append(
|
lines.append(' "SORTED_LANGUAGE_INDICES size mismatch");')
|
||||||
' "SORTED_LANGUAGE_INDICES size mismatch");'
|
|
||||||
)
|
|
||||||
|
|
||||||
_write_file(output_path, lines)
|
_write_file(output_path, lines)
|
||||||
|
|
||||||
@@ -478,7 +498,7 @@ def generate_strings_header(
|
|||||||
"""Generate I18nStrings.h."""
|
"""Generate I18nStrings.h."""
|
||||||
lines: List[str] = [
|
lines: List[str] = [
|
||||||
"#pragma once",
|
"#pragma once",
|
||||||
'#include <string>',
|
"#include <string>",
|
||||||
"",
|
"",
|
||||||
'#include "I18nKeys.h"',
|
'#include "I18nKeys.h"',
|
||||||
"",
|
"",
|
||||||
@@ -565,9 +585,8 @@ def generate_strings_cpp(
|
|||||||
# Helpers
|
# Helpers
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _append_string_entry(
|
|
||||||
lines: List[str], text: str, comment: str = ""
|
def _append_string_entry(lines: List[str], text: str, comment: str = "") -> None:
|
||||||
) -> None:
|
|
||||||
"""Escape *text*, format as indented C++ lines, append comma (and optional comment)."""
|
"""Escape *text*, format as indented C++ lines, append comma (and optional comment)."""
|
||||||
segments = escape_cpp_string(text)
|
segments = escape_cpp_string(text)
|
||||||
formatted = format_cpp_string_literal(segments)
|
formatted = format_cpp_string_literal(segments)
|
||||||
@@ -587,6 +606,7 @@ def _write_file(path: str, lines: List[str]) -> None:
|
|||||||
# Main
|
# Main
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
def main(translations_dir=None, output_dir=None) -> None:
|
def main(translations_dir=None, output_dir=None) -> None:
|
||||||
# Default paths (relative to project root)
|
# Default paths (relative to project root)
|
||||||
default_translations_dir = "lib/I18n/translations"
|
default_translations_dir = "lib/I18n/translations"
|
||||||
@@ -601,7 +621,6 @@ def main(translations_dir=None, output_dir=None) -> None:
|
|||||||
translations_dir = default_translations_dir
|
translations_dir = default_translations_dir
|
||||||
output_dir = default_output_dir
|
output_dir = default_output_dir
|
||||||
|
|
||||||
|
|
||||||
if not os.path.isdir(translations_dir):
|
if not os.path.isdir(translations_dir):
|
||||||
print(f"Error: Translations directory not found: {translations_dir}")
|
print(f"Error: Translations directory not found: {translations_dir}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -620,10 +639,16 @@ def main(translations_dir=None, output_dir=None) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
out = Path(output_dir)
|
out = Path(output_dir)
|
||||||
generate_keys_header(languages, language_names, string_keys, str(out / "I18nKeys.h"))
|
generate_keys_header(
|
||||||
|
languages, language_names, string_keys, str(out / "I18nKeys.h")
|
||||||
|
)
|
||||||
generate_strings_header(languages, language_names, str(out / "I18nStrings.h"))
|
generate_strings_header(languages, language_names, str(out / "I18nStrings.h"))
|
||||||
generate_strings_cpp(
|
generate_strings_cpp(
|
||||||
languages, language_names, string_keys, translations, str(out / "I18nStrings.cpp")
|
languages,
|
||||||
|
language_names,
|
||||||
|
string_keys,
|
||||||
|
translations,
|
||||||
|
str(out / "I18nStrings.cpp"),
|
||||||
)
|
)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
|
|||||||
Reference in New Issue
Block a user