The version of Inter is updated to use a variable font, which is supported widely among modern browsers. Using `display: swap` means that the browser will render the text of the spec even before Inter is loaded, making the website appear to load faster on mobile. Allow the browser to use the local Inter font if it exists.
131 lines
4.9 KiB
Python
Executable file
131 lines
4.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# Copyright 2021 The Matrix.org Foundation C.I.C.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# This script takes a google fonts CSS URL, downloads the referenced fonts locally
|
|
# and spits out a modified CSS file which now points to those local fonts.
|
|
#
|
|
# Purely for the purposes of converting a website to use local font files instead of
|
|
# making requests to Google Fonts.
|
|
|
|
import re
|
|
import requests
|
|
import subprocess
|
|
import sys
|
|
|
|
# Pull the font filename to process and output directory to point at
|
|
if len(sys.argv) < 4:
|
|
print(f"""
|
|
Error: Not enough arguments.
|
|
|
|
Usage: {sys.argv[0]} google_fonts_url font_directory css_font_path
|
|
* google fonts url: A URL leading to a google font css file (i.e https://fonts.googleapis.com/css?family=Inter)
|
|
* font directory: The location that font files will be downloaded to (i.e ../../fonts)
|
|
* font path: The directory the resulting CSS will be pointing to, relative to site root (i.e /unstable/css/fonts).
|
|
This is where the browser will look for fonts.
|
|
""")
|
|
sys.exit(1)
|
|
|
|
google_fonts_url = sys.argv[1]
|
|
font_output_dir = sys.argv[2]
|
|
css_font_path = sys.argv[3]
|
|
|
|
# Get font name
|
|
if google_fonts_url.count(":") > 1:
|
|
# Account for font weights specified in the URL
|
|
# (i.e https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i)
|
|
url_match = re.match(r".*family=(.*):", google_fonts_url)
|
|
else:
|
|
url_match = re.match(r".*family=(.*)", google_fonts_url)
|
|
|
|
if not url_match:
|
|
print("Unable to extract font name, invalid google fonts URL:", google_fonts_url)
|
|
print("URL should look something like: https://fonts.googleapis.com/css?family=Inter...")
|
|
sys.exit(1)
|
|
|
|
font_name = url_match.group(1)
|
|
|
|
# Ensure font paths end with a trailing slash
|
|
if not font_output_dir.endswith("/"):
|
|
font_output_dir += "/"
|
|
if not css_font_path.endswith("/"):
|
|
css_font_path += "/"
|
|
|
|
# Download the css file and split by newline
|
|
resp = requests.get(
|
|
google_fonts_url,
|
|
# We need to set a believable user-agent, else google fonts won't give us
|
|
# all of the font weights we requested for some reason
|
|
headers={
|
|
"User-Agent": "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0"
|
|
}
|
|
)
|
|
if resp.status_code != 200:
|
|
print("Failed to download:", google_fonts_url, resp.status_code)
|
|
sys.exit(1)
|
|
|
|
original_contents = resp.text.split("\n")
|
|
|
|
# Download all referenced font files and write out new font file
|
|
new_css_file_lines = []
|
|
|
|
# Store metadata for helping give friendly names to each font file
|
|
font_lang = None
|
|
font_family = None
|
|
font_style = None
|
|
for line in original_contents:
|
|
# Check if this line contains a font URL
|
|
match = re.match(r".*url\((.*)\) format.*", line)
|
|
if match:
|
|
# Download the font file
|
|
font_url = match.group(1)
|
|
print("Downloading font:", font_url)
|
|
|
|
resp = requests.get(font_url)
|
|
if resp.status_code == 200:
|
|
# Save the font file
|
|
filename = "%s-%s-%s.woff2" % (
|
|
font_family, font_lang, font_style
|
|
)
|
|
font_filepath = font_output_dir + filename
|
|
with open(font_filepath, "wb") as f:
|
|
print("Writing font file:", font_filepath)
|
|
f.write(resp.content)
|
|
|
|
# Replace google URL with local URL and allow the browser to load the
|
|
# local font if it exists.
|
|
line = re.sub(r"url\(.+?\)", f"local('{font_family}'), url({css_font_path + filename})", line)
|
|
else:
|
|
print("Warning: failed to download font file:", font_url)
|
|
|
|
# Check for font metadata. If there is some, we'll note it down and use it to help
|
|
# name font files when we write them out.
|
|
# Makes for nicer font filenames than fvQtMwCp50KnMw2boKod... etc.
|
|
font_lang_match = re.match(r"^/\* (.+) \*/$", line)
|
|
if font_lang_match:
|
|
font_lang = font_lang_match.group(1)
|
|
font_family_match = re.match(r".*font-family: '(.+)';$", line)
|
|
if font_family_match:
|
|
font_family = font_family_match.group(1)
|
|
font_style_match = re.match(r".*font-style: (.+);$", line)
|
|
if font_style_match:
|
|
font_style = font_style_match.group(1)
|
|
|
|
# Append the potentially modified line to the new css file
|
|
new_css_file_lines.append(line)
|
|
|
|
# Write out the new font css file
|
|
with open(font_name + ".css", "w") as f:
|
|
new_css_file_contents = "\n".join(new_css_file_lines)
|
|
f.write(new_css_file_contents)
|