Replacing Java FontBox with Python’s FontTools

During the past few days I’ve compared Apache PDFBox/FontBox with the Python FontTools library.

Because I found that the FontTools-library was a lot better at extracting information about fonts, I’ve worked to replace the tooling I wrote for preprocessing data for my ThorType website with a python lib of my own.

This would lead to one digression after another, and I’ve decided to try and generalise the generation of TypeScript files containing fonts and their metadata and share it in a library hosted on PyPi.

For this I set up the tsfontconverter repository on GitHub which uses a GitHub action to build and release on PyPi here.

The most annoying part of working with Python compared to Java are:

  1. Packaging: The tree structure and imports in Java packages are just far easier and more thought out and
  2. Reflection: Since Java is a strongly typed language, combining reflection with annotations makes serialising and auto-translating class definition to TypeScript far more straightforward.

To get around the reflection limitations, I’ve found that later versions of Python offer a few features I can use to automatically translate Class definitions to TypeScript types.

  • The @dataclass annotation is useful for creating typed classes similar to what’s known as a ‘record’ in later versions of Java. It offers a built in __dict__ method similar to the manually created to_dict-method I’ve been using together with json.dumps to serialise to json
  • The py-ts-interfaces library looks like a promising candidate for auto-translating between Python datatypes and TypeScript types
  • Regular Expressions will most likely play a role since Python is initially a scripting language and scripting languages were initially meant to deal with strings

When all this is done, I should be able to have a minimal Python script that simply imports the tsfontconverter-library and generates TypeScript-arrays containing both the metadata in plain text form and a base64-encoded data-URI ready for embedding into any Next.js application I want.

Then finally there’s the issue of testing whether or not the TypeScript-definitions are correct, this is thankfully as simple as just taking the plain text of the old TypeScript-definition file and comparing it to the output of the new function.