#!/usr/bin/env python3 """ Fix all SVG files to be properly readable on all devices Focus on text size, contrast, and responsive design """ import os import re from pathlib import Path def fix_svg_content(content, filename): """ Apply comprehensive fixes to SVG content """ # 1. Fix SVG header for responsiveness # Remove any width/height attributes and ensure proper viewBox if "]*>" svg_replacement = f'' content = re.sub(svg_pattern, svg_replacement, content, count=1) # 2. Fix all font sizes - MINIMUM 16px for readability def increase_font_size(match): size = int(match.group(1)) if size < 14: return f'font-size="16"' elif size < 16: return f'font-size="18"' elif size < 18: return f'font-size="20"' else: return f'font-size="{size + 4}"' # Increase all fonts slightly content = re.sub(r'font-size="(\d+)"', increase_font_size, content) # 3. Fix ALL text colors for maximum contrast # Replace all light colors with dark, readable ones color_replacements = { # Light grays to dark gray/black "#CBD5E0": "#1F2937", "#A0AEC0": "#374151", "#E2E8F0": "#1F2937", "#EDF2F7": "#111827", "#F7FAFC": "#111827", "#9CA3AF": "#374151", "#D1D5DB": "#4B5563", "#718096": "#374151", "#4A5568": "#1F2937", # Light blues to dark blues "#90CDF4": "#1E40AF", "#63B3ED": "#2563EB", "#4A90E2": "#1D4ED8", "#81E6D9": "#0E7490", "#4FD1C5": "#0891B2", "#38D4B2": "#0D9488", # Light purples to dark purples "#E9D8FD": "#6B21A8", "#D6BCFA": "#7C3AED", "#B794F4": "#9333EA", "#9F7AEA": "#7C3AED", # Light oranges to dark oranges "#FBD38D": "#C2410C", "#F6AD55": "#EA580C", "#ED8936": "#C2410C", # Light reds to dark reds "#FEB2B2": "#B91C1C", "#FC8181": "#DC2626", "#E53E3E": "#DC2626", # Light greens to dark greens "#9AE6B4": "#047857", "#68D391": "#059669", "#48BB78": "#047857", "#38A169": "#059669", "#B2F5EA": "#047857", # Generic light to dark "#888": "#374151", "#888888": "#374151", "#FAFAFA": "transparent", "#fff": "#111827", "#ffffff": "#111827", "#FFF": "#111827", "#FFFFFF": "#111827", } for old_color, new_color in color_replacements.items(): # Replace in fill attributes content = re.sub( f'fill="{old_color}"', f'fill="{new_color}"', content, flags=re.IGNORECASE ) # Replace in stroke attributes content = re.sub( f'stroke="{old_color}"', f'stroke="{new_color}"', content, flags=re.IGNORECASE, ) # Replace in style attributes content = re.sub( f"fill:{old_color}", f"fill:{new_color}", content, flags=re.IGNORECASE ) content = re.sub( f"stroke:{old_color}", f"stroke:{new_color}", content, flags=re.IGNORECASE ) # 4. Remove white/light backgrounds content = re.sub(r']*fill="#FAFAFA"[^>]*>', "", content) content = re.sub(r']*fill="white"[^>]*>', "", content) content = re.sub(r']*fill="#FFFFFF"[^>]*>', "", content) content = re.sub(r']*fill="#ffffff"[^>]*>', "", content) # 5. Fix stroke widths for visibility content = re.sub(r'stroke-width="1"', 'stroke-width="2"', content) content = re.sub(r'stroke-width="0\.5"', 'stroke-width="2"', content) # 6. Fix font weights content = re.sub(r'font-weight="bold"', 'font-weight="700"', content) # 7. Fix font families for better rendering content = re.sub( r'font-family="[^"]*"', 'font-family="system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif"', content, ) # 8. Ensure arrows and markers are visible content = re.sub( r'', '', content, ) # 9. Add slight padding to the viewBox if needed viewbox_match = re.search(r'viewBox="(\d+)\s+(\d+)\s+(\d+)\s+(\d+)"', content) if viewbox_match: x, y, width, height = map(int, viewbox_match.groups()) # Add 20px padding new_viewbox = f'viewBox="{x - 20} {y - 20} {width + 40} {height + 40}"' content = re.sub(r'viewBox="[^"]*"', new_viewbox, content, count=1) return content def process_all_svgs(): """Process all SVG files in the docs directory""" docs_dir = Path("docs") svg_files = list(docs_dir.glob("**/*.svg")) # Filter out font files svg_files = [ f for f in svg_files if "fontawesome" not in str(f).lower() and "favicon" not in str(f).lower() ] print(f"Found {len(svg_files)} SVG files to fix") print("=" * 60) fixed = 0 errors = 0 for svg_file in svg_files: try: print(f"Processing: {svg_file.relative_to(docs_dir)}") # Read the file with open(svg_file, "r", encoding="utf-8") as f: content = f.read() # Apply fixes fixed_content = fix_svg_content(content, svg_file.name) # Write back with open(svg_file, "w", encoding="utf-8") as f: f.write(fixed_content) print(f" ✓ Fixed successfully") fixed += 1 except Exception as e: print(f" ✗ Error: {e}") errors += 1 print() print("=" * 60) print(f"COMPLETED: {fixed} files fixed, {errors} errors") print() print("Improvements applied:") print("• All text now ≥16px (readable on mobile)") print("• High contrast colors (dark text, no light grays)") print("• 100% responsive width") print("• Removed white backgrounds") print("• Enhanced stroke widths") print("• Added padding to prevent cutoff") print("=" * 60) if __name__ == "__main__": print("=" * 60) print("SVG READABILITY FIXER") print("Making all diagrams actually readable!") print("=" * 60) print() process_all_svgs()