Skip to content

Commit

Permalink
Merge pull request #900 from googlefonts/tokens
Browse files Browse the repository at this point in the history
Some tokens fixes
  • Loading branch information
khaledhosny authored May 2, 2023
2 parents d088543 + b9a27c0 commit ad5d41f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 12 deletions.
21 changes: 16 additions & 5 deletions Lib/glyphsLib/builder/tokens.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import re
import fnmatch
from collections import OrderedDict


def _like(got, expected):
expected = expected.replace("?", ".")
expected = expected.replace("*", ".*")
# Technically we should be a bit stricter than this
return re.match(expected, str(got))
# LIKE is similar to Unix shell-style wildcards supported by fnmatch
return fnmatch.fnmatchcase(str(got), expected)


class TokenExpander:
Expand Down Expand Up @@ -213,7 +212,7 @@ def _parse_glyph_predicate_to_array(self):
return list(glyphs.keys())

def _parse_optional_not(self):
m = re.match(r"^\s*not\s+", self.glyph_predicate)
m = re.match(r"(?i)^\s*(not|!)\s+", self.glyph_predicate)
if m:
self.glyph_predicate = self.glyph_predicate[len(m[0]) :]
return True
Expand Down Expand Up @@ -294,7 +293,17 @@ def _get_value_for_layer(self, layer, value):
"Unknown glyph property '%s' at position %i" % (value, self.position)
) from e

gsglyph_attr_getters = {
"colorIndex": lambda g: g.color,
"countOfUnicodes": lambda g: len(g.unicodes),
"countOfLayers": lambda g: len(g.layers),
}

def _get_value_for_glyph(self, g, value):
getter = self.gsglyph_attr_getters.get(value, None)
if getter:
return getter(g)

try:
return getattr(g, value)
except AttributeError as exc:
Expand All @@ -313,6 +322,8 @@ def _get_value_for_glyph(self, g, value):
"!=": lambda got, exp: got != exp,
">=": lambda got, exp: got >= exp,
"<=": lambda got, exp: got <= exp,
">": lambda got, exp: got > exp,
"<": lambda got, exp: got < exp,
"between": lambda got, exp: got >= exp[0] and got <= exp[1],
"in": lambda got, exp: got in exp,
}
Expand Down
24 changes: 23 additions & 1 deletion tests/data/TokenTest.glyphs
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,31 @@ width = 600;
note = "I love it!";
},
{
glyphname = space;
lastChange = "2023-04-30 16:25:25 +0000";
layers = (
{
layerId = m01;
width = 200;
},
{
layerId = "11119B89-ADF6-486B-9172-E51437C3592A";
width = 200;
},
{
associatedMasterId = m01;
layerId = "54D50A9B-7A3E-4CD6-AC9C-62E91FCBECBA";
name = Test;
width = 200;
}
);
unicode = (32,160);
},
{
category = Separator;
color = 5;
glyphname = Sacute;
lastChange = "2023-04-28 17:52:32 +0000";
lastChange = "2023-04-28 22:20:21 +0000";
layers = (
{
layerId = m01;
Expand Down
34 changes: 28 additions & 6 deletions tests/tokens_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,40 @@
"A.sc",
False,
), # will expand to all glyph names that end in ".sc"
("$[not name endswith '.sc']", "A Sacute", False),
("$[name endswith '.sc' or not name endswith '.sc']", "A.sc A Sacute", False),
("$[not name endswith '.sc']", "A space Sacute", False),
("$[NOT name endswith '.sc']", "A space Sacute", False),
("$[! name endswith '.sc']", "A space Sacute", False),
(
"$[name endswith '.sc' or not name endswith '.sc']",
"A.sc A space Sacute",
False,
),
(
"$[name ENDSWITH '.sc' OR NOT name ENDSWITH '.sc']",
"A.sc A space Sacute",
False,
),
(
"$[name endswith '.sc' || ! name endswith '.sc']",
"A.sc A space Sacute",
False,
),
("$[name endswith '.sc' and not name endswith '.sc']", "", False),
("$[name ENDSWITH '.sc' AND NOT name ENDSWITH '.sc']", "", False),
("$[name endswith '.sc' && ! name endswith '.sc']", "", False),
("$[name like 'A']", "A", False),
("$[name like 'Sacut']", "", False),
("$[name like 'S?cute']", "Sacute", False),
("$[name like 'S*']", "Sacute", False),
# ('$[layer0.width < 500]', "", False), # layer0 = first master
# ('$[layers.count > 1]', "", False), # compare numbers with: == != <= >= < >
# ('$[direction == 2]', "", False), # 0=LTR, 1=BiDi, 2=RTL
# ('$[colorIndex == 5]', "", False),
("$[colorIndex == 5]", "Sacute", False),
# ('$[case == smallCaps]', "", False),
# predefined constants: noCase, upper, lower, smallCaps, minor, other
(
'$[name matches "S|s.*"]',
"A.sc Sacute",
"A.sc space Sacute",
False,
), # "matches": regular expression
# ('$[leftMetricsKey like "*"]', "", False), # "like": wildcard search
Expand All @@ -85,8 +107,8 @@
('$[rightKerningGroup like "L"]', "A", False),
('$[unicode beginswith "41"]', "A", False), # beginswith, endswith, contains
('$[note contains "love it"]', "A.sc", False), # glyph note
# ('$[countOfUnicodes > 1]', "", False),
# ('$[countOfLayers > 1]', "", False),
("$[countOfUnicodes > 1]", "space", False),
("$[countOfLayers > 2]", "space", False),
('$[subCategory like "Arrow"]', "Sacute", False),
# ('$[hasHints == 0]', "", False), # boolean: false, no, 0 versus true, yes, 1
# ('$[isColorGlyph == true]', "", False),
Expand Down

0 comments on commit ad5d41f

Please sign in to comment.