[feaLib] Clean up class names of Abstract Syntax Tree statements
The class names of tree nodes for substitution and positioning rules are now consistent with `builder.py`, which in turn is consistent with `otTables.py`.
This commit is contained in:
parent
5b1b1d17f6
commit
d622f99982
@ -80,14 +80,13 @@ class MarkClassDefinition(object):
|
||||
self.glyphLocations = {} # glyph --> (filepath, line, column)
|
||||
|
||||
|
||||
class AlternateSubstitution(Statement):
|
||||
class AlternateSubstStatement(Statement):
|
||||
def __init__(self, location, glyph, from_class):
|
||||
Statement.__init__(self, location)
|
||||
self.glyph, self.from_class = (glyph, from_class)
|
||||
|
||||
def build(self, builder):
|
||||
builder.add_alternate_substitution(self.location, self.glyph,
|
||||
self.from_class)
|
||||
builder.add_alternate_subst(self.location, self.glyph, self.from_class)
|
||||
|
||||
|
||||
class Anchor(Expression):
|
||||
@ -104,7 +103,19 @@ class AnchorDefinition(Statement):
|
||||
self.name, self.x, self.y, self.contourpoint = name, x, y, contourpoint
|
||||
|
||||
|
||||
class CursiveAttachmentPositioning(Statement):
|
||||
class ChainContextSubstStatement(Statement):
|
||||
def __init__(self, location, old_prefix, old, old_suffix, lookups):
|
||||
Statement.__init__(self, location)
|
||||
self.old, self.lookups = old, lookups
|
||||
self.old_prefix, self.old_suffix = old_prefix, old_suffix
|
||||
|
||||
def build(self, builder):
|
||||
builder.add_chain_context_subst(
|
||||
self.location, self.old_prefix, self.old, self.old_suffix,
|
||||
self.lookups)
|
||||
|
||||
|
||||
class CursivePosStatement(Statement):
|
||||
def __init__(self, location, glyphclass, entryAnchor, exitAnchor):
|
||||
Statement.__init__(self, location)
|
||||
self.glyphclass = glyphclass
|
||||
@ -144,7 +155,7 @@ class IgnoreSubstitutionRule(Statement):
|
||||
self.prefix, self.glyphs, self.suffix = (prefix, glyphs, suffix)
|
||||
|
||||
|
||||
class LigatureSubstitution(Statement):
|
||||
class LigatureSubstStatement(Statement):
|
||||
def __init__(self, location, glyphs, replacement):
|
||||
Statement.__init__(self, location)
|
||||
self.glyphs, self.replacement = (glyphs, replacement)
|
||||
@ -156,8 +167,7 @@ class LigatureSubstitution(Statement):
|
||||
# glyph classes, the implementation software will enumerate
|
||||
# all specific glyph sequences if glyph classes are detected"
|
||||
for glyphs in sorted(itertools.product(*self.glyphs)):
|
||||
builder.add_ligature_substitution(
|
||||
self.location, glyphs, self.replacement)
|
||||
builder.add_ligature_subst(self.location, glyphs, self.replacement)
|
||||
|
||||
|
||||
class LookupReferenceStatement(Statement):
|
||||
@ -170,7 +180,7 @@ class LookupReferenceStatement(Statement):
|
||||
s.build(builder)
|
||||
|
||||
|
||||
class MarkToBaseAttachmentPositioning(Statement):
|
||||
class MarkBasePosStatement(Statement):
|
||||
def __init__(self, location, base, marks):
|
||||
Statement.__init__(self, location)
|
||||
self.base, self.marks = base, marks
|
||||
@ -179,7 +189,7 @@ class MarkToBaseAttachmentPositioning(Statement):
|
||||
builder.add_mark_base_pos(self.location, self.base, self.marks)
|
||||
|
||||
|
||||
class MarkToLigatureAttachmentPositioning(Statement):
|
||||
class MarkLigPosStatement(Statement):
|
||||
def __init__(self, location, ligatures, marks):
|
||||
Statement.__init__(self, location)
|
||||
self.ligatures, self.marks = ligatures, marks
|
||||
@ -188,17 +198,16 @@ class MarkToLigatureAttachmentPositioning(Statement):
|
||||
pass # TODO: Implement this.
|
||||
|
||||
|
||||
class MultipleSubstitution(Statement):
|
||||
class MultipleSubstStatement(Statement):
|
||||
def __init__(self, location, glyph, replacement):
|
||||
Statement.__init__(self, location)
|
||||
self.glyph, self.replacement = glyph, replacement
|
||||
|
||||
def build(self, builder):
|
||||
builder.add_multiple_substitution(self.location,
|
||||
self.glyph, self.replacement)
|
||||
builder.add_multiple_subst(self.location, self.glyph, self.replacement)
|
||||
|
||||
|
||||
class PairAdjustmentPositioning(Statement):
|
||||
class PairPosStatement(Statement):
|
||||
def __init__(self, location, enumerated,
|
||||
glyphclass1, valuerecord1, glyphclass2, valuerecord2):
|
||||
Statement.__init__(self, location)
|
||||
@ -212,24 +221,24 @@ class PairAdjustmentPositioning(Statement):
|
||||
self.glyphclass2, self.valuerecord2)
|
||||
|
||||
|
||||
class ReverseChainingSingleSubstitution(Statement):
|
||||
class ReverseChainSingleSubstStatement(Statement):
|
||||
def __init__(self, location, old_prefix, old_suffix, mapping):
|
||||
Statement.__init__(self, location)
|
||||
self.old_prefix, self.old_suffix = old_prefix, old_suffix
|
||||
self.mapping = mapping
|
||||
|
||||
def build(self, builder):
|
||||
builder.add_reverse_chaining_single_substitution(
|
||||
builder.add_reverse_chain_single_subst(
|
||||
self.location, self.old_prefix, self.old_suffix, self.mapping)
|
||||
|
||||
|
||||
class SingleSubstitution(Statement):
|
||||
class SingleSubstStatement(Statement):
|
||||
def __init__(self, location, mapping):
|
||||
Statement.__init__(self, location)
|
||||
self.mapping = mapping
|
||||
|
||||
def build(self, builder):
|
||||
builder.add_single_substitution(self.location, self.mapping)
|
||||
builder.add_single_subst(self.location, self.mapping)
|
||||
|
||||
|
||||
class ScriptStatement(Statement):
|
||||
@ -241,7 +250,7 @@ class ScriptStatement(Statement):
|
||||
builder.set_script(self.location, self.script)
|
||||
|
||||
|
||||
class SingleAdjustmentPositioning(Statement):
|
||||
class SinglePosStatement(Statement):
|
||||
def __init__(self, location, glyphclass, valuerecord):
|
||||
Statement.__init__(self, location)
|
||||
self.glyphclass, self.valuerecord = glyphclass, valuerecord
|
||||
@ -256,20 +265,6 @@ class SubtableStatement(Statement):
|
||||
Statement.__init__(self, location)
|
||||
|
||||
|
||||
class SubstitutionRule(Statement):
|
||||
def __init__(self, location, old, new):
|
||||
Statement.__init__(self, location)
|
||||
self.old, self.new = (old, new)
|
||||
self.old_prefix = []
|
||||
self.old_suffix = []
|
||||
self.lookups = [None] * len(old)
|
||||
|
||||
def build(self, builder):
|
||||
builder.add_substitution(
|
||||
self.location, self.old_prefix, self.old, self.old_suffix,
|
||||
self.new, self.lookups)
|
||||
|
||||
|
||||
class ValueRecord(Statement):
|
||||
def __init__(self, location, xPlacement, yPlacement, xAdvance, yAdvance,
|
||||
xPlaDevice, yPlaDevice, xAdvDevice, yAdvDevice):
|
||||
|
@ -305,14 +305,13 @@ class Builder(object):
|
||||
lookup_builders.append(None)
|
||||
return lookup_builders
|
||||
|
||||
def add_substitution(self, location, old_prefix, old, old_suffix, new,
|
||||
lookups):
|
||||
assert len(new) == 0, new
|
||||
def add_chain_context_subst(self, location,
|
||||
old_prefix, old, old_suffix, lookups):
|
||||
lookup = self.get_lookup_(location, ChainContextSubstBuilder)
|
||||
lookup.substitutions.append((old_prefix, old, old_suffix,
|
||||
self.find_lookup_builders_(lookups)))
|
||||
|
||||
def add_alternate_substitution(self, location, glyph, from_class):
|
||||
def add_alternate_subst(self, location, glyph, from_class):
|
||||
lookup = self.get_lookup_(location, AlternateSubstBuilder)
|
||||
if glyph in lookup.alternates:
|
||||
raise FeatureLibError(
|
||||
@ -320,11 +319,11 @@ class Builder(object):
|
||||
location)
|
||||
lookup.alternates[glyph] = from_class
|
||||
|
||||
def add_ligature_substitution(self, location, glyphs, replacement):
|
||||
def add_ligature_subst(self, location, glyphs, replacement):
|
||||
lookup = self.get_lookup_(location, LigatureSubstBuilder)
|
||||
lookup.ligatures[glyphs] = replacement
|
||||
|
||||
def add_multiple_substitution(self, location, glyph, replacements):
|
||||
def add_multiple_subst(self, location, glyph, replacements):
|
||||
lookup = self.get_lookup_(location, MultipleSubstBuilder)
|
||||
if glyph in lookup.mapping:
|
||||
raise FeatureLibError(
|
||||
@ -332,12 +331,12 @@ class Builder(object):
|
||||
location)
|
||||
lookup.mapping[glyph] = replacements
|
||||
|
||||
def add_reverse_chaining_single_substitution(self, location, old_prefix,
|
||||
old_suffix, mapping):
|
||||
def add_reverse_chain_single_subst(self, location, old_prefix,
|
||||
old_suffix, mapping):
|
||||
lookup = self.get_lookup_(location, ReverseChainSingleSubstBuilder)
|
||||
lookup.substitutions.append((old_prefix, old_suffix, mapping))
|
||||
|
||||
def add_single_substitution(self, location, mapping):
|
||||
def add_single_subst(self, location, mapping):
|
||||
lookup = self.get_lookup_(location, SingleSubstBuilder)
|
||||
for (from_glyph, to_glyph) in mapping.items():
|
||||
if from_glyph in lookup.mapping:
|
||||
|
@ -304,10 +304,10 @@ class Parser(object):
|
||||
raise FeatureLibError(
|
||||
'"enumerate" is only allowed with pair positionings',
|
||||
self.cur_token_location_)
|
||||
return ast.SingleAdjustmentPositioning(location, gc1, value1)
|
||||
return ast.SinglePosStatement(location, gc1, value1)
|
||||
else:
|
||||
return ast.PairAdjustmentPositioning(location, enumerated,
|
||||
gc1, value1, gc2, value2)
|
||||
return ast.PairPosStatement(location, enumerated,
|
||||
gc1, value1, gc2, value2)
|
||||
|
||||
def parse_position_cursive_(self, enumerated, vertical):
|
||||
location = self.cur_token_location_
|
||||
@ -321,7 +321,7 @@ class Parser(object):
|
||||
entryAnchor = self.parse_anchor_()
|
||||
exitAnchor = self.parse_anchor_()
|
||||
self.expect_symbol_(";")
|
||||
return ast.CursiveAttachmentPositioning(
|
||||
return ast.CursivePosStatement(
|
||||
location, glyphclass, entryAnchor, exitAnchor)
|
||||
|
||||
def parse_position_base_(self, enumerated, vertical):
|
||||
@ -335,7 +335,7 @@ class Parser(object):
|
||||
base = self.parse_glyphclass_(accept_glyphname=True)
|
||||
marks = self.parse_anchor_marks_()
|
||||
self.expect_symbol_(";")
|
||||
return ast.MarkToBaseAttachmentPositioning(location, base, marks)
|
||||
return ast.MarkBasePosStatement(location, base, marks)
|
||||
|
||||
def parse_position_ligature_(self, enumerated, vertical):
|
||||
location = self.cur_token_location_
|
||||
@ -351,8 +351,7 @@ class Parser(object):
|
||||
self.expect_keyword_("ligComponent")
|
||||
marks.append(self.parse_anchor_marks_())
|
||||
self.expect_symbol_(";")
|
||||
return ast.MarkToLigatureAttachmentPositioning(
|
||||
location, ligatures, marks)
|
||||
return ast.MarkLigPosStatement(location, ligatures, marks)
|
||||
|
||||
def parse_script_(self):
|
||||
assert self.is_cur_keyword_("script")
|
||||
@ -397,7 +396,8 @@ class Parser(object):
|
||||
raise FeatureLibError(
|
||||
'Expected a single glyphclass after "from"',
|
||||
location)
|
||||
return ast.AlternateSubstitution(location, list(old[0])[0], new[0])
|
||||
return ast.AlternateSubstStatement(location,
|
||||
list(old[0])[0], new[0])
|
||||
|
||||
num_lookups = len([l for l in lookups if l is not None])
|
||||
|
||||
@ -415,8 +415,8 @@ class Parser(object):
|
||||
'Expected a glyph class with %d elements after "by", '
|
||||
'but found a glyph class with %d elements' %
|
||||
(len(glyphs), len(replacements)), location)
|
||||
return ast.SingleSubstitution(location,
|
||||
dict(zip(glyphs, replacements)))
|
||||
return ast.SingleSubstStatement(location,
|
||||
dict(zip(glyphs, replacements)))
|
||||
|
||||
# GSUB lookup type 2: Multiple substitution.
|
||||
# Format: "substitute f_f_i by f f i;"
|
||||
@ -424,15 +424,15 @@ class Parser(object):
|
||||
len(old) == 1 and len(old[0]) == 1 and
|
||||
len(new) > 1 and max([len(n) for n in new]) == 1 and
|
||||
num_lookups == 0):
|
||||
return ast.MultipleSubstitution(location, tuple(old[0])[0],
|
||||
tuple([list(n)[0] for n in new]))
|
||||
return ast.MultipleSubstStatement(location, tuple(old[0])[0],
|
||||
tuple([list(n)[0] for n in new]))
|
||||
|
||||
# GSUB lookup type 4: Ligature substitution.
|
||||
# Format: "substitute f f i by f_f_i;"
|
||||
if (not reverse and len(old_prefix) == 0 and len(old_suffix) == 0 and
|
||||
len(old) > 1 and len(new) == 1 and len(new[0]) == 1 and
|
||||
num_lookups == 0):
|
||||
return ast.LigatureSubstitution(location, old, list(new[0])[0])
|
||||
return ast.LigatureSubstStatement(location, old, list(new[0])[0])
|
||||
|
||||
# GSUB lookup type 8: Reverse chaining substitution.
|
||||
if reverse:
|
||||
@ -458,14 +458,14 @@ class Parser(object):
|
||||
'Expected a glyph class with %d elements after "by", '
|
||||
'but found a glyph class with %d elements' %
|
||||
(len(glyphs), len(replacements)), location)
|
||||
return ast.ReverseChainingSingleSubstitution(
|
||||
return ast.ReverseChainSingleSubstStatement(
|
||||
location, old_prefix, old_suffix,
|
||||
dict(zip(glyphs, replacements)))
|
||||
|
||||
rule = ast.SubstitutionRule(location, old, new)
|
||||
rule.old_prefix, rule.old_suffix = old_prefix, old_suffix
|
||||
rule.lookups = lookups
|
||||
rule.reverse = reverse
|
||||
# GSUB lookup type 6: Chaining contextual substitution.
|
||||
assert len(new) == 0, new
|
||||
rule = ast.ChainContextSubstStatement(
|
||||
location, old_prefix, old, old_suffix, lookups)
|
||||
return rule
|
||||
|
||||
def parse_subtable_(self):
|
||||
|
@ -329,7 +329,7 @@ class ParserTest(unittest.TestCase):
|
||||
def test_gpos_type_1_glyph(self):
|
||||
doc = self.parse("feature kern {pos one <1 2 3 4>;} kern;")
|
||||
pos = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(pos), ast.SingleAdjustmentPositioning)
|
||||
self.assertEqual(type(pos), ast.SinglePosStatement)
|
||||
self.assertEqual(pos.glyphclass, {"one"})
|
||||
self.assertEqual(pos.valuerecord.makeString(vertical=False),
|
||||
"<1 2 3 4>")
|
||||
@ -337,14 +337,14 @@ class ParserTest(unittest.TestCase):
|
||||
def test_gpos_type_1_glyphclass_horizontal(self):
|
||||
doc = self.parse("feature kern {pos [one two] -300;} kern;")
|
||||
pos = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(pos), ast.SingleAdjustmentPositioning)
|
||||
self.assertEqual(type(pos), ast.SinglePosStatement)
|
||||
self.assertEqual(pos.glyphclass, {"one", "two"})
|
||||
self.assertEqual(pos.valuerecord.makeString(vertical=False), "-300")
|
||||
|
||||
def test_gpos_type_1_glyphclass_vertical(self):
|
||||
doc = self.parse("feature vkrn {pos [one two] -300;} vkrn;")
|
||||
pos = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(pos), ast.SingleAdjustmentPositioning)
|
||||
self.assertEqual(type(pos), ast.SinglePosStatement)
|
||||
self.assertEqual(pos.glyphclass, {"one", "two"})
|
||||
self.assertEqual(pos.valuerecord.makeString(vertical=True), "-300")
|
||||
|
||||
@ -363,7 +363,7 @@ class ParserTest(unittest.TestCase):
|
||||
" pos [T V] -60 [a b c] <1 2 3 4>;"
|
||||
"} kern;")
|
||||
pos = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(pos), ast.PairAdjustmentPositioning)
|
||||
self.assertEqual(type(pos), ast.PairPosStatement)
|
||||
self.assertFalse(pos.enumerated)
|
||||
self.assertEqual(pos.glyphclass1, {"T", "V"})
|
||||
self.assertEqual(pos.valuerecord1.makeString(vertical=False), "-60")
|
||||
@ -376,7 +376,7 @@ class ParserTest(unittest.TestCase):
|
||||
" enum pos [T V] -60 [a b c] <1 2 3 4>;"
|
||||
"} kern;")
|
||||
pos = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(pos), ast.PairAdjustmentPositioning)
|
||||
self.assertEqual(type(pos), ast.PairPosStatement)
|
||||
self.assertTrue(pos.enumerated)
|
||||
self.assertEqual(pos.glyphclass1, {"T", "V"})
|
||||
self.assertEqual(pos.valuerecord1.makeString(vertical=False), "-60")
|
||||
@ -389,7 +389,7 @@ class ParserTest(unittest.TestCase):
|
||||
" pos [T V] <1 2 3 4> [a b c] <NULL>;"
|
||||
"} kern;")
|
||||
pos = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(pos), ast.PairAdjustmentPositioning)
|
||||
self.assertEqual(type(pos), ast.PairPosStatement)
|
||||
self.assertFalse(pos.enumerated)
|
||||
self.assertEqual(pos.glyphclass1, {"T", "V"})
|
||||
self.assertEqual(pos.valuerecord1.makeString(vertical=False),
|
||||
@ -402,7 +402,7 @@ class ParserTest(unittest.TestCase):
|
||||
" pos [T V] [a b c] <1 2 3 4>;"
|
||||
"} kern;")
|
||||
pos = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(pos), ast.PairAdjustmentPositioning)
|
||||
self.assertEqual(type(pos), ast.PairPosStatement)
|
||||
self.assertFalse(pos.enumerated)
|
||||
self.assertEqual(pos.glyphclass1, {"T", "V"})
|
||||
self.assertEqual(pos.valuerecord1.makeString(vertical=False),
|
||||
@ -415,7 +415,7 @@ class ParserTest(unittest.TestCase):
|
||||
" enumerate position [T V] [a b c] <1 2 3 4>;"
|
||||
"} kern;")
|
||||
pos = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(pos), ast.PairAdjustmentPositioning)
|
||||
self.assertEqual(type(pos), ast.PairPosStatement)
|
||||
self.assertTrue(pos.enumerated)
|
||||
self.assertEqual(pos.glyphclass1, {"T", "V"})
|
||||
self.assertEqual(pos.valuerecord1.makeString(vertical=False),
|
||||
@ -428,7 +428,7 @@ class ParserTest(unittest.TestCase):
|
||||
" position cursive A <anchor 12 -2> <anchor 2 3>;"
|
||||
"} kern;")
|
||||
pos = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(pos), ast.CursiveAttachmentPositioning)
|
||||
self.assertEqual(type(pos), ast.CursivePosStatement)
|
||||
self.assertEqual(pos.glyphclass, {"A"})
|
||||
self.assertEqual((pos.entryAnchor.x, pos.entryAnchor.y), (12, -2))
|
||||
self.assertEqual((pos.exitAnchor.x, pos.exitAnchor.y), (2, 3))
|
||||
@ -453,7 +453,7 @@ class ParserTest(unittest.TestCase):
|
||||
" <anchor 210 -10> mark @BOTTOM_MARKS;"
|
||||
"} test;")
|
||||
pos = doc.statements[-1].statements[0]
|
||||
self.assertEqual(type(pos), ast.MarkToBaseAttachmentPositioning)
|
||||
self.assertEqual(type(pos), ast.MarkBasePosStatement)
|
||||
self.assertEqual(pos.base, {"a", "e", "o", "u"})
|
||||
(a1, m1), (a2, m2) = pos.marks
|
||||
self.assertEqual((a1.x, a1.y), (250, 450))
|
||||
@ -489,7 +489,7 @@ class ParserTest(unittest.TestCase):
|
||||
" <anchor 30 -10> mark @BOTTOM_MARKS;"
|
||||
"} test;")
|
||||
pos = doc.statements[-1].statements[0]
|
||||
self.assertEqual(type(pos), ast.MarkToLigatureAttachmentPositioning)
|
||||
self.assertEqual(type(pos), ast.MarkLigPosStatement)
|
||||
self.assertEqual(pos.ligatures, {"a_f_f_i", "o_f_f_i"})
|
||||
[(a11, m11), (a12, m12)], [(a2, m2)], [], [(a4, m4)] = pos.marks
|
||||
self.assertEqual((a11.x, a11.y, m11.name), (50, 600, "TOP_MARKS"))
|
||||
@ -528,7 +528,7 @@ class ParserTest(unittest.TestCase):
|
||||
def test_rsub_format_a(self):
|
||||
doc = self.parse("feature test {rsub a [b B] c' d [e E] by C;} test;")
|
||||
rsub = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(rsub), ast.ReverseChainingSingleSubstitution)
|
||||
self.assertEqual(type(rsub), ast.ReverseChainSingleSubstStatement)
|
||||
self.assertEqual(rsub.old_prefix, [{"a"}, {"b", "B"}])
|
||||
self.assertEqual(rsub.mapping, {"c": "C"})
|
||||
self.assertEqual(rsub.old_suffix, [{"d"}, {"e", "E"}])
|
||||
@ -539,7 +539,7 @@ class ParserTest(unittest.TestCase):
|
||||
" reversesub A B [one.fitted one.oldstyle]' C [d D] by one;"
|
||||
"} smcp;")
|
||||
rsub = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(rsub), ast.ReverseChainingSingleSubstitution)
|
||||
self.assertEqual(type(rsub), ast.ReverseChainSingleSubstStatement)
|
||||
self.assertEqual(rsub.old_prefix, [{"A"}, {"B"}])
|
||||
self.assertEqual(rsub.old_suffix, [{"C"}, {"d", "D"}])
|
||||
self.assertEqual(rsub.mapping, {
|
||||
@ -553,7 +553,7 @@ class ParserTest(unittest.TestCase):
|
||||
" reversesub BACK TRACK [a-d]' LOOK AHEAD by [A.sc-D.sc];"
|
||||
"} test;")
|
||||
rsub = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(rsub), ast.ReverseChainingSingleSubstitution)
|
||||
self.assertEqual(type(rsub), ast.ReverseChainSingleSubstStatement)
|
||||
self.assertEqual(rsub.old_prefix, [{"BACK"}, {"TRACK"}])
|
||||
self.assertEqual(rsub.old_suffix, [{"LOOK"}, {"AHEAD"}])
|
||||
self.assertEqual(rsub.mapping, {
|
||||
@ -598,7 +598,7 @@ class ParserTest(unittest.TestCase):
|
||||
def test_substitute_single_format_a(self): # GSUB LookupType 1
|
||||
doc = self.parse("feature smcp {substitute a by a.sc;} smcp;")
|
||||
sub = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(sub), ast.SingleSubstitution)
|
||||
self.assertEqual(type(sub), ast.SingleSubstStatement)
|
||||
self.assertEqual(sub.mapping, {"a": "a.sc"})
|
||||
|
||||
def test_substitute_single_format_b(self): # GSUB LookupType 1
|
||||
@ -607,7 +607,7 @@ class ParserTest(unittest.TestCase):
|
||||
" substitute [one.fitted one.oldstyle] by one;"
|
||||
"} smcp;")
|
||||
sub = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(sub), ast.SingleSubstitution)
|
||||
self.assertEqual(type(sub), ast.SingleSubstStatement)
|
||||
self.assertEqual(sub.mapping, {
|
||||
"one.fitted": "one",
|
||||
"one.oldstyle": "one"
|
||||
@ -619,7 +619,7 @@ class ParserTest(unittest.TestCase):
|
||||
" substitute [a-d] by [A.sc-D.sc];"
|
||||
"} smcp;")
|
||||
sub = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(sub), ast.SingleSubstitution)
|
||||
self.assertEqual(type(sub), ast.SingleSubstStatement)
|
||||
self.assertEqual(sub.mapping, {
|
||||
"a": "A.sc",
|
||||
"b": "B.sc",
|
||||
@ -637,7 +637,7 @@ class ParserTest(unittest.TestCase):
|
||||
def test_substitute_multiple(self): # GSUB LookupType 2
|
||||
doc = self.parse("lookup Look {substitute f_f_i by f f i;} Look;")
|
||||
sub = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(sub), ast.MultipleSubstitution)
|
||||
self.assertEqual(type(sub), ast.MultipleSubstStatement)
|
||||
self.assertEqual(sub.glyph, "f_f_i")
|
||||
self.assertEqual(sub.replacement, ("f", "f", "i"))
|
||||
|
||||
@ -646,7 +646,7 @@ class ParserTest(unittest.TestCase):
|
||||
" substitute a from [a.1 a.2 a.3];"
|
||||
"} test;")
|
||||
sub = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(sub), ast.AlternateSubstitution)
|
||||
self.assertEqual(type(sub), ast.AlternateSubstStatement)
|
||||
self.assertEqual(sub.glyph, "a")
|
||||
self.assertEqual(sub.from_class, {"a.1", "a.2", "a.3"})
|
||||
|
||||
@ -656,14 +656,14 @@ class ParserTest(unittest.TestCase):
|
||||
" substitute ampersand from @Ampersands;"
|
||||
"} test;")
|
||||
[glyphclass, sub] = doc.statements[0].statements
|
||||
self.assertEqual(type(sub), ast.AlternateSubstitution)
|
||||
self.assertEqual(type(sub), ast.AlternateSubstStatement)
|
||||
self.assertEqual(sub.glyph, "ampersand")
|
||||
self.assertEqual(sub.from_class, {"ampersand.1", "ampersand.2"})
|
||||
|
||||
def test_substitute_ligature(self): # GSUB LookupType 4
|
||||
doc = self.parse("feature liga {substitute f f i by f_f_i;} liga;")
|
||||
sub = doc.statements[0].statements[0]
|
||||
self.assertEqual(type(sub), ast.LigatureSubstitution)
|
||||
self.assertEqual(type(sub), ast.LigatureSubstStatement)
|
||||
self.assertEqual(sub.glyphs, [{"f"}, {"f"}, {"i"}])
|
||||
self.assertEqual(sub.replacement, "f_f_i")
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user