fonttools/Snippets/print-json.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

154 lines
3.8 KiB
Python
Raw Normal View History

import fontTools.ttLib as ttLib
from fontTools.ttLib.ttVisitor import TTVisitor
from fontTools.misc.textTools import Tag
2022-08-15 21:40:05 -06:00
from array import array
class JsonVisitor(TTVisitor):
def _open(self, s):
print(s, file=self.file)
self._indent += self.indent
2022-08-15 21:34:30 -06:00
self.comma = False
def _close(self, s):
2022-08-15 21:34:30 -06:00
self._indent = self._indent[: -len(self.indent)]
print("\n%s%s" % (self._indent, s), end="", file=self.file)
self.comma = True
def __init__(self, file, indent=" "):
self.file = file
self.indent = indent
self._indent = ""
def visitObject(self, obj):
self._open("{")
super().visitObject(obj)
2022-08-15 21:34:30 -06:00
if self.comma:
print(",", end="", file=self.file)
print(
'\n%s"type": "%s"' % (self._indent, obj.__class__.__name__),
end="",
file=self.file,
)
self._close("}")
def visitAttr(self, obj, attr, value):
2022-08-15 21:34:30 -06:00
if self.comma:
print(",", file=self.file)
print('%s"%s": ' % (self._indent, attr), end="", file=self.file)
self.visit(value)
2022-08-15 21:34:30 -06:00
self.comma = True
def visitList(self, obj, *args, **kwargs):
self._open("[")
2022-08-15 21:34:30 -06:00
comma = False
for value in obj:
2022-08-15 21:34:30 -06:00
if comma:
print(",", end="", file=self.file)
print(file=self.file)
print(self._indent, end="", file=self.file)
self.visit(value, *args, **kwargs)
2022-08-15 21:34:30 -06:00
comma = True
self._close("]")
def visitDict(self, obj, *args, **kwargs):
self._open("{")
2022-08-15 21:34:30 -06:00
comma = False
for key, value in obj.items():
2022-08-15 21:34:30 -06:00
if comma:
print(",", end="", file=self.file)
print(file=self.file)
print('%s"%s": ' % (self._indent, key), end="", file=self.file)
self.visit(value, *args, **kwargs)
2022-08-15 21:34:30 -06:00
comma = True
self._close("}")
def visitLeaf(self, obj):
if isinstance(obj, tuple):
obj = list(obj)
2022-08-15 21:40:05 -06:00
elif isinstance(obj, bytes):
obj = list(obj)
2022-08-15 21:34:30 -06:00
if obj is None:
s = "null"
2022-08-15 21:40:05 -06:00
elif obj is True:
2022-08-15 21:34:30 -06:00
s = "true"
2022-08-15 21:40:05 -06:00
elif obj is False:
2022-08-15 21:34:30 -06:00
s = "false"
else:
s = repr(obj)
if s[0] == "'":
s = '"' + s[1:-1] + '"'
2022-08-15 21:34:30 -06:00
print("%s" % s, end="", file=self.file)
@JsonVisitor.register(ttLib.TTFont)
def visit(self, font):
if hasattr(visitor, "font"):
2022-08-15 21:34:30 -06:00
print("{}", end="", file=self.file)
return False
visitor.font = font
self._open("{")
for tag in font.keys():
2022-08-15 21:34:30 -06:00
if self.comma:
print(",", file=self.file)
print('\n%s"%s": ' % (self._indent, tag), end="", file=self.file)
visitor.visit(font[tag])
self._close("}")
del visitor.font
return False
2022-08-15 21:59:33 -06:00
@JsonVisitor.register(ttLib.GlyphOrder)
def visit(self, obj):
self.visitList(self.font.getGlyphOrder())
return False
@JsonVisitor.register_attr(ttLib.getTableClass("glyf"), "glyphOrder")
def visit(visitor, obj, attr, value):
return False
@JsonVisitor.register(ttLib.getTableModule("glyf").GlyphCoordinates)
def visit(self, obj):
self.visitList(obj)
return False
@JsonVisitor.register(Tag)
def visit(self, obj):
2022-08-15 21:34:30 -06:00
print('"%s"' % str(obj), end="", file=self.file)
return False
2022-08-15 21:59:33 -06:00
2022-08-15 21:40:05 -06:00
@JsonVisitor.register(array)
def visit(self, obj):
self.visitList(obj)
return False
2022-08-15 21:59:33 -06:00
2022-08-15 21:40:05 -06:00
@JsonVisitor.register(bytearray)
def visit(self, obj):
self.visitList(obj)
return False
if __name__ == "__main__":
from fontTools.ttLib import TTFont
import sys
if len(sys.argv) != 2:
print("usage: print-json.py font")
sys.exit()
font = TTFont(sys.argv[1])
visitor = JsonVisitor(sys.stdout)
visitor.visit(font)