[feaLib] Resolve references to glyph classes
This commit is contained in:
parent
a0bbd5fab9
commit
3936e334f1
@ -66,10 +66,19 @@ class Parser(object):
|
||||
|
||||
def parse_glyphclass_reference_(self):
|
||||
result = set()
|
||||
if self.next_token_type_ is Lexer.GLYPHCLASS:
|
||||
self.advance_lexer_()
|
||||
gc = self.resolve_glyphclass_(self.cur_token_)
|
||||
if gc is None:
|
||||
raise ParserError("Unknown glyph class @%s" % self.cur_token_,
|
||||
self.cur_token_location_)
|
||||
result.update(gc.glyphs)
|
||||
return result
|
||||
|
||||
self.expect_symbol_("[")
|
||||
while self.next_token_ != "]":
|
||||
if self.next_token_type_ is Lexer.NAME:
|
||||
self.advance_lexer_()
|
||||
self.advance_lexer_()
|
||||
if self.cur_token_type_ is Lexer.NAME:
|
||||
if self.next_token_ == "-":
|
||||
range_location_ = self.cur_token_location_
|
||||
range_start = self.cur_token_
|
||||
@ -80,6 +89,16 @@ class Parser(object):
|
||||
range_end))
|
||||
else:
|
||||
result.add(self.cur_token_)
|
||||
elif self.cur_token_type_ is Lexer.GLYPHCLASS:
|
||||
gc = self.resolve_glyphclass_(self.cur_token_)
|
||||
if gc is None:
|
||||
raise ParserError(
|
||||
"Unknown glyph class @%s" % self.cur_token_,
|
||||
self.cur_token_location_)
|
||||
result.update(gc.glyphs)
|
||||
else:
|
||||
raise ParserError("Expected glyph name, range, or reference",
|
||||
self.cur_token_location_)
|
||||
self.expect_symbol_("]")
|
||||
return result
|
||||
|
||||
|
@ -24,11 +24,26 @@ class ParserTest(unittest.TestCase):
|
||||
self.assertEqual(gc.name, "dash")
|
||||
self.assertEqual(gc.glyphs, {"endash", "emdash", "figuredash"})
|
||||
|
||||
def test_glyphclass_bad(self):
|
||||
self.assertRaisesRegex(
|
||||
ParserError, "Expected glyph name, range, or reference",
|
||||
self.parse, "@bad = [a 123];")
|
||||
|
||||
def test_glyphclass_duplicate(self):
|
||||
self.assertRaisesRegex(
|
||||
ParserError, "Glyph class @dup already defined",
|
||||
self.parse, "@dup = [a b]; @dup = [x];")
|
||||
|
||||
def test_glyphclass_empty(self):
|
||||
[gc] = self.parse("@empty_set = [];").statements
|
||||
self.assertEqual(gc.name, "empty_set")
|
||||
self.assertEqual(gc.glyphs, set())
|
||||
|
||||
def test_glyphclass_equality(self):
|
||||
[foo, bar] = self.parse("@foo = [a b]; @bar = @foo;").statements
|
||||
self.assertEqual(foo.glyphs, {"a", "b"})
|
||||
self.assertEqual(bar.glyphs, {"a", "b"})
|
||||
|
||||
def test_glyphclass_range_uppercase(self):
|
||||
[gc] = self.parse("@swashes = [X.swash-Z.swash];").statements
|
||||
self.assertEqual(gc.name, "swashes")
|
||||
@ -72,13 +87,16 @@ class ParserTest(unittest.TestCase):
|
||||
"a", "foo.09", "foo.10", "foo.11", "X.sc", "Y.sc", "Z.sc"
|
||||
})
|
||||
|
||||
# TODO: self.parse("@foo = [a b]; @bar = [@foo];")
|
||||
# TODO: self.parse("@foo = [a b]; @bar = @foo;")
|
||||
|
||||
def test_glyphclass_empty(self):
|
||||
[gc] = self.parse("@empty_set = [];").statements
|
||||
self.assertEqual(gc.name, "empty_set")
|
||||
self.assertEqual(gc.glyphs, set())
|
||||
def test_glyphclass_reference(self):
|
||||
[vowels_lc, vowels_uc, vowels] = self.parse(
|
||||
"@Vowels.lc = [a e i o u]; @Vowels.uc = [A E I O U]; " +
|
||||
"@Vowels = [@Vowels.lc @Vowels.uc y Y];").statements
|
||||
self.assertEqual(vowels_lc.glyphs, set(list("aeiou")))
|
||||
self.assertEqual(vowels_uc.glyphs, set(list("AEIOU")))
|
||||
self.assertEqual(vowels.glyphs, set(list("aeiouyAEIOUY")))
|
||||
self.assertRaisesRegex(
|
||||
ParserError, "Unknown glyph class @unknown",
|
||||
self.parse, "@bad = [@unknown];")
|
||||
|
||||
def test_languagesystem(self):
|
||||
[langsys] = self.parse("languagesystem latn DEU;").statements
|
||||
|
Loading…
x
Reference in New Issue
Block a user