blob: 76b033458637576d3bd30106a1b6c416de852c1e [file]
"""Shared Furo theme assets for LLVM Sphinx projects."""
import zlib
from pathlib import Path
from sphinx.util.fileutil import copy_asset
_SHARED_STATIC_PREFIX = "llvm-sphinx"
_SHARED_STATIC_DIR = Path(__file__).parents[1] / "_static"
def _furo_pygments_stylesheet():
from furo import get_pygments_stylesheet
return get_pygments_stylesheet()
def _rebuild_on_pygments_change(app, env, added, changed, removed):
if app.builder.format != "html":
return ()
stylesheet = _furo_pygments_stylesheet().encode()
checksum = zlib.crc32(stylesheet.translate(None, b"\r"))
previous_checksum = getattr(env, "_llvm_furo_pygments_checksum", None)
env._llvm_furo_pygments_checksum = checksum
if checksum != previous_checksum:
return env.found_docs
return ()
def _install_furo_pygments_writer(app):
if app.builder.format != "html":
return
# Sphinx normally writes pygments.css immediately before rendering HTML,
# which lets it add a checksum of that file to the stylesheet URL. Furo
# replaces the file at build-finished to add dark-mode styles, after Sphinx
# has already calculated the checksum. Generate Furo's final contents at
# Sphinx's normal asset-writing point so the checksum matches the file that
# Furo writes again at build-finished.
def create_pygments_style_file():
pygments_css = Path(app.builder.outdir) / "_static" / "pygments.css"
pygments_css.parent.mkdir(parents=True, exist_ok=True)
pygments_css.write_text(_furo_pygments_stylesheet(), encoding="utf-8")
app.builder.create_pygments_style_file = create_pygments_style_file
def _add_shared_static_files(app):
if app.builder.format != "html":
return
app.add_js_file(f"{_SHARED_STATIC_PREFIX}/copybutton.js")
app.add_css_file(f"{_SHARED_STATIC_PREFIX}/copybutton.css")
def _copy_shared_static_files(app, exception):
if exception is not None or app.builder.format != "html":
return
copy_asset(
str(_SHARED_STATIC_DIR),
str(Path(app.builder.outdir) / "_static" / _SHARED_STATIC_PREFIX),
)
def setup(app):
# Furo initializes the light and dark Pygments styles in its own
# builder-inited handler at the default priority (500).
app.connect("builder-inited", _install_furo_pygments_writer, priority=600)
app.connect("env-get-outdated", _rebuild_on_pygments_change)
app.connect("builder-inited", _add_shared_static_files)
app.connect("build-finished", _copy_shared_static_files)
return {
"version": "1.0",
"parallel_read_safe": True,
"parallel_write_safe": True,
}