| | |
| | import re |
| | import os |
| | import sys |
| | import subprocess |
| | from pathlib import Path |
| |
|
| | def process_mermaid_diagrams(content, file_dir): |
| | """Convert mermaid diagrams to images""" |
| | mermaid_pattern = r'```mermaid\n(.*?)\n```' |
| |
|
| | def replace_mermaid(match): |
| | mermaid_code = match.group(1) |
| | |
| | diagram_hash = str(abs(hash(mermaid_code))) |
| | mermaid_file = f"{file_dir}/mermaid_{diagram_hash}.mmd" |
| | svg_file = f"{file_dir}/mermaid_{diagram_hash}.svg" |
| | png_file = f"{file_dir}/mermaid_{diagram_hash}.png" |
| |
|
| | |
| | try: |
| | with open(mermaid_file, 'w', encoding='utf-8') as f: |
| | f.write(mermaid_code) |
| | except Exception as e: |
| | print(f"Error writing mermaid file: {e}") |
| | return f'\n```\n{mermaid_code}\n```\n' |
| |
|
| | try: |
| | |
| | config_file = os.path.join(file_dir, '..', '..', '.github', 'workflows', 'puppeteer-config.json') |
| | if os.path.exists(config_file): |
| | result = subprocess.run([ |
| | 'mmdc', '-i', mermaid_file, '-o', svg_file, |
| | '--theme', 'default', '--backgroundColor', 'white', |
| | '--configFile', config_file, |
| | '--puppeteerConfig', config_file |
| | ], check=True, capture_output=True, text=True, timeout=60) |
| | else: |
| | |
| | result = subprocess.run([ |
| | 'mmdc', '-i', mermaid_file, '-o', svg_file, |
| | '--theme', 'default', '--backgroundColor', 'white', |
| | '--puppeteerConfig', '{"args": ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage", "--disable-gpu", "--single-process"]}' |
| | ], check=True, capture_output=True, text=True, timeout=60) |
| |
|
| | |
| | subprocess.run([ |
| | 'rsvg-convert', '-f', 'png', '-o', png_file, |
| | '--width', '1200', '--height', '800', svg_file |
| | ], check=True, capture_output=True, text=True) |
| |
|
| | |
| | try: |
| | os.remove(mermaid_file) |
| | if os.path.exists(svg_file): |
| | os.remove(svg_file) |
| | except: |
| | pass |
| |
|
| | |
| | return ( |
| | f'\n<div class="mermaid-container">\n\n' |
| | f'})\n\n' |
| | f'</div>\n' |
| | ) |
| |
|
| | except subprocess.CalledProcessError as e: |
| | print(f"Error converting mermaid diagram: {e}") |
| | print(f"Command output: {e.stderr if e.stderr else 'No stderr'}") |
| | |
| | |
| | try: |
| | print("Trying basic mmdc command...") |
| | subprocess.run([ |
| | 'mmdc', '-i', mermaid_file, '-o', svg_file, |
| | '--puppeteerConfig', '{"args": ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage", "--disable-gpu", "--single-process"]}' |
| | ], check=True, capture_output=True, text=True, timeout=60) |
| | |
| | |
| | subprocess.run([ |
| | 'rsvg-convert', '-f', 'png', '-o', png_file, |
| | '--width', '1200', '--height', '800', svg_file |
| | ], check=True, capture_output=True, text=True) |
| | |
| | |
| | try: |
| | os.remove(mermaid_file) |
| | if os.path.exists(svg_file): |
| | os.remove(svg_file) |
| | except: |
| | pass |
| | |
| | return ( |
| | f'\n<div class="mermaid-container">\n\n' |
| | f'})\n\n' |
| | f'</div>\n' |
| | ) |
| | |
| | except subprocess.CalledProcessError as e2: |
| | print(f"Basic mmdc also failed: {e2}") |
| | try: |
| | os.remove(mermaid_file) |
| | except: |
| | pass |
| | |
| | |
| | print("All Mermaid rendering methods failed, keeping original code") |
| | return f'\n```mermaid\n{mermaid_code}\n```\n' |
| |
|
| | except Exception as e: |
| | print(f"Unexpected error with mermaid: {e}") |
| | try: |
| | os.remove(mermaid_file) |
| | except: |
| | pass |
| | return f'\n```mermaid\n{mermaid_code}\n```\n' |
| |
|
| | return re.sub(mermaid_pattern, replace_mermaid, content, flags=re.DOTALL) |
| |
|
| |
|
| | def clean_emojis_and_fix_images(content, file_dir): |
| | """Remove/replace emojis and fix image paths""" |
| | emoji_replacements = { |
| | 'π΅': '[Audio]', |
| | 'π¬': '[Video]', |
| | 'π': '[Document]', |
| | 'π': '[Analytics]', |
| | 'π§ ': '[AI]', |
| | 'π₯': '[Media]', |
| | 'π': '[File]', |
| | 'β
': '[Success]', |
| | 'β': '[Failed]' |
| | } |
| |
|
| | for emoji, replacement in emoji_replacements.items(): |
| | content = content.replace(emoji, replacement) |
| |
|
| | |
| | img_pattern = r'!\[([^\]]*)\]\(([^)]+)\)' |
| |
|
| | def replace_image(match): |
| | alt_text = match.group(1) |
| | img_path = match.group(2) |
| |
|
| | if not img_path.startswith(('http://', 'https://', '/')): |
| | abs_img_path = os.path.join(file_dir, img_path) |
| | if os.path.exists(abs_img_path): |
| | img_path = os.path.relpath(abs_img_path, file_dir) |
| |
|
| | return ( |
| | f'<img src="{img_path}" alt="{alt_text}" ' |
| | f'style="max-width: 100%; height: auto; display: block; margin: 1em auto;" />' |
| | ) |
| |
|
| | content = re.sub(img_pattern, replace_image, content) |
| |
|
| | |
| | content = re.sub( |
| | r'<img\s+([^>]*?)\s*/?>', |
| | lambda m: ( |
| | f'<img {m.group(1)} ' |
| | f'style="max-width: 100%; height: auto; display: block; margin: 1em auto;" />' |
| | ), |
| | content |
| | ) |
| |
|
| | return content |
| |
|
| | def main(): |
| | if len(sys.argv) != 2: |
| | print("Usage: python preprocess_markdown.py <markdown_file>") |
| | sys.exit(1) |
| |
|
| | md_file = sys.argv[1] |
| |
|
| | if not os.path.exists(md_file): |
| | print(f"Error: File {md_file} does not exist") |
| | sys.exit(1) |
| |
|
| | try: |
| | file_dir = os.path.dirname(os.path.abspath(md_file)) |
| |
|
| | with open(md_file, 'r', encoding='utf-8') as f: |
| | content = f.read() |
| |
|
| | print(f"Processing file: {md_file}") |
| | print(f"File directory: {file_dir}") |
| | print(f"Content length: {len(content)} characters") |
| |
|
| | |
| | content = process_mermaid_diagrams(content, file_dir) |
| | print(f"Mermaid processing complete. Content length: {len(content)}") |
| |
|
| | |
| | content = clean_emojis_and_fix_images(content, file_dir) |
| | print(f"Image path fixing complete. Content length: {len(content)}") |
| |
|
| | |
| | processed_file = md_file.replace('.md', '_processed.md') |
| | with open(processed_file, 'w', encoding='utf-8') as f: |
| | f.write(content) |
| |
|
| | print(f"Processed file saved as: {processed_file}") |
| | print(processed_file) |
| |
|
| | except Exception as e: |
| | print(f"Error processing {md_file}: {e}") |
| | import traceback |
| | traceback.print_exc() |
| | sys.exit(1) |
| |
|
| | if __name__ == "__main__": |
| | main() |