diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 1a010bc..b56a36a 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -9,6 +9,14 @@ them, not here. ## Adapted material +### MyST book theme + +- Source: +- Copyright (c) 2023 Executable Books. +- License: MIT +- Used in: `docs/build_docs.py` adjusts the documentation theme so navigation sections + are expanded in the initial page and remain expanded when browser code starts. + ### PyDESeq2 `cytepool/stats/deseq2.py` takes from PyDESeq2 0.5.4 (https://github.com/owkin/PyDESeq2, diff --git a/docs/build_docs.py b/docs/build_docs.py index d60804e..0fa25c9 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -273,7 +273,7 @@ def link_shared_brand_assets(html: Path) -> None: config["options"][key]: source_options[key] for key in ("logo", "logo_dark", "favicon", "style") } - nodes = [config["parts"]["navbar_end"]["mdast"]] + nodes = [config["parts"]["footer"]["mdast"]] symbols = [] while nodes: node = nodes.pop() @@ -337,6 +337,69 @@ def link_shared_brand_assets(html: Path) -> None: (html / "myst-theme.css").unlink() +def prepare_site_template(site: Path) -> None: + import yaml + + template_url = yaml.safe_load((site / "myst.yml").read_text())["site"]["template"] + template = ( + site + / "_build" + / "templates" + / "site" + / hashlib.sha256(template_url.encode()).hexdigest() + ) + if not (template / "template.yml").is_file(): + subprocess.run( + ["myst", "templates", "download", "--site", template_url], + cwd=site, + check=True, + ) + replacements = { + "build/index.js": ( + 'Pje.default.useState(i);(0,Pje.useEffect)(()=>{o.state==="idle"' + "&&s(tzt([t],e,r).includes(t.id))}", + 'Pje.default.useState(!0);(0,Pje.useEffect)(()=>{o.state==="idle"&&s(!0)}', + ), + "public/build/_shared/chunk-LS4ALTVG.js": ( + '_0.default.useState(o);(0,_0.useEffect)(()=>{i.state==="idle"' + "&&a(DS([t],e,r).includes(t.id))}", + '_0.default.useState(!0);(0,_0.useEffect)(()=>{i.state==="idle"&&a(!0)}', + ), + } + fingerprint = hashlib.sha256( + json.dumps(replacements, sort_keys=True).encode() + ).hexdigest()[:12] + for filename, (original, expanded) in replacements.items(): + path = template / filename + if not path.is_file() and filename.startswith("public/"): + path = path.with_stem(f"{path.stem}-{fingerprint}") + content = path.read_text() + if content.count(original) == 1 and expanded not in content: + path.write_text(content.replace(original, expanded)) + elif original in content or content.count(expanded) != 1: + raise ValueError(f"Unexpected navigation component in {path}") + modules = list((template / "public" / "build").rglob("*.js")) + filenames = { + path.name: f"{path.stem}-{fingerprint}.js" + for path in modules + if not path.stem.endswith(f"-{fingerprint}") + } + if not filenames: + return + if len({path.name for path in modules}) != len(modules): + raise ValueError(f"Duplicate browser module filenames in {template}") + references = re.compile(r"(? None: sitemap = html / "sitemap.xml" origin = re.search(r"(https?://[^<]+)", sitemap.read_text()) @@ -358,6 +421,7 @@ def main() -> None: site = stage_site() except ValueError as error: raise SystemExit(str(error)) from None + prepare_site_template(site) subprocess.run(["myst", "build", "--html", "--strict"], cwd=site, check=True) html = site / "_build" / "html" try: @@ -367,12 +431,32 @@ def main() -> None: except ValueError as error: raise SystemExit(str(error)) from None script_url = "https://docs.nygen.io/assets/brand/docs.js" - script = f'' + head = ( + '' + ) + head += """""" + head += f'' for page in html.rglob("*.html"): contents = page.read_text() if contents.count("") != 1: raise ValueError(f"Expected one HTML head in {page}") - page.write_text(contents.replace("", script + "", 1)) + page.write_text(contents.replace("", head + "", 1)) shutil.copytree( API, html / "api", diff --git a/docs/source/myst.yml b/docs/source/myst.yml index 22b6d74..5954894 100644 --- a/docs/source/myst.yml +++ b/docs/source/myst.yml @@ -99,7 +99,7 @@ site: template: https://github.com/myst-templates/book-theme/archive/23f2df5493e23dfb1d9433c8aa64c87beb4232a3.zip parts: primary_sidebar_footer: '' - navbar_end: 'Nygen documentation home' + footer: 'Nygen documentation home' options: folders: true style: https://docs.nygen.io/assets/brand/myst.css