diff --git a/.gitmodules b/.gitmodules index b76244d3..5e606ab2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "themes/docsy"] path = themes/docsy - url = https://github.com/google/docsy.git + url = https://github.com/matrix-org/docsy.git + branch = master diff --git a/assets-hugo/scss/_variables_project.scss b/assets-hugo/scss/_variables_project.scss index e8fb3633..1e7e3950 100644 --- a/assets-hugo/scss/_variables_project.scss +++ b/assets-hugo/scss/_variables_project.scss @@ -33,5 +33,9 @@ $warning-background: #FFE0E0; $table-row-alternate: $secondary-lightest-background; $table-row-default: $secondary-lighter-background; +/* + Opt to serve fonts locally by overriding web-font-path to be a non-google fonts URL. + This is only possible with our modified docsy theme: https://github.com/matrix-org/docsy + */ +$web-font-path: "../css/fonts/Inter.css"; $google_font_name: "Inter"; -$google_font_family: "Inter:300,300i,400,400i,700,700i"; diff --git a/static/css/fonts/Inter.css b/static/css/fonts/Inter.css new file mode 100644 index 00000000..c308cb83 --- /dev/null +++ b/static/css/fonts/Inter.css @@ -0,0 +1,168 @@ +/* cyrillic-ext */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + src: url(../../fonts/Inter-cyrillic-ext-normal-300.woff2); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + src: url(../../fonts/Inter-cyrillic-normal-300.woff2); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + src: url(../../fonts/Inter-greek-ext-normal-300.woff2); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + src: url(../../fonts/Inter-greek-normal-300.woff2); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + src: url(../../fonts/Inter-vietnamese-normal-300.woff2); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + src: url(../../fonts/Inter-latin-ext-normal-300.woff2); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + src: url(../../fonts/Inter-latin-normal-300.woff2); + unicode-range: 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; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + src: url(../../fonts/Inter-cyrillic-ext-normal-400.woff2); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + src: url(../../fonts/Inter-cyrillic-normal-400.woff2); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + src: url(../../fonts/Inter-greek-ext-normal-400.woff2); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + src: url(../../fonts/Inter-greek-normal-400.woff2); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + src: url(../../fonts/Inter-vietnamese-normal-400.woff2); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + src: url(../../fonts/Inter-latin-ext-normal-400.woff2); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + src: url(../../fonts/Inter-latin-normal-400.woff2); + unicode-range: 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; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + src: url(../../fonts/Inter-cyrillic-ext-normal-700.woff2); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + src: url(../../fonts/Inter-cyrillic-normal-700.woff2); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + src: url(../../fonts/Inter-greek-ext-normal-700.woff2); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + src: url(../../fonts/Inter-greek-normal-700.woff2); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + src: url(../../fonts/Inter-vietnamese-normal-700.woff2); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + src: url(../../fonts/Inter-latin-ext-normal-700.woff2); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + src: url(../../fonts/Inter-latin-normal-700.woff2); + unicode-range: 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; +} diff --git a/static/css/fonts/README.md b/static/css/fonts/README.md new file mode 100644 index 00000000..e6eb74eb --- /dev/null +++ b/static/css/fonts/README.md @@ -0,0 +1,30 @@ +# Fonts + +## Inter.css + +`Inter.css` is a local copy of +https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i, modified to pull +font files (`.woff2`) from local sources. It was created +using `download_google_fonts_css.py`. + +## download_google_fonts_css.py + +`download_google_fonts_css.py` is a script that takes a google fonts CSS URL, downloads +the file and linked fonts, then saves the fonts locally along with a modified CSS file to +load them. Example call: + +```sh +python3 download_google_fonts_css.py \ + "https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i" \ + ../../fonts \ + ../../fonts +``` + +Which would pop out a `Inter.css` file that should be `@import url("Inter.css")`d +somewhere in the site's SCSS (currently in +[/assets-hugo/scss/_variables_project.scss](/assets-hugo/scss/_variables_project.scss)). + +Re-running the script and committing any new files is only necessary when a desired +font updates (not very often), or we want to change the font we're using. In that case, +remove the existing font files at `/static/fonts/*.woff2` and re-run the script with a +different URL. \ No newline at end of file diff --git a/static/css/fonts/download_google_fonts_css.py b/static/css/fonts/download_google_fonts_css.py new file mode 100755 index 00000000..f903843e --- /dev/null +++ b/static/css/fonts/download_google_fonts_css.py @@ -0,0 +1,134 @@ +#!/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 +font_weight = 0 +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-%d.woff2" % ( + font_family, font_lang, font_style, font_weight + ) + font_filepath = font_output_dir + filename + with open(font_filepath, "w") as f: + print("Writing font file:", font_filepath) + f.write(resp.text) + + # Replace google URL with local URL + line = re.sub(r"url\(.+\)", f"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) + font_weight_match = re.match(r".*font-weight: (.+);$", line) + if font_weight_match: + font_weight = int(font_weight_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) diff --git a/static/css/fonts/requirements.txt b/static/css/fonts/requirements.txt new file mode 100644 index 00000000..f2293605 --- /dev/null +++ b/static/css/fonts/requirements.txt @@ -0,0 +1 @@ +requests diff --git a/static/fonts/Inter-cyrillic-ext-normal-300.woff2 b/static/fonts/Inter-cyrillic-ext-normal-300.woff2 new file mode 100644 index 00000000..968dbbf3 Binary files /dev/null and b/static/fonts/Inter-cyrillic-ext-normal-300.woff2 differ diff --git a/static/fonts/Inter-cyrillic-ext-normal-400.woff2 b/static/fonts/Inter-cyrillic-ext-normal-400.woff2 new file mode 100644 index 00000000..bec815b9 Binary files /dev/null and b/static/fonts/Inter-cyrillic-ext-normal-400.woff2 differ diff --git a/static/fonts/Inter-cyrillic-ext-normal-700.woff2 b/static/fonts/Inter-cyrillic-ext-normal-700.woff2 new file mode 100644 index 00000000..23a5988d Binary files /dev/null and b/static/fonts/Inter-cyrillic-ext-normal-700.woff2 differ diff --git a/static/fonts/Inter-cyrillic-normal-300.woff2 b/static/fonts/Inter-cyrillic-normal-300.woff2 new file mode 100644 index 00000000..c40ca197 Binary files /dev/null and b/static/fonts/Inter-cyrillic-normal-300.woff2 differ diff --git a/static/fonts/Inter-cyrillic-normal-400.woff2 b/static/fonts/Inter-cyrillic-normal-400.woff2 new file mode 100644 index 00000000..4480c694 Binary files /dev/null and b/static/fonts/Inter-cyrillic-normal-400.woff2 differ diff --git a/static/fonts/Inter-cyrillic-normal-700.woff2 b/static/fonts/Inter-cyrillic-normal-700.woff2 new file mode 100644 index 00000000..fecd9802 Binary files /dev/null and b/static/fonts/Inter-cyrillic-normal-700.woff2 differ diff --git a/static/fonts/Inter-greek-ext-normal-300.woff2 b/static/fonts/Inter-greek-ext-normal-300.woff2 new file mode 100644 index 00000000..dbffc09b Binary files /dev/null and b/static/fonts/Inter-greek-ext-normal-300.woff2 differ diff --git a/static/fonts/Inter-greek-ext-normal-400.woff2 b/static/fonts/Inter-greek-ext-normal-400.woff2 new file mode 100644 index 00000000..503ae66b Binary files /dev/null and b/static/fonts/Inter-greek-ext-normal-400.woff2 differ diff --git a/static/fonts/Inter-greek-ext-normal-700.woff2 b/static/fonts/Inter-greek-ext-normal-700.woff2 new file mode 100644 index 00000000..a7f82128 Binary files /dev/null and b/static/fonts/Inter-greek-ext-normal-700.woff2 differ diff --git a/static/fonts/Inter-greek-normal-300.woff2 b/static/fonts/Inter-greek-normal-300.woff2 new file mode 100644 index 00000000..ac8d7eab Binary files /dev/null and b/static/fonts/Inter-greek-normal-300.woff2 differ diff --git a/static/fonts/Inter-greek-normal-400.woff2 b/static/fonts/Inter-greek-normal-400.woff2 new file mode 100644 index 00000000..745fbd32 Binary files /dev/null and b/static/fonts/Inter-greek-normal-400.woff2 differ diff --git a/static/fonts/Inter-greek-normal-700.woff2 b/static/fonts/Inter-greek-normal-700.woff2 new file mode 100644 index 00000000..f2c62111 Binary files /dev/null and b/static/fonts/Inter-greek-normal-700.woff2 differ diff --git a/static/fonts/Inter-latin-ext-normal-300.woff2 b/static/fonts/Inter-latin-ext-normal-300.woff2 new file mode 100644 index 00000000..ea63a77d Binary files /dev/null and b/static/fonts/Inter-latin-ext-normal-300.woff2 differ diff --git a/static/fonts/Inter-latin-ext-normal-400.woff2 b/static/fonts/Inter-latin-ext-normal-400.woff2 new file mode 100644 index 00000000..483a3d0d Binary files /dev/null and b/static/fonts/Inter-latin-ext-normal-400.woff2 differ diff --git a/static/fonts/Inter-latin-ext-normal-700.woff2 b/static/fonts/Inter-latin-ext-normal-700.woff2 new file mode 100644 index 00000000..26761af1 Binary files /dev/null and b/static/fonts/Inter-latin-ext-normal-700.woff2 differ diff --git a/static/fonts/Inter-latin-normal-300.woff2 b/static/fonts/Inter-latin-normal-300.woff2 new file mode 100644 index 00000000..758703fc Binary files /dev/null and b/static/fonts/Inter-latin-normal-300.woff2 differ diff --git a/static/fonts/Inter-latin-normal-400.woff2 b/static/fonts/Inter-latin-normal-400.woff2 new file mode 100644 index 00000000..8ff30ee1 Binary files /dev/null and b/static/fonts/Inter-latin-normal-400.woff2 differ diff --git a/static/fonts/Inter-latin-normal-700.woff2 b/static/fonts/Inter-latin-normal-700.woff2 new file mode 100644 index 00000000..ce4cb16a Binary files /dev/null and b/static/fonts/Inter-latin-normal-700.woff2 differ diff --git a/static/fonts/Inter-vietnamese-normal-300.woff2 b/static/fonts/Inter-vietnamese-normal-300.woff2 new file mode 100644 index 00000000..5a9656a1 Binary files /dev/null and b/static/fonts/Inter-vietnamese-normal-300.woff2 differ diff --git a/static/fonts/Inter-vietnamese-normal-400.woff2 b/static/fonts/Inter-vietnamese-normal-400.woff2 new file mode 100644 index 00000000..022a0ee2 Binary files /dev/null and b/static/fonts/Inter-vietnamese-normal-400.woff2 differ diff --git a/static/fonts/Inter-vietnamese-normal-700.woff2 b/static/fonts/Inter-vietnamese-normal-700.woff2 new file mode 100644 index 00000000..a66d145f Binary files /dev/null and b/static/fonts/Inter-vietnamese-normal-700.woff2 differ diff --git a/themes/docsy b/themes/docsy index b7562e9c..5023a291 160000 --- a/themes/docsy +++ b/themes/docsy @@ -1 +1 @@ -Subproject commit b7562e9cb99c652ebb5ade75d2203db08ad81ede +Subproject commit 5023a2914528e012ecf3ec85a56028c00ee97dd2