map gettext strings to keys/modules for ftl conversion
This commit is contained in:
parent
49f363e6ab
commit
44489a480f
@ -103,14 +103,6 @@ def newCardSchedulingLabels() -> Dict[int, Any]:
|
||||
}
|
||||
|
||||
|
||||
def alignmentLabels() -> Dict[int, Any]:
|
||||
return {
|
||||
0: _("Center"),
|
||||
1: _("Left"),
|
||||
2: _("Right"),
|
||||
}
|
||||
|
||||
|
||||
def dynOrderLabels() -> Dict[int, Any]:
|
||||
return {
|
||||
0: _("Oldest seen first"),
|
||||
|
@ -4,6 +4,8 @@
|
||||
import os
|
||||
import json
|
||||
import polib
|
||||
import pprint
|
||||
import re
|
||||
|
||||
# Read strings from all .po and .pot files and store them in a JSON file
|
||||
# for quick access.
|
||||
@ -30,20 +32,251 @@ def get_msgstr(entry):
|
||||
return adjusted[0]
|
||||
return None
|
||||
|
||||
|
||||
module_map = {
|
||||
"__init__": "qt-misc",
|
||||
"about": "about",
|
||||
"addcards": "adding",
|
||||
"addfield": "fields",
|
||||
"addmodel": "notetypes",
|
||||
"addonconf": "addons",
|
||||
"addons": "addons",
|
||||
"anki2": "importing",
|
||||
"browser": "browsing",
|
||||
"browserdisp": "browsing",
|
||||
"browseropts": "browsing",
|
||||
"changemap": "browsing",
|
||||
"changemodel": "browsing",
|
||||
"clayout_top": "card-templates",
|
||||
"clayout": "card-templates",
|
||||
"collection": "collection",
|
||||
"consts": "consts",
|
||||
"csvfile": "importing",
|
||||
"customstudy": "custom-study",
|
||||
"dconf": "scheduling",
|
||||
"debug": "qt-misc",
|
||||
"deckbrowser": "decks",
|
||||
"deckchooser": "qt-misc",
|
||||
"deckconf": "scheduling",
|
||||
"decks": "decks",
|
||||
"dyndconf": "decks",
|
||||
"dyndeckconf": "decks",
|
||||
"editaddon": "addons",
|
||||
"editcurrent": "editing",
|
||||
"edithtml": "editing",
|
||||
"editor": "editing",
|
||||
"errors": "qt-misc",
|
||||
"exporting": "exporting",
|
||||
"fields": "fields",
|
||||
"finddupes": "browsing",
|
||||
"findreplace": "browsing",
|
||||
"getaddons": "addons",
|
||||
"importing": "importing",
|
||||
"latex": "media",
|
||||
"main": "qt-misc",
|
||||
"mnemo": "importing",
|
||||
"modelchooser": "qt-misc",
|
||||
"modelopts": "notetypes",
|
||||
"models": "notetypes",
|
||||
"noteimp": "importing",
|
||||
"overview": "studying",
|
||||
"preferences": "preferences",
|
||||
"previewer": "qt-misc",
|
||||
"profiles": "profiles",
|
||||
"progress": "qt-misc",
|
||||
"reposition": "browsing",
|
||||
"reschedule": "browsing",
|
||||
"reviewer": "studying",
|
||||
"schedv2": "scheduling",
|
||||
"setgroup": "browsing",
|
||||
"setlang": "preferences",
|
||||
"sidebar": "browsing",
|
||||
"sound": "media",
|
||||
"studydeck": "decks",
|
||||
"taglimit": "custom-study",
|
||||
"template": "card-templates",
|
||||
"toolbar": "qt-misc",
|
||||
"update": "qt-misc",
|
||||
"utils": "qt-misc",
|
||||
"webview": "qt-misc",
|
||||
"stats": "stats",
|
||||
}
|
||||
|
||||
text_remap = {
|
||||
"actions": [
|
||||
"Add",
|
||||
"Cancel",
|
||||
"Choose",
|
||||
"Close",
|
||||
"Copy",
|
||||
"Decks",
|
||||
"Delete",
|
||||
"Export",
|
||||
"Filter",
|
||||
"Help",
|
||||
"Import",
|
||||
"Manage...",
|
||||
"Name:",
|
||||
"New name:",
|
||||
"New",
|
||||
"Options for %s",
|
||||
"Options",
|
||||
"Preview",
|
||||
"Rebuild",
|
||||
"Rename Deck",
|
||||
"Rename",
|
||||
"Replay Audio",
|
||||
"Reposition",
|
||||
"Save",
|
||||
"Search",
|
||||
"Shortcut key: %s",
|
||||
"Suspend Card",
|
||||
"Blue Flag",
|
||||
"Green Flag",
|
||||
"Orange Flag",
|
||||
"Red Flag",
|
||||
"Custom Study",
|
||||
],
|
||||
"decks": [
|
||||
"Deck",
|
||||
"New deck name:",
|
||||
"Decreasing intervals",
|
||||
"Increasing intervals",
|
||||
"Latest added first",
|
||||
"Most lapses",
|
||||
"Oldest seen first",
|
||||
"Order added",
|
||||
"Order due",
|
||||
"Random",
|
||||
"Relative overdueness",
|
||||
],
|
||||
"scheduling": [
|
||||
"days",
|
||||
"Lapses",
|
||||
"Reviews",
|
||||
"At least one step is required.",
|
||||
"Steps must be numbers.",
|
||||
"Show new cards in order added",
|
||||
"Show new cards in random order",
|
||||
"Show new cards after reviews",
|
||||
"Show new cards before reviews",
|
||||
"Mix new cards and reviews",
|
||||
"Learning",
|
||||
"Review",
|
||||
],
|
||||
"fields": ["Add Field"],
|
||||
"editing": ["Tags", "Cards", "Fields", "LaTeX"],
|
||||
"notetypes": ["Type", "Note Types"],
|
||||
"studying": ["Space"],
|
||||
"qt-misc": ["&Edit", "&Guide...", "&Help", "&Undo", "Unexpected response code: %s"],
|
||||
"adding": ["Added"],
|
||||
}
|
||||
|
||||
blacklist = {"Anki", "%", "Dialog", "Center", "Left", "Right", "~", "&Cram..."}
|
||||
|
||||
|
||||
def determine_module(text, files):
|
||||
if text in blacklist:
|
||||
return None
|
||||
|
||||
if "&" in text:
|
||||
return "qt-accel"
|
||||
|
||||
for (module, texts) in text_remap.items():
|
||||
if text in texts:
|
||||
return module
|
||||
|
||||
if len(files) == 1:
|
||||
return list(files)[0]
|
||||
|
||||
assert False
|
||||
|
||||
|
||||
modules = dict()
|
||||
|
||||
remap_keys = {"browsing-": "browsing-type-here-to-search"}
|
||||
|
||||
|
||||
def generate_key(module: str, text: str) -> str:
|
||||
key = re.sub("<.*?>", "", text)
|
||||
key = re.sub("%[dsf.0-9]+", "", key)
|
||||
key = key.replace("+", "and")
|
||||
key = re.sub("[^a-z0-9 ]", "", key.lower())
|
||||
words = key.split(" ")
|
||||
if len(words) > 6:
|
||||
words = words[:6]
|
||||
key = "-".join(words)
|
||||
key = re.sub("--+", "-", key)
|
||||
key = re.sub("-$|^-", "", key)
|
||||
|
||||
key = f"{module}-{key}"
|
||||
|
||||
if key in remap_keys:
|
||||
key = remap_keys[key]
|
||||
|
||||
return key
|
||||
|
||||
|
||||
seen_keys = set()
|
||||
|
||||
|
||||
def migrate_entry(entry):
|
||||
if entry.msgid_plural:
|
||||
# print("skip plural", entry.msgid)
|
||||
return
|
||||
|
||||
text = entry.msgid
|
||||
files = set(
|
||||
[os.path.splitext(os.path.basename(e[0]))[0] for e in entry.occurrences]
|
||||
)
|
||||
# drop translations only used by old graphs
|
||||
if len(files) == 1 and "stats" in files:
|
||||
return None
|
||||
|
||||
files2 = set()
|
||||
for file in files:
|
||||
if file == "stats":
|
||||
continue
|
||||
file = module_map[file]
|
||||
files2.add(file)
|
||||
module = determine_module(text, files2)
|
||||
if not module:
|
||||
return
|
||||
|
||||
key = generate_key(module, text)
|
||||
|
||||
if key in seen_keys:
|
||||
key += "2"
|
||||
assert key not in seen_keys
|
||||
seen_keys.add(key)
|
||||
|
||||
modules.setdefault(module, [])
|
||||
modules[module].append((key, text))
|
||||
|
||||
return None
|
||||
|
||||
|
||||
langs = {}
|
||||
|
||||
# .pot first
|
||||
base = "repo/desktop"
|
||||
base = "../../../anki-i18n/qtpo/desktop"
|
||||
pot = os.path.join(base, "anki.pot")
|
||||
pot_cat = polib.pofile(pot)
|
||||
|
||||
migration_map = []
|
||||
|
||||
for entry in pot_cat:
|
||||
if entry.msgid_plural:
|
||||
msgstr = [entry.msgid, entry.msgid_plural]
|
||||
else:
|
||||
msgstr = entry.msgid
|
||||
|
||||
langs.setdefault("en", {})[entry.msgid] = msgstr
|
||||
|
||||
if d := migrate_entry(entry):
|
||||
migration_map.append(d)
|
||||
|
||||
|
||||
# then .po files
|
||||
folders = (d for d in os.listdir(base) if d != "anki.pot")
|
||||
for lang in folders:
|
||||
@ -58,3 +291,19 @@ for lang in folders:
|
||||
with open("strings.json", "w") as file:
|
||||
file.write(json.dumps(langs))
|
||||
print("wrote to strings.json")
|
||||
|
||||
# old text -> (module, new key)
|
||||
strings_by_module = {}
|
||||
keys_by_text = {}
|
||||
for (module, items) in modules.items():
|
||||
items.sort()
|
||||
strings_by_module[module] = items
|
||||
for item in items:
|
||||
(key, text) = item
|
||||
assert text not in keys_by_text
|
||||
keys_by_text[text] = (module, key)
|
||||
|
||||
with open("strings_by_module.json", "w") as file:
|
||||
file.write(json.dumps(strings_by_module))
|
||||
with open("keys_by_text.json", "w") as file:
|
||||
file.write(json.dumps(keys_by_text))
|
||||
|
Loading…
Reference in New Issue
Block a user