Just to preface: I know this is a big feature request and I don’t expect you to accept it or to handle it in any timely manner. Still, this is something that is useful and fills a gap to other feature languages like FEE.
I propose an additional glyph class predicate field: classes
. This allows to check whether a glyph is part of a glyph class or not.
$[classes contains "CombiningMarks"]
This predicate can, of course, be combined with other predicates like isAligned
, countOfUnicodes
, etc. But, it is also very useful on its own because it allows to perform all basic set operations on glyphs classes.
Set operations
Identity (trivial)
# @A
[ $[classes contains "A"] ]
Identity is trivial since it is the same as writing @A
.
Complement
# complement(@A)
[ $[not classes contains "A"] ]
Union (trivial)
# union(@A, @B)
[ $[classes contains "A" or classes contains "B"] ]
Set union is the second trivial example since [@A @B]
already does a similar thing. The difference is that a union does not contain duplicate members.
Intersection
# intersection(@A, @B)
[ $[classes contains "A" and classes contains "B"] ]
Difference
# difference(@A, @B)
[ $[classes contains "A" and not classes contains "B"] ]
Symmetric difference
# symmetric_difference(@A, @B)
# -- expressed as union of differences:
[ $[(classes contains "A" and not classes contains "B") or (not classes contains "A" and classes contains "B")] ]
# -- expressed as “in one but not both”:
[ $[(classes contains "A" or classes contains "B") and not (classes contains "A" and classes contains "B")] ]
(I don’t think the symmetric difference is particularly useful for font-design, but it is neat that it is possible.)
Details
The new classes
field would be a list of strings where each string corresponds to a glyph class that contains the respective glyph. Using the standard contains
operator one can check whether a glyph belongs to a class or not.
For example, all non-digit glyphs:
$[not classes contains "Digits"]
The classes
field should probably contain only class names of classes defined above the token. This also makes recursive predicates impossible.