diff --git a/conf.py b/conf.py index 156a7529..24b99bb8 100644 --- a/conf.py +++ b/conf.py @@ -95,6 +95,35 @@ html_show_sourcelink = False +def namespace_generated_labels(spec_dir, version): + """Prefix the labels generated by ``pre_build.py`` with the spec version. + + ``pre_build.py`` emits targets such as ``(examples:multiscales_strict:...)=`` + and ``(schemas:image)=``. Every version submodule uses the exact same names, + so once Sphinx reads them all into a single project the duplicates collapse + and *all* of them resolve to whichever version happened to be read first + (``dev``). Links on the 0.5 examples/schemas pages then silently pointed at + the dev spec. + + Hand-written spec labels already namespace themselves as ``version0.5:...``; + do the same for the generated ones. This is done here in the superproject so + we do not have to edit, commit, and bump every ngff-spec version submodule. + """ + import re + from pathlib import Path + + prefix = f"version{version}:" + # target definition at the start of a line, and MyST link to such a target + target_re = re.compile(r"^\((examples|schemas):", re.MULTILINE) + link_re = re.compile(r"\]\(#(examples|schemas):") + + for md_file in Path(spec_dir).rglob("*.md"): + text = md_file.read_text(encoding="utf-8") + patched = link_re.sub(rf"](#{prefix}\1:", target_re.sub(rf"({prefix}\1:", text)) + if patched != text: + md_file.write_text(patched, encoding="utf-8") + + def build_served_html(): import glob import subprocess @@ -143,6 +172,9 @@ def build_served_html(): subprocess.check_call([sys.executable, script]) print("✅ Built rendered examples/schemas for version", version) + namespace_generated_labels(spec_dir, version) + print(f"✅ Namespaced generated labels for version {version}") + # build jupyter-book docs in specification submodules myst_file = glob.glob(f"specifications/{version}/**/myst.yml", recursive=True)[ 0