|
5 | 5 |
|
6 | 6 |
|
7 | 7 | def _sync_example_notebooks(app): |
8 | | - """Copy every *.ipynb from the repo examples/ dir into docs/source/examples/. |
| 8 | + """Copy every *.ipynb from the repo ``examples/`` dir into |
| 9 | + ``docs/source/examples/`` so Sphinx can find them. |
9 | 10 |
|
10 | | - This keeps the docs in sync with the authoritative source notebooks without |
11 | | - requiring a manual copy step. The ReadTheDocs pre_build step in |
12 | | - .readthedocs.yaml also does this, but running it here means local ``make |
13 | | - docs`` builds are always up to date as well. |
| 11 | + ``docs/source/examples/*.ipynb`` is gitignored — the authoritative copies |
| 12 | + live in ``examples/``. Running this at every Sphinx build keeps the docs |
| 13 | + in sync, both locally (``make docs``) and on ReadTheDocs (in addition to |
| 14 | + the pre_build ``cp`` step in ``.readthedocs.yml``). |
| 15 | +
|
| 16 | + We use ``shutil.copy`` (not ``copy2``) so the destination mtime is updated |
| 17 | + to ``now`` — this guarantees Sphinx's incremental build sees the file as |
| 18 | + changed and re-renders it instead of using a cached ``.doctree``. |
14 | 19 | """ |
15 | 20 | src = Path(app.srcdir).parent.parent / "examples" |
16 | 21 | dst = Path(app.srcdir) / "examples" |
17 | | - dst.mkdir(exist_ok=True) |
18 | | - for nb in src.glob("*.ipynb"): |
19 | | - shutil.copy2(nb, dst / nb.name) |
| 22 | + if not src.is_dir(): |
| 23 | + print(f"[conf.py] WARNING: examples source dir not found: {src}") |
| 24 | + return |
| 25 | + dst.mkdir(parents=True, exist_ok=True) |
| 26 | + copied = [] |
| 27 | + for nb in sorted(src.glob("*.ipynb")): |
| 28 | + shutil.copy(nb, dst / nb.name) |
| 29 | + copied.append(nb.name) |
| 30 | + print(f"[conf.py] Synced {len(copied)} notebook(s) from {src} -> {dst}: {copied}") |
20 | 31 |
|
21 | 32 |
|
22 | 33 | def setup(app): |
|
0 commit comments