Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """ | |
| Generate SVG versions of Mermaid diagrams for documentation | |
| """ | |
| import os | |
| import re | |
| import requests | |
| import json | |
| from pathlib import Path | |
| from typing import Optional | |
| class MermaidToSVGConverter: | |
| """Convert Mermaid diagrams to SVG format""" | |
| def __init__(self): | |
| self.mermaid_api_url = "https://mermaid.ink/img/" | |
| def extract_mermaid_code(self, markdown_file: Path) -> Optional[str]: | |
| """Extract Mermaid code from a Markdown file""" | |
| try: | |
| with open(markdown_file, 'r', encoding='utf-8') as f: | |
| content = f.read() | |
| # Find Mermaid code blocks | |
| mermaid_pattern = r'```mermaid\s*\n(.*?)\n```' | |
| match = re.search(mermaid_pattern, content, re.DOTALL) | |
| if match: | |
| return match.group(1).strip() | |
| else: | |
| print(f"No Mermaid diagram found in {markdown_file}") | |
| return None | |
| except Exception as e: | |
| print(f"Error reading {markdown_file}: {e}") | |
| return None | |
| def convert_to_svg(self, mermaid_code: str, output_path: Path) -> bool: | |
| """Convert Mermaid code to SVG using mermaid.ink service""" | |
| try: | |
| # Encode the Mermaid code for the URL | |
| import base64 | |
| import urllib.parse | |
| # Create the data URL format expected by mermaid.ink | |
| mermaid_data = f"%%{{init: {{'theme': 'base', 'themeVariables': {{'primaryColor': '#e3f2fd', 'primaryTextColor': '#1976d2', 'primaryBorderColor': '#01579b', 'lineColor': '#424242', 'secondaryColor': '#fff3e0', 'tertiaryColor': '#fce4ec'}}}}}}%%\n{mermaid_code}" | |
| # Base64 encode the mermaid code | |
| encoded = base64.b64encode(mermaid_data.encode('utf-8')).decode('utf-8') | |
| url_encoded = urllib.parse.quote(encoded) | |
| # Create the full URL | |
| full_url = f"{self.mermaid_api_url}{url_encoded}" | |
| # Make the request | |
| response = requests.get(full_url, timeout=30) | |
| if response.status_code == 200: | |
| # Save the SVG | |
| with open(output_path, 'wb') as f: | |
| f.write(response.content) | |
| print(f"β Generated SVG: {output_path}") | |
| return True | |
| else: | |
| print(f"β Failed to generate SVG for {output_path}: HTTP {response.status_code}") | |
| return False | |
| except Exception as e: | |
| print(f"β Error generating SVG for {output_path}: {e}") | |
| return False | |
| def process_markdown_file(self, markdown_file: Path, output_dir: Path) -> bool: | |
| """Process a single Markdown file and generate its SVG""" | |
| # Extract Mermaid code | |
| mermaid_code = self.extract_mermaid_code(markdown_file) | |
| if not mermaid_code: | |
| return False | |
| # Create output filename | |
| svg_filename = markdown_file.stem + ".svg" | |
| output_path = output_dir / svg_filename | |
| # Convert to SVG | |
| return self.convert_to_svg(mermaid_code, output_path) | |
| def main(): | |
| """Main function to generate SVGs for all documentation files""" | |
| print("π Generating SVG versions of documentation diagrams...") | |
| # Setup paths | |
| docs_dir = Path(__file__).parent.parent / "docs" | |
| svgs_dir = docs_dir / "svgs" | |
| # Create SVGs directory | |
| svgs_dir.mkdir(exist_ok=True) | |
| # Initialize converter | |
| converter = MermaidToSVGConverter() | |
| # Process all Markdown files in docs directory | |
| markdown_files = [ | |
| "README.md", | |
| "architecture.md", | |
| "interface-workflow.md", | |
| "training-pipeline.md", | |
| "deployment-pipeline.md", | |
| "data-flow.md" | |
| ] | |
| success_count = 0 | |
| total_count = len(markdown_files) | |
| for filename in markdown_files: | |
| markdown_path = docs_dir / filename | |
| if markdown_path.exists(): | |
| print(f"\nπ Processing {filename}...") | |
| if converter.process_markdown_file(markdown_path, svgs_dir): | |
| success_count += 1 | |
| else: | |
| print(f"β οΈ File not found: {markdown_path}") | |
| print(f"\nπ SVG generation complete!") | |
| print(f"β Successfully generated: {success_count}/{total_count} SVGs") | |
| print(f"π SVGs saved to: {svgs_dir}") | |
| if success_count < total_count: | |
| print(f"β Failed to generate: {total_count - success_count} SVGs") | |
| return 1 | |
| return 0 | |
| if __name__ == "__main__": | |
| exit(main()) | |