Merge pull request #9513 from guoyunhe/translation-update-script

Add translation update scripts to integrate with localization platforms
This commit is contained in:
Twinaphex 2020-02-15 02:39:31 +01:00 committed by GitHub
commit 1c031466fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 312 additions and 96 deletions

View File

@ -71,7 +71,11 @@ static const struct retro_keybind retro_keybinds_1[] = {
{ true, RARCH_LOAD_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
{ true, RARCH_SAVE_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
{ true, RARCH_FULLSCREEN_TOGGLE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
#ifdef HAVE_LAKKA
{ true, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_RESTART_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
#else
{ true, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
#endif
{ true, RARCH_STATE_SLOT_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
{ true, RARCH_STATE_SLOT_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
{ true, RARCH_REWIND, MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
@ -235,7 +239,11 @@ static const struct retro_keybind retro_keybinds_1[] = {
{ true, RARCH_LOAD_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, RETROK_F4, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
{ true, RARCH_SAVE_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, RETROK_F2, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
{ true, RARCH_FULLSCREEN_TOGGLE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, RETROK_f, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
#ifdef HAVE_LAKKA
{ true, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_RESTART_KEY, RETROK_ESCAPE, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
#else
{ true, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, RETROK_ESCAPE, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
#endif
{ true, RARCH_STATE_SLOT_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, RETROK_F7, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
{ true, RARCH_STATE_SLOT_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, RETROK_F6, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },
{ true, RARCH_REWIND, MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, RETROK_r, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL },

3
intl/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.json
crowdin.yaml
crowdin.yml

23
intl/README.md Normal file
View File

@ -0,0 +1,23 @@
# Internationalization Workflow (Draft)
## Steps
- Developers update strings in `msg_hash_us.h`.
- Developers (can set a cron job) run `./h2json.py msg_hash_us.h` to generate `msg_hash_us.json`. It is just a convenient format that is supported by Weblate/Crowdin/Transifex and doesn't need to be inversion control.
- Developers (can set a cron job) upload `msg_hash_us.json` to Weblate/Crowdin/Transifex.
- Translators translate strings on Weblate/Crowdin/Transifex.
- Developers (can set a cron job) download `msg_hash_xx.json` files.
- Developers (can set a cron job) run `./json2h.py msg_hash_xx.json` to generate `msg_hash_xx.h`.
## Pros
- No new dependencies.
- No performance impact.
- Don't require translators to know how to use Git, how to read C code and how to create Pull Request.
- Translators will be informed whenever a source string changes.
## Cron job setup
1. [Install crowdin cli tool](https://support.crowdin.com/cli-tool/)
2. Get the `intl/crowdin.yaml` file from someone who have crowdin admin accounts
3. Add cron job `cd path/to/retroarch/intl && ./crowin_sync.sh`

27
intl/crowdin_sync.sh Executable file
View File

@ -0,0 +1,27 @@
#!/bin/bash
# Update source code
git pull
# Convert source *.h to *.json
./h2json.py msg_hash_us.h
# Upload source file
crowdin upload sources
# Crowdin need some time to process data
sleep 1m
# Download translation files
crowdin download translations
# Convert translation *.json to *.h
for f in *.json
do
./json2h.py $f
done
# Commit new translations
git add .
git commit -m "Synchronize translations"
git push

55
intl/h2json.py Executable file
View File

@ -0,0 +1,55 @@
#!/usr/bin/env python3
# Convert *.h to *.json
# Usage: ./h2json.py msg_has_us.h
import re
import sys
import json
try:
h_filename = sys.argv[1]
json_filename = h_filename.replace('.h', '.json')
except IndexError:
print("Usage: ./h2json.py msg_has_us.h")
sys.exit(1)
p = re.compile('MSG_HASH\(\s*[A-Z0-9_]+,\s*\".*\"\s*\)')
header = """#if defined(_MSC_VER) && !defined(_XBOX) && (_MSC_VER >= 1500 && _MSC_VER < 1900)
#if (_MSC_VER >= 1700)
/* https://support.microsoft.com/en-us/kb/980263 */
#pragma execution_character_set("utf-8")
#endif
#pragma warning(disable:4566)
#endif
"""
def parse_message(message):
key_start = message.find('(') + 1
key_end = message.find(',')
key = message[key_start:key_end].strip()
value_start = message.find('"') + 1
value_end = message.rfind('"')
value = message[value_start:value_end].strip()
return key, value
try:
with open(h_filename, 'r+') as h_file:
text = h_file.read()
result = p.findall(text)
seen = set()
messages = {}
for msg in result:
key, val = parse_message(msg)
messages[key] = val
if key not in seen:
seen.add(key)
else:
print("Duplicate key: " + key)
with open(json_filename, 'w') as json_file:
json.dump(messages, json_file, indent=2)
except EnvironmentError:
print('Cannot read/write ' + h_filename)

74
intl/json2h.py Executable file
View File

@ -0,0 +1,74 @@
#!/usr/bin/env python3
# Convert *.json to *.h
# Usage: ./json2h.py msg_hash_fr.json
import re
import sys
import json
try:
json_filename = sys.argv[1]
h_filename = json_filename.replace('.json', '.h')
except IndexError:
print("Usage: ./template.py <language_postfix>")
sys.exit(1)
if json_filename == 'msg_hash_us.json':
print("Skip")
sys.exit(0)
p = re.compile('MSG_HASH\(\s*[A-Z0-9_]+,\s*\".*\"\s*\)')
def parse_message(message):
key_start = message.find('(') + 1
key_end = message.find(',')
key = message[key_start:key_end].strip()
value_start = message.find('"') + 1
value_end = message.rfind('"')
value = message[value_start:value_end].strip()
return key, value
def parse_messages(text):
result = p.findall(text)
seen = set()
msg_list = []
for msg in result:
key, val = parse_message(msg)
item = {'key': key, 'val': val, 'msg': msg}
msg_list.append(item)
if key not in seen:
seen.add(key)
else:
print("Duplicate key: " + key)
return msg_list
def update(messages, template):
new_translation = template
template_messages = parse_messages(template)
for tp_msg in template_messages:
if tp_msg['key'] in messages:
tp_msg_val = tp_msg['val']
tl_msg_val = messages[tp_msg['key']]
old_msg = tp_msg['msg']
new_msg = old_msg.replace(tp_msg_val, tl_msg_val)
new_translation = new_translation.replace(old_msg, new_msg)
return new_translation
with open('msg_hash_us.h', 'r') as template_file:
template = template_file.read()
try:
with open(json_filename, 'r+') as json_file:
messages = json.load(json_file)
new_translation = update(messages, template)
with open(h_filename, 'w') as h_file:
h_file.seek(0)
h_file.write(new_translation)
h_file.truncate()
except EnvironmentError:
print('Cannot read/write ' + json_filename)

View File

@ -1,3 +1,11 @@
#if defined(_MSC_VER) && !defined(_XBOX) && (_MSC_VER >= 1500 && _MSC_VER < 1900)
#if (_MSC_VER >= 1700)
/* https://support.microsoft.com/en-us/kb/980263 */
#pragma execution_character_set("utf-8")
#endif
#pragma warning(disable:4566)
#endif
#ifdef HAVE_LAKKA_SWITCH
MSG_HASH(
MENU_ENUM_LABEL_VALUE_SWITCH_GPU_PROFILE,
@ -1466,17 +1474,14 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE,
"Pause toggle"
)
#ifdef HAVE_LAKKA
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY,
MENU_ENUM_LABEL_VALUE_INPUT_META_RESTART_KEY,
"Restart RetroArch"
)
#else
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY,
"Quit RetroArch"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_RESET,
"Reset game"
@ -2567,12 +2572,6 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_MIDI_SETTINGS,
"MIDI"
)
#ifdef HAVE_LAKKA
MSG_HASH(
MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH,
"Restart RetroArch"
)
#else
MSG_HASH(
MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH,
"Quit RetroArch"
@ -2581,7 +2580,6 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH,
"Restart RetroArch"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DETAIL,
"Database Entry"
@ -2732,15 +2730,14 @@ MSG_HASH(
)
#ifdef HAVE_LAKKA_SWITCH
MSG_HASH(
MENU_ENUM_LABEL_VALUE_REBOOT,
MENU_ENUM_LABEL_VALUE_REBOOT_RCM,
"Reboot into RCM"
)
#else
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_REBOOT,
"Reboot"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY,
"Recording Config"
@ -6037,12 +6034,6 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION,
"Show information specific to the device."
)
#ifdef HAVE_LAKKA
MSG_HASH(
MENU_ENUM_SUBLABEL_QUIT_RETROARCH,
"Restart the program."
)
#else
MSG_HASH(
MENU_ENUM_SUBLABEL_QUIT_RETROARCH,
"Quit the program."
@ -6051,7 +6042,6 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_RESTART_RETROARCH,
"Restart the program."
)
#endif
MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_WINDOW_WIDTH,
"Set the custom width for the display window."
@ -7335,16 +7325,6 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_SHOW_HELP,
"Show/hide the 'Help' option."
)
#ifdef HAVE_LAKKA
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH,
"Show Restart RetroArch"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_SHOW_QUIT_RETROARCH,
"Show/hide the 'Restart RetroArch' option."
)
#else
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH,
"Show Quit RetroArch"
@ -7361,7 +7341,6 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_SHOW_RESTART_RETROARCH,
"Show/hide the 'Restart RetroArch' option."
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_SHOW_REBOOT,
"Show Reboot"

View File

@ -305,7 +305,11 @@ default_sublabel_macro(action_bind_sublabel_content_special, MENU_
default_sublabel_macro(action_bind_sublabel_load_content_history, MENU_ENUM_SUBLABEL_LOAD_CONTENT_HISTORY)
default_sublabel_macro(action_bind_sublabel_network_information, MENU_ENUM_SUBLABEL_NETWORK_INFORMATION)
default_sublabel_macro(action_bind_sublabel_system_information, MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION)
#ifdef HAVE_LAKKA
default_sublabel_macro(action_bind_sublabel_quit_retroarch, MENU_ENUM_SUBLABEL_RESTART_RETROARCH)
#else
default_sublabel_macro(action_bind_sublabel_quit_retroarch, MENU_ENUM_SUBLABEL_QUIT_RETROARCH)
#endif
default_sublabel_macro(action_bind_sublabel_restart_retroarch, MENU_ENUM_SUBLABEL_RESTART_RETROARCH)
default_sublabel_macro(action_bind_sublabel_menu_widgets, MENU_ENUM_SUBLABEL_MENU_WIDGETS_ENABLE)
default_sublabel_macro(action_bind_sublabel_video_window_width, MENU_ENUM_SUBLABEL_VIDEO_WINDOW_WIDTH)

View File

@ -7675,6 +7675,15 @@ static bool setting_append_list(
#endif
#if !defined(IOS)
/* Apple rejects iOS apps that let you forcibly quit them. */
#ifdef HAVE_LAKKA
CONFIG_ACTION(
list, list_info,
MENU_ENUM_LABEL_QUIT_RETROARCH,
MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH,
&group_info,
&subgroup_info,
parent_group);
#else
CONFIG_ACTION(
list, list_info,
MENU_ENUM_LABEL_QUIT_RETROARCH,
@ -7682,6 +7691,7 @@ static bool setting_append_list(
&group_info,
&subgroup_info,
parent_group);
#endif
menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_QUIT);
#endif
@ -7713,6 +7723,15 @@ static bool setting_append_list(
&subgroup_info,
parent_group);
#endif
#ifdef HAVE_LAKKA_SWITCH
CONFIG_ACTION(
list, list_info,
MENU_ENUM_LABEL_REBOOT,
MENU_ENUM_LABEL_VALUE_REBOOT_RCM,
&group_info,
&subgroup_info,
parent_group);
#else
CONFIG_ACTION(
list, list_info,
MENU_ENUM_LABEL_REBOOT,
@ -7720,6 +7739,7 @@ static bool setting_append_list(
&group_info,
&subgroup_info,
parent_group);
#endif
menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REBOOT);
CONFIG_ACTION(
@ -13267,6 +13287,22 @@ static bool setting_append_list(
general_read_handler,
SD_FLAG_LAKKA_ADVANCED);
#ifdef HAVE_LAKKA
CONFIG_BOOL(
list, list_info,
&settings->bools.menu_show_quit_retroarch,
MENU_ENUM_LABEL_MENU_SHOW_QUIT_RETROARCH,
MENU_ENUM_LABEL_VALUE_MENU_SHOW_RESTART_RETROARCH,
menu_show_quit_retroarch,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
#else
CONFIG_BOOL(
list, list_info,
&settings->bools.menu_show_quit_retroarch,
@ -13281,6 +13317,7 @@ static bool setting_append_list(
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
#endif
#ifdef HAVE_LAKKA
CONFIG_BOOL(

View File

@ -793,6 +793,7 @@ enum msg_hash_enums
MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY,
MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY,
MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY,
MENU_ENUM_LABEL_VALUE_INPUT_META_RESTART_KEY,
MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS,
MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS,
MENU_ENUM_LABEL_VALUE_INPUT_META_BSV_RECORD_TOGGLE,

View File

@ -3432,7 +3432,11 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = {
DECLARE_META_BIND(1, load_state, RARCH_LOAD_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY),
DECLARE_META_BIND(1, save_state, RARCH_SAVE_STATE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY),
DECLARE_META_BIND(2, toggle_fullscreen, RARCH_FULLSCREEN_TOGGLE_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY),
#ifdef HAVE_LAKKA
DECLARE_META_BIND(2, exit_emulator, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_RESTART_KEY),
#else
DECLARE_META_BIND(2, exit_emulator, RARCH_QUIT_KEY, MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY),
#endif
DECLARE_META_BIND(2, state_slot_increase, RARCH_STATE_SLOT_PLUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS),
DECLARE_META_BIND(2, state_slot_decrease, RARCH_STATE_SLOT_MINUS, MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS),
DECLARE_META_BIND(1, rewind, RARCH_REWIND, MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND),
@ -28599,6 +28603,7 @@ bool is_input_keyboard_display_on(void)
}
#ifdef HAVE_ACCESSIBILITY
bool accessibility_speak_priority(const char* speak_text, int priority)
{
RARCH_LOG("Spoke: %s\n", speak_text);