Skip to content

Commit 04093bb

Browse files
migrate images
1 parent ed1a76f commit 04093bb

File tree

43 files changed

+175
-30
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+175
-30
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#!/usr/bin/env python3
2+
"""Copy user-guide images into the standard per-page folder and update doc refs.
3+
4+
Standard:
5+
static/img/user-guide/<section>/<page>/
6+
where <section> and <page> are slugified from the doc path under user-guide/.
7+
"""
8+
9+
from __future__ import annotations
10+
11+
import argparse
12+
import os
13+
import re
14+
import shutil
15+
from pathlib import Path
16+
from typing import Iterable, Optional
17+
18+
19+
def slugify(value: str) -> str:
20+
value = value.strip().lower()
21+
value = re.sub(r"[^a-z0-9]+", "-", value)
22+
return value.strip("-")
23+
24+
25+
def iter_image_refs(markdown: str) -> Iterable[str]:
26+
# Match Markdown image syntax: ![alt](/img/user-guide/.../file.png)
27+
pattern = re.compile(r"!\[[^\]]*\]\((/img/user-guide/[^\)]+)\)")
28+
for match in pattern.finditer(markdown):
29+
yield match.group(1)
30+
31+
32+
def compute_standard_dir(doc_path: Path, repo_root: Path) -> Optional[Path]:
33+
rel = doc_path.relative_to(repo_root / "user-guide")
34+
parts = rel.parts
35+
if len(parts) < 2:
36+
return None
37+
38+
section = slugify(parts[0])
39+
page = slugify(Path(parts[-1]).stem)
40+
return repo_root / "static" / "img" / "user-guide" / section / page
41+
42+
43+
def update_markdown_refs(markdown: str, old_to_new: dict[str, str]) -> str:
44+
for old, new in old_to_new.items():
45+
markdown = markdown.replace(old, new)
46+
return markdown
47+
48+
49+
def find_existing_image_by_name(repo_root: Path, filename: str) -> Optional[Path]:
50+
matches = list((repo_root / "static" / "img" / "user-guide").rglob(filename))
51+
if len(matches) == 1:
52+
return matches[0]
53+
return None
54+
55+
56+
def standardize(doc_path: Path, repo_root: Path, dry_run: bool) -> None:
57+
standard_dir = compute_standard_dir(doc_path, repo_root)
58+
if standard_dir is None:
59+
print(f"skipping (no section folder): {doc_path}")
60+
return
61+
standard_dir.mkdir(parents=True, exist_ok=True)
62+
63+
markdown = doc_path.read_text(encoding="utf-8")
64+
old_to_new: dict[str, str] = {}
65+
66+
for ref in iter_image_refs(markdown):
67+
# Only move user-guide images referenced by this doc
68+
if not ref.startswith("/img/user-guide/"):
69+
continue
70+
src = repo_root / "static" / ref.lstrip("/")
71+
if not src.exists():
72+
fallback = find_existing_image_by_name(repo_root, src.name)
73+
if fallback is None:
74+
print(f"missing source for {ref} in {doc_path}")
75+
continue
76+
src = fallback
77+
78+
dest = standard_dir / src.name
79+
new_ref = f"/img/user-guide/{standard_dir.relative_to(repo_root / 'static' / 'img' / 'user-guide').as_posix()}/{src.name}"
80+
81+
if src.resolve() == dest.resolve():
82+
continue
83+
84+
old_to_new[ref] = new_ref
85+
86+
if dest.exists():
87+
continue
88+
89+
if dry_run:
90+
print(f"DRY RUN: would copy {src} -> {dest}")
91+
else:
92+
dest.parent.mkdir(parents=True, exist_ok=True)
93+
shutil.copy2(str(src), str(dest))
94+
print(f"copied {src} -> {dest}")
95+
96+
if old_to_new:
97+
updated = update_markdown_refs(markdown, old_to_new)
98+
if dry_run:
99+
print(f"DRY RUN: would update refs in {doc_path}")
100+
else:
101+
doc_path.write_text(updated, encoding="utf-8")
102+
print(f"updated refs in {doc_path}")
103+
else:
104+
print("no image refs to update")
105+
106+
107+
def iter_doc_paths(target: Path) -> Iterable[Path]:
108+
if target.is_dir():
109+
yield from target.rglob("*.md")
110+
yield from target.rglob("*.mdx")
111+
else:
112+
yield target
113+
114+
115+
def main() -> None:
116+
parser = argparse.ArgumentParser(
117+
description="Move user-guide images into the standard per-page folder and update doc refs."
118+
)
119+
parser.add_argument(
120+
"target",
121+
help="Path to a user-guide doc file or directory (e.g., user-guide/03-Extending your Pioreactor/ or a specific .md/.mdx file)",
122+
)
123+
parser.add_argument(
124+
"--repo-root",
125+
default=os.getcwd(),
126+
help="Repository root (default: cwd)",
127+
)
128+
parser.add_argument("--dry-run", action="store_true", help="Print actions without changing files")
129+
args = parser.parse_args()
130+
131+
target = Path(args.target).resolve()
132+
repo_root = Path(args.repo_root).resolve()
133+
134+
if not target.exists():
135+
raise SystemExit(f"Target not found: {target}")
136+
137+
docs_root = repo_root / "user-guide"
138+
for doc_path in iter_doc_paths(target):
139+
if docs_root not in doc_path.parents:
140+
continue
141+
standardize(doc_path, repo_root, args.dry_run)
142+
143+
144+
if __name__ == "__main__":
145+
main()

static/img/user-guide/02-experiment-basics/11-running-self-test/inventory-self-test-button.png renamed to static/img/user-guide/01-getting-started/03-pre-flight-hardware-check/inventory-self-test-button.png

File renamed without changes.

static/img/user-guide/02-experiment-basics/11-running-self-test/inventory-self-test-pre.png renamed to static/img/user-guide/01-getting-started/03-pre-flight-hardware-check/inventory-self-test-pre.png

File renamed without changes.

static/img/user-guide/02-experiment-basics/11-running-self-test/inventory-self-test-running.png renamed to static/img/user-guide/01-getting-started/03-pre-flight-hardware-check/inventory-self-test-running.png

File renamed without changes.

static/img/user-guide/02-experiment-basics/11-running-self-test/self_test_results.png renamed to static/img/user-guide/01-getting-started/03-pre-flight-hardware-check/self_test_results.png

File renamed without changes.
492 KB

static/img/user-guide/02-experiment-basics/04-set-up-an-experiment/settings.png renamed to static/img/user-guide/02-experiment-basics/06-monitor-experiment/settings.png

File renamed without changes.

static/img/user-guide/03-extending-your-pioreactor/01-cluster-management/01-create-cluster/inventory-actions.png renamed to static/img/user-guide/03-extending-your-pioreactor/01-create-cluster/inventory-actions.png

File renamed without changes.

static/img/user-guide/03-extending-your-pioreactor/01-cluster-management/01-create-cluster/inventory-add-modal.png renamed to static/img/user-guide/03-extending-your-pioreactor/01-create-cluster/inventory-add-modal.png

File renamed without changes.

static/img/user-guide/03-extending-your-pioreactor/01-cluster-management/01-create-cluster/inventory-add-pioreactor.png renamed to static/img/user-guide/03-extending-your-pioreactor/01-create-cluster/inventory-add-pioreactor.png

File renamed without changes.

0 commit comments

Comments
 (0)