32 lines
1.9 KiB
Python
32 lines
1.9 KiB
Python
"""Fetch public font assets and OFL licenses. Run only when refreshing assets."""
|
|
from pathlib import Path
|
|
import urllib.request
|
|
import re
|
|
|
|
out = Path(__file__).resolve().parent.parent / 'assets' / 'fonts'
|
|
out.mkdir(parents=True, exist_ok=True)
|
|
fonts = [('DM Sans', 'dm-sans', 'dmsans'), ('IBM Plex Sans', 'ibm-plex-sans', 'ibmplexsans'), ('Manrope', 'manrope', 'manrope')]
|
|
for family, slug, upstream in fonts:
|
|
url = 'https://fonts.googleapis.com/css2?family=' + family.replace(' ', '+') + ':wght@400;500;600;700&display=swap'
|
|
req = urllib.request.Request(url, headers={'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36'})
|
|
css = urllib.request.urlopen(req, timeout=25).read().decode()
|
|
# Google returns one Latin block per requested weight. Keep all four real weights.
|
|
sources = []
|
|
for weight in ['400','500','600','700']:
|
|
blocks = re.findall(r'/\* latin \*/\s*(@font-face\s*\{[^}]+\})', css)
|
|
block = next((b for b in blocks if f'font-weight: {weight};' in b), None)
|
|
if not block:
|
|
raise RuntimeError(f'No Latin block for {family} {weight}')
|
|
source = re.search(r'url\(([^)]+)\)', block).group(1)
|
|
data = urllib.request.urlopen(source, timeout=25).read()
|
|
assert data[:4] == b'wOF2', 'Expected WOFF2'
|
|
name = f'{slug}-{weight}.woff2'
|
|
(out / name).write_bytes(data)
|
|
sources.append(f'{weight}: {source}')
|
|
license_url = f'https://raw.githubusercontent.com/google/fonts/main/ofl/{upstream}/OFL.txt'
|
|
license_text = urllib.request.urlopen(license_url, timeout=25).read()
|
|
assert b'SIL OPEN FONT LICENSE' in license_text
|
|
(out / f'{slug}-OFL.txt').write_bytes(license_text)
|
|
(out / f'{slug}-sources.txt').write_text(f'{family}\nCSS: {url}\nLicense: {license_url}\n' + '\n'.join(sources) + '\n')
|
|
print(f'{family}: 4 WOFF2 weights and OFL license saved')
|