[voltLib] parse substitution as single, multiple or ligature sub

This commit is contained in:
moyogo 2016-02-10 14:35:59 +00:00
parent c564b31f47
commit e93f7384a5
3 changed files with 66 additions and 1 deletions

View File

@ -81,6 +81,21 @@ class SubstitutionDefinition(ast.Statement):
self.mapping = zip(src, dest)
class SubstitutionSingleDefinition(SubstitutionDefinition):
def __init__(self, location, src, dest):
SubstitutionDefinition.__init__(self, location, src, dest)
class SubstitutionMultipleDefinition(SubstitutionDefinition):
def __init__(self, location, src, dest):
SubstitutionDefinition.__init__(self, location, src, dest)
class SubstitutionLigatureDefinition(SubstitutionDefinition):
def __init__(self, location, src, dest):
SubstitutionDefinition.__init__(self, location, src, dest)
class PositionAttachDefinition(ast.Statement):
def __init__(self, location, coverage, coverage_to):
ast.Statement.__init__(self, location)

View File

@ -288,7 +288,22 @@ class Parser(object):
dest.append(self.parse_coverage_())
self.expect_keyword_("END_SUB")
self.expect_keyword_("END_SUBSTITUTION")
sub = ast.SubstitutionDefinition(location, src, dest)
max_src = max([len(cov) for cov in src])
max_dest = max([len(cov) for cov in dest])
# many to many or mixed is invalid
if (max_src > 1 and max_dest > 1):
raise VoltLibError(
"Invalid substitution type",
location)
elif (max_src == 1 and
max_dest == 1):
sub = ast.SubstitutionSingleDefinition(location, src, dest)
elif (max_src == 1 and
max_dest > 1):
sub = ast.SubstitutionMultipleDefinition(location, src, dest)
elif (max_src > 1 and
max_dest == 1):
sub = ast.SubstitutionLigatureDefinition(location, src, dest)
return sub
def parse_position_(self):

View File

@ -443,6 +443,41 @@ class ParserTest(unittest.TestCase):
'END_SUBSTITUTION'
).statements
def test_substitution_invalid_many_to_many(self):
with self.assertRaisesRegex(
VoltLibError,
r'Invalid substitution type'):
[lookup] = self.parse(
'DEF_LOOKUP "invalid_substitution" PROCESS_BASE PROCESS_MARKS '
'ALL DIRECTION LTR\n'
'IN_CONTEXT\n'
'END_CONTEXT\n'
'AS_SUBSTITUTION\n'
'SUB GLYPH "f" GLYPH "i"\n'
'WITH GLYPH "f.alt" GLYPH "i.alt"\n'
'END_SUB\n'
'END_SUBSTITUTION'
).statements
def test_substitution_invalid_mixed(self):
with self.assertRaisesRegex(
VoltLibError,
r'Invalid substitution type'):
[lookup] = self.parse(
'DEF_LOOKUP "invalid_substitution" PROCESS_BASE PROCESS_MARKS '
'ALL DIRECTION LTR\n'
'IN_CONTEXT\n'
'END_CONTEXT\n'
'AS_SUBSTITUTION\n'
'SUB GLYPH "fi"\n'
'WITH GLYPH "f" GLYPH "i"\n'
'END_SUB\n'
'SUB GLYPH "f" GLYPH "l"\n'
'WITH GLYPH "f_l"\n'
'END_SUB\n'
'END_SUBSTITUTION'
).statements
def test_substitution_single(self):
[lookup] = self.parse(
'DEF_LOOKUP "smcp" PROCESS_BASE PROCESS_MARKS ALL '