diff --git a/README.md b/README.md index 60c9fde..d037fed 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# CyteBase +

CyteBase

Tests diff --git a/docs/build_docs.py b/docs/build_docs.py index 8727121..cb5198d 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -391,6 +391,9 @@ def write_discovery_files( f'' f'' ) + if route.endswith("/"): + script_url = "https://docs.nygen.io/assets/brand/docs.js" + links += f'' if not count: links = canonical_tag + links if contents.count("") != 1: @@ -618,6 +621,79 @@ def update_toc(entries: list[dict]) -> None: return SITE +def link_shared_brand_assets(html: Path) -> None: + source_options = yaml.safe_load((SOURCE / "myst.yml").read_text())["site"][ + "options" + ] + config = json.loads((html / "config.json").read_text()) + urls = { + config["options"][key]: source_options[key] + for key in ("logo", "logo_dark", "favicon", "style") + } + nodes = [config["parts"]["navbar_end"]["mdast"]] + symbols = [] + while nodes: + node = nodes.pop() + if node.get("type") == "image" and node.get("class") == "brand-symbol": + symbols.append(node["url"]) + nodes.extend(node.get("children", [])) + if len(symbols) != 1: + raise ValueError(f"Expected one Nygen symbol in {html / 'config.json'}") + urls[symbols[0]] = "https://docs.nygen.io/assets/brand/logo/nygen-symbol.svg" + base_url = os.environ.get("BASE_URL", "").rstrip("/") + for page in html.rglob("*"): + if page.suffix not in {".html", ".json"}: + continue + contents = page.read_text() + for local, public in urls.items(): + contents = contents.replace(f"{base_url}/build{local}", public) + contents = contents.replace(local, public) + for name, public in ( + ("favicon.ico", source_options["favicon"]), + ("myst-theme.css", source_options["style"]), + ): + contents = contents.replace(f"{base_url}/{name}", public) + page.write_text(contents) + roots = list((html / "build").glob("root-*.js")) + if len(roots) != 1: + raise ValueError(f"Expected one generated theme root in {html / 'build'}") + contents = roots[0].read_text() + for name, public in ( + ("favicon.ico", source_options["favicon"]), + ("myst-theme.css", source_options["style"]), + ): + pattern = r'href:`\$\{[\w$]+\|\|""\}/' + re.escape(name) + r"`" + contents, count = re.subn(pattern, f"href:{json.dumps(public)}", contents) + if count != 1: + raise ValueError(f"Expected one {name} link in {roots[0]}") + roots[0].write_text(contents) + renames = { + roots[0].name: f"root-{hashlib.sha256(contents.encode()).hexdigest()[:12]}.js" + } + manifests = list((html / "build").glob("manifest-*.js")) + if len(manifests) != 1: + raise ValueError(f"Expected one generated manifest in {html / 'build'}") + contents = manifests[0].read_text().replace(roots[0].name, renames[roots[0].name]) + renames[manifests[0].name] = ( + f"manifest-{hashlib.sha256(contents.encode()).hexdigest()[:12]}.js" + ) + for page in html.rglob("*"): + if page.suffix not in {".html", ".json", ".js"}: + continue + contents = page.read_text() + updated = contents + for old, new in renames.items(): + updated = updated.replace(old, new) + if updated != contents: + page.write_text(updated) + for old, new in renames.items(): + (html / "build" / old).rename(html / "build" / new) + for local in urls: + (html / "build" / local.lstrip("/")).unlink() + (html / "favicon.ico").unlink() + (html / "myst-theme.css").unlink() + + def main() -> None: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( @@ -646,6 +722,7 @@ def main() -> None: SITE / "_build" / "html", DOCS / "build" / "api" / ".doctrees" ), ) + link_shared_brand_assets(SITE / "_build" / "html") if __name__ == "__main__": diff --git a/docs/source/myst.yml b/docs/source/myst.yml index 0d714e4..0eadda3 100644 --- a/docs/source/myst.yml +++ b/docs/source/myst.yml @@ -1,6 +1,7 @@ version: 1 project: title: CyteBase + short_title: Overview description: Search a catalog of public single-cell datasets and open them as cloud-hosted CyteArc DataStores. github: https://github.com/NygenAnalytics/CyteBase @@ -42,10 +43,16 @@ project: - file: developers/build_pipeline.md title: Build pipeline site: - template: book-theme + template: https://github.com/myst-templates/book-theme/archive/23f2df5493e23dfb1d9433c8aa64c87beb4232a3.zip parts: primary_sidebar_footer: + navbar_end: 'Nygen documentation home' options: folders: true + style: https://docs.nygen.io/assets/brand/myst.css + favicon: https://docs.nygen.io/assets/brand/logo/cytebase.ico + logo: https://docs.nygen.io/assets/brand/logo/cytebase.svg + logo_dark: https://docs.nygen.io/assets/brand/logo/cytebase.svg + logo_alt: CyteBase logo_text: CyteBase hide_authors: true diff --git a/docs/source/reference/api/conf.py b/docs/source/reference/api/conf.py index d72dc77..b8ac098 100644 --- a/docs/source/reference/api/conf.py +++ b/docs/source/reference/api/conf.py @@ -25,9 +25,13 @@ language = "en" html_theme = "sphinx_book_theme" +html_css_files = ["https://docs.nygen.io/assets/brand/docs.css"] +html_logo = "https://docs.nygen.io/assets/brand/logo/cytebase.svg" +html_favicon = "https://docs.nygen.io/assets/brand/logo/cytebase.ico" html_title = "CyteBase API reference" html_baseurl = "https://docs.nygen.io/CyteBase/api/" html_theme_options = { + "logo": {"text": "CyteBase", "alt_text": "CyteBase"}, "repository_url": "https://github.com/NygenAnalytics/CyteBase", "path_to_docs": "docs/source/reference/api", "use_repository_button": True, diff --git a/pyproject.toml b/pyproject.toml index 4d95ea2..16630ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,7 +89,7 @@ dev = [ # Builds the MyST site and the Sphinx API reference, and runs the documentation # notebooks, which plot through CyteArc. docs = [ - "mystmd>=1.11.0", + "mystmd==1.11.0", "jupytext>=1.19.6", "ipykernel>=7.3.0", "nbclient>=0.10", diff --git a/uv.lock b/uv.lock index 447e5a9..e777afc 100644 --- a/uv.lock +++ b/uv.lock @@ -918,7 +918,7 @@ docs = [ { name = "ipykernel", specifier = ">=7.3.0" }, { name = "jupytext", specifier = ">=1.19.6" }, { name = "myst-parser" }, - { name = "mystmd", specifier = ">=1.11.0" }, + { name = "mystmd", specifier = "==1.11.0" }, { name = "nbclient", specifier = ">=0.10" }, { name = "nbformat", specifier = ">=5.10" }, { name = "pyyaml" },