summaryrefslogtreecommitdiff
path: root/editor/translations
diff options
context:
space:
mode:
authorHaoyu Qiu <timothyqiu32@gmail.com>2022-03-03 18:25:11 +0800
committerHaoyu Qiu <timothyqiu32@gmail.com>2022-03-03 18:31:40 +0800
commitd6df2ffad8beabc12acccbafd3afa00d7e501d9c (patch)
tree8f2b9b9eec95c4f123f9b4b29519deda436f83ff /editor/translations
parent33fc69dfb055175bfd16372473fa63405a3463f8 (diff)
i18n: Make property paths and categories translatable
Diffstat (limited to 'editor/translations')
-rwxr-xr-xeditor/translations/extract.py172
1 files changed, 93 insertions, 79 deletions
diff --git a/editor/translations/extract.py b/editor/translations/extract.py
index 2594629e5c..65d1341e9e 100755
--- a/editor/translations/extract.py
+++ b/editor/translations/extract.py
@@ -2,6 +2,7 @@
import fnmatch
import os
+import re
import shutil
import subprocess
import sys
@@ -31,6 +32,15 @@ for root, dirnames, filenames in os.walk("."):
matches.sort()
+remaps = {}
+remap_re = re.compile(r'capitalize_string_remaps\["(.+)"\] = "(.+)";')
+with open("editor/editor_property_name_processor.cpp") as f:
+ for line in f:
+ m = remap_re.search(line)
+ if m:
+ remaps[m.group(1)] = m.group(2)
+
+
unique_str = []
unique_loc = {}
ctx_group = {} # Store msgctx, msg, and locations.
@@ -53,6 +63,43 @@ msgstr ""
"""
+# Regex "(?P<name>(?:[^"\\]|\\.)*)" creates a group named `name` that matches a string.
+message_patterns = {
+ re.compile(r'RTR\("(?P<message>(?:[^"\\]|\\.)*)"(?:, "(?P<context>(?:[^"\\]|\\.)*)")?\)'): False,
+ re.compile(r'TTR\("(?P<message>(?:[^"\\]|\\.)*)"(?:, "(?P<context>(?:[^"\\]|\\.)*)")?\)'): False,
+ re.compile(r'TTRC\("(?P<message>(?:[^"\\]|\\.)*)"\)'): False,
+ re.compile(
+ r'TTRN\("(?P<message>(?:[^"\\]|\\.)*)", "(?P<plural_message>(?:[^"\\]|\\.)*)",[^,)]+?(?:, "(?P<context>(?:[^"\\]|\\.)*)")?\)'
+ ): False,
+ re.compile(
+ r'RTRN\("(?P<message>(?:[^"\\]|\\.)*)", "(?P<plural_message>(?:[^"\\]|\\.)*)",[^,)]+?(?:, "(?P<context>(?:[^"\\]|\\.)*)")?\)'
+ ): False,
+ re.compile(r'_initial_set\("(?P<message>[^"]+?)",'): True,
+ re.compile(r'GLOBAL_DEF(?:_RST)?\("(?P<message>[^".]+?)",'): True,
+ re.compile(r'EDITOR_DEF(?:_RST)?\("(?P<message>[^"]+?)",'): True,
+ re.compile(r'ADD_PROPERTY\(PropertyInfo\(Variant::[A-Z]+,\s*"(?P<message>[^"]+?)",'): True,
+ re.compile(r'ADD_GROUP\("(?P<message>[^"]+?)",'): False,
+}
+
+
+# See String::camelcase_to_underscore().
+capitalize_re = re.compile(r"(?<=\D)(?=\d)|(?<=\d)(?=\D([a-z]|\d))")
+
+
+def _process_editor_string(name):
+ # See String::capitalize().
+ # fmt: off
+ capitalized = " ".join(
+ part.title()
+ for part in capitalize_re.sub("_", name).replace("_", " ").split()
+ )
+ # fmt: on
+ # See EditorStringProcessor::process_string().
+ for key, value in remaps.items():
+ capitalized = capitalized.replace(key, value)
+ return capitalized
+
+
def _write_message(msgctx, msg, msg_plural, location):
global main_po
main_po += "#: " + location + "\n"
@@ -180,11 +227,6 @@ def _extract_translator_comment(line, is_block_translator_comment):
def process_file(f, fname):
-
- global main_po, unique_str, unique_loc
-
- patterns = ['RTR("', 'TTR("', 'TTRC("', 'TTRN("', 'RTRN("']
-
l = f.readline()
lc = 1
reading_translator_comment = False
@@ -207,86 +249,58 @@ def process_file(f, fname):
if not reading_translator_comment:
translator_comment = translator_comment[:-1] # Remove extra \n at the end.
- idx = 0
- pos = 0
-
- while not reading_translator_comment and pos >= 0:
- # Loop until a pattern is found. If not, next line.
- pos = l.find(patterns[idx], pos)
- if pos == -1:
- if idx < len(patterns) - 1:
- idx += 1
- pos = 0
- continue
- pos += len(patterns[idx])
-
- # Read msg until "
- msg = ""
- while pos < len(l) and (l[pos] != '"' or l[pos - 1] == "\\"):
- msg += l[pos]
- pos += 1
-
- # Read plural.
- msg_plural = ""
- if patterns[idx] in ['TTRN("', 'RTRN("']:
- pos = l.find('"', pos + 1)
- pos += 1
- while pos < len(l) and (l[pos] != '"' or l[pos - 1] == "\\"):
- msg_plural += l[pos]
- pos += 1
-
- # Read context.
- msgctx = ""
- pos += 1
- read_ctx = False
- while pos < len(l):
- if l[pos] == ")":
- break
- elif l[pos] == '"':
- read_ctx = True
- break
- pos += 1
-
- pos += 1
- if read_ctx:
- while pos < len(l) and (l[pos] != '"' or l[pos - 1] == "\\"):
- msgctx += l[pos]
- pos += 1
-
- # File location.
- location = os.path.relpath(fname).replace("\\", "/")
- if line_nb:
- location += ":" + str(lc)
-
- # Write translator comment.
- _write_translator_comment(msgctx, msg, translator_comment)
+ if not reading_translator_comment:
+ for pattern, is_property_path in message_patterns.items():
+ for m in pattern.finditer(l):
+ location = os.path.relpath(fname).replace("\\", "/")
+ if line_nb:
+ location += ":" + str(lc)
+
+ groups = m.groupdict("")
+ msg = groups.get("message", "")
+ msg_plural = groups.get("plural_message", "")
+ msgctx = groups.get("context", "")
+
+ if is_property_path:
+ for part in msg.split("/"):
+ _add_message(_process_editor_string(part), msg_plural, msgctx, location, translator_comment)
+ else:
+ _add_message(msg, msg_plural, msgctx, location, translator_comment)
translator_comment = ""
- if msgctx != "":
- # If it's a new context or a new message within an existing context, then write new msgid.
- # Else add location to existing msgid.
- if not msgctx in ctx_group:
- _write_message(msgctx, msg, msg_plural, location)
- ctx_group[msgctx] = {msg: [location]}
- elif not msg in ctx_group[msgctx]:
- _write_message(msgctx, msg, msg_plural, location)
- ctx_group[msgctx][msg] = [location]
- elif not location in ctx_group[msgctx][msg]:
- _add_additional_location(msgctx, msg, location)
- ctx_group[msgctx][msg].append(location)
- else:
- if not msg in unique_str:
- _write_message(msgctx, msg, msg_plural, location)
- unique_str.append(msg)
- unique_loc[msg] = [location]
- elif not location in unique_loc[msg]:
- _add_additional_location(msgctx, msg, location)
- unique_loc[msg].append(location)
-
l = f.readline()
lc += 1
+def _add_message(msg, msg_plural, msgctx, location, translator_comment):
+ global main_po, unique_str, unique_loc
+
+ # Write translator comment.
+ _write_translator_comment(msgctx, msg, translator_comment)
+ translator_comment = ""
+
+ if msgctx != "":
+ # If it's a new context or a new message within an existing context, then write new msgid.
+ # Else add location to existing msgid.
+ if not msgctx in ctx_group:
+ _write_message(msgctx, msg, msg_plural, location)
+ ctx_group[msgctx] = {msg: [location]}
+ elif not msg in ctx_group[msgctx]:
+ _write_message(msgctx, msg, msg_plural, location)
+ ctx_group[msgctx][msg] = [location]
+ elif not location in ctx_group[msgctx][msg]:
+ _add_additional_location(msgctx, msg, location)
+ ctx_group[msgctx][msg].append(location)
+ else:
+ if not msg in unique_str:
+ _write_message(msgctx, msg, msg_plural, location)
+ unique_str.append(msg)
+ unique_loc[msg] = [location]
+ elif not location in unique_loc[msg]:
+ _add_additional_location(msgctx, msg, location)
+ unique_loc[msg].append(location)
+
+
print("Updating the editor.pot template...")
for fname in matches: