88
99Usage:
1010 uv run --with pillow,pyyaml python3 scripts/generate_og_images.py [--force]
11+ uv run --with pillow,pyyaml python3 scripts/generate_og_images.py \
12+ --paths _posts/2026-05-20-some-post.md
1113"""
1214
1315from __future__ import annotations
@@ -397,6 +399,25 @@ def slug_from_filename(filename: str) -> str:
397399 return m .group (1 ) if m else filename .rsplit ("." , 1 )[0 ]
398400
399401
402+ def resolve_post_paths (paths : list [str ] | None ) -> list [Path ]:
403+ """Resolve repo-relative or absolute post paths."""
404+ if not paths :
405+ return sorted (POSTS_DIR .glob ("*.md" ))
406+
407+ resolved : list [Path ] = []
408+ for raw_path in paths :
409+ candidate = Path (raw_path )
410+ if not candidate .is_absolute ():
411+ candidate = ROOT / candidate
412+ candidate = candidate .resolve ()
413+ if not candidate .exists ():
414+ raise FileNotFoundError (f"Post path not found: { raw_path } " )
415+ if candidate .suffix != ".md" :
416+ raise ValueError (f"Post path must be a markdown file: { raw_path } " )
417+ resolved .append (candidate )
418+ return sorted (dict .fromkeys (resolved ))
419+
420+
400421# ---------------------------------------------------------------------------
401422# Main
402423# ---------------------------------------------------------------------------
@@ -405,6 +426,11 @@ def main() -> None:
405426 parser = argparse .ArgumentParser (description = "Generate OG images for blog posts" )
406427 parser .add_argument ("--force" , action = "store_true" ,
407428 help = "Regenerate all images, ignoring mtime checks" )
429+ parser .add_argument (
430+ "--paths" ,
431+ nargs = "+" ,
432+ help = "Specific post paths to generate (repo-relative or absolute)" ,
433+ )
408434 args = parser .parse_args ()
409435
410436 OG_DIR .mkdir (parents = True , exist_ok = True )
@@ -421,7 +447,7 @@ def main() -> None:
421447 generate_site_default (default_path , tagline , force = args .force )
422448
423449 # --- Blog posts ---
424- posts = sorted ( POSTS_DIR . glob ( "*.md" ) )
450+ posts = resolve_post_paths ( args . paths )
425451 generated = 0
426452 skipped = 0
427453
0 commit comments