Spaces:
Sleeping
Sleeping
File size: 2,474 Bytes
6981282 | 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 | import hashlib
import subprocess
import tempfile
from dataclasses import dataclass
from functools import lru_cache
from pathlib import Path
@dataclass
class CompilationResult:
success: bool
pdf_data: bytes = b""
error_log: str = ""
def _compute_hash(content: str) -> str:
return hashlib.md5(content.encode()).hexdigest()
@lru_cache(maxsize=128)
def _cached_compile(content_hash: str, latex_content: str) -> tuple[bool, bytes, str]:
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = Path(tmpdir)
tex_file = tmppath / "document.tex"
tex_file.write_text(latex_content)
try:
result = subprocess.run(
[
"pdflatex",
"-interaction=nonstopmode",
"-halt-on-error",
"-output-directory", str(tmppath),
str(tex_file)
],
capture_output=True,
text=True,
timeout=30
)
pdf_file = tmppath / "document.pdf"
if pdf_file.exists():
return (True, pdf_file.read_bytes(), "")
else:
log_file = tmppath / "document.log"
error_log = log_file.read_text() if log_file.exists() else result.stdout
return (False, b"", _extract_errors(error_log))
except subprocess.TimeoutExpired:
return (False, b"", "Compilation timed out after 30 seconds")
except FileNotFoundError:
return (False, b"", "pdflatex not found. Please install TeX Live.")
except Exception as e:
return (False, b"", f"Compilation error: {str(e)}")
def _extract_errors(log: str) -> str:
lines = log.split("\n")
error_lines = []
capture = False
for line in lines:
if line.startswith("!"):
capture = True
if capture:
error_lines.append(line)
if line.strip() == "" and error_lines:
capture = False
if len(error_lines) > 50:
break
return "\n".join(error_lines) if error_lines else log[-2000:]
def compile_latex(latex_content: str) -> CompilationResult:
content_hash = _compute_hash(latex_content)
success, pdf_data, error_log = _cached_compile(content_hash, latex_content)
return CompilationResult(success=success, pdf_data=pdf_data, error_log=error_log)
|