"""Prefix every image output with the object name, and fix every reference. Renaming files is the easy half. The half that breaks a project silently is the references: METHODS.md and the three analysis notes cite these filenames, and the scripts that WRITE them would otherwise recreate the old names on the next run. So this rewrites the markdown and the scripts in the same pass. Dry run by default; pass --apply to actually move anything. """ import os import re import sys import layout ROOT = layout.SESSION PREFIX = "NGC5128-" IMAGE_EXT = (".png", ".jpg", ".jpeg", ".tif", ".tiff") APPLY = "--apply" in sys.argv def image_files(): """Every image in the stacked tree that is not already prefixed.""" out = [] for folder in (ROOT, layout.path("original")): if not os.path.isdir(folder): continue for name in sorted(os.listdir(folder)): path = os.path.join(folder, name) if not os.path.isfile(path): continue if not name.lower().endswith(IMAGE_EXT): continue if name.startswith(PREFIX): continue out.append((folder, name, PREFIX + name)) return out renames = image_files() print(f"{len(renames)} image files to rename\n") for folder, old, new in renames: where = os.path.relpath(folder, ROOT) print(f" {where}/{old} -> {new}") # Build the substitution map. Longest names first so that a short name which is # a substring of a longer one cannot corrupt it. mapping = {old: new for _, old, new in renames} ordered = sorted(mapping, key=len, reverse=True) targets = [] for folder, _, _ in [(ROOT, None, None)]: for name in os.listdir(folder): if name.lower().endswith(".md"): targets.append(os.path.join(folder, name)) scripts = layout.path("scripts") if os.path.isdir(scripts): for name in os.listdir(scripts): if name.lower().endswith(".py"): targets.append(os.path.join(scripts, name)) print(f"\nchecking {len(targets)} markdown and script files for references") edits = [] for path in targets: try: text = open(path, encoding="utf-8").read() except UnicodeDecodeError: text = open(path, encoding="latin-1").read() updated = text hits = 0 for old in ordered: # A reference is the bare filename; guard the left edge so an already # prefixed occurrence is not double-prefixed. pattern = re.compile(r"(?