1
0
forked from 0ad/0ad

Allow more general contexts in json translatable strings

While at it fix the messages.json from ea72437739 (missing excludeMask
and make the keywords objects not arrays)
Comments By: Freagarach
Differential Revision: D4483
This was SVN commit r26422.
This commit is contained in:
bb 2022-02-19 17:21:23 +00:00
parent e2bf494cf9
commit 0f07c368ed
2 changed files with 188 additions and 116 deletions

View File

@ -11,10 +11,13 @@
"simulation/data/civs/**.json"
],
"options": {
"keywords": [
"Special",
"AINames"
]
"keywords": {
"Name": {},
"Description": {},
"History": {},
"Special": {},
"AINames": {}
}
}
},
{
@ -23,10 +26,10 @@
"simulation/templates/special/players/**.xml"
],
"options": {
"keywords": [
"GenericName",
"History"
]
"keywords": {
"GenericName": {},
"History": {}
}
}
}
]
@ -299,10 +302,10 @@
"campaigns/**.json"
],
"options": {
"keywords": [
"Name",
"Description"
],
"keywords": {
"Name": {},
"Description": {}
},
"context": "Campaign Template"
}
}
@ -382,10 +385,10 @@
"gui/credits/texts/**.json"
],
"options": {
"keywords": [
"Title",
"Subtitle"
]
"keywords": {
"Title": {},
"Subtitle": {}
}
}
},
{
@ -394,10 +397,10 @@
"gui/hotkeys/spec/**.json"
],
"options": {
"keywords": [
"name",
"desc"
],
"keywords": {
"name": {},
"desc": {}
},
"context": "hotkey metadata"
}
},
@ -407,10 +410,10 @@
"gui/options/**.json"
],
"options": {
"keywords": [
"label",
"tooltip"
]
"keywords": {
"label": {},
"tooltip": {}
}
}
},
{
@ -419,9 +422,9 @@
"simulation/data/resources/**.json"
],
"options": {
"keywords": [
"description"
]
"keywords": {
"description": {}
}
}
},
{
@ -430,10 +433,12 @@
"simulation/data/resources/**.json"
],
"options": {
"keywords": [
"name",
"subtypes"
],
"keywords": {
"name": {},
"subtypes": {
"extractFromInnerKeys": true
}
},
"comments": [
"Translation: Word as used at the beginning of a sentence or as a single-word sentence."
],
@ -446,10 +451,12 @@
"simulation/data/resources/**.json"
],
"options": {
"keywords": [
"name",
"subtypes"
],
"keywords": {
"name": {},
"subtypes": {
"extractFromInnerKeys": true
}
},
"comments": [
"Translation: Word as used in the middle of a sentence (which may require using lowercase for your language)."
],
@ -570,6 +577,7 @@
"simulation/templates/**.xml"
],
"excludeMasks": [
"simulation/templates/special/players/**.xml",
"simulation/templates/structures/**.xml",
"simulation/templates/template_structure_*.xml",
"simulation/templates/template_unit_*.xml",
@ -603,10 +611,10 @@
"simulation/data/damage_types/*.json"
],
"options": {
"keywords": [
"name",
"description"
],
"keywords": {
"name": {},
"description": {}
},
"context": "damage type"
}
},
@ -616,11 +624,11 @@
"simulation/data/status_effects/*.json"
],
"options": {
"keywords": [
"statusName",
"applierTooltip",
"receiverTooltip"
],
"keywords": {
"statusName": {},
"applierTooltip": {},
"receiverTooltip": {}
},
"context": "status effect"
}
},
@ -630,10 +638,10 @@
"simulation/data/attack_effects/*.json"
],
"options": {
"keywords": [
"name",
"description"
],
"keywords": {
"name": {},
"description": {}
},
"context": "effect caused by an attack"
}
}
@ -651,10 +659,10 @@
"simulation/data/auras/**.json"
],
"options": {
"keywords": [
"auraName",
"auraDescription"
]
"keywords": {
"auraName": {},
"auraDescription": {}
}
}
}
]
@ -671,13 +679,15 @@
"simulation/data/technologies/**.json"
],
"options": {
"keywords": [
"specificName",
"genericName",
"description",
"tooltip",
"requirementsTooltip"
]
"keywords": {
"specificName": {
"extractFromInnerKeys": true
},
"genericName": {},
"description": {},
"tooltip": {},
"requirementsTooltip": {}
}
}
}
]
@ -717,9 +727,9 @@
"simulation/data/settings/player_defaults.json"
],
"options": {
"keywords": [
"Name"
]
"keywords": {
"Name": {}
}
}
},
{
@ -728,7 +738,9 @@
"simulation/data/settings/game_speeds.json"
],
"options": {
"keywords": ["Title"]
"keywords": {
"Title": {}
}
}
},
{
@ -737,7 +749,10 @@
"simulation/data/settings/victory_conditions/*.json"
],
"options": {
"keywords": ["Title", "Description"]
"keywords": {
"Title": {},
"Description": {}
}
}
},
{
@ -746,7 +761,9 @@
"simulation/data/settings/starting_resources.json"
],
"options": {
"keywords": ["Title"],
"keywords": {
"Title": {}
},
"context": "startingResources"
}
},
@ -756,7 +773,10 @@
"simulation/data/settings/trigger_difficulties.json"
],
"options": {
"keywords": ["Title", "Tooltip"]
"keywords": {
"Title": {},
"Tooltip": {}
}
}
},
{
@ -765,10 +785,10 @@
"simulation/data/settings/map_sizes.json"
],
"options": {
"keywords": [
"Name",
"Tooltip"
]
"keywords": {
"Name": {},
"Tooltip": {}
}
}
},
{
@ -777,10 +797,10 @@
"simulation/ai/**.json"
],
"options": {
"keywords": [
"name",
"description"
]
"keywords": {
"name": {},
"description": {}
}
}
}
]
@ -802,10 +822,10 @@
]
},
"options": {
"keywords": [
"Name",
"Description"
]
"keywords": {
"Name": {},
"Description": {}
}
}
},
{
@ -838,10 +858,14 @@
"keywords": {
"ScriptSettings": {
"extractJson": {
"keywords": [
"Name",
"Description"
]
"keywords": {
"Name": {
"extractFromInnerKeys": true
},
"Description": {
"extractFromInnerKeys": true
}
}
}
}
}
@ -853,7 +877,11 @@
"maps/random/rmbiome/**.json"
],
"options": {
"keywords": ["Description"],
"keywords": {
"Description": {
"extractFromInnerKeys": true
}
},
"context": "biome definition"
}
}
@ -891,10 +919,10 @@
"keywords": {
"ScriptSettings": {
"extractJson": {
"keywords": [
"Name",
"Description"
]
"keywords": {
"Name": {},
"Description": {}
}
}
}
}

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
# Copyright (C) 2020 Wildfire Games.
# Copyright (C) 2022 Wildfire Games.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
@ -326,20 +326,20 @@ class json(Extractor):
def extractFromFile(self, filepath):
with codecs.open(filepath, "r", 'utf-8') as fileObject:
for message, breadcrumbs in self.extractFromString(fileObject.read()):
yield message, None, self.context, self.formatBreadcrumbs(breadcrumbs), None, self.comments
for message, context, breadcrumbs in self.extractFromString(fileObject.read()):
yield message, None, context, self.formatBreadcrumbs(breadcrumbs), None, self.comments
def extractFromString(self, string):
self.breadcrumbs = []
jsonDocument = jsonParser.loads(string)
if isinstance(jsonDocument, list):
for message, breadcrumbs in self.parseList(jsonDocument):
for message, context, breadcrumbs in self.parseList(jsonDocument):
if message: # Skip empty strings.
yield message, breadcrumbs
yield message, context, breadcrumbs
elif isinstance(jsonDocument, dict):
for message, breadcrumbs in self.parseDictionary(jsonDocument):
for message, context, breadcrumbs in self.parseDictionary(jsonDocument):
if message: # Skip empty strings.
yield message, breadcrumbs
yield message, context, breadcrumbs
else:
raise Exception("Unexpected JSON document parent structure (not a list or a dictionary). You must extend the JSON extractor to support it.")
@ -348,11 +348,11 @@ class json(Extractor):
for listItem in itemsList:
self.breadcrumbs.append(index)
if isinstance(listItem, list):
for message, breadcrumbs in self.parseList(listItem):
yield message, breadcrumbs
for message, context, breadcrumbs in self.parseList(listItem):
yield message, context, breadcrumbs
elif isinstance(listItem, dict):
for message, breadcrumbs in self.parseDictionary(listItem):
yield message, breadcrumbs
for message, context, breadcrumbs in self.parseDictionary(listItem):
yield message, context, breadcrumbs
del self.breadcrumbs[-1]
index += 1
@ -361,35 +361,79 @@ class json(Extractor):
self.breadcrumbs.append(keyword)
if keyword in self.keywords:
if isinstance(dictionary[keyword], str):
yield dictionary[keyword], self.breadcrumbs
yield self.extractString(dictionary[keyword], keyword)
elif isinstance(dictionary[keyword], list):
for message, breadcrumbs in self.extractList(dictionary[keyword]):
yield message, breadcrumbs
for message, context, breadcrumbs in self.extractList(dictionary[keyword], keyword):
yield message, context, breadcrumbs
elif isinstance(dictionary[keyword], dict):
for message, breadcrumbs in self.extractDictionary(dictionary[keyword]):
yield message, breadcrumbs
extract = None
if "extractFromInnerKeys" in self.keywords[keyword] and self.keywords[keyword]["extractFromInnerKeys"]:
for message, context, breadcrumbs in self.extractDictionaryInnerKeys(dictionary[keyword], keyword):
yield message, context, breadcrumbs
else:
extract = self.extractDictionary(dictionary[keyword], keyword)
if extract:
yield extract
elif isinstance(dictionary[keyword], list):
for message, breadcrumbs in self.parseList(dictionary[keyword]):
yield message, breadcrumbs
for message, context, breadcrumbs in self.parseList(dictionary[keyword]):
yield message, context, breadcrumbs
elif isinstance(dictionary[keyword], dict):
for message, breadcrumbs in self.parseDictionary(dictionary[keyword]):
yield message, breadcrumbs
for message, context, breadcrumbs in self.parseDictionary(dictionary[keyword]):
yield message, context, breadcrumbs
del self.breadcrumbs[-1]
def extractList(self, itemsList):
def extractString(self, string, keyword):
context = None
if "tagAsContext" in self.keywords[keyword]:
context = keyword
elif "customContext" in self.keywords[keyword]:
context = self.keywords[keyword]["customContext"]
else:
context = self.context
return string, context, self.breadcrumbs
def extractList(self, itemsList, keyword):
index = 0
for listItem in itemsList:
self.breadcrumbs.append(index)
if isinstance(listItem, str):
yield listItem, self.breadcrumbs
yield self.extractString(listItem, keyword)
elif isinstance(listItem, dict):
extract = self.extractDictionary(dictionary[keyword], keyword)
if extract:
yield extract
del self.breadcrumbs[-1]
index += 1
def extractDictionary(self, dictionary):
for keyword in dictionary:
self.breadcrumbs.append(keyword)
if isinstance(dictionary[keyword], str):
yield dictionary[keyword], self.breadcrumbs
def extractDictionary(self, dictionary, keyword):
message = dictionary.get("_string", None)
self.breadcrumbs.append("_string")
if message and isinstance(message, str):
context = None
if "context" in dictionary:
context = str(dictionary["context"])
elif "tagAsContext" in self.keywords[keyword]:
context = keyword
elif "customContext" in self.keywords[keyword]:
context = self.keywords[keyword]["customContext"]
else:
context = self.context
return message, context, self.breadcrumbs
del self.breadcrumbs[-1]
return None
def extractDictionaryInnerKeys(self, dictionary, keyword):
for innerKeyword in dictionary:
self.breadcrumbs.append(innerKeyword)
if isinstance(dictionary[innerKeyword], str):
yield self.extractString(dictionary[innerKeyword], keyword)
elif isinstance(dictionary[innerKeyword], list):
for message, context, breadcrumbs in self.extractList(dictionary[innerKeyword], keyword):
yield message, context, breadcrumbs
elif isinstance(dictionary[innerKeyword], dict):
extract = self.extractDictionary(dictionary[innerKeyword], keyword)
if extract:
yield extract
del self.breadcrumbs[-1]
@ -416,14 +460,14 @@ class xml(Extractor):
for element in xmlDocument.iter(keyword):
position = element.sourceline
if element.text is not None:
context = None
comments = []
if "extractJson" in self.keywords[keyword]:
jsonExtractor = self.getJsonExtractor()
jsonExtractor.setOptions(self.keywords[keyword]["extractJson"])
for message, breadcrumbs in jsonExtractor.extractFromString(element.text):
for message, context, breadcrumbs in jsonExtractor.extractFromString(element.text):
yield message, None, context, json.formatBreadcrumbs(breadcrumbs), position, comments
else:
context = None
breadcrumb = None
if "locationAttributes" in self.keywords[keyword]:
attributes = [element.get(attribute) for attribute in self.keywords[keyword]["locationAttributes"] if attribute in element.attrib]