Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ them, not here.

## Adapted material

### MyST book theme

- Source: <https://github.com/jupyter-book/myst-theme>
- 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,
Expand Down
90 changes: 87 additions & 3 deletions docs/build_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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"(?<![\w$().\[\]-])[\w$().\[\]-]+\.js\b")
for path in [template / "build" / "index.js", *modules]:
path.write_text(
references.sub(
lambda match: filenames.get(match[0], match[0]), path.read_text()
)
)
for path in modules:
if path.name in filenames:
path.rename(path.with_name(filenames[path.name]))


def set_crawler_origin(html: Path) -> None:
sitemap = html / "sitemap.xml"
origin = re.search(r"<loc>(https?://[^<]+)</loc>", sitemap.read_text())
Expand All @@ -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:
Expand All @@ -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'<script defer src="{script_url}"></script>'
head = (
'<link rel="preload" as="font" '
'href="https://docs.nygen.io/assets/brand/fonts/inter/latin.woff2" '
'type="font/woff2" crossorigin/>'
)
head += """<script>
(() => {
const observer = new MutationObserver(() => {
if (!document.querySelector('main')) return;
observer.disconnect();
const sidebar = document.querySelector('.myst-primary-sidebar-nav');
const home = document.querySelector('.myst-home-link');
if (sidebar?.clientHeight && home) {
const saved = sessionStorage.getItem('nygen-docs-sidebar:' + home.pathname);
if (saved !== null) sidebar.scrollTop = Number(saved);
}
});
observer.observe(document.documentElement, {childList: true, subtree: true});
})();
</script>"""
head += f'<script defer src="{script_url}"></script>'
for page in html.rglob("*.html"):
contents = page.read_text()
if contents.count("</head>") != 1:
raise ValueError(f"Expected one HTML head in {page}")
page.write_text(contents.replace("</head>", script + "</head>", 1))
page.write_text(contents.replace("</head>", head + "</head>", 1))
shutil.copytree(
API,
html / "api",
Expand Down
2 changes: 1 addition & 1 deletion docs/source/myst.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ site:
template: https://github.com/myst-templates/book-theme/archive/23f2df5493e23dfb1d9433c8aa64c87beb4232a3.zip
parts:
primary_sidebar_footer: '<!-- No sidebar footer. -->'
navbar_end: '<a class="docs-home-link" href="https://docs.nygen.io/"><img class="brand-symbol" src="https://docs.nygen.io/assets/brand/logo/nygen-symbol.svg" alt="Nygen documentation home" width="32" height="32"></a>'
footer: '<a class="docs-home-link" href="https://docs.nygen.io/"><img class="brand-symbol" src="https://docs.nygen.io/assets/brand/logo/nygen-symbol.svg" alt="Nygen documentation home" width="32" height="32"></a>'
options:
folders: true
style: https://docs.nygen.io/assets/brand/myst.css
Expand Down