Validate the groups.

git-svn-id: http://svn.robofab.com/branches/ufo3k@362 b5fa9d6c-a76f-4ffd-b3cb-f825fc41095c
This commit is contained in:
Tal Leming 2011-10-03 15:17:31 +00:00
parent 1ef1e295c9
commit a829b0dc72
2 changed files with 92 additions and 26 deletions

View File

@ -126,11 +126,23 @@ class UFOReader(object):
if testGroups != self._upConvertedKerningData["originalGroups"]:
raise UFOLibError("The data in groups.plist has been modified since it was converted to UFO 3 format.")
else:
groups = self._readGroups()
invalidFormatMessage = "groups.plist is not properly formatted."
if not isinstance(data, dict):
raise UFOLibError(invalidFormatMessage)
for groupName, glyphList in data.items():
if not isinstance(groupName, basestring):
raise UFOLibError(invalidFormatMessage)
elif not isinstance(glyphList, list):
raise UFOLibError(invalidFormatMessage)
for glyphName in glyphList:
if not isinstance(glyphName, basestring):
raise UFOLibError(invalidFormatMessage)
self._upConvertedKerningData = dict(
kerning={},
originalKerning=self._readKerning(),
groups={},
originalGroups=self._readGroups()
originalGroups=groups
)
# convert kerning and groups
kerning, groups = convertUFO1OrUFO2KerningToUFO3Kerning(
@ -223,17 +235,6 @@ class UFOReader(object):
if not self._checkForFile(path):
return {}
data = self._readPlist(path)
invalidFormatMessage = "groups.plist is not properly formatted."
if not isinstance(data, dict):
raise UFOLibError(invalidFormatMessage)
for groupName, glyphList in data.items():
if not isinstance(groupName, basestring):
raise UFOLibError(invalidFormatMessage)
elif not isinstance(glyphList, list):
raise UFOLibError(invalidFormatMessage)
for glyphName in glyphList:
if not isinstance(glyphName, basestring):
raise UFOLibError(invalidFormatMessage)
return data
def readGroups(self):
@ -243,10 +244,14 @@ class UFOReader(object):
# handle up conversion
if self._formatVersion < 3:
self._upConvertKerning()
return self._upConvertedKerningData["groups"]
groups = self._upConvertedKerningData["groups"]
# normal
else:
return self._readGroups()
groups = self._readGroups()
valid, message = validateGroups(groups)
if not valid:
raise UFOLibError(message)
return groups
# fontinfo.plist
@ -714,17 +719,9 @@ class UFOWriter(object):
Write groups.plist. This method requires a
dict of glyph groups as an argument.
"""
invalidFormatMessage = "The groups are not properly formatted."
if not isinstance(groups, dict):
raise UFOLibError(invalidFormatMessage)
for groupName, glyphList in groups.items():
if not isinstance(groupName, basestring):
raise UFOLibError(invalidFormatMessage)
if not isinstance(glyphList, list):
raise UFOLibError(invalidFormatMessage)
for glyphName in glyphList:
if not isinstance(glyphName, basestring):
raise UFOLibError(invalidFormatMessage)
valid, message = validateGroups(groups)
if not valid:
raise UFOLibError(message)
self._makeDirectory()
path = os.path.join(self._path, GROUPS_FILENAME)
groupsNew = {}

View File

@ -673,7 +673,6 @@ def imageValidator(value):
return False
return True
# -------------------
# layercontents.plist
# -------------------
@ -732,6 +731,76 @@ def layerContentsValidator(value, ufoPath):
return False, "The required default glyph set is not in the UFO."
return True, None
# ------------
# groups.plist
# ------------
def validateGroups(value):
"""
>>> groups = {"A" : ["A", "A"], "A2" : ["A"]}
>>> validateGroups(groups)
(True, None)
>>> groups = {"" : ["A"]}
>>> validateGroups(groups)
(False, 'A group has an empty name.')
>>> groups = {"public.awesome" : ["A"]}
>>> validateGroups(groups)
(False, 'The group data contains a group with an illegal public.* group name.')
>>> groups = {"public.kern1." : ["A"]}
>>> validateGroups(groups)
(False, 'The group data contains a kerning group with an incomplete name.')
>>> groups = {"public.kern2." : ["A"]}
>>> validateGroups(groups)
(False, 'The group data contains a kerning group with an incomplete name.')
>>> groups = {"public.kern1.A" : ["A"], "public.kern2.A" : ["A"]}
>>> validateGroups(groups)
(True, None)
>>> groups = {"public.kern1.A1" : ["A"], "public.kern1.A2" : ["A"]}
>>> validateGroups(groups)
(False, 'The glyph "A" occurs in too many kerning groups.')
"""
bogusFormatMessage = "The group data is not in the correct format."
if not isinstance(value, dict):
return False, bogusFormatMessage
firstSideMapping = {}
secondSideMapping = {}
for groupName, glyphList in value.items():
if not isinstance(groupName, basestring):
return False, bogusFormatMessage
if not isinstance(glyphList, (list, tuple)):
return False, bogusFormatMessage
if not groupName:
return False, "A group has an empty name."
if groupName.startswith("public."):
if not groupName.startswith("public.kern1.") and not groupName.startswith("public.kern2."):
return False, "The group data contains a group with an illegal public.* group name."
else:
if len("public.kernN.") == len(groupName):
return False, "The group data contains a kerning group with an incomplete name."
if groupName.startswith("public.kern1."):
d = firstSideMapping
else:
d = secondSideMapping
for glyphName in glyphList:
if not isinstance(glyphName, basestring):
return False, "The group data %s contains an invalid member." % groupName
if glyphName in d:
return False, "The glyph \"%s\" occurs in too many kerning groups." % glyphName
d[glyphName] = groupName
return True, None
# -------------
# lib.plist/lib
# -------------
if __name__ == "__main__":
import doctest
doctest.testmod()