Skip to content

Commit c406541

Browse files
glatosinskiumarcor
andcommitted
Added embedding default fonts in the theme
* Added `sphinx_immaterial.resources` module that contains pre-downloaded fonts delivered with the wheel. * Updated `add_google_fonts` method so it first checks the `sphinx_immaterial.resources` module for bundled fonts, then it checks local cache, and in the end it downloads fonts from remote server * Added downloading default fonts during stage/wheel building to `sphinx_immaterial.resources` module * Added stub `sphinx_immaterial.resources` module Signed-off-by: Grzegorz Latosinski <[email protected]> Co-authored-by: Unai Martinez-Corral <[email protected]>
1 parent cf05997 commit c406541

File tree

7 files changed

+67
-9
lines changed

7 files changed

+67
-9
lines changed

.readthedocs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ sphinx:
2121
# Optionally declare the Python requirements required to build your docs
2222
python:
2323
install:
24+
- requirements: docs/requirements.txt
2425
- method: setuptools
2526
path: .
26-
- requirements: docs/requirements.txt

docs/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
sphinx_immaterial[json,clang-format,keys,cpp]
22
sphinxcontrib-details-directive
33
sphinx-jinja
4+
pydantic
5+
importlib_resources

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ pydantic
44
typing-extensions
55
appdirs
66
requests
7+
importlib-resources

setup.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
import setuptools.command.develop
3131
import setuptools.command.install
3232
import setuptools.command.sdist
33+
from sphinx_immaterial.google_fonts import install_google_fonts
34+
35+
from importlib_resources import files
36+
from sphinx_immaterial import resources
37+
38+
from sphinx_immaterial import DEFAULT_THEME_OPTIONS
3339

3440
with open("requirements.txt", encoding="utf-8") as reqs:
3541
REQUIREMENTS = [reqs.readlines()]
@@ -146,6 +152,11 @@ def run(self):
146152
target = {"min": "build", "dev": "build:dev"}
147153

148154
try:
155+
install_google_fonts(
156+
files(resources),
157+
files(resources),
158+
DEFAULT_THEME_OPTIONS["font"].values(),
159+
)
149160
tgt = target[self.bundle_type]
150161
node_modules_path = os.path.join(root_dir, "node_modules")
151162
if self.skip_npm_reinstall and os.path.exists(node_modules_path):
@@ -187,6 +198,8 @@ def run(self):
187198
"*.html",
188199
"custom_admonitions.css",
189200
"theme.conf",
201+
"resources/*.response",
202+
"resources/*/*.response",
190203
],
191204
"sphinx_immaterial.apidoc.cpp.cppreference_data": ["*.xml"],
192205
},

sphinx_immaterial/external_resource_cache.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import os
44
import tempfile
55
from typing import Dict, Optional
6+
from importlib_resources import files
67

78
import appdirs
89
import requests
910
import sphinx.application
1011
import sphinx.config
1112
import sphinx.util.logging
1213

14+
from sphinx_immaterial import resources
15+
1316
logger = sphinx.util.logging.getLogger(__name__)
1417

1518

@@ -22,13 +25,23 @@ def get_url(
2225
req_json_encoded = json.dumps(req_json).encode("utf-8")
2326
req_key = hashlib.sha256(req_json_encoded).hexdigest()
2427

25-
resp_path = os.path.join(cache_dir, f"{req_key}.response")
28+
# First try the in-module resources
29+
mod_res_path = files(resources) / f"{req_key}.response"
2630
try:
27-
with open(resp_path, "rb") as f:
31+
with open(str(mod_res_path), "rb") as f:
2832
return f.read()
2933
except FileNotFoundError:
3034
pass
3135

36+
# Secondly, look at the cache
37+
resp_path = os.path.join(cache_dir, f"{req_key}.response")
38+
if cache_dir:
39+
try:
40+
with open(resp_path, "rb") as f:
41+
return f.read()
42+
except FileNotFoundError:
43+
pass
44+
3245
logger.info("Fetching: %s with %r", url, headers)
3346
r = requests.get( # pylint: disable=missing-timeout
3447
url, headers=headers, stream=True
@@ -37,6 +50,9 @@ def get_url(
3750

3851
response_content = r.content
3952

53+
if not cache_dir:
54+
return response_content
55+
4056
# Write request.
4157
req_path = os.path.join(cache_dir, f"{req_key}.request")
4258
os.makedirs(cache_dir, exist_ok=True)

sphinx_immaterial/google_fonts.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,25 @@ def _adjust_css_urls(css_content: bytes, renamed_fonts: Dict[str, str]) -> str:
6060
_TTF_FONT_PATHS_KEY = "sphinx_immaterial_ttf_font_paths"
6161

6262

63-
def add_google_fonts(app: sphinx.application.Sphinx, fonts: List[str]):
64-
cache_dir = os.path.join(get_cache_dir(app), "google_fonts")
65-
static_dir = os.path.join(app.outdir, "_static")
66-
# _static path
67-
font_dir = os.path.join(static_dir, "fonts")
63+
def install_google_fonts(cache_dir: str, font_dir: str, fonts: List[str]):
64+
"""
65+
Saves google fonts to given directory.
66+
67+
Firstly, it tries to load fonts from cache directory.
68+
If it fails, it downloads fonts from remote locations.
69+
70+
The font files are saved to font_dir.
71+
72+
Parameters
73+
----------
74+
cache_dir : str
75+
Directory with cached downloaded files.
76+
If cache_dir is empty, skip checking cache
77+
font_dir : str
78+
Target directory where fonts are saved
79+
fonts : List[str]
80+
List of fonts to save
81+
"""
6882
os.makedirs(font_dir, exist_ok=True)
6983

7084
with concurrent.futures.ThreadPoolExecutor(max_workers=32) as executor:
@@ -166,7 +180,16 @@ async def do_fetch():
166180
css_content = dict(zip(css_future_keys, await asyncio.gather(*css_futures)))
167181
return css_content
168182

169-
css_content = asyncio.run(do_fetch())
183+
return asyncio.run(do_fetch())
184+
185+
186+
def add_google_fonts(app: sphinx.application.Sphinx, fonts: List[str]):
187+
cache_dir = os.path.join(get_cache_dir(app), "google_fonts")
188+
static_dir = os.path.join(app.outdir, "_static")
189+
# _static path
190+
font_dir = os.path.join(static_dir, "fonts")
191+
192+
css_content = install_google_fonts(cache_dir, font_dir, fonts)
170193

171194
# Write fonts css file
172195
ttf_font_paths = {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""
2+
Module holding additional resources, i.e. built-in fonts
3+
"""

0 commit comments

Comments
 (0)