From e93f7384a52cbd8fd1776f88fd1201902be6aecc Mon Sep 17 00:00:00 2001 From: moyogo Date: Wed, 10 Feb 2016 14:35:59 +0000 Subject: [PATCH] [voltLib] parse substitution as single, multiple or ligature sub --- Lib/fontTools/voltLib/ast.py | 15 ++++++++++++ Lib/fontTools/voltLib/parser.py | 17 +++++++++++++- Lib/fontTools/voltLib/parser_test.py | 35 ++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/Lib/fontTools/voltLib/ast.py b/Lib/fontTools/voltLib/ast.py index 4210ce4ba..097e418e1 100644 --- a/Lib/fontTools/voltLib/ast.py +++ b/Lib/fontTools/voltLib/ast.py @@ -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) diff --git a/Lib/fontTools/voltLib/parser.py b/Lib/fontTools/voltLib/parser.py index 193a24cf0..f7738fc82 100644 --- a/Lib/fontTools/voltLib/parser.py +++ b/Lib/fontTools/voltLib/parser.py @@ -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): diff --git a/Lib/fontTools/voltLib/parser_test.py b/Lib/fontTools/voltLib/parser_test.py index e4b87918a..fcc2d77a7 100644 --- a/Lib/fontTools/voltLib/parser_test.py +++ b/Lib/fontTools/voltLib/parser_test.py @@ -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 '