|
1 | | -"""Render the OSCAR doctrine into the docs site at build time. |
| 1 | +"""Render the OSCAR doctrine and worked examples into the docs site at build time. |
2 | 2 |
|
3 | | -The OSCAR doctrine lives in the OSCAR repo (added here as the ``oscar/`` |
4 | | -submodule), so it has a single source of truth. This mkdocs-gen-files script |
5 | | -copies the markdown from ``oscar/docs/`` into the virtual site tree under |
6 | | -``oscar/`` on every build, rewriting repo-relative links (to templates, |
7 | | -examples, and the like) so they resolve to the OSCAR repo on GitHub. |
| 3 | +The OSCAR content lives in the OSCAR repo (added here as the ``oscar/`` submodule), |
| 4 | +a single source of truth. This mkdocs-gen-files script copies the doctrine |
| 5 | +(``oscar/docs``) and the worked-example write-ups (``oscar/examples/*/README.md``) |
| 6 | +into the virtual site tree under ``oscar/`` on every build, rewriting links so they |
| 7 | +resolve either to the rendered doctrine pages or to the OSCAR repo on GitHub. |
8 | 8 |
|
9 | | -Nothing is duplicated in git: edit the docs in the OSCAR repo, bump the |
10 | | -submodule here, and docs.osc.earth reflects the change on the next build. |
| 9 | +Nothing is duplicated in git: edit the docs in the OSCAR repo, bump the submodule |
| 10 | +here, and docs.osc.earth reflects the change on the next build. |
11 | 11 | """ |
12 | 12 |
|
13 | 13 | from __future__ import annotations |
|
17 | 17 |
|
18 | 18 | import mkdocs_gen_files |
19 | 19 |
|
20 | | -SRC = Path("oscar/docs") |
21 | 20 | REPO = "https://github.com/OpenScience-Collective/oscar" |
| 21 | +DOCS_SRC = Path("oscar/docs") |
| 22 | +EXAMPLES_SRC = Path("oscar/examples") |
22 | 23 |
|
23 | | -# Links like ](../../templates/llms.txt) point at files that live in the OSCAR |
24 | | -# repo, not the docs site. Rewrite any "up and out" link to a GitHub blob URL. |
| 24 | +# Doctrine: repo-relative "up and out" links (templates, and the like) -> GitHub blob. |
25 | 25 | _UP_AND_OUT = re.compile(r"\]\((?:\.\./)+([^)]+)\)") |
| 26 | +# Example: after/ links (files or directories) -> GitHub. |
| 27 | +_AFTER = re.compile(r"\]\((after/[^)]*)\)") |
| 28 | +# Examples index: sibling directory links like ](nemar/) -> the rendered page. |
| 29 | +_EX_DIR = re.compile(r"\]\(([a-z][a-z0-9-]*)/\)") |
26 | 30 |
|
27 | 31 |
|
28 | | -def rewrite_links(text: str) -> str: |
| 32 | +def rewrite_doctrine(text: str) -> str: |
29 | 33 | return _UP_AND_OUT.sub(lambda m: f"]({REPO}/blob/main/{m.group(1)})", text) |
30 | 34 |
|
31 | 35 |
|
32 | | -if not SRC.is_dir(): |
| 36 | +def rewrite_example(text: str, name: str) -> str: |
| 37 | + # Doctrine cross-links (../../docs/X) stay on the site as ../../X. |
| 38 | + text = text.replace("](../../docs/", "](../../") |
| 39 | + |
| 40 | + # after/ links point at files that are not rendered here; send them to GitHub. |
| 41 | + def _after(m: re.Match) -> str: |
| 42 | + target = m.group(1) |
| 43 | + kind = "tree" if target.endswith("/") else "blob" |
| 44 | + return f"]({REPO}/{kind}/main/examples/{name}/{target})" |
| 45 | + |
| 46 | + return _AFTER.sub(_after, text) |
| 47 | + |
| 48 | + |
| 49 | +if not DOCS_SRC.is_dir(): |
33 | 50 | raise SystemExit( |
34 | | - f"OSCAR docs not found at {SRC}. Initialise the submodule with: " |
| 51 | + f"OSCAR docs not found at {DOCS_SRC}. Initialise the submodule with: " |
35 | 52 | "git submodule update --init oscar" |
36 | 53 | ) |
37 | 54 |
|
38 | | -for src in sorted(SRC.rglob("*.md")): |
39 | | - rel = src.relative_to(SRC) |
| 55 | +# Doctrine pages. |
| 56 | +for src in sorted(DOCS_SRC.rglob("*.md")): |
| 57 | + rel = src.relative_to(DOCS_SRC) |
40 | 58 | dest = rel.with_name("index.md") if rel.name == "README.md" else rel |
41 | 59 | out = (Path("oscar") / dest).as_posix() |
42 | 60 | with mkdocs_gen_files.open(out, "w") as fh: |
43 | | - fh.write(rewrite_links(src.read_text(encoding="utf-8"))) |
| 61 | + fh.write(rewrite_doctrine(src.read_text(encoding="utf-8"))) |
44 | 62 | mkdocs_gen_files.set_edit_path(out, f"{REPO}/edit/main/docs/{rel.as_posix()}") |
| 63 | + |
| 64 | +# Worked-example write-ups: the examples index, then one page per example. |
| 65 | +if EXAMPLES_SRC.is_dir(): |
| 66 | + index = EXAMPLES_SRC / "README.md" |
| 67 | + if index.is_file(): |
| 68 | + out = "oscar/examples/index.md" |
| 69 | + text = _EX_DIR.sub(lambda m: f"]({m.group(1)}/index.md)", index.read_text(encoding="utf-8")) |
| 70 | + with mkdocs_gen_files.open(out, "w") as fh: |
| 71 | + fh.write(text) |
| 72 | + mkdocs_gen_files.set_edit_path(out, f"{REPO}/edit/main/examples/README.md") |
| 73 | + |
| 74 | + for readme in sorted(EXAMPLES_SRC.glob("*/README.md")): |
| 75 | + name = readme.parent.name |
| 76 | + out = f"oscar/examples/{name}/index.md" |
| 77 | + with mkdocs_gen_files.open(out, "w") as fh: |
| 78 | + fh.write(rewrite_example(readme.read_text(encoding="utf-8"), name)) |
| 79 | + mkdocs_gen_files.set_edit_path(out, f"{REPO}/edit/main/examples/{name}/README.md") |
0 commit comments