wmlvalidator, wmlgrammar and wmldata: now it checks translatable lines.
schema.cfg: it was removed type "tstring" and can now be optional parameters
This commit is contained in:
parent
7a04c01dc7
commit
a79de2c35c
5 changed files with 121 additions and 106 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -55,6 +55,9 @@ projectfiles/**/*.layout
|
|||
projectfiles/**/*_build_log.html
|
||||
projectfiles/**/*objs*
|
||||
|
||||
# Itelijei
|
||||
.idea
|
||||
|
||||
# eclipse
|
||||
.settings
|
||||
!utils/umc_dev/org.wesnoth*/.settings/
|
||||
|
|
195
data/schema.cfg
195
data/schema.cfg
|
@ -3,7 +3,6 @@
|
|||
identifier="re ^[a-zA-Z0-9_ ]+$"
|
||||
identifierlist="re ^([a-zA-Z0-9_ ]+,)*[a-zA-Z0-9_ ]+$"
|
||||
string="re ^[\d\w\s]*$"
|
||||
tstring="re ^[\d\w\s]*$"
|
||||
integer="re ^(\+|-)?[0-9]+$"
|
||||
float="re ^(\+|-)?[0-9]+(\.[0-9]*)?$"
|
||||
boolean="enum true,false,yes,no,on,off"
|
||||
|
@ -40,8 +39,8 @@
|
|||
[/description]
|
||||
_entry="repeated entry"
|
||||
|
||||
text="optional tstring"
|
||||
title="optional tstring"
|
||||
text="optional string translatable"
|
||||
title="optional string translatable"
|
||||
[/about]
|
||||
[about-campaign:about]
|
||||
[description]
|
||||
|
@ -58,9 +57,9 @@
|
|||
-type indicates the type of setting, only if is an int do min, max and step have meaning"
|
||||
[/description]
|
||||
default="optional string"
|
||||
description="optional tstring"
|
||||
description="optional string translatable"
|
||||
field="required identifier"
|
||||
name="required tstring"
|
||||
name="required string translatable"
|
||||
type="required about_preference_type"
|
||||
|
||||
min="optional integer"
|
||||
|
@ -71,7 +70,7 @@
|
|||
_aspect="repeated aspect"
|
||||
_stage="repeated stage"
|
||||
|
||||
description="required string" #maybe tstring?
|
||||
description="required string" #maybe string translatable?
|
||||
id="required identifier"
|
||||
version="required integer"
|
||||
[/ai]
|
||||
|
@ -85,9 +84,9 @@
|
|||
[campaign]
|
||||
_about="repeated about-campaign"
|
||||
|
||||
abbrev="required identifier"
|
||||
abbrev="required identifier translatable"
|
||||
define="required identifier" #TODO: maybe require it to be uppercase?
|
||||
description="required tstring"
|
||||
description="required string translatable"
|
||||
difficulties="required string" #TODO: should be a list of identifiers, same maybe as above
|
||||
difficulty_descriptions="required string" #TODO: this one's especially complicated
|
||||
extra_defines="optional string" #TODO: should be a list of identifiers, maybe uppercase?
|
||||
|
@ -95,7 +94,7 @@
|
|||
icon="optional path"
|
||||
id="required string"
|
||||
image="optional path"
|
||||
name="required tstring"
|
||||
name="required string translatable"
|
||||
rank="required integer"
|
||||
[/campaign]
|
||||
[entry]
|
||||
|
@ -227,17 +226,17 @@
|
|||
[race]
|
||||
_trait="repeated trait"
|
||||
|
||||
description="optional tstring"
|
||||
female_name="optional tstring"
|
||||
female_names="optional tstring"
|
||||
description="optional string translatable"
|
||||
female_name="optional string translatable"
|
||||
female_names="optional string translatable"
|
||||
id="required identifier"
|
||||
ignore_global_traits="optional boolean"
|
||||
male_name="optional tstring"
|
||||
male_names="optional tstring"
|
||||
male_name="optional string translatable"
|
||||
male_names="optional string translatable"
|
||||
markov_chain_size="optional integer"
|
||||
name="optional tstring"
|
||||
name="optional string translatable"
|
||||
num_traits="optional integer" # FIXME: are we sure this is optional?
|
||||
plural_name="optional tstring"
|
||||
plural_name="optional string translatable"
|
||||
[/race]
|
||||
[resolution]
|
||||
_label="repeated label-theme"
|
||||
|
@ -262,7 +261,7 @@
|
|||
sections_generator="optional identifier"
|
||||
sort_sections="optional boolean"
|
||||
sort_topics="optional sort_topics_type"
|
||||
title="required tstring"
|
||||
title="required string translatable"
|
||||
topics="optional string" # TODO: list of identifiers
|
||||
[/section]
|
||||
#[terrain_graphics]
|
||||
|
@ -271,89 +270,89 @@
|
|||
# map="optional string"
|
||||
# no_flag="optional string"
|
||||
# probability="
|
||||
#[/terrain_graphics]
|
||||
[textdomain]
|
||||
name="required string"
|
||||
path="optional path" # required for UMC, implicit for mainline
|
||||
[/textdomain]
|
||||
[theme]
|
||||
_partialresolution="repeated partialresolution"
|
||||
_resolution="repeated resolution"
|
||||
#[/terrain_graphics]
|
||||
[textdomain]
|
||||
name="required string"
|
||||
path="optional path" # required for UMC, implicit for mainline
|
||||
[/textdomain]
|
||||
[theme]
|
||||
_partialresolution="repeated partialresolution"
|
||||
_resolution="repeated resolution"
|
||||
|
||||
name="required string"
|
||||
[/theme]
|
||||
[topic]
|
||||
generator="optional string" #TODO: maybe a special kind of identifier
|
||||
id="required string" #TODO: see above
|
||||
text="optional tstring"
|
||||
title="required tstring"
|
||||
[/topic]
|
||||
[toplevel]
|
||||
sections="required string" #TODO: should be list of identifiers
|
||||
topics="required string" #TODO: see above
|
||||
[/toplevel]
|
||||
[units]
|
||||
_movetype="repeated movetype"
|
||||
_race="repeated race"
|
||||
_trait="repeated trait"
|
||||
_unit_type="repeated unit_type"
|
||||
[/units]
|
||||
alignments="enum chaotic,neutral,lawful"
|
||||
[unit_type]
|
||||
_abilities="optional abilities"
|
||||
_advancement="repeated advancement"
|
||||
_animation="repeated animation"
|
||||
#.*_anim
|
||||
#[element]
|
||||
# freq="repeated"
|
||||
# match="re ^[a-z_]+_anim$"
|
||||
# name="animation"
|
||||
#[/element]
|
||||
_attack="repeated attack"
|
||||
_death="repeated animation"
|
||||
_defend="repeated animation"
|
||||
_defense="optional defense"
|
||||
_female="optional female"
|
||||
_male="optional male"
|
||||
_movement_costs="optional movement_costs"
|
||||
_portrait="repeated portrait"
|
||||
_resistance="optional resistance"
|
||||
_trait="repeated trait"
|
||||
_variation="repeated variation"
|
||||
name="required string"
|
||||
[/theme]
|
||||
[topic]
|
||||
generator="optional string" #TODO: maybe a special kind of identifier
|
||||
id="required string" #TODO: see above
|
||||
text="optional string translatable"
|
||||
title="required string translatable"
|
||||
[/topic]
|
||||
[toplevel]
|
||||
sections="required string" #TODO: should be list of identifiers
|
||||
topics="required string" #TODO: see above
|
||||
[/toplevel]
|
||||
[units]
|
||||
_movetype="repeated movetype"
|
||||
_race="repeated race"
|
||||
_trait="repeated trait"
|
||||
_unit_type="repeated unit_type"
|
||||
[/units]
|
||||
alignments="enum chaotic,neutral,lawful"
|
||||
[unit_type]
|
||||
_abilities="optional abilities"
|
||||
_advancement="repeated advancement"
|
||||
_animation="repeated animation"
|
||||
#.*_anim
|
||||
#[element]
|
||||
# freq="repeated"
|
||||
# match="re ^[a-z_]+_anim$"
|
||||
# name="animation"
|
||||
#[/element]
|
||||
_attack="repeated attack"
|
||||
_death="repeated animation"
|
||||
_defend="repeated animation"
|
||||
_defense="optional defense"
|
||||
_female="optional female"
|
||||
_male="optional male"
|
||||
_movement_costs="optional movement_costs"
|
||||
_portrait="repeated portrait"
|
||||
_resistance="optional resistance"
|
||||
_trait="repeated trait"
|
||||
_variation="repeated variation"
|
||||
|
||||
#TODO: make [base_unit] do its job
|
||||
advances_to="optional identifierlist" #should be required
|
||||
alignment="optional alignments" # required
|
||||
cost="optional integer" # required
|
||||
description="optional tstring"
|
||||
die_sound="optional pathlist"
|
||||
do_not_list="optional boolean"
|
||||
ellipse="optional path"
|
||||
experience="optional integer" # required
|
||||
flag_rgb="optional string" # list of integers
|
||||
gender="optional string" # enum male,female
|
||||
halo="optional string" # should be animlist: list of imagepaths with animation length
|
||||
hide_help="optional boolean"
|
||||
hitpoints="optional integer" # required
|
||||
id="required identifier"
|
||||
ignore_race_traits="optional boolean"
|
||||
image="optional path" # required
|
||||
level="optional integer" # required
|
||||
movement="optional integer" # required
|
||||
movement_type="optional identifier" # required
|
||||
name="optional tstring" # required
|
||||
profile="optional path"
|
||||
race="optional identifier" # required
|
||||
undead_variation="optional identifier"
|
||||
usage="optional identifier" # required
|
||||
zoc="optional boolean"
|
||||
[/unit_type]
|
||||
[variation:unit_type]
|
||||
id="forbidden identifier"
|
||||
inherit="optional boolean"
|
||||
variation_name="required identifier"
|
||||
[/variation:unit_type]
|
||||
[/schema]
|
||||
#TODO: make [base_unit] do its job
|
||||
advances_to="optional identifierlist" #should be required
|
||||
alignment="optional alignments" # required
|
||||
cost="optional integer" # required
|
||||
description="optional string translatable"
|
||||
die_sound="optional pathlist"
|
||||
do_not_list="optional boolean"
|
||||
ellipse="optional path"
|
||||
experience="optional integer" # required
|
||||
flag_rgb="optional string" # list of integers
|
||||
gender="optional string" # enum male,female
|
||||
halo="optional string" # should be animlist: list of imagepaths with animation length
|
||||
hide_help="optional boolean"
|
||||
hitpoints="optional integer" # required
|
||||
id="required identifier"
|
||||
ignore_race_traits="optional boolean"
|
||||
image="optional path" # required
|
||||
level="optional integer" # required
|
||||
movement="optional integer" # required
|
||||
movement_type="optional identifier" # required
|
||||
name="optional string translatable" # required
|
||||
profile="optional path"
|
||||
race="optional identifier" # required
|
||||
undead_variation="optional identifier"
|
||||
usage="optional identifier" # required
|
||||
zoc="optional boolean"
|
||||
[/unit_type]
|
||||
[variation:unit_type]
|
||||
id="forbidden identifier"
|
||||
inherit="optional boolean"
|
||||
variation_name="required identifier"
|
||||
[/variation:unit_type]
|
||||
[/schema]
|
||||
|
||||
## Things that still need to be converted, in a similar format.
|
||||
## Note that this is derived from the old wmlgrammar, which was incomplete
|
||||
|
|
|
@ -38,7 +38,9 @@ class Data:
|
|||
pos = indent * " "
|
||||
result = pos + "\ " + magenta + self.name + off + " (" + self.__class__.__name__ + ")"
|
||||
if show_contents:
|
||||
result += "'" + self.get_value() + "'"
|
||||
if self.is_translatable() == True:
|
||||
result += " _"
|
||||
result += " '" + self.get_value() + "'"
|
||||
if write:
|
||||
# The input usually is utf8, but it also may be not - for example
|
||||
# if a .png image is transmitted over WML. As this is only for
|
||||
|
@ -61,6 +63,9 @@ class Data:
|
|||
def get_value(self):
|
||||
return ""
|
||||
|
||||
def is_translatable(self):
|
||||
return False
|
||||
|
||||
def get_type(self):
|
||||
return self.__class__.__name__
|
||||
|
||||
|
@ -87,6 +92,9 @@ class DataText(Data):
|
|||
def set_value(self, data):
|
||||
self.data = data
|
||||
|
||||
def is_translatable(self):
|
||||
return self.translatable
|
||||
|
||||
class DataBinary(Data):
|
||||
"""A binary chunk of WML."""
|
||||
def __init__(self, name, binary):
|
||||
|
|
|
@ -19,7 +19,6 @@ class Grammar(object):
|
|||
"float": re.compile("^(\\+|-)?[0-9]+(\.[0-9]*)?$"),
|
||||
"integer": re.compile("^(\\+|-)?[0-9]+$"),
|
||||
"string": re.compile(".*"),
|
||||
"tstring": re.compile(".*"),
|
||||
}
|
||||
self.elements = {}
|
||||
self.categories = collections.defaultdict(list)
|
||||
|
@ -113,13 +112,14 @@ class ExtElement(Element):
|
|||
|
||||
class Attribute(object):
|
||||
def __init__(self, schema, datatypes):
|
||||
first, second = schema.data.split(" ", 1)
|
||||
if second not in datatypes:
|
||||
raise Exception("Unknown datatype '%s'" % second)
|
||||
parts = schema.data.split(" ")
|
||||
if parts[1] not in datatypes:
|
||||
raise Exception("Unknown datatype '%s'" % parts[1])
|
||||
self.name = schema.name
|
||||
self.freq = parse_frequency(first)
|
||||
self.type = second
|
||||
self.re = datatypes[second]
|
||||
self.freq = parse_frequency(parts[0])
|
||||
self.type = parts[1]
|
||||
self.optionals = parts[2:]
|
||||
self.re = datatypes[parts[1]]
|
||||
|
||||
def match(self, name):
|
||||
return self.name == name
|
||||
|
|
|
@ -47,6 +47,7 @@ class Validator:
|
|||
|
||||
# TODO: the blocks below probably need to be rewritten
|
||||
|
||||
# TODO: Retorno deve ser mostrado em mensagens mais organizadas, como numa tabela
|
||||
# Validate the attributes
|
||||
for attribute in schema.get_attributes():
|
||||
matches = node.get_texts(attribute.name)
|
||||
|
@ -60,6 +61,10 @@ class Validator:
|
|||
for match in matches:
|
||||
if not attribute.validate(match.data):
|
||||
print "(%s:%d) Attribute '[%s] %s's value should be %s, found: %s" % (node.file, node.line, verbosename, attribute.name, attribute.type, match.data)
|
||||
if 'translatable' in attribute.optionals and match.is_translatable() == False:
|
||||
print "(%s:%d) Attribute '[%s] %s's value is translatable, but haven't _ at the beginning" % (node.file, node.line, verbosename, attribute.name)
|
||||
elif 'translatable' not in attribute.optionals and match.is_translatable() == True:
|
||||
print "(%s:%d) Attribute '[%s] %s's value isn't translatable, but have a _ at the beginning" % (node.file, node.line, verbosename, attribute.name)
|
||||
node.remove(match) # Get rid of these so we can see what's left
|
||||
for attribute in node.get_all_text():
|
||||
print "(%s:%d) Attribute '[%s] %s' found, which has no meaning there" % (node.file, node.line, verbosename, attribute.name)
|
||||
|
|
Loading…
Add table
Reference in a new issue