Metadata-Version: 2.4
Name: assemblerpdf
Version: 1.0.5
Summary: Generador de PDFs usando WeasyPrint, diseñado para formularios y reportes con componentes genéricos.
Author-email: EcosistemaUNP <ecosistema@unp.gov.co>
License: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: django>=3.2
Requires-Dist: weasyprint>=60.0
Requires-Dist: jinja2>=3.0.0
Requires-Dist: requests>=2.25.0

# 🚀 assemblerpdf

> ✨ **Generador de PDFs dinámicos utilizando WeasyPrint con componentes HTML genéricos, modulares y reutilizables.**

Esta librería permite ensamblar PDFs complejos utilizando un conjunto de componentes reutilizables (`grid_row`, `input`, `textarea`, `checkbox`, `radio`, etc.), con soporte para la fuente **Inter** descargada automáticamente, y con soporte para la instalación automatizada y manual de las dependencias del sistema operativo (Pango, Cairo, etc.).

---

## ⚡ Instalación

### 1. Instalar la librería en Python
Puedes instalar la librería en modo editable localmente para desarrollo:

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

### 2. Instalar dependencias del sistema operativo (Requisito para WeasyPrint)

WeasyPrint requiere librerías nativas del sistema (Cairo, Pango y GdkPixbuf) para renderizar PDFs de alta calidad. 

#### Método Automatizado (Recomendado)
Puedes dejar que `assemblerpdf` intente detectar tu sistema operativo e instalar automáticamente las librerías del sistema y descargar las fuentes corriendo el siguiente script interactivo en Python:

```python
import assemblerpdf
assemblerpdf.install_dependencies()
```

---

#### Método Manual (Por si falla la autoinstalación)

##### 🪟 Windows
1. Descarga e instala **MSYS2** desde [msys2.org](https://www.msys2.org/) (o instálalo vía PowerShell ejecutando `winget install MSYS2.MSYS2`).
2. Abre la consola de MSYS2 (UCRT64 o MINGW64) y ejecuta:
   ```bash
   pacman -S --noconfirm mingw-w64-x86_64-pango mingw-w64-x86_64-shared-mime-info
   ```
3. La librería `assemblerpdf` agregará automáticamente `C:\msys64\mingw64\bin` al path de DLLs en runtime de Python. Si tienes MSYS2 en otra ruta, asegúrate de añadir su directorio `/bin` a tu variable de entorno `PATH`.

##### 🍎 macOS
Si utilizas **Homebrew**, abre tu terminal y ejecuta:
```bash
brew install weasyprint
```

##### 🐧 Linux (Debian / Ubuntu / Mint)
Asegura los paquetes de Cairo y Pango usando `apt`:
```bash
sudo apt-get update
sudo apt-get install -y libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info
```

##### 🐧 Linux (Fedora / RHEL / CentOS)
Usa `dnf` para instalar las dependencias nativas:
```bash
sudo dnf install -y pango cairo gdk-pixbuf2 libffi-devel
```

---

## 🛠️ Guía de Uso

### 1. Instanciar el Ensamblador (`BaseFormAssembler`)

El ensamblador principal es `BaseFormAssembler`. Al instanciarlo, puedes configurarlo con metadatos fijos que se aplicarán de manera consistente en la decoración (encabezados, pies de página con número de página y bordes decorativos en cada hoja).

```python
from assemblerpdf import BaseFormAssembler

# 1. Definir el contexto global de datos para renderizado de variables
context = {
    "primerNombre": "Juan",
    "primerApellido": "Pérez",
    "numeroRadicado": "RAD-2026-000123"
}

# 2. Inicializar el ensamblador con opciones de personalización
assembler = BaseFormAssembler(
    context=context,
    codigo="GSC-FT-11-V10",          # Código del documento impreso en el pie de página
    fecha="Oficialización: 22/10/2024", # Fecha en el pie de página
    version="10",                      # Versión en el pie de página
    auto_decorations=True,             # Activa bordes y folio automático de página (Pág X de Y)
    custom_css_content="""
        /* CSS adicional para sobreescribir estilos por defecto si es necesario */
        .form-label {
            font-weight: bold;
            color: #002857;
        }
    """
)
```

---

### 2. Métodos del Ensamblador

Añade contenido a tu PDF de forma secuencial utilizando sus métodos principales:

#### A. `add_component(template_name, component_context)`
Agrega un componente HTML individual utilizando un contexto de variables locales.
* **`template_name`**: Nombre de la plantilla en `assemblerpdf` o `sistema` (ej. `header.html`, `section.html`, `checkbox.html`, `textarea.html`).
* **`component_context`**: Diccionario con los parámetros del componente.

```python
assembler.add_component("header.html", {
    "titulo1": "FORMULARIO DE SOLICITUD DE INSCRIPCIÓN",
    "titulo2": "UNIDAD NACIONAL DE PROTECCIÓN"
})

assembler.add_component("section.html", {
    "titulo": "Datos de Radicación",
    "icono": "fa-solid fa-file-contract"
})
```

#### B. `add_grid_row(columns)`
Permite maquetar filas con múltiples columnas alineadas y anchos distribuidos de forma precisa.
* **`columns`**: Lista de diccionarios, donde cada uno describe una columna con la siguiente estructura:
  * `template`: plantilla del componente.
  * `context`: variables locales para el componente.
  * `ancho`: porcentaje de la celda (ej. `'50%'`, `'25%'`).

```python
assembler.add_grid_row([
    {
        "template": "input.html",
        "context": {"label": "Número de Radicado", "valor": context["numeroRadicado"], "name": "radicado"},
        "ancho": "70%"
    },
    {
        "template": "input.html",
        "context": {"label": "Fecha", "valor": "2026-06-03", "name": "fecha_rad"},
        "ancho": "30%"
    }
])
```

#### C. `add_page_break()`
Inserta un salto de página manual obligatorio en el PDF.
```python
assembler.add_page_break()
```

#### D. `add_raw_html(html_content)`
Inyecta un fragmento de HTML crudo en el flujo del documento. Es ideal para textos de advertencia pequeños, firmas específicas o scripts.
```python
assembler.add_raw_html('<p class="warning-text">* Recuerde firmar al final de este formulario.</p>')
```

---

### 3. Compilar el PDF (`build`)

El método `build()` compila las plantillas HTML a través de WeasyPrint y retorna los bytes del PDF. Puedes escribir los bytes en disco o retornarlos como respuesta HTTP (ej. `HttpResponse` en Django, FastAPI, Flask).

```python
# Generar los bytes del documento
pdf_bytes = assembler.build()

# Guardar a archivo local
with open("documento_generado.pdf", "wb") as f:
    f.write(pdf_bytes)
```

---

## 🎨 Componentes Disponibles de la Librería

La librería incluye los siguientes componentes listos para su uso:
* **`header.html`**: Encabezado corporativo configurable con títulos y logotipos en base64.
* **`section.html`**: Encabezado de sección con soporte opcional de iconos de *FontAwesome*.
* **`input.html`**: Campo de entrada con etiqueta que se vuelve un `div` estático en modo no interactivo (`interactive=False`).
* **`textarea.html`**: Área de texto multilínea con auto-paginación inteligente para textos largos.
* **`checkbox.html`**: Lista de opciones de selección múltiple con iconos de check.
* **`radio.html`**: Opciones de selección única estilo botón de radio.
* **`signature.html`**: Componente modular para renderizado de firmas en cuadrícula.
