summaryrefslogtreecommitdiff
path: root/misc/pylib/robofab/tools/fontlabFeatureSplitter.py
blob: 3e0173dfc4a9f94bf3edb1d0975f9e5e6c9303a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import re

featureRE = re.compile(
    "^"            # start of line
    "\s*"          #
    "feature"      # feature
    "\s+"          #
    "(\w{4})"      # four alphanumeric characters
    "\s*"          #
    "\{"           # {
    , re.MULTILINE # run in multiline to preserve line seps
)

def splitFeaturesForFontLab(text):
    """
    >>> result = splitFeaturesForFontLab(testText)
    >>> result == expectedTestResult
    True
    """
    classes = ""
    features = []
    while text:
        m = featureRE.search(text)
        if m is None:
            classes = text
            text = ""
        else:
            start, end = m.span()
            # if start is not zero, this is the first match
            # and all previous lines are part of the "classes"
            if start > 0:
                assert not classes
                classes = text[:start]
            # extract the current feature
            featureName = m.group(1)
            featureText = text[start:end]
            text = text[end:]
            # grab all text before the next feature definition
            # and add it to the current definition
            if text:
                m = featureRE.search(text)
                if m is not None:
                    start, end = m.span()
                    featureText += text[:start]
                    text = text[start:]
                else:
                    featureText += text
                    text = ""
            # store the feature
            features.append((featureName, featureText))
    return classes, features

testText = """
@class1 = [a b c d];

feature liga {
    sub f i by fi;
} liga;

@class2 = [x y z];

feature salt {
    sub a by a.alt;
} salt; feature ss01 {sub x by x.alt} ss01;

feature ss02 {sub y by y.alt} ss02;

# feature calt {
#     sub a b' by b.alt;
# } calt;
"""

expectedTestResult = (
    "\n@class1 = [a b c d];\n",
    [
        ("liga", "\nfeature liga {\n    sub f i by fi;\n} liga;\n\n@class2 = [x y z];\n"),
        ("salt", "\nfeature salt {\n    sub a by a.alt;\n} salt; feature ss01 {sub x by x.alt} ss01;\n"),
        ("ss02", "\nfeature ss02 {sub y by y.alt} ss02;\n\n# feature calt {\n#     sub a b' by b.alt;\n# } calt;\n")
    ]
)


if __name__ == "__main__":
    import doctest
    doctest.testmod()