File: debug-merge.py

package info (click to toggle)
fonts-montserrat 9.000-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 72,376 kB
  • sloc: python: 200; makefile: 45; sh: 15
file content (76 lines) | stat: -rw-r--r-- 2,817 bytes parent folder | download
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
from glyphsLib import load, to_designspace
from ufo2ft.featureCompiler import FeatureCompiler, parseLayoutFeatures
from fontTools.feaLib import ast
import argparse


class Checker:
    def __init__(self, sources):
        self.masters = []
        for source in sources:
            self.masters.append(
                {
                    "ufo": source.font,
                    "name": source.name,
                    "compiler": FeatureCompiler(source.font),
                }
            )
            self.masters[-1]["writers"] = self.masters[-1]["compiler"].featureWriters

    def check_all_the_same(self, items, description, print_items=None):
        if all(i == items[0] for i in items[1:]):
            return True
        print(" MERGE PROBLEM: Not all masters " + description + ":")
        if print_items is not None:
            items = print_items
        for master, item in zip(self.masters, items):
            print("  %s: %s" % (master["name"], item))
        print("\n")
        return False


parser = argparse.ArgumentParser(description="Debug a merge error in a Glyphs file")
parser.add_argument(
    "glyphs_file", metavar="glyphs_file", type=str, help="The Glyphs file to debug"
)
args = parser.parse_args()
print("Converting to UFO")
ds = to_designspace(load(args.glyphs_file), minimal=True)
checker = Checker(ds.sources)

for writers in zip(*[m["writers"] for m in checker.masters]):
    features = writers[0].features
    # Start a new feature file for each master
    written = []
    for writer, master in zip(writers, checker.masters):
        master["featurefile"] = parseLayoutFeatures(master["ufo"])
        written.append(writer.write(master["ufo"], master["featurefile"]))
    if not written[0]:
        continue
    print(
        "Checking compatibility of %s feature%s"
        % ("/".join(features), "s" if len(features) > 1 else "")
    )
    if not checker.check_all_the_same(
        ["yes" if w else "no" for w in written], " had this feature"
    ):
        continue
    # Now check compatibility of each feature file. Normally the problem is
    # incompatible lookups
    feature_files = [m["featurefile"] for m in checker.masters]
    lookups_by_name = [
        {s.name: s for s in f.statements if isinstance(s, ast.LookupBlock)}
        for f in feature_files
    ]
    all_lookup_names = set()
    for names in lookups_by_name:
        all_lookup_names.update(names.keys())
    for lookup in all_lookup_names:
        checker.check_all_the_same(
            ["yes" if lookup in my_lookups else "no" for my_lookups in lookups_by_name],
            "had a %s lookup" % lookup,
            print_items=[
                my_lookups[lookup].asFea() if lookup in my_lookups else "<Missing>"
                for my_lookups in lookups_by_name
            ],
        )