Skip to content

Instantly share code, notes, and snippets.

@bornfree
Last active November 17, 2018 08:26
Show Gist options
  • Save bornfree/95b7fb496bc38e0932895fd0a5f03ed5 to your computer and use it in GitHub Desktop.
Save bornfree/95b7fb496bc38e0932895fd0a5f03ed5 to your computer and use it in GitHub Desktop.
Convert Google Fonts Protobuf to JSON
"""
This will read through the Google Fonts repo and make unified JSON of it
"""
import os
import sys
import io
from collections import defaultdict
import json
def is_font_dir(path, font_folders):
for f in os.listdir(path):
f_path = os.path.join(path, f)
if os.path.isfile(f_path) and f == "METADATA.pb":
font_folders.append(path)
return
elif os.path.isdir(f_path):
is_font_dir(f_path, font_folders)
def metadata_to_json(metadata_file_path):
lines = io.open(metadata_file_path, encoding="utf-8").readlines()
font_json = defaultdict(list)
nested = False
nested_json = defaultdict(list)
for line in lines:
line = line.strip()
if ":" in line:
key, value = line.split(":")[0:2]
if nested is True:
nested_json[key].append(value)
else:
font_json[key].append(value)
elif " {" in line:
nested = True
nested_key, _ = line.split(" ")
elif "}" in line:
nested = False
font_json[nested_key].append(nested_json)
nested_json = defaultdict(list)
return font_json
def clean(val):
if type(val) is not str:
return val
val = val.strip()
if val.startswith("\"") and val.endswith("\""):
val = val[1:-1]
return val.strip()
def simplify_json(font_json):
for k,v in font_json.items():
for i, val in enumerate(v):
if type(val) is dict or type(val) is defaultdict:
font_json[k][i] = simplify_json(val)
else:
font_json[k][i] = clean(val)
for k,v in font_json.items():
if len(v) == 1 and k != "fonts":
font_json[k] = clean(v[0])
return font_json
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Please provide path to Google Fonts repo")
exit(0)
# Get Google Fonts directory
gfonts_path = sys.argv[1]
# Recurse and find all fonts directory
font_folders = []
is_font_dir(gfonts_path, font_folders)
print("Found {} font folders.".format(len(font_folders)))
print("Parsing...")
fonts_info = []
with io.open("fonts.json", "w", encoding="utf-8") as f:
for folder in font_folders:
metadata_path = os.path.join(folder, "METADATA.pb")
font_json = metadata_to_json(metadata_path)
font_json = simplify_json(font_json)
font_json["files_path"] = folder
fonts_info.append(font_json)
json.dump({"info": fonts_info}, f)
print("Fonts info written to fonts.json")
@bornfree
Copy link
Author

Google Fonts repo unfortunately stopped keeping metadata as JSON.
And I do not know how to parse Protobuf natively in Python.

This scripts converts all the metadata into one big nice JSON.
Clone https://github.com/google/fonts and then run

python google-fonts-protobuf-to-json.py path-to-google-fonts-directory

It will create fonts.json in the current directory if if all went well which will look like:

{
  "info": [
    {
      "fonts": [
        {
          "post_script_name": "CraftyGirls-Regular",
          "style": "normal",
          "name": "Crafty Girls",
          "full_name": "Crafty Girls Regular",
          "copyright": "Copyright (c) 2010 by Font Diner, Inc DBA Tart Workshop. All rights reserved.",
          "filename": "CraftyGirls-Regular.ttf",
          "weight": "400"
        }
      ],
      "designer": "Tart Workshop",
      "name": "Crafty Girls",
      "date_added": "2011-01-06",
      "category": "HANDWRITING",
      "subsets": [
        "latin",
        "menu"
      ],
      "license": "APACHE2",
      "files_path": "google-fonts/apache/craftygirls"
    },
    {
      "fonts": [
        {
          "post_script_name": "Arimo-Regular",
          "style": "normal",
          "name": "Arimo",
          "full_name": "Arimo Regular",
          "copyright": "Digitized data copyright (c) 2010-2012 Google Corporation.",
          "filename": "Arimo-Regular.ttf",
          "weight": "400"
        },
        {
          "post_script_name": "Arimo-Italic",
          "style": "italic",
          "name": "Arimo",
          "full_name": "Arimo Italic",
          "copyright": "Digitized data copyright (c) 2010-2012 Google Corporation.",
          "filename": "Arimo-Italic.ttf",
          "weight": "400"
        },
        {
          "post_script_name": "Arimo-Bold",
          "style": "normal",
          "name": "Arimo",
          "full_name": "Arimo Bold"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment