1
0
mirror of synced 2024-09-23 19:18:24 +02:00
ImHex/dist/langtool.py
xtex 187d90e8f2
lang: Update Chinese (Simplified) translations (#1894)
Co-authored-by: JustFor <35858818+zhongqingsong@users.noreply.github.com>
2024-09-15 15:17:25 +02:00

215 lines
8.1 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
from pathlib import Path
import argparse
import json
# This fixes a CJK full-width character input issue
# which makes left halves of deleted characters displayed on screen
# pylint: disable=unused-import
import re
import readline
DEFAULT_LANG = "en_US"
DEFAULT_LANG_PATH = "plugins/*/romfs/lang/"
INVALID_TRANSLATION = ""
def main():
parser = argparse.ArgumentParser(
prog="langtool",
description="ImHex translate tool",
)
parser.add_argument(
"command",
choices=[
"check",
"translate",
"update",
"create",
"retranslate",
"untranslate",
"fmtzh",
],
)
parser.add_argument(
"-c", "--langdir", default=DEFAULT_LANG_PATH, help="Language folder glob"
)
parser.add_argument("-l", "--lang", default="", help="Language to translate")
parser.add_argument(
"-r", "--reflang", default="", help="Language for reference when translating"
)
parser.add_argument(
"-k", "--keys", help="Keys to re-translate (only in re/untranslate mode)"
)
args = parser.parse_args()
command = args.command
lang = args.lang
print(f"Running in {command} mode")
lang_files_glob = f"{lang}.json" if lang != "" else "*.json"
lang_folders = set(Path(".").glob(args.langdir))
if len(lang_folders) == 0:
print(f"Error: {args.langdir} matches nothing")
return 1
for lang_folder in lang_folders:
if not lang_folder.is_dir():
print(f"Error: {lang_folder} is not a folder")
return 1
default_lang_data = {}
default_lang_path = lang_folder / Path(DEFAULT_LANG + ".json")
if not default_lang_path.exists():
print(
f"Error: Default language file {default_lang_path} does not exist in {lang_folder}"
)
return 1
with default_lang_path.open("r", encoding="utf-8") as file:
default_lang_data = json.load(file)
reference_lang_data = None
reference_lang_path = lang_folder / Path(args.reflang + ".json")
if reference_lang_path.exists():
with reference_lang_path.open("r", encoding="utf-8") as file:
reference_lang_data = json.load(file)
if command == "create" and lang != "":
lang_file_path = lang_folder / Path(lang + ".json")
if lang_file_path.exists():
continue
exist_lang_data = None
for lang_folder1 in lang_folders:
lang_file_path1 = lang_folder1 / Path(lang + ".json")
if lang_file_path1.exists():
with lang_file_path1.open("r", encoding="utf-8") as file:
exist_lang_data = json.load(file)
break
print(f"Creating new language file '{lang_file_path}'")
with lang_file_path.open("w", encoding="utf-8") as new_lang_file:
new_lang_data = {
"code": lang,
"language": (
exist_lang_data["language"]
if exist_lang_data
else input("Enter language name: ")
),
"country": (
exist_lang_data["country"]
if exist_lang_data
else input("Enter country name: ")
),
"translations": {},
}
json.dump(new_lang_data, new_lang_file, indent=4, ensure_ascii=False)
lang_files = set(lang_folder.glob(lang_files_glob))
if len(lang_files) == 0:
print(f"Warn: Language file for '{lang}' does not exist in '{lang_folder}'")
for lang_file_path in lang_files:
if (
lang_file_path.stem == f"{DEFAULT_LANG}.json"
or lang_file_path.stem == f"{args.reflang}.json"
):
continue
print(f"\nProcessing '{lang_file_path}'")
if not (command == "update" or command == "create"):
print("\n----------------------------\n")
with lang_file_path.open("r+", encoding="utf-8") as target_lang_file:
lang_data = json.load(target_lang_file)
for key, value in default_lang_data["translations"].items():
has_translation = (
key in lang_data["translations"]
and lang_data["translations"][key] != INVALID_TRANSLATION
)
if (
has_translation
and not (
(command == "retranslate" or command == "untranslate")
and re.compile(args.keys).fullmatch(key)
)
and not command == "fmtzh"
):
continue
if command == "check":
print(
f"Error: Translation {lang_data['code']} is missing translation for key '{key}'"
)
elif (
command == "translate"
or command == "retranslate"
or command == "untranslate"
):
if command == "untranslate" and not has_translation:
continue
reference_tranlsation = (
" '%s'" % reference_lang_data["translations"][key]
if (
reference_lang_data
and key in reference_lang_data["translations"]
)
else ""
)
print(
f"\033[1m'{key}' '{value}'{reference_tranlsation}\033[0m => {lang_data['language']}",
end="",
)
if has_translation:
translation = lang_data["translations"][key]
print(f" <= \033[1m'{translation}'\033[0m")
print() # for a new line
if command == "untranslate":
lang_data["translations"][key] = INVALID_TRANSLATION
continue
try:
new_value = input("=> ")
lang_data["translations"][key] = new_value
except KeyboardInterrupt:
break
elif command == "update" or command == "create":
lang_data["translations"][key] = INVALID_TRANSLATION
elif command == "fmtzh":
if has_translation:
lang_data["translations"][key] = fmtzh(
lang_data["translations"][key]
)
keys_to_remove = []
for key, value in lang_data["translations"].items():
if key not in default_lang_data["translations"]:
keys_to_remove.append(key)
for key in keys_to_remove:
lang_data["translations"].pop(key)
print(
f"Removed unused key '{key}' from translation '{lang_data['code']}'"
)
target_lang_file.seek(0)
target_lang_file.truncate()
json.dump(
lang_data,
target_lang_file,
indent=4,
sort_keys=True,
ensure_ascii=False,
)
def fmtzh(text: str) -> str:
text = re.sub(r"(\.{3}|\.{6})", "……", text)
text = text.replace("!", "")
text = re.sub(r"([^\.\na-zA-Z\d])\.$", "\1", text, flags=re.M)
text = text.replace("?", "")
return text
if __name__ == "__main__":
exit(main())