http://www.adobe.com/devnet/opentype/afdko/topic_feature_file_syntax.html#10
For example, @mhosken is interested in experimenting with inlining
custom syntax (such as Python snippets) into feature files. After this
change, such experiments can be done on top of feaLib because the
Abstract Syntax Tree now contains the tag and content of `anonymous`
blocks.
* feaLib: limit language statements to 1 feature block
language exclude_dflt statements should only apply to lookups
defined in their feature block and not to lookups defined
in previous blocks sharing the same feature tag
* feaLib: add BuilderTest::test_FeatureFile_multiple_feature_blocks
Before this change, we had only emitted a SinglePos (GPOS type 1) lookup
for a statement like `pos A' B' 20`; after this change, we always emit a
chain rule even if there is no context. There is a semantic difference if
the rule is preceded by a `ignore pos` statement. Omitting context-free
contextual chains was actually not a (premature) optimization, but an
artifact that came from the representation of glyph patterns.
https://github.com/behdad/fonttools/issues/516
Although this construct is in violation of the `ignore sub` grammar
given by the current OpenType Feature File syntax specification,
the very same specification document illustrates (in example 3
of section 5.f.ii) the `ignore sub` statement with a comma-separated
list of backgrack/input/lookahead triples.
See https://github.com/adobe-type-tools/afdko/issues/105 for a request
to amend the OpenType Feature File syntax specification.
After this code change, feaLib can now parse testdata/spec5f_ii_3.fea;
the output is identical to what is generated by Adobe's makeotf tool.
https://github.com/behdad/fonttools/issues/503
https://github.com/behdad/fonttools/issues/445
Not sure whether it makes much sense to define a contextual chain
that points to a GSUB type 3, but the OpenType feature file syntax
does not explicitly forbid it. Adobe's `makeotf` tool rejects this
kind of input with "Contextual alternate rule not yet supported";
this implies that the construct is valid (albeit definitely exotic).
Before this change, the compiler had (essentially) implemented lookup
references by inlining the statements of the invoked lookup into the
current feature block. After this change, the lookup gets compiled
separately, and any call sites make explicit calls.
Resolves https://github.com/behdad/fonttools/issues/445 for single
substitutions. The compact forms for chaining to other GSUB types
are not yet supported; these will get fixed in follow-up changes.
Before this change, we silently generated bad fonts. After this
change, we emit the exact same output like `makeotf` for specific
kerning pairs, and reject the input file for the not yet implemented
class-based kerning. (The implementation of class-based kerning
is coming soon).
Before this change, the compiler would enumerate only the first
glyph class of a kerning pair. However, that behavior did not match
the behavior of the `makeotf` tool.
For GPOS type 2, the OpenType Feature File format makes a semantic
difference between `glyph` and `[glyph]`, so we need to pass the
syntax tree for the kerned glyphs and glyph classes down to the builder.
Previously, we were expanding syntax tree nodes to glyphSets at
parsing time. Therefore, the builder could not distinguish a statement
for kerning two single glyphs from a statement for kerning two glyph
glasses, where each glyph class would consist of a singleton
glyph. (Debating whether or not it makes much sense to have this
distinction is outside the scope of fonttools; we want to implement
the language in its present form).
The builder does not yet use this information for building different
tables. This change is just about plumbing.
Again, this will be needed for eventually distinguishing `glyph`
from `[glyph]` or `@CLASS`, which makes a semantic difference
when building GPOS type 2 tables.
This will be needed for implementing class-based kerning. According
to the OpenType Feature File specification, a different table needs to
be built for `glyph` versus `[glyph]`.
No output is generated yet, this change is just on the parser.
The OpenType Feature File specification is surprisingly vague about
the exact syntax of chaining contextual positioning rules, so I expect
that we will have to iterate on this parser. However, the test case
in parser_test.py gets recognized by `makeotf`, so the current
implementation is unlikely to be completely wrong.
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`.