File size: 3,001 Bytes
cc01c7a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f970d0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc01c7a
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import re
import requests
import io
import logging

logger = logging.getLogger(__name__)

def generate_latex(markdown_text: str) -> str:
    """Converts basic markdown with MathJax into a raw LaTeX document string."""
    tex = markdown_text
    
    # Protect math blocks temporarily so regex doesn't mess up math internals
    math_blocks = []
    def save_math(match):
        math_blocks.append(match.group(0))
        return f"__MATH_{len(math_blocks)-1}__"
        
    tex = re.sub(r'\$\$.*?\$\$', save_math, tex, flags=re.DOTALL)
    tex = re.sub(r'\$.*?\$', save_math, tex)
    
    # Markdown -> LaTeX conversions
    tex = re.sub(r'\*\*(.*?)\*\*', r'\\textbf{\1}', tex)
    tex = re.sub(r'\*(.*?)\*', r'\\textit{\1}', tex)
    tex = re.sub(r'^### (.*)$', r'\\subsubsection*{\1}', tex, flags=re.MULTILINE)
    tex = re.sub(r'^## (.*)$', r'\\subsection*{\1}', tex, flags=re.MULTILINE)
    tex = re.sub(r'^# (.*)$', r'\\section*{\1}', tex, flags=re.MULTILINE)
    
    # Simple list handling
    tex = re.sub(r'^- (.*)$', r'\\item \1', tex, flags=re.MULTILINE)
    if "\\item" in tex:
        # Extremely naive list wrapping
        tex = re.sub(r'((\\item.*\n?)+)', r'\\begin{itemize}\n\1\\end{itemize}\n', tex)
    
    # Replace empty lines with double escape for spacing if needed
    # Actually, empty lines in LaTeX are good for paragraph breaks.
    
    # Restore math blocks
    for i, block in enumerate(math_blocks):
        tex = tex.replace(f"__MATH_{i}__", block)
        
    preamble = r"""\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amsmath, amssymb, amsfonts}
\usepackage{geometry}
\geometry{a4paper, margin=1in}
\usepackage{hyperref}
\usepackage{xcolor}

\title{MathMinds Generated Report}
\author{MathMinds AI Assistant}
\date{\today}

\begin{document}
\maketitle

"""
    return preamble + tex + "\n\n\\end{document}"


def compile_pdf(tex_content: str) -> bytes:
    """Compiles a complete LaTeX string to a PDF using public latexonline.cc API."""
    try:
        import urllib.parse
        
        encoded_tex = urllib.parse.quote(tex_content)
        url = f"https://latexonline.cc/compile?text={encoded_tex}"
        
        # If the encoded URL is massive, the server might reject the GET request.
        # Fallback to the POST /data endpoint with a multipart file upload.
        if len(url) > 8000:
            logger.info("URL too long, falling back to POST /data multipart")
            r = requests.post(
                "https://latexonline.cc/data?command=pdflatex",
                files={"file": ("document.tex", tex_content)},
                timeout=45
            )
        else:
            r = requests.get(url, timeout=45)
            
        if r.status_code == 200:
            return r.content
        else:
            logger.error(f"LaTeX compile failed: {r.status_code} - {r.text[:200]}")
    except Exception as e:
        logger.error(f"LaTeX API exception: {e}")
    return b""