xref: /aosp_15_r20/external/fonttools/Snippets/print-json.py (revision e1fe3e4ad2793916b15cccdc4a7da52a7e1dd0e9)
1*e1fe3e4aSElliott Hughesimport fontTools.ttLib as ttLib
2*e1fe3e4aSElliott Hughesfrom fontTools.ttLib.ttVisitor import TTVisitor
3*e1fe3e4aSElliott Hughesfrom fontTools.misc.textTools import Tag
4*e1fe3e4aSElliott Hughesfrom array import array
5*e1fe3e4aSElliott Hughes
6*e1fe3e4aSElliott Hughes
7*e1fe3e4aSElliott Hughesclass JsonVisitor(TTVisitor):
8*e1fe3e4aSElliott Hughes    def _open(self, s):
9*e1fe3e4aSElliott Hughes        print(s, file=self.file)
10*e1fe3e4aSElliott Hughes        self._indent += self.indent
11*e1fe3e4aSElliott Hughes        self.comma = False
12*e1fe3e4aSElliott Hughes
13*e1fe3e4aSElliott Hughes    def _close(self, s):
14*e1fe3e4aSElliott Hughes        self._indent = self._indent[: -len(self.indent)]
15*e1fe3e4aSElliott Hughes        print("\n%s%s" % (self._indent, s), end="", file=self.file)
16*e1fe3e4aSElliott Hughes        self.comma = True
17*e1fe3e4aSElliott Hughes
18*e1fe3e4aSElliott Hughes    def __init__(self, file, indent="  "):
19*e1fe3e4aSElliott Hughes        self.file = file
20*e1fe3e4aSElliott Hughes        self.indent = indent
21*e1fe3e4aSElliott Hughes        self._indent = ""
22*e1fe3e4aSElliott Hughes
23*e1fe3e4aSElliott Hughes    def visitObject(self, obj):
24*e1fe3e4aSElliott Hughes        self._open("{")
25*e1fe3e4aSElliott Hughes        super().visitObject(obj)
26*e1fe3e4aSElliott Hughes        if self.comma:
27*e1fe3e4aSElliott Hughes            print(",", end="", file=self.file)
28*e1fe3e4aSElliott Hughes        print(
29*e1fe3e4aSElliott Hughes            '\n%s"type": "%s"' % (self._indent, obj.__class__.__name__),
30*e1fe3e4aSElliott Hughes            end="",
31*e1fe3e4aSElliott Hughes            file=self.file,
32*e1fe3e4aSElliott Hughes        )
33*e1fe3e4aSElliott Hughes        self._close("}")
34*e1fe3e4aSElliott Hughes
35*e1fe3e4aSElliott Hughes    def visitAttr(self, obj, attr, value):
36*e1fe3e4aSElliott Hughes        if self.comma:
37*e1fe3e4aSElliott Hughes            print(",", file=self.file)
38*e1fe3e4aSElliott Hughes        print('%s"%s": ' % (self._indent, attr), end="", file=self.file)
39*e1fe3e4aSElliott Hughes        self.visit(value)
40*e1fe3e4aSElliott Hughes        self.comma = True
41*e1fe3e4aSElliott Hughes
42*e1fe3e4aSElliott Hughes    def visitList(self, obj, *args, **kwargs):
43*e1fe3e4aSElliott Hughes        self._open("[")
44*e1fe3e4aSElliott Hughes        comma = False
45*e1fe3e4aSElliott Hughes        for value in obj:
46*e1fe3e4aSElliott Hughes            if comma:
47*e1fe3e4aSElliott Hughes                print(",", end="", file=self.file)
48*e1fe3e4aSElliott Hughes                print(file=self.file)
49*e1fe3e4aSElliott Hughes            print(self._indent, end="", file=self.file)
50*e1fe3e4aSElliott Hughes            self.visit(value, *args, **kwargs)
51*e1fe3e4aSElliott Hughes            comma = True
52*e1fe3e4aSElliott Hughes        self._close("]")
53*e1fe3e4aSElliott Hughes
54*e1fe3e4aSElliott Hughes    def visitDict(self, obj, *args, **kwargs):
55*e1fe3e4aSElliott Hughes        self._open("{")
56*e1fe3e4aSElliott Hughes        comma = False
57*e1fe3e4aSElliott Hughes        for key, value in obj.items():
58*e1fe3e4aSElliott Hughes            if comma:
59*e1fe3e4aSElliott Hughes                print(",", end="", file=self.file)
60*e1fe3e4aSElliott Hughes                print(file=self.file)
61*e1fe3e4aSElliott Hughes            print('%s"%s": ' % (self._indent, key), end="", file=self.file)
62*e1fe3e4aSElliott Hughes            self.visit(value, *args, **kwargs)
63*e1fe3e4aSElliott Hughes            comma = True
64*e1fe3e4aSElliott Hughes        self._close("}")
65*e1fe3e4aSElliott Hughes
66*e1fe3e4aSElliott Hughes    def visitLeaf(self, obj):
67*e1fe3e4aSElliott Hughes        if isinstance(obj, tuple):
68*e1fe3e4aSElliott Hughes            obj = list(obj)
69*e1fe3e4aSElliott Hughes        elif isinstance(obj, bytes):
70*e1fe3e4aSElliott Hughes            obj = list(obj)
71*e1fe3e4aSElliott Hughes
72*e1fe3e4aSElliott Hughes        if obj is None:
73*e1fe3e4aSElliott Hughes            s = "null"
74*e1fe3e4aSElliott Hughes        elif obj is True:
75*e1fe3e4aSElliott Hughes            s = "true"
76*e1fe3e4aSElliott Hughes        elif obj is False:
77*e1fe3e4aSElliott Hughes            s = "false"
78*e1fe3e4aSElliott Hughes        else:
79*e1fe3e4aSElliott Hughes            s = repr(obj)
80*e1fe3e4aSElliott Hughes
81*e1fe3e4aSElliott Hughes        if s[0] == "'":
82*e1fe3e4aSElliott Hughes            s = '"' + s[1:-1] + '"'
83*e1fe3e4aSElliott Hughes
84*e1fe3e4aSElliott Hughes        print("%s" % s, end="", file=self.file)
85*e1fe3e4aSElliott Hughes
86*e1fe3e4aSElliott Hughes
87*e1fe3e4aSElliott Hughes@JsonVisitor.register(ttLib.TTFont)
88*e1fe3e4aSElliott Hughesdef visit(self, font):
89*e1fe3e4aSElliott Hughes    if hasattr(visitor, "font"):
90*e1fe3e4aSElliott Hughes        print("{}", end="", file=self.file)
91*e1fe3e4aSElliott Hughes        return False
92*e1fe3e4aSElliott Hughes    visitor.font = font
93*e1fe3e4aSElliott Hughes
94*e1fe3e4aSElliott Hughes    self._open("{")
95*e1fe3e4aSElliott Hughes    for tag in font.keys():
96*e1fe3e4aSElliott Hughes        if self.comma:
97*e1fe3e4aSElliott Hughes            print(",", file=self.file)
98*e1fe3e4aSElliott Hughes        print('\n%s"%s": ' % (self._indent, tag), end="", file=self.file)
99*e1fe3e4aSElliott Hughes        visitor.visit(font[tag])
100*e1fe3e4aSElliott Hughes    self._close("}")
101*e1fe3e4aSElliott Hughes
102*e1fe3e4aSElliott Hughes    del visitor.font
103*e1fe3e4aSElliott Hughes    return False
104*e1fe3e4aSElliott Hughes
105*e1fe3e4aSElliott Hughes
106*e1fe3e4aSElliott Hughes@JsonVisitor.register(ttLib.GlyphOrder)
107*e1fe3e4aSElliott Hughesdef visit(self, obj):
108*e1fe3e4aSElliott Hughes    self.visitList(self.font.getGlyphOrder())
109*e1fe3e4aSElliott Hughes    return False
110*e1fe3e4aSElliott Hughes
111*e1fe3e4aSElliott Hughes
112*e1fe3e4aSElliott Hughes@JsonVisitor.register_attr(ttLib.getTableClass("glyf"), "glyphOrder")
113*e1fe3e4aSElliott Hughesdef visit(visitor, obj, attr, value):
114*e1fe3e4aSElliott Hughes    return False
115*e1fe3e4aSElliott Hughes
116*e1fe3e4aSElliott Hughes
117*e1fe3e4aSElliott Hughes@JsonVisitor.register(ttLib.getTableModule("glyf").GlyphCoordinates)
118*e1fe3e4aSElliott Hughesdef visit(self, obj):
119*e1fe3e4aSElliott Hughes    self.visitList(obj)
120*e1fe3e4aSElliott Hughes    return False
121*e1fe3e4aSElliott Hughes
122*e1fe3e4aSElliott Hughes
123*e1fe3e4aSElliott Hughes@JsonVisitor.register(Tag)
124*e1fe3e4aSElliott Hughesdef visit(self, obj):
125*e1fe3e4aSElliott Hughes    print('"%s"' % str(obj), end="", file=self.file)
126*e1fe3e4aSElliott Hughes    return False
127*e1fe3e4aSElliott Hughes
128*e1fe3e4aSElliott Hughes
129*e1fe3e4aSElliott Hughes@JsonVisitor.register(array)
130*e1fe3e4aSElliott Hughesdef visit(self, obj):
131*e1fe3e4aSElliott Hughes    self.visitList(obj)
132*e1fe3e4aSElliott Hughes    return False
133*e1fe3e4aSElliott Hughes
134*e1fe3e4aSElliott Hughes
135*e1fe3e4aSElliott Hughes@JsonVisitor.register(bytearray)
136*e1fe3e4aSElliott Hughesdef visit(self, obj):
137*e1fe3e4aSElliott Hughes    self.visitList(obj)
138*e1fe3e4aSElliott Hughes    return False
139*e1fe3e4aSElliott Hughes
140*e1fe3e4aSElliott Hughes
141*e1fe3e4aSElliott Hughesif __name__ == "__main__":
142*e1fe3e4aSElliott Hughes    from fontTools.ttLib import TTFont
143*e1fe3e4aSElliott Hughes    import sys
144*e1fe3e4aSElliott Hughes
145*e1fe3e4aSElliott Hughes    if len(sys.argv) != 2:
146*e1fe3e4aSElliott Hughes        print("usage: print-json.py font")
147*e1fe3e4aSElliott Hughes        sys.exit()
148*e1fe3e4aSElliott Hughes
149*e1fe3e4aSElliott Hughes    font = TTFont(sys.argv[1])
150*e1fe3e4aSElliott Hughes
151*e1fe3e4aSElliott Hughes    visitor = JsonVisitor(sys.stdout)
152*e1fe3e4aSElliott Hughes    visitor.visit(font)
153