ci/translations: Add a linter to check for invalid characters, fix current issues (#2774)

This commit is contained in:
Tyler Wilding
2023-06-25 14:13:32 -05:00
committed by GitHub
parent cb895d4ba0
commit 4018d15fde
11 changed files with 138 additions and 25 deletions
+3
View File
@@ -38,3 +38,6 @@ jobs:
- name: Check for Incorrect Asserts
run: python ./scripts/ci/check-for-asserts.py
- name: Check for Invalid Translation Characters
run: python ./scripts/ci/lint-characters.py
+2 -2
View File
@@ -8,9 +8,9 @@
"name": "Append File Docs",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/temp/convert_subs.py",
"program": "${workspaceFolder}/scripts/ci/lint-characters.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}/temp",
"cwd": "${workspaceFolder}",
"args": []
},
]
+1
View File
@@ -551,6 +551,7 @@ static std::vector<ReplaceInfo> s_replace_info_jak1 = {
// other
{"A~Y~-21H~-5Vº~Z", "Å"},
{"N~Y~-6Hº~Z~+10H", ""},
{"O~Y~-16H~-1V/~Z", "Ø"},
// tildes
{"N~Y~-22H~-4V<TIL>~Z", "Ñ"},
@@ -456,7 +456,7 @@
],
"geologist-reminder-moles": [
"HAR NI LYCKATS FÖSA DE BLIXTANDE MULLVADARNA TILLBAKA NER UNDER MARKEN?",
"NI BORDE SKYNDA PÅ DIREKT SOLLJUS ÄR INTE RIKTIGT BRA FÖR DEM!"
"NI BORDE SKYNDA PÅ - DIREKT SOLLJUS ÄR INTE RIKTIGT BRA FÖR DEM!"
],
"geologist-reminder-money": [
"JAG BEHÖVER DE DÄR KULORNA OM JAG SKA KUNNA FORSÄTTA MED MIN FORSKNING!"
@@ -798,7 +798,7 @@
"ELLER SKA DU KUNNA HJÄLPA MIG UT UR DEN HÄR RÖRAN!?",
"JAG KOMMER FORTSÄTTA BABBLA! FÖR ENLIGT MIN PROFESSIONELLA ÅSIKT",
"ÄNDRINGEN ÄR EN FÖRBÄTTRING.",
"OCH DESSUTOM JAK SKULLE INTE KUNNA HJÄLPA DIG ÄVEN OM JAG KUNDE DET.",
"OCH DESSUTOM... JAK SKULLE INTE KUNNA HJÄLPA DIG ÄVEN OM JAG KUNDE DET.",
"VA!?",
"DET FINNS BARA EN PERSON SOM HAR STUDERAT MÖRK ECO TILLRÄCKLIGT LÄNGE",
"FÖR ATT KUNNA HA EN CHANS ATT ÄNDRA DIG TILLBAKA TILL DIN FÖRRA FORM:",
@@ -2474,7 +2474,7 @@
"VI SKULLE KANSKE KUNNA DUCKA FRÅN FLADDERMÖSSEN!"
],
"sksp0157": [
"SÅG DU DET DÄR`? BARA TRE ANKARE KVAR!"
"SÅG DU DET DÄR? BARA TRE ANKARE KVAR!"
],
"sksp0158": [
"WOW! BARA TVÅ ANKARE TILL.."
@@ -34,11 +34,11 @@
"012d": "50HZ",
"012e": "JAK AND DAXTER",
"012f": "TALÁLD MEG A REJTETT ENERGIACELLÁT",
"0130": "NINCS ELEGENDŐ HELY A MEMORY_CARD_SLOT_~D-BE ILLESZTETT MEMORY_CARD_(PS2)-N",
"0131": "NINCS MEMORY_CARD_(PS2) A MEMORY_CARD_SLOT_~D-BEN",
"0132": "MEMORY_CARD_(PS2) A MEMORY_CARD_SLOT_~D-BEN NINCS MEGFORMÁZVA",
"0130": "NINCS ELEGENDŐ HELY A MEMORY CARD SLOT ~D-BE ILLESZTETT MEMORY CARD (PS2)-N",
"0131": "NINCS MEMORY CARD (PS2) A MEMORY CARD SLOT ~D-BEN",
"0132": "MEMORY CARD (PS2) A MEMORY CARD SLOT ~D-BEN NINCS MEGFORMÁZVA",
"0133": "JAK AND DAXTER ~DKB SZABAD HELYET IGÉNYEL",
"0134": "HELYEZZ BE EGY ELEGENDŐ SZABAD HELLYEL RENDELKEZŐ MEMORY_CARD_(PS2)-T, VAGY NEM FOGOD TUDNI ELMENTENI A JÁTÉKOT",
"0134": "HELYEZZ BE EGY ELEGENDŐ SZABAD HELLYEL RENDELKEZŐ MEMORY CARD (PS2)-T, VAGY NEM FOGOD TUDNI ELMENTENI A JÁTÉKOT",
"0135": "HA NEM FORMÁZOD MEG, AKKOR NEM FOGOD TUDNI ELMENTENI A JÁTÉKOT",
"0136": "ADATOK MENTÉSE",
"0137": "ADATOK BETÖLTÉSE",
@@ -51,7 +51,7 @@
"0140": "VÁLASSZ FÁJLT A MENTÉSHEZ",
"0141": "VÁLASSZ FÁJLT A BETÖLTÉSHEZ",
"0142": "EGY JAK AND DAXTER MENTÉS MÁR LÉTEZIK AZ ÁLTALAD KIVÁLASZTOTT FÁJLON",
"0143": "HELYEZZ BE EGY MEMORY_CARD_(PS2)-T A MEMORY_CARD_SLOT_~D-BE AMI TARTALMAZ JAK AND DAXTER MENTÉST",
"0143": "HELYEZZ BE EGY MEMORY CARD (PS2)-T A MEMORY CARD SLOT ~D-BE AMI TARTALMAZ JAK AND DAXTER MENTÉST",
"0144": "FOLYTATOD?",
"014b": "JÁTÉK BETÖLTÉSE",
"014c": "JÁTÉK MENTÉSE",
@@ -63,19 +63,19 @@
"0152": "HIBA A MENTÉS KÖZBEN",
"0153": "HIBA A FORMÁZÁS KÖZBEN",
"0154": "HIBA A MENTÉSFÁJL LÉTREHOZÁSA KÖZBEN",
"0156": "MEMORY_CARD_(PS2) A MEMORY_CARD_SLOT_~D-BEN EL LETT TÁVOLÍTVA",
"0156": "MEMORY CARD (PS2) A MEMORY CARD SLOT ~D-BEN EL LETT TÁVOLÍTVA",
"0157": "AZ AUTOMATIKUS MENTÉS KI LETT KAPCSOLVA",
"0158": "HASZNÁLD A JÁTÉK MENTÉSE OPCIÓT HOGY MANUÁLISAN ELMENTSD A JÁTÉKOT ÉS VISSZAKAPCSOLD AZ AUTOMATIKUS MENTÉST",
"0159": "NINCS JAK AND DAXTER JÁTÉK ADAT A MEMORY_CARD_SLOT_~D-BEN LÉVŐ MEMORY_CARD_(PS2)-N",
"0159": "NINCS JAK AND DAXTER JÁTÉK ADAT A MEMORY CARD SLOT ~D-BEN LÉVŐ MEMORY CARD (PS2)-N",
"015a": "SZERETNÉL LÉTREHOZNI EGY ÚJ JAK AND DAXTER MENTÉSFÁJLT?",
"015b": "ELLENŐRIZD A MEMORY_CARD_SLOT_~D-BEN LÉVŐ MEMORY_CARD_(PS2)-T",
"015b": "ELLENŐRIZD A MEMORY CARD SLOT ~D-BEN LÉVŐ MEMORY CARD (PS2)-T",
"015c": "ÚJ JÁTÉK",
"015d": "VISSZAMÉSZ?",
"015e": "OKÉ",
"015f": "KILÉPÉS A DEMÓBÓL",
"0160": "AMIKOR A KÖVETKEZŐ IKON MEGJELENIK, AKKOR A HALADÁSOD MENTÉS ALATT VAN",
"0162": "FELADAT TELJESÍTVE",
"0163": "ELLENŐRIZD A MEMORY_CARD_SLOT_~D-BEN LÉVŐ MEMORY_CARD_(PS2)-T ÉS PRÓBÁLD ÚJRA",
"0163": "ELLENŐRIZD A MEMORY CARD SLOT ~D-BEN LÉVŐ MEMORY CARD (PS2)-T ÉS PRÓBÁLD ÚJRA",
"0164": "A KÉPERNYŐ MOST 60HZ-RE FOG VÁLTANI",
"0165": "HA NEM MEGFELELŐEN JELENIK MEG A KÉP, AKKOR A KIJELZŐD NEM TÁMOGATJA EZT A MÓDOT",
"0166": "HA ÍGY VAN, AKKOR VÁRJ 10 MÁSODPERCET ÉS A KÉP VISSZA FOG VÁLTANI",
@@ -103,7 +103,7 @@
"103c": "4X3 (PS2)",
"103d": "16X9 (PS2)",
"103e": "~DX~D",
"103f": "TRYK <PAD_SQUARE> FOR AT SLÅ UNDERTEKTER TIL ELLER FRA",
"103f": "TRYK <PAD_SQUARE> FOR AT SLÅ UNDERTEKTER TIL ELLER FRA",
"107a": "UNDERTEKSTSPROG",
"107b": "VIS TALER MED UNDERTEKSTER",
"107c": "ALTID",
@@ -80,7 +80,7 @@
"1105": "A HARC VÉGE",
"1106": "VÁLTOZAT 1",
"1107": "VÁLTOZAT 2",
"1110": "ENGLISH (UK},",
"1110": "ENGLISH (UK)",
"1111": "PORTUGUÊS",
"1112": "PORTUGUÊS (BRASIL)",
"1113": "SUOMI",
@@ -16,7 +16,7 @@
"1024": "ミュージック ゲイン",
"1025": "アクター カリング",
"1026": "バックグラウンド カリング",
"1027": "環境マッピングを強制する",
"1027": "??マッピングを??する",
"1030": "DISCORDリッチプレゼンス",
"1031": "ディスプレー モード",
"1032": "ウィンドウ",
@@ -25,11 +25,11 @@
"1035": "ゲーム クォリティ",
"1036": "~D X ~D",
"1037": "PS2 アスペクト レーショ",
"1038": "PS2アスペクト比が有効になると、4×3と16×9しかのアスペクト比が選択できません。続行しますか",
"1038": "PS2アスペクト?が??になると、4x3と16x9しかのアスペクト?が??できません??行しますか?",
"1039": "アスペクト レーショ (PS2)",
"1040": "サブタイトル オン",
"1041": "サブタイトル オフ",
"1042": "テキストの言語",
"1042": "テキストの??",
"1043": "ディスプレー",
"1044": "ディスプレー ~D",
"1050": "MSAA",
@@ -158,7 +158,7 @@
"10f2": "END OF THE PASS",
"10f3": "ヤミノ洞くつへ",
"10f4": "ガイセツ山へ",
"10f5": "宝石りたち",
"10f5": "宝石?りたち",
"10f6": "ROBOT CAVE SCAFFOLDING",
"10f7": "PRECURSOR ROBOT TOP",
"10f8": "メイン洞くつ",
@@ -15,7 +15,7 @@
"1023": "MUSIKK TONE-UT",
"1024": "MUSIKK TONE-INN",
"1025": "SKUESPILLINGUTSLUTNING",
"1026": "\nBAKGRUNNSUTSLUTNING",
"1026": "BAKGRUNNSUTSLUTNING",
"1027": "FORCE MILJØKARTLEGGING",
"1030": "DISCORD RICH-PRESENCE",
"1031": "SKJERMINNSTILLINGER",
@@ -68,7 +68,7 @@
"1093": "OÄNDLIG GUL ECO",
"1094": "BLÅ DAXTER",
"1095": "ODÖDLIGHET",
"1096": "ALLA MUSIK LÅTAR\n",
"1096": "ALLA MUSIK LÅTAR",
"1097": "ANVÄND SYSTEM TID",
"1098": "NÅ 100% KLART",
"1099": "KLARA SPELET",
@@ -124,13 +124,13 @@
"10d0": "STANDARD",
"10d1": "OANVÄND",
"10d2": "GRÖN VIS MAN",
"10d3": "GRÖN VIS MANS HYDDA",
"10d3": "GRÖN VIS MAN'S HYDDA",
"10d4": "FÅGELSKÅDARE",
"10d5": "BONDE",
"10d6": "KEIRA",
"10d7": "BORGMÄSTARE",
"10d8": "SKULPTÖR",
"10d9": "JAKS FARBROR",
"10d9": "JAK'S FARBROR",
"10da": "HAMN",
"10db": "UTGÅNG TILL FÖRBJUDNA TEMPLET",
"10dc": "LURKER MASKIN",
@@ -153,7 +153,7 @@
"10ed": "OANVÄND 1",
"10ee": "AVFYRNINGSFÄLLOR",
"10ef": "OANVÄND 2",
"10f0": "DÖD MANS DAL",
"10f0": "DÖD MAN'S DAL",
"10f1": "MITTEN AV PASSET",
"10f2": "SLUET AV PASSET",
"10f3": "TILL SPINDEL GROTTAN",
+109
View File
@@ -0,0 +1,109 @@
import glob
import json
import re
# TODO - add a way to make this auto replace bad characters with `?`
# fmt: off
JAK1_ALLOWED_CHARACTERS = [
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"'", "!", "(", ")", "+", "-", ",", ".", "/", ":", "=", "<", ">", "*", "%", "?", "\"",
"`", "ˇ", "¨", "º", "¡", "¿", "Æ", "Ç", "ß", "", "", " ", "Å", "Ø",
"Ñ", "Ã", "Õ", "Á", "É", "Í", "Ó", "Ú", "Ő", "Ű", "Â", "Ê", "Î", "Ô", "Û", "À", "È", "Ì", "Ò", "Ù", "Ä", "Ë", "Ï", "Ö", "ö", "Ü",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Œ", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "",
"~"
]
JAK1_ALLOWED_CODES = [
"<TIL>",
"<PAD_X>", "<PAD_TRIANGLE>", "<PAD_CIRCLE>", "<PAD_SQUARE>"
]
# fmt: on
invalid_characters_found = False
def is_allowed_code(pos, text):
# Find any occurences of allowed codes in the string
# if the position overlaps with these occurrences, it's allowed
for code in JAK1_ALLOWED_CODES:
for match in re.finditer(code, text):
if pos >= match.start() and pos <= match.end():
return match.end()
return -1
def char_allowed(char):
return char in JAK1_ALLOWED_CHARACTERS
def lint_jak1_characters(text):
invalid_characters_found = False
pos = 0
while pos < len(text):
character = text[pos]
if not char_allowed(character):
# Check to see if it's an allowed code
code_end_pos = is_allowed_code(pos, text)
if code_end_pos == -1:
print(
"Character '{}' not allowed - Found in {}".format(character, text)
)
invalid_characters_found = True
pos = pos + 1
else:
# advance to the end of the code and continue checking
pos = code_end_pos
else:
pos = pos + 1
return invalid_characters_found
# Iterate through the translations making sure there are no characters that are not allowed
text_files = glob.glob("./game/assets/jak1/text/*.json")
for text_file in text_files:
print("Checking {}...".format(text_file))
with open(text_file, encoding="utf-8") as f:
file_data = json.load(f)
for id, text in file_data.items():
invalid_chars_exist = lint_jak1_characters(text)
if invalid_chars_exist:
invalid_characters_found = True
subtitle_files = glob.glob("./game/assets/jak1/subtitle/*lines*.json")
for subtitle_file in subtitle_files:
print("Checking {}...".format(subtitle_file))
with open(subtitle_file, encoding="utf-8") as f:
file_data = json.load(f)
# Check Speakers
for id, text in file_data["speakers"].items():
invalid_chars_exist = lint_jak1_characters(text)
if invalid_chars_exist:
invalid_characters_found = True
# Check Lines
for id, lines in file_data["cutscenes"].items():
for line in lines:
invalid_chars_exist = lint_jak1_characters(line)
if invalid_chars_exist:
invalid_characters_found = True
for id, lines in file_data["hints"].items():
for line in lines:
invalid_chars_exist = lint_jak1_characters(line)
if invalid_chars_exist:
invalid_characters_found = True
if invalid_characters_found:
print("Invalid characters were found, see above")
exit(1)
else:
print("No invalid characters found!")