Metadata-Version: 2.4
Name: CloudMatchPDF
Version: 2.0.0
Summary: Framework de generación de reportes LaTeX científicos vía Cloud
Home-page: https://github.com/JoseJimenez5/CloudMatchPDF
Author: Jose V. Jimenez
Author-email: "Jose V. Jimenez" <jose.jimenez05@epn.edu.ec>
License: MIT
Project-URL: Homepage, https://github.com/JoseJimenez5/CloudMatchPDF
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.31.0
Requires-Dist: sympy>=1.12
Requires-Dist: numpy>=1.26.4
Requires-Dist: matplotlib>=3.8.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.2; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# CloudMatchPDF v2.0

![Python](https://img.shields.io/badge/Python-3.8%2B-blue)
![License](https://img.shields.io/badge/License-MIT-green)
![Version](https://img.shields.io/badge/Version-2.0.0-orange)

CloudMatchPDF es un framework Python para automatizar la generación de documentos LaTeX técnicos y académicos. Integra cálculo simbólico con SymPy, visualización con Matplotlib y compilación distribuida en la nube, eliminando la necesidad de instalaciones locales de TeX Live.

## Novedades v2.0

- **Modelo de documento orientado a objetos**: Nueva arquitectura con `Document`, `Section`, `Paragraph`, `Equation`, etc. que permite manipular documentos como objetos en lugar de strings LaTeX
- **Arquitectura de compiladores extensible**: Sistema de backends con `CompilerBackend` como clase base. Incluye `CloudCompilerBackend` (nube) y `LocalCompiler` (pdflatex local)
- **Seguridad mejorada**: Eliminación completa de `eval()`, ahora usa `sympify()` de SymPy para parsear funciones matemáticas de forma segura
- **Soporte para tablas**: Nuevo método `add_table()` para generar tablas LaTeX
- **Soporte para imágenes**: Nuevo método `add_image()` para incluir imágenes externas
- **Manejo de errores específico**: Excepciones específicas (`ValueError`, `requests.Timeout`, etc.) en lugar de `Exception` genérico

## Características Principales

- **LatexBuilder**: Constructor de documentos con API fluida. Permite inyectar ecuaciones de SymPy, bloques de código y gráficas vectoriales sin tocar LaTeX
- **Integración Gráfica**: Renderizado de funciones matemáticas y figuras de Matplotlib mediante primitivas vectoriales de LaTeX
- **LatexValidator**: Sistema de sanitización que escapa caracteres reservados y valida sintaxis LaTeX
- **CloudCompiler**: Motor de compilación asíncrona que utiliza mirrors distribuidos en la nube

## Dependencias

- Python 3.8+
- SymPy >= 1.12
- Matplotlib >= 3.8.0
- NumPy >= 1.26.4
- requests >= 2.31.0

## Instalación

```bash
pip install -e .
```

## Estructura del Proyecto

```
CloudMatchPDF/
├── src/cloudmatchpdf/
│   ├── __init__.py              # Exporta clases públicas
│   ├── latex_builder.py         # API fluida tradicional
│   ├── latex_validator.py       # Validación y sanitización
│   ├── cloud_compiler.py        # Wrapper backwards compatibility
│   ├── compiler_backend.py      # Clase base abstracta
│   ├── document_model.py        # Modelo de documento v2.0
│   ├── latex_renderer.py        # Renderer LaTeX v2.0
│   └── backends/
│       ├── __init__.py
│       ├── cloud_backend.py     # Compilación en la nube
│       └── local_backend.py     # Compilación local
├── tests/
│   ├── test_builder.py
│   ├── test_compiler.py
│   ├── test_validator.py
│   ├── test_document_model.py   # Tests v2.0
│   └── test_backends.py         # Tests v2.0
├── examples/
│   └── pruebas.py               # Ejemplo con fallback Local -> Nube
├── setup.py
├── requirements.txt
└── README.md
```

## Ejemplos de Uso

### Opción 1: Modelo de documento v2.0 (Recomendado)

```python
from cloudmatchpdf import Document, LatexRenderer
from cloudmatchpdf.backends import CloudCompilerBackend, LocalCompiler
from cloudmatchpdf.latex_validator import LatexValidator
import sympy as sp

# Crear documento
doc = Document(title="Análisis de Osciladores", author="Jose V. Jimenez")

# Construir con API fluida
(doc.add_section("Cinemática del Sistema")
    .add_text("Se analiza la ecuación de movimiento para un sistema masa-resorte:")
    .add_equation(sp.Function('x')(sp.Symbol('t')), subtitle="Posición temporal")
    .add_plot(obj="sin(x) * exp(-0.1*x)", caption="Decaimiento", x_range="0:10")
    .add_table(
        data=[["1.0", "2.5"], ["2.0", "4.8"], ["3.0", "7.1"]],
        headers=["Tiempo (s)", "Posición (m)"],
        caption="Datos experimentales"
    )
)

# Renderizar a LaTeX
renderer = LatexRenderer(doc)
latex = renderer.render()

# Validar
safe_latex = LatexValidator.process(latex)

# Fallback: Local -> Nube
# Primero intenta compilación local (rápida, sin internet)
local_compiler = LocalCompiler()
if local_compiler.compile(safe_latex, output="report.pdf"):
    print("✅ Compilación local exitosa")
else:
    print("❌ Local falló, intentando nube...")
    # Si local falla, usa compilación en la nube
    cloud_compiler = CloudCompilerBackend()
    if cloud_compiler.compile(safe_latex, output="report.pdf"):
        print("✅ Compilación en nube exitosa")
    else:
        print("❌ Todos los métodos fallaron")
```

### Opción 2: API tradicional (LatexBuilder)

```python
from cloudmatchpdf.latex_builder import LatexBuilder
from cloudmatchpdf.cloud_compiler import CloudCompiler
import sympy as sp

doc = LatexBuilder(title="Reporte", author="Autor")
doc.add_section("Introducción").add_text("Texto")
doc.add_equation(sp.sin(sp.Symbol('x')))

compiler = CloudCompiler()
compiler.compile(doc.build(), output="report.pdf")
```

## Referencia de la API

### Document (v2.0)

- `add_section(title, numbered=True)`: Añade sección
- `add_subsection(title, numbered=True)`: Añade subsección
- `add_text(text)`: Añade párrafo
- `add_equation(expr, subtitle)`: Añade ecuación SymPy
- `add_math_block(latex_str, numbered)`: Añade bloque matemático LaTeX
- `add_plot(obj, caption, x_range)`: Añade gráfica
- `add_table(data, caption, headers)`: Añade tabla
- `add_image(path, caption, width)`: Añade imagen
- `add_package(name, options)`: Añade paquete LaTeX

### LatexRenderer

- `render()`: Convierte Document a código LaTeX

### Backends

**CloudCompilerBackend**: Compila en la nube (3 endpoints por defecto)
- LaTeXOnline (GET): `https://latexonline.cc/compile`
- LaTeXOnline (POST): `https://latexonline.cc/compile`
- TeXLive-Net: `https://texlive.net/cgi-bin/latexml.cgi`
- Ventaja: No requiere instalación local de TeX Live
- Requiere: Conexión a internet
- `add_endpoint(name, method, url, param="text")`: Agrega endpoint personalizado

**LocalCompiler**: Compila con pdflatex local
- Ventaja: Compilación rápida sin dependencias externas
- Requiere: pdflatex instalado

### Crear backend personalizado

```python
from cloudmatchpdf.compiler_backend import CompilerBackend

class CustomBackend(CompilerBackend):
    def compile(self, latex: str, output: str) -> bool:
        # Tu lógica personalizada
        pass
```

## Tests

```bash
pytest tests/
```

## Troubleshooting

**Problema: pdflatex no encontrado**
- Solución: Instala TeX Live o MikTeX, o usa `CloudCompilerBackend` en su lugar

**Problema: Sin conexión a internet**
- Solución: Usa `LocalCompiler` con pdflatex instalado localmente

**Problema: Timeout en compilación cloud**
- Solución: Aumenta el timeout: `CloudCompilerBackend(timeout=60)`

**Problema: Underscore sin escapar**
- Solución: Usa `LatexValidator.process()` antes de compilar

## Contributing

Las contribuciones son bienvenidas. Para contribuir:

1. Fork el proyecto
2. Crea una rama para tu feature (`git checkout -b feature/nueva-funcionalidad`)
3. Commit tus cambios (`git commit -am 'Agrega nueva funcionalidad'`)
4. Push a la rama (`git push origin feature/nueva-funcionalidad`)
5. Abre un Pull Request

## Licencia

Desarrollado por Jose V. Jimenez para uso académico y personal.

