An open API service indexing awesome lists of open source software.

https://github.com/fontsource/google-font-metadata

A metadata generator that fetches and parses the Google Fonts API.
https://github.com/fontsource/google-font-metadata

fonts fontsource google-font google-fonts google-fonts-api metadata metadata-generator unicode-range

Last synced: 8 months ago
JSON representation

A metadata generator that fetches and parses the Google Fonts API.

Awesome Lists containing this project

README

          

# Google Font Metadata

[![npm version](https://badge.fury.io/js/google-font-metadata.svg)](https://badge.fury.io/js/google-font-metadata) [![License](https://badgen.net/badge/license/MIT/green)](https://github.com/fontsource/google-font-metadata/blob/master/LICENSE) [![GitHub stars](https://img.shields.io/github/stars/fontsource/google-font-metadata.svg?style=social&label=Star)](https://github.com/fontsource/google-font-metadata/stargazers)

A metadata generator that fetches and parses the Google Fonts API to be primarily used for the [Fontsource monorepo](https://github.com/fontsource/fontsource).

## Installation

Install the package from `npm`:

```shell
npm install google-font-metadata
```

## Usage

The project exports the following data:

```ts
import {
APIv1,
APIv2,
APIVariable,
APIIconStatic,
APIIconVariable,
APILicense,
APIRegistry,
} from "google-font-metadata";
const {
APIv1,
APIv2,
APIVariable,
APIIconStatic,
APIIconVariable,
APILicense,
APIRegistry,
} = require("google-font-metadata");

console.dir(APIv2);
```

## APIv1

Uses the Google Fonts CSS APIv1 that includes different font files for each subset, but does NOT include unicode-range values. This isn't usually recommended.

It exports [`data/google-fonts-v1.json`](https://github.com/fontsource/google-font-metadata/tree/main/data/google-fonts-v1.json).

```json
{
...
"abel": {
"family": "Abel",
"id": "abel",
"subsets": ["latin"],
"weights": [400],
"styles": ["normal"],
"variants": {
"400": {
"normal": {
"latin": {
"url": {
"woff2": "https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE2V9BPQ.woff2",
"woff": "https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE2V9BOw.woff",
"truetype": "https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE2V9BOA.ttf"
}
}
}
}
},
"defSubset": "latin",
"lastModified": "2022-04-20",
"version": "v18",
"category": "sans-serif"
},
...
}
```

## APIv2

Uses the Google Fonts CSS APIv2 and includes the unicode-range values for every subset. However, the API serves `ttf` files with **ALL** subsets included in one file and therefore all links for those file types in the same subset lead to the same link for each weight and style. `woff2` and `woff` files are individually split per subset.

Exports [`data/google-fonts-v2.json`](https://github.com/fontsource/google-font-metadata/tree/main/data/google-fonts-v2.json).

```json
{
...
"abel": {
"family": "Abel",
"id": "abel",
"subsets": ["latin"],
"weights": [400],
"styles": ["normal"],
"unicodeRange": {
"latin": "U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD"
},
"variants": {
"400": {
"normal": {
"latin": {
"url": {
"woff2": "https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE2V9BPQ.woff2",
"woff": "https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE6Vs.woff",
"truetype": "https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE6Vg.ttf"
}
}
}
}
},
"defSubset": "latin",
"lastModified": "2022-04-20",
"version": "v18",
"category": "sans-serif"
},
...
}
```

Note that fonts with large glyphsets such as the Japanese, Korean or Chinese language, are divided into many smaller **numbered** subsets that utilize the unicode-range @fontface selector. An example is Noto Sans JP which returns the following:

```json
{
...
"noto-sans-jp": {
"family": "Noto Sans JP",
"id": "noto-sans-jp",
"subsets": ["japanese", "latin"],
"weights": [100, 300, 400, 500, 700, 900],
"styles": ["normal"],
"unicodeRange": {
"[0]": "U+25ee8,...,U+2f9f4",
"[1]": "U+1f235-1f23b,...,U+25ed8",
...
"[119]": "U+20,...,U+ff0e"
},
"variants": {
"100": {
"normal": {
"[0]": {
"url": {
"woff2": "https://fonts.gstatic.com/s/notosansjp/v42/-F6ofjtqLzI2JPCgQBnw7HFQoggPkENvl4B0ZLgOquiXidBa3qHiDcp2RQ.0.woff2",
"woff": "https://fonts.gstatic.com/s/notosansjp/v42/-F62fjtqLzI2JPCgQBnw7HFoxQII2lcnk-AFfrgQrvWXpdFg3KXxAMsKMbdN.0.woff",
"opentype": "https://fonts.gstatic.com/s/notosansjp/v42/-F6ofjtqLzI2JPCgQBnw7HFQoggM.otf"
}
},
...,
},
...,
}
}
}
...
}
```

## APIVariable

Scrapes the Google Fonts directory and uses the Google Fonts API to generate all the relevant axis definitions and download variant metadata. You can learn more variable font axis' [here](https://fonts.google.com/variablefonts).

There are 3 default variants:

- `wght` - Only links to font files that only have the `wght` axis.
- `standard` - A default set of fonts that includes `wght, wdth, slnt, opsz` axis' if available.
- `full` - Links to font files that have all the axis' included within them.

Furthermore, a variant is generated for each unique axis in the font, e.g. if `wdth` exists, `variants.wdth.normal.latin` will exist. Note that the `wght` axis is also included in each unique custom variant.

Note that `standard` or `full` variants may not exist if there are no relevant axes in the font for that classification. This is to prevent duplicate variants with different names.

Exports [`data/variable.json`](https://github.com/fontsource/google-font-metadata/tree/main/data/variable.json).

```json
{
...
"akshar": {
"family": "Akshar",
"id": "akshar",
"axes": {
"wght": { "default": "400", "min": "300", "max": "700", "step": "1" }
},
"variants": {
"wght": {
"normal": {
"devanagari": "https://fonts.gstatic.com/s/akshar/v5/Yq6V-LyHWTfz9rGCpR5lhOc.woff2",
"latin-ext": "https://fonts.gstatic.com/s/akshar/v5/Yq6V-LyHWTfz9rGCqh5lhOc.woff2",
"latin": "https://fonts.gstatic.com/s/akshar/v5/Yq6V-LyHWTfz9rGCpB5l.woff2"
}
},
"full": {
"normal": {
"devanagari": "https://fonts.gstatic.com/s/akshar/v5/Yq6V-LyHWTfz9rGCpR5lhOc.woff2",
"latin-ext": "https://fonts.gstatic.com/s/akshar/v5/Yq6V-LyHWTfz9rGCqh5lhOc.woff2",
"latin": "https://fonts.gstatic.com/s/akshar/v5/Yq6V-LyHWTfz9rGCpB5l.woff2"
}
},
"standard": {
"normal": {
"devanagari": "https://fonts.gstatic.com/s/akshar/v5/Yq6V-LyHWTfz9rGCpR5lhOc.woff2",
"latin-ext": "https://fonts.gstatic.com/s/akshar/v5/Yq6V-LyHWTfz9rGCqh5lhOc.woff2",
"latin": "https://fonts.gstatic.com/s/akshar/v5/Yq6V-LyHWTfz9rGCpB5l.woff2"
}
}
}
},
...
}
```

Note that certain fonts such as Inter or Recursive have the SLNT axis, meaning their `font-style` in CSS won't be `normal` or `italic` on property `full` but `oblique x deg x deg`. Refer to the [CSS test fixture](https://github.com/fontsource/google-font-metadata/blob/v4/tests/fixtures/variable-parser/recursive-slnt-normal.css) for Recursive. While still showing as `normal` in metadata, it is up to the developer to include the `oblique` style if they are generating CSS using the `min` and `max` values from `recursive.axes.slnt` property.

### APIDirect and APIVariableDirect

These are arrays of generated objects from the `npx gfm generate [key]` command. It is unlikely you will use this.

```ts
import { APIDirect, APIVariableDirect } from "google-font-metadata";
const { APIDirect, APIVariableDirect } = require("google-font-metadata");
```

Exports [`data/api-response.json`](https://github.com/fontsource/google-font-metadata/tree/main/data/api-response.json) and [`data/variable-response.json`](https://github.com/fontsource/google-font-metadata/tree/main/data/variable-response.json) respectively.

## APILicense

Scrapes the [Google Fonts Attribution](https://fonts.google.com/attribution) page and returns a readable object.

```json
{
...
"abel": {
"id": "abel",
"authors": {
"copyright": "Copyright 2011, Matthew Desmond with Reserved Font Name Abel.",
"website": "http://www.madtype.com",
"email": "mattdesmond@gmail.com"
},
"license": {
"type": "SIL Open Font License, 1.1",
"url": "http://scripts.sil.org/OFL"
},
"original": "Copyright (c) 2011, Matthew Desmond (http://www.madtype.com | mattdesmond@gmail.com), with Reserved Font Name Abel."
},
...
}
```

Exports [`data/licenses.json`](https://github.com/fontsource/google-font-metadata/tree/main/data/licenses.json)

## APIRegistry

```json
{
...
{
"name": "Thick Stroke",
"tag": "XOPQ",
"min": -1000,
"max": 2000,
"default": 88,
"precision": 0
},
...
}
```

Exports [`data/axis-registry.json`](https://github.com/fontsource/google-font-metadata/tree/main/data/axis-registry.json)

You can refer to [`src/index.ts`](https://github.com/fontsource/google-font-metadata/blob/main/src/index.ts) and [`src/data.ts`](https://github.com/fontsource/google-font-metadata/blob/main/src/data.ts) to see all exports.

## Updating API Files

You can use the `gfm` CLI tool to update the metadata with fresh results from the Google APIs.

`npx gfm generate [key]` - Fetches the default Google Fonts API which can be used for parsing later. This has to be called before `npx gfm parse`.

Flags:

- `-n, --normal` - Only fetch the normal Google Developer API for APIv1 and APIv2.
- `-v, --variable` - Only scrape the variable axis page for APIVariable. Note `key` does not need to be given if this option is passed.

You are able to get a Google Fonts API `key` value from [here](https://console.developers.google.com/apis/credentials). Alternatively, you can use a `.env` file with `API_KEY=keyvalue` instead of providing a key argument in the command.

##

`npx gfm parse` - Parses through the Google Fonts CSS API and generate full metadata using the `generate` command data.

Flags:

- `-1, --v1` - Only parse and update APIv1.
- `-2, --v2` - Only parse and update APIv2.
- `-v, --variable` - Only parse and update APIVariable.
- `-l, --license` - Only parse and update APILicense.
- `-f, --force` - This skips the cache and force parses every font.
- `--no-validate` - This skips invoking `npx gfm validate` after finishing parsing.

##

`npx gfm validate` - Helper command to validate your existing metadata with a schema. This is automatically invoked with `npx gfm parse`.

Flags:

- `-1, --v1` - Only validate APIv1.
- `-2, --v2` - Only validate APIv2.
- `-v, --variable` - Only validate APIVariable.