68 lines
2.8 KiB
Python
68 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
LANGUAGES: dict[str, str] = {
|
|
"en": "English",
|
|
"zh": "中文 (Chinese)",
|
|
"ja": "日本語 (Japanese)",
|
|
"ko": "한국어 (Korean)",
|
|
}
|
|
|
|
TARGET_LANGUAGE_OPTIONS: list[str] = [
|
|
LANGUAGES["zh"],
|
|
LANGUAGES["ja"],
|
|
LANGUAGES["ko"],
|
|
LANGUAGES["en"],
|
|
]
|
|
|
|
_LABEL_TO_CODE: dict[str, str] = {label: code for code, label in LANGUAGES.items()}
|
|
|
|
|
|
def label_to_code(label: str) -> str:
|
|
"""Map a dropdown label back to its language code (defaults to 'en')."""
|
|
return _LABEL_TO_CODE.get(label, "en")
|
|
|
|
|
|
CAMERA_GLOSSARY: dict[str, dict[str, str]] = {
|
|
# Azimuth / horizontal direction
|
|
"front view": {"zh": "正面视角", "ja": "正面", "ko": "정면"},
|
|
"front-right quarter view": {"zh": "右前方视角", "ja": "右前方", "ko": "우측 전방"},
|
|
"right side view": {"zh": "右侧视角", "ja": "右側面", "ko": "우측면"},
|
|
"back-right quarter view": {"zh": "右后方视角", "ja": "右後方", "ko": "우측 후방"},
|
|
"back view": {"zh": "背面视角", "ja": "背面", "ko": "후면"},
|
|
"back-left quarter view": {"zh": "左后方视角", "ja": "左後方", "ko": "좌측 후방"},
|
|
"left side view": {"zh": "左侧视角", "ja": "左側面", "ko": "좌측면"},
|
|
"front-left quarter view": {"zh": "左前方视角", "ja": "左前方", "ko": "좌측 전방"},
|
|
# Elevation / vertical direction
|
|
"low-angle shot": {"zh": "仰拍", "ja": "ローアングル", "ko": "로우 앵글"},
|
|
"eye-level shot": {"zh": "平视", "ja": "アイレベル", "ko": "아이 레벨"},
|
|
"elevated shot": {"zh": "高角度", "ja": "ハイアングル", "ko": "하이 앵글"},
|
|
"high-angle shot": {"zh": "俯拍", "ja": "俯瞰", "ko": "부감"},
|
|
# Distance / shot size
|
|
"wide shot": {"zh": "远景", "ja": "ワイドショット", "ko": "와이드 샷"},
|
|
"medium shot": {"zh": "中景", "ja": "ミディアムショット", "ko": "미디엄 샷"},
|
|
"close-up": {"zh": "特写", "ja": "クローズアップ", "ko": "클로즈업"},
|
|
}
|
|
|
|
|
|
_SORTED_PHRASES = sorted(CAMERA_GLOSSARY.keys(), key=len, reverse=True)
|
|
_PHRASE_RE = re.compile(
|
|
r"(?<![A-Za-z])(" + "|".join(re.escape(p) for p in _SORTED_PHRASES) + r")(?![A-Za-z])",
|
|
re.IGNORECASE,
|
|
)
|
|
|
|
|
|
def translate_camera_terms(text: str, lang_code: str) -> str:
|
|
if not text or lang_code == "en" or lang_code not in ("zh", "ja", "ko"):
|
|
return text
|
|
|
|
def _sub(match: re.Match) -> str:
|
|
phrase = match.group(1)
|
|
entry = CAMERA_GLOSSARY.get(phrase.lower())
|
|
if not entry:
|
|
return phrase
|
|
return entry.get(lang_code, phrase)
|
|
|
|
return _PHRASE_RE.sub(_sub, text)
|