#!/usr/bin/env python3 """ PPT Master - Examples Index Generator Automatically scans the examples directory and generates a README.md index file. Usage: python3 scripts/generate_examples_index.py python3 scripts/generate_examples_index.py examples """ import sys from pathlib import Path from datetime import datetime from collections import defaultdict from console_encoding import configure_utf8_stdio configure_utf8_stdio() try: from project_utils import find_all_projects, get_project_info, CANVAS_FORMATS except ImportError: print("Error: Cannot import the project_utils module") print("Please ensure project_utils.py is in the same directory") sys.exit(1) def generate_examples_index(examples_dir: str = 'examples') -> str: """ Generate a README.md index for the examples directory Args: examples_dir: Path to the examples directory Returns: Generated README.md content """ examples_path = Path(examples_dir) if not examples_path.exists(): print(f"[ERROR] Directory not found: {examples_dir}") return "" print(f"[SCAN] Scanning directory: {examples_dir}") # Find all projects projects = find_all_projects(examples_dir) if not projects: print("[WARN] No projects found") return "" print(f"Found {len(projects)} project(s)") # Collect project information projects_info = [] for project_path in projects: info = get_project_info(str(project_path)) projects_info.append(info) # Sort by date (newest first) projects_info.sort(key=lambda x: x['date'], reverse=True) # Group by format by_format = defaultdict(list) for info in projects_info: by_format[info['format']].append(info) # Generate README content content = [] content.append("# PPT Master Example Projects Index\n") content.append("> This file is auto-generated by `skills/ppt-master/scripts/generate_examples_index.py`\n") content.append(f"> Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n") # Overview statistics content.append("## [Stats] Overview\n") content.append(f"- **Total projects**: {len(projects_info)}") content.append(f"- **Canvas formats**: {len(by_format)} type(s)") total_svgs = sum(info['svg_count'] for info in projects_info) content.append(f"- **SVG files**: {total_svgs}") # Statistics by format content.append("\n### Format Distribution\n") for fmt_key in sorted(by_format.keys(), key=lambda x: len(by_format[x]), reverse=True): count = len(by_format[fmt_key]) fmt_name = CANVAS_FORMATS.get(fmt_key, {}).get('name', fmt_key) content.append(f"- **{fmt_name}**: {count} project(s)") # Recently updated content.append("\n## [New] Recently Updated\n") for info in projects_info[:5]: content.append( f"- **{info['name']}** ({info['format_name']}) - {info['date_formatted']}") # Project list by format content.append("\n## [List] Project List\n") # Define format display order format_order = ['ppt169', 'ppt43', 'wechat', 'xiaohongshu', 'moments', 'story', 'banner', 'a4'] for fmt_key in format_order: if fmt_key not in by_format: continue fmt_info = CANVAS_FORMATS.get(fmt_key, {}) fmt_name = fmt_info.get('name', fmt_key) dimensions = fmt_info.get('dimensions', '') content.append(f"\n### {fmt_name} ({dimensions})\n") projects_list = by_format[fmt_key] # Sort by date projects_list.sort(key=lambda x: x['date'], reverse=True) for info in projects_list: # Project name and link project_link = f"./{info['dir_name']}" # Build project entry line = f"- **[{info['name']}]({project_link})**" # Add date line += f" - {info['date_formatted']}" # Add SVG count line += f" - {info['svg_count']} page(s)" content.append(line) # Other uncategorized formats other_formats = set(by_format.keys()) - set(format_order) if other_formats: content.append("\n### Other Formats\n") for fmt_key in sorted(other_formats): projects_list = by_format[fmt_key] for info in projects_list: project_link = f"./{info['dir_name']}" line = f"- **[{info['name']}]({project_link})**" line += f" ({info['format_name']}) - {info['date_formatted']}" line += f" - {info['svg_count']} page(s)" content.append(line) # Usage instructions content.append("\n## [Docs] Usage Instructions\n") content.append("### Preview Projects\n") content.append("Each project contains the following files:\n") content.append("- `README.md` - Project documentation") content.append("- `Design Spec & Content Outline.md` - Full design specification") content.append("- `svg_output/` - SVG output files\n") content.append("**Method 1: Using an HTTP server (recommended)**\n") content.append("```bash") content.append( "python3 -m http.server --directory examples//svg_output 8000") content.append("# Visit http://localhost:8000") content.append("```\n") content.append("**Method 2: Open SVG directly**\n") content.append("```bash") content.append( "open examples//svg_output/slide_01_cover.svg") content.append("```\n") # Create new project content.append("### Create a New Project\n") content.append("Refer to existing project structures, or use the project management tool:\n") content.append("```bash") content.append( "python3 scripts/project_manager.py init my_project --format ppt169") content.append("```\n") # Contribution guidelines content.append("## [Contribute] Contributing Example Projects\n") content.append("We welcome you to share your projects in the examples directory!\n") content.append("### Project Requirements\n") content.append("1. Follow the standard project structure") content.append("2. Include a complete README.md and design specification") content.append("3. SVG files must comply with technical specifications") content.append("4. Directory naming format: `{project_name}_{format}_{YYYYMMDD}`\n") content.append("### Submission Process\n") content.append("1. Create a project under the `examples/` directory") content.append( "2. Validate the project: `python3 scripts/project_manager.py validate examples/`") content.append("3. Update the index: `python3 scripts/generate_examples_index.py`") content.append("4. Submit a Pull Request\n") # Related resources content.append("## [Resources] Related Resources\n") content.append("- [Quick Start](../README.md)") content.append("- [Workflow Tutorial](../../AGENTS.md)") content.append("- [Canvas Formats](../references/canvas-formats.md)") content.append("- [Role Definitions](../references/)") content.append("- [Chart Templates](../templates/charts/README.md)\n") # Footer content.append("---\n") content.append( f"*Auto-generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} by PPT Master*") return "\n".join(content) def main() -> None: """Run the CLI entry point.""" examples_dir = 'examples' if len(sys.argv) > 1: if sys.argv[1] in {'-h', '--help', 'help'}: print(__doc__) sys.exit(0) examples_dir = sys.argv[1] print("=" * 80) print("PPT Master - Examples Index Generator") print("=" * 80 + "\n") # Generate index content content = generate_examples_index(examples_dir) if not content: print("\n[ERROR] Generation failed") sys.exit(1) # Write to file output_file = Path(examples_dir) / 'README.md' try: with open(output_file, 'w', encoding='utf-8') as f: f.write(content) print(f"\n[OK] Index file generated: {output_file}") print(f" Contains {len(content.splitlines())} lines") # Display statistics projects_count = content.count('- **[') print(f" Indexed {projects_count} project(s)") except Exception as e: print(f"\n[ERROR] Failed to write file: {e}") sys.exit(1) if __name__ == '__main__': main()