assemblerpdf 1.0.4__tar.gz → 1.0.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. assemblerpdf-1.0.5/PKG-INFO +202 -0
  2. assemblerpdf-1.0.5/README.md +179 -0
  3. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/pyproject.toml +1 -1
  4. assemblerpdf-1.0.5/src/assemblerpdf/templates/assemblerpdf/fields/field_input.html +7 -0
  5. assemblerpdf-1.0.5/src/assemblerpdf/templates/assemblerpdf/fields/field_label.html +1 -0
  6. assemblerpdf-1.0.5/src/assemblerpdf/templates/assemblerpdf/fields/input.html +10 -0
  7. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/archivese.html +3 -1
  8. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/datos_basicosinf.html +28 -0
  9. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/fiila_dos_check.html +15 -5
  10. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/fila_cinco_zona.html +15 -5
  11. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/fila_cuatro.html +44 -0
  12. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/fila_cuatro_si_no.html +68 -0
  13. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/fila_cuatro_zona.html +70 -0
  14. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/fila_dos.html +24 -0
  15. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/fila_dos_zona.html +15 -5
  16. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/fila_tres.html +34 -0
  17. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/fila_tres_zona.html +24 -8
  18. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/fila_uno.html +14 -0
  19. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/iformfilacuatro.html +42 -0
  20. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/input_solitario.html +14 -0
  21. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/label_input_dos.html +26 -0
  22. assemblerpdf-1.0.5/src/assemblerpdf/templates/sistema/texarea.html +18 -0
  23. assemblerpdf-1.0.5/src/assemblerpdf.egg-info/PKG-INFO +202 -0
  24. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf.egg-info/SOURCES.txt +2 -0
  25. assemblerpdf-1.0.4/PKG-INFO +0 -86
  26. assemblerpdf-1.0.4/README.md +0 -63
  27. assemblerpdf-1.0.4/src/assemblerpdf/templates/assemblerpdf/fields/input.html +0 -12
  28. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/datos_basicosinf.html +0 -16
  29. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/fila_cuatro.html +0 -20
  30. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/fila_cuatro_si_no.html +0 -46
  31. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/fila_cuatro_zona.html +0 -48
  32. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/fila_dos.html +0 -12
  33. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/fila_tres.html +0 -16
  34. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/fila_uno.html +0 -8
  35. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/iformfilacuatro.html +0 -20
  36. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/input_solitario.html +0 -9
  37. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/label_input_dos.html +0 -24
  38. assemblerpdf-1.0.4/src/assemblerpdf/templates/sistema/texarea.html +0 -9
  39. assemblerpdf-1.0.4/src/assemblerpdf.egg-info/PKG-INFO +0 -86
  40. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/MANIFEST.in +0 -0
  41. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/setup.cfg +0 -0
  42. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/__init__.py +0 -0
  43. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/assemblers/__init__.py +0 -0
  44. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/assemblers/base.py +0 -0
  45. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/assemblers/form.py +0 -0
  46. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/assemblers/report.py +0 -0
  47. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/core.py +0 -0
  48. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/fonts/Inter-Bold.ttf +0 -0
  49. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/fonts/Inter-Medium.ttf +0 -0
  50. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/fonts/Inter-Regular.ttf +0 -0
  51. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/img/Logo-unp-rojo.png +0 -0
  52. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/img/logo-mininterior-rojo.jpg +0 -0
  53. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/fields/checkbox.html +0 -0
  54. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/fields/radio.html +0 -0
  55. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/fields/textarea.html +0 -0
  56. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/layout/footer.html +0 -0
  57. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/layout/footer_fixed.html +0 -0
  58. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/layout/grid_row.html +0 -0
  59. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/layout/header.html +0 -0
  60. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/layout/section.html +0 -0
  61. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/layout/style.html +0 -0
  62. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/assemblerpdf/misc/signature.html +0 -0
  63. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/anexos.html +0 -0
  64. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/anexos_limpio.html +0 -0
  65. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/autoriza_envio.html +0 -0
  66. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/checkbox.html +0 -0
  67. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/control_cambios.html +0 -0
  68. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/datos_ot.html +0 -0
  69. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/encaso_de.html +0 -0
  70. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/fila_instructivo.html +0 -0
  71. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/fila_tres_checkbox.html +0 -0
  72. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/firma.html +0 -0
  73. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/firma_doble.html +0 -0
  74. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/firmaop2.html +0 -0
  75. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/firmas_oficializacion.html +0 -0
  76. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/hechos_sobrevinientes.html +0 -0
  77. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/hechos_sobrevinientes_vacio.html +0 -0
  78. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/informacion_doble.html +0 -0
  79. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/input_2checks.html +0 -0
  80. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/input_check.html +0 -0
  81. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/input_checkbox.html +0 -0
  82. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/leyenda_autoriza_correo.html +0 -0
  83. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/leyenda_superiol.html +0 -0
  84. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/logos.html +0 -0
  85. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/manifiesto.html +0 -0
  86. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/notificacion_correo.html +0 -0
  87. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/oficializacion.html +0 -0
  88. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/pregunta_si_no.html +0 -0
  89. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/pregunta_tresopciones.html +0 -0
  90. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/qr_oficializacion.html +0 -0
  91. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/situacion_amenaza.html +0 -0
  92. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/style.html +0 -0
  93. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/subtitulo_icono.html +0 -0
  94. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/subtitulo_icono_largo.html +0 -0
  95. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/tabla_doble.html +0 -0
  96. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/tabla_instructivo.html +0 -0
  97. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/tabla_matriz_riesgo.html +0 -0
  98. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/tabla_proyeccion.html +0 -0
  99. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/tabla_simple.html +0 -0
  100. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/tipo_identificacion.html +0 -0
  101. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/tipos_checkbox.html +0 -0
  102. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/titulo.html +0 -0
  103. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/titulo_logo.html +0 -0
  104. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/templates/sistema/titulo_principal.html +0 -0
  105. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/utils/__init__.py +0 -0
  106. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf/utils/template_loader.py +0 -0
  107. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf.egg-info/dependency_links.txt +0 -0
  108. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf.egg-info/requires.txt +0 -0
  109. {assemblerpdf-1.0.4 → assemblerpdf-1.0.5}/src/assemblerpdf.egg-info/top_level.txt +0 -0
@@ -0,0 +1,202 @@
1
+ Metadata-Version: 2.4
2
+ Name: assemblerpdf
3
+ Version: 1.0.5
4
+ Summary: Generador de PDFs usando WeasyPrint, diseñado para formularios y reportes con componentes genéricos.
5
+ Author-email: EcosistemaUNP <ecosistema@unp.gov.co>
6
+ License: MIT
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ Requires-Dist: django>=3.2
20
+ Requires-Dist: weasyprint>=60.0
21
+ Requires-Dist: jinja2>=3.0.0
22
+ Requires-Dist: requests>=2.25.0
23
+
24
+ # 🚀 assemblerpdf
25
+
26
+ > ✨ **Generador de PDFs dinámicos utilizando WeasyPrint con componentes HTML genéricos, modulares y reutilizables.**
27
+
28
+ 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.).
29
+
30
+ ---
31
+
32
+ ## ⚡ Instalación
33
+
34
+ ### 1. Instalar la librería en Python
35
+ Puedes instalar la librería en modo editable localmente para desarrollo:
36
+
37
+ ```bash
38
+ pip install -e .
39
+ ```
40
+
41
+ ### 2. Instalar dependencias del sistema operativo (Requisito para WeasyPrint)
42
+
43
+ WeasyPrint requiere librerías nativas del sistema (Cairo, Pango y GdkPixbuf) para renderizar PDFs de alta calidad.
44
+
45
+ #### Método Automatizado (Recomendado)
46
+ 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:
47
+
48
+ ```python
49
+ import assemblerpdf
50
+ assemblerpdf.install_dependencies()
51
+ ```
52
+
53
+ ---
54
+
55
+ #### Método Manual (Por si falla la autoinstalación)
56
+
57
+ ##### 🪟 Windows
58
+ 1. Descarga e instala **MSYS2** desde [msys2.org](https://www.msys2.org/) (o instálalo vía PowerShell ejecutando `winget install MSYS2.MSYS2`).
59
+ 2. Abre la consola de MSYS2 (UCRT64 o MINGW64) y ejecuta:
60
+ ```bash
61
+ pacman -S --noconfirm mingw-w64-x86_64-pango mingw-w64-x86_64-shared-mime-info
62
+ ```
63
+ 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`.
64
+
65
+ ##### 🍎 macOS
66
+ Si utilizas **Homebrew**, abre tu terminal y ejecuta:
67
+ ```bash
68
+ brew install weasyprint
69
+ ```
70
+
71
+ ##### 🐧 Linux (Debian / Ubuntu / Mint)
72
+ Asegura los paquetes de Cairo y Pango usando `apt`:
73
+ ```bash
74
+ sudo apt-get update
75
+ sudo apt-get install -y libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info
76
+ ```
77
+
78
+ ##### 🐧 Linux (Fedora / RHEL / CentOS)
79
+ Usa `dnf` para instalar las dependencias nativas:
80
+ ```bash
81
+ sudo dnf install -y pango cairo gdk-pixbuf2 libffi-devel
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 🛠️ Guía de Uso
87
+
88
+ ### 1. Instanciar el Ensamblador (`BaseFormAssembler`)
89
+
90
+ 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).
91
+
92
+ ```python
93
+ from assemblerpdf import BaseFormAssembler
94
+
95
+ # 1. Definir el contexto global de datos para renderizado de variables
96
+ context = {
97
+ "primerNombre": "Juan",
98
+ "primerApellido": "Pérez",
99
+ "numeroRadicado": "RAD-2026-000123"
100
+ }
101
+
102
+ # 2. Inicializar el ensamblador con opciones de personalización
103
+ assembler = BaseFormAssembler(
104
+ context=context,
105
+ codigo="GSC-FT-11-V10", # Código del documento impreso en el pie de página
106
+ fecha="Oficialización: 22/10/2024", # Fecha en el pie de página
107
+ version="10", # Versión en el pie de página
108
+ auto_decorations=True, # Activa bordes y folio automático de página (Pág X de Y)
109
+ custom_css_content="""
110
+ /* CSS adicional para sobreescribir estilos por defecto si es necesario */
111
+ .form-label {
112
+ font-weight: bold;
113
+ color: #002857;
114
+ }
115
+ """
116
+ )
117
+ ```
118
+
119
+ ---
120
+
121
+ ### 2. Métodos del Ensamblador
122
+
123
+ Añade contenido a tu PDF de forma secuencial utilizando sus métodos principales:
124
+
125
+ #### A. `add_component(template_name, component_context)`
126
+ Agrega un componente HTML individual utilizando un contexto de variables locales.
127
+ * **`template_name`**: Nombre de la plantilla en `assemblerpdf` o `sistema` (ej. `header.html`, `section.html`, `checkbox.html`, `textarea.html`).
128
+ * **`component_context`**: Diccionario con los parámetros del componente.
129
+
130
+ ```python
131
+ assembler.add_component("header.html", {
132
+ "titulo1": "FORMULARIO DE SOLICITUD DE INSCRIPCIÓN",
133
+ "titulo2": "UNIDAD NACIONAL DE PROTECCIÓN"
134
+ })
135
+
136
+ assembler.add_component("section.html", {
137
+ "titulo": "Datos de Radicación",
138
+ "icono": "fa-solid fa-file-contract"
139
+ })
140
+ ```
141
+
142
+ #### B. `add_grid_row(columns)`
143
+ Permite maquetar filas con múltiples columnas alineadas y anchos distribuidos de forma precisa.
144
+ * **`columns`**: Lista de diccionarios, donde cada uno describe una columna con la siguiente estructura:
145
+ * `template`: plantilla del componente.
146
+ * `context`: variables locales para el componente.
147
+ * `ancho`: porcentaje de la celda (ej. `'50%'`, `'25%'`).
148
+
149
+ ```python
150
+ assembler.add_grid_row([
151
+ {
152
+ "template": "input.html",
153
+ "context": {"label": "Número de Radicado", "valor": context["numeroRadicado"], "name": "radicado"},
154
+ "ancho": "70%"
155
+ },
156
+ {
157
+ "template": "input.html",
158
+ "context": {"label": "Fecha", "valor": "2026-06-03", "name": "fecha_rad"},
159
+ "ancho": "30%"
160
+ }
161
+ ])
162
+ ```
163
+
164
+ #### C. `add_page_break()`
165
+ Inserta un salto de página manual obligatorio en el PDF.
166
+ ```python
167
+ assembler.add_page_break()
168
+ ```
169
+
170
+ #### D. `add_raw_html(html_content)`
171
+ Inyecta un fragmento de HTML crudo en el flujo del documento. Es ideal para textos de advertencia pequeños, firmas específicas o scripts.
172
+ ```python
173
+ assembler.add_raw_html('<p class="warning-text">* Recuerde firmar al final de este formulario.</p>')
174
+ ```
175
+
176
+ ---
177
+
178
+ ### 3. Compilar el PDF (`build`)
179
+
180
+ 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).
181
+
182
+ ```python
183
+ # Generar los bytes del documento
184
+ pdf_bytes = assembler.build()
185
+
186
+ # Guardar a archivo local
187
+ with open("documento_generado.pdf", "wb") as f:
188
+ f.write(pdf_bytes)
189
+ ```
190
+
191
+ ---
192
+
193
+ ## 🎨 Componentes Disponibles de la Librería
194
+
195
+ La librería incluye los siguientes componentes listos para su uso:
196
+ * **`header.html`**: Encabezado corporativo configurable con títulos y logotipos en base64.
197
+ * **`section.html`**: Encabezado de sección con soporte opcional de iconos de *FontAwesome*.
198
+ * **`input.html`**: Campo de entrada con etiqueta que se vuelve un `div` estático en modo no interactivo (`interactive=False`).
199
+ * **`textarea.html`**: Área de texto multilínea con auto-paginación inteligente para textos largos.
200
+ * **`checkbox.html`**: Lista de opciones de selección múltiple con iconos de check.
201
+ * **`radio.html`**: Opciones de selección única estilo botón de radio.
202
+ * **`signature.html`**: Componente modular para renderizado de firmas en cuadrícula.
@@ -0,0 +1,179 @@
1
+ # 🚀 assemblerpdf
2
+
3
+ > ✨ **Generador de PDFs dinámicos utilizando WeasyPrint con componentes HTML genéricos, modulares y reutilizables.**
4
+
5
+ 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.).
6
+
7
+ ---
8
+
9
+ ## ⚡ Instalación
10
+
11
+ ### 1. Instalar la librería en Python
12
+ Puedes instalar la librería en modo editable localmente para desarrollo:
13
+
14
+ ```bash
15
+ pip install -e .
16
+ ```
17
+
18
+ ### 2. Instalar dependencias del sistema operativo (Requisito para WeasyPrint)
19
+
20
+ WeasyPrint requiere librerías nativas del sistema (Cairo, Pango y GdkPixbuf) para renderizar PDFs de alta calidad.
21
+
22
+ #### Método Automatizado (Recomendado)
23
+ 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:
24
+
25
+ ```python
26
+ import assemblerpdf
27
+ assemblerpdf.install_dependencies()
28
+ ```
29
+
30
+ ---
31
+
32
+ #### Método Manual (Por si falla la autoinstalación)
33
+
34
+ ##### 🪟 Windows
35
+ 1. Descarga e instala **MSYS2** desde [msys2.org](https://www.msys2.org/) (o instálalo vía PowerShell ejecutando `winget install MSYS2.MSYS2`).
36
+ 2. Abre la consola de MSYS2 (UCRT64 o MINGW64) y ejecuta:
37
+ ```bash
38
+ pacman -S --noconfirm mingw-w64-x86_64-pango mingw-w64-x86_64-shared-mime-info
39
+ ```
40
+ 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`.
41
+
42
+ ##### 🍎 macOS
43
+ Si utilizas **Homebrew**, abre tu terminal y ejecuta:
44
+ ```bash
45
+ brew install weasyprint
46
+ ```
47
+
48
+ ##### 🐧 Linux (Debian / Ubuntu / Mint)
49
+ Asegura los paquetes de Cairo y Pango usando `apt`:
50
+ ```bash
51
+ sudo apt-get update
52
+ sudo apt-get install -y libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info
53
+ ```
54
+
55
+ ##### 🐧 Linux (Fedora / RHEL / CentOS)
56
+ Usa `dnf` para instalar las dependencias nativas:
57
+ ```bash
58
+ sudo dnf install -y pango cairo gdk-pixbuf2 libffi-devel
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 🛠️ Guía de Uso
64
+
65
+ ### 1. Instanciar el Ensamblador (`BaseFormAssembler`)
66
+
67
+ 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).
68
+
69
+ ```python
70
+ from assemblerpdf import BaseFormAssembler
71
+
72
+ # 1. Definir el contexto global de datos para renderizado de variables
73
+ context = {
74
+ "primerNombre": "Juan",
75
+ "primerApellido": "Pérez",
76
+ "numeroRadicado": "RAD-2026-000123"
77
+ }
78
+
79
+ # 2. Inicializar el ensamblador con opciones de personalización
80
+ assembler = BaseFormAssembler(
81
+ context=context,
82
+ codigo="GSC-FT-11-V10", # Código del documento impreso en el pie de página
83
+ fecha="Oficialización: 22/10/2024", # Fecha en el pie de página
84
+ version="10", # Versión en el pie de página
85
+ auto_decorations=True, # Activa bordes y folio automático de página (Pág X de Y)
86
+ custom_css_content="""
87
+ /* CSS adicional para sobreescribir estilos por defecto si es necesario */
88
+ .form-label {
89
+ font-weight: bold;
90
+ color: #002857;
91
+ }
92
+ """
93
+ )
94
+ ```
95
+
96
+ ---
97
+
98
+ ### 2. Métodos del Ensamblador
99
+
100
+ Añade contenido a tu PDF de forma secuencial utilizando sus métodos principales:
101
+
102
+ #### A. `add_component(template_name, component_context)`
103
+ Agrega un componente HTML individual utilizando un contexto de variables locales.
104
+ * **`template_name`**: Nombre de la plantilla en `assemblerpdf` o `sistema` (ej. `header.html`, `section.html`, `checkbox.html`, `textarea.html`).
105
+ * **`component_context`**: Diccionario con los parámetros del componente.
106
+
107
+ ```python
108
+ assembler.add_component("header.html", {
109
+ "titulo1": "FORMULARIO DE SOLICITUD DE INSCRIPCIÓN",
110
+ "titulo2": "UNIDAD NACIONAL DE PROTECCIÓN"
111
+ })
112
+
113
+ assembler.add_component("section.html", {
114
+ "titulo": "Datos de Radicación",
115
+ "icono": "fa-solid fa-file-contract"
116
+ })
117
+ ```
118
+
119
+ #### B. `add_grid_row(columns)`
120
+ Permite maquetar filas con múltiples columnas alineadas y anchos distribuidos de forma precisa.
121
+ * **`columns`**: Lista de diccionarios, donde cada uno describe una columna con la siguiente estructura:
122
+ * `template`: plantilla del componente.
123
+ * `context`: variables locales para el componente.
124
+ * `ancho`: porcentaje de la celda (ej. `'50%'`, `'25%'`).
125
+
126
+ ```python
127
+ assembler.add_grid_row([
128
+ {
129
+ "template": "input.html",
130
+ "context": {"label": "Número de Radicado", "valor": context["numeroRadicado"], "name": "radicado"},
131
+ "ancho": "70%"
132
+ },
133
+ {
134
+ "template": "input.html",
135
+ "context": {"label": "Fecha", "valor": "2026-06-03", "name": "fecha_rad"},
136
+ "ancho": "30%"
137
+ }
138
+ ])
139
+ ```
140
+
141
+ #### C. `add_page_break()`
142
+ Inserta un salto de página manual obligatorio en el PDF.
143
+ ```python
144
+ assembler.add_page_break()
145
+ ```
146
+
147
+ #### D. `add_raw_html(html_content)`
148
+ Inyecta un fragmento de HTML crudo en el flujo del documento. Es ideal para textos de advertencia pequeños, firmas específicas o scripts.
149
+ ```python
150
+ assembler.add_raw_html('<p class="warning-text">* Recuerde firmar al final de este formulario.</p>')
151
+ ```
152
+
153
+ ---
154
+
155
+ ### 3. Compilar el PDF (`build`)
156
+
157
+ 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).
158
+
159
+ ```python
160
+ # Generar los bytes del documento
161
+ pdf_bytes = assembler.build()
162
+
163
+ # Guardar a archivo local
164
+ with open("documento_generado.pdf", "wb") as f:
165
+ f.write(pdf_bytes)
166
+ ```
167
+
168
+ ---
169
+
170
+ ## 🎨 Componentes Disponibles de la Librería
171
+
172
+ La librería incluye los siguientes componentes listos para su uso:
173
+ * **`header.html`**: Encabezado corporativo configurable con títulos y logotipos en base64.
174
+ * **`section.html`**: Encabezado de sección con soporte opcional de iconos de *FontAwesome*.
175
+ * **`input.html`**: Campo de entrada con etiqueta que se vuelve un `div` estático en modo no interactivo (`interactive=False`).
176
+ * **`textarea.html`**: Área de texto multilínea con auto-paginación inteligente para textos largos.
177
+ * **`checkbox.html`**: Lista de opciones de selección múltiple con iconos de check.
178
+ * **`radio.html`**: Opciones de selección única estilo botón de radio.
179
+ * **`signature.html`**: Componente modular para renderizado de firmas en cuadrícula.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "assemblerpdf"
7
- version = "1.0.4"
7
+ version = "1.0.5"
8
8
  description = "Generador de PDFs usando WeasyPrint, diseñado para formularios y reportes con componentes genéricos."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -0,0 +1,7 @@
1
+ {% if interactive|default(True) %}
2
+ <input type="text" class="form-control {{ class_control|default('') }}" name="{{ name }}" value="{{ valor|default('') }}" placeholder="{{ placeholder|default('') }}" {% if disabled %}disabled{% endif %} style="{{ style_control|default('') }}">
3
+ {% else %}
4
+ <div class="form-control-static {{ class_control|default('') }}" style="{{ style_control|default('') }}">
5
+ {{ valor|default('') }}
6
+ </div>
7
+ {% endif %}
@@ -0,0 +1 @@
1
+ <label class="form-label {{ class_label|default('') }}" style="{{ style_label|default('') }}">{{ label }}</label>
@@ -0,0 +1,10 @@
1
+ <div class="form-group {{ class_group|default('') }}" style="margin-bottom: {{ margin_bottom|default('8px') }}; {{ style_group|default('') }}">
2
+ {% if label %}
3
+ {% with label=label class_label=class_label style_label=style_label %}
4
+ {% include "assemblerpdf/fields/field_label.html" %}
5
+ {% endwith %}
6
+ {% endif %}
7
+ {% with interactive=interactive name=name valor=valor placeholder=placeholder disabled=disabled class_control=class_control style_control=style_control %}
8
+ {% include "assemblerpdf/fields/field_input.html" %}
9
+ {% endwith %}
10
+ </div>
@@ -11,7 +11,9 @@
11
11
  </div>
12
12
  </td>
13
13
  <td class="celda-c" style="position: relative; width: 900px;">
14
- <input style="margin: 3px;" type="text" id="veredaDomicilio" name="" value="">
14
+ {% with valor=valor name=name interactive=interactive|default(True) style_control="margin: 3px;" placeholder=placeholder disabled=disabled %}
15
+ {% include "assemblerpdf/fields/field_input.html" %}
16
+ {% endwith %}
15
17
  </td>
16
18
  </tr>
17
19
  </table>
@@ -0,0 +1,28 @@
1
+ <div class="especial-dos" style="margin-bottom: 10px;">
2
+ <table>
3
+ <tr>
4
+ <td class="celda-i" style="width: 50%;">
5
+ {% if label1 %}
6
+ {% with label=label1 style_label="font-weight: bold; color: #002857;" %}
7
+ {% include "assemblerpdf/fields/field_label.html" %}
8
+ {% endwith %}
9
+ {% endif %}
10
+ {% with valor=valor1 name=name1 interactive=interactive1|default(interactive|default(True)) class_control=class_control1 style_control="width: 100%;" placeholder=placeholder1 disabled=disabled1 %}
11
+ {% include "assemblerpdf/fields/field_input.html" %}
12
+ {% endwith %}
13
+ </td>
14
+ </tr>
15
+ <tr>
16
+ <td class="celda-c" style="width: 50%;">
17
+ {% if label2 %}
18
+ {% with label=label2 style_label="font-weight: bold; color: #002857;" %}
19
+ {% include "assemblerpdf/fields/field_label.html" %}
20
+ {% endwith %}
21
+ {% endif %}
22
+ {% with valor=valor2 name=name2 interactive=interactive2|default(interactive|default(True)) class_control=class_control2 style_control="width: 100%;" placeholder=placeholder2 disabled=disabled2 %}
23
+ {% include "assemblerpdf/fields/field_input.html" %}
24
+ {% endwith %}
25
+ </td>
26
+ </tr>
27
+ </table>
28
+ </div>
@@ -1,11 +1,21 @@
1
1
  <table>
2
2
  <tr>
3
- <td class="celda-i" style="width: {{ ancho1 }};">
4
- <label>{{ label1 }}</label>
5
- <input type="text" value="{{ valor1 }}">
3
+ <td class="celda-i" style="width: {{ ancho1|default('50%') }};">
4
+ {% if label1 %}
5
+ {% with label=label1 class_label=class_label1 style_label=style_label1 %}
6
+ {% include "assemblerpdf/fields/field_label.html" %}
7
+ {% endwith %}
8
+ {% endif %}
9
+ {% with valor=valor1 name=name1 interactive=interactive1|default(interactive|default(True)) class_control=class_control1 style_control=style_control1 placeholder=placeholder1|default(placeholder|default('')) disabled=disabled1|default(disabled) %}
10
+ {% include "assemblerpdf/fields/field_input.html" %}
11
+ {% endwith %}
6
12
  </td>
7
- <td class="celda-d" style="width: {{ ancho4 }};">
8
- <label>{{ label4 }}</label>
13
+ <td class="celda-d" style="width: {{ ancho4|default('50%') }};">
14
+ {% if label4 %}
15
+ {% with label=label4 class_label=class_label4 style_label=style_label4 %}
16
+ {% include "assemblerpdf/fields/field_label.html" %}
17
+ {% endwith %}
18
+ {% endif %}
9
19
  <div style="position: relative; height: 35px;">
10
20
  <!-- Opción Siempre -->
11
21
  <div class="chequeo-i" style="position: absolute; left: 0; min-width: 200px;">
@@ -1,11 +1,21 @@
1
1
  <table>
2
2
  <tr>
3
- <td class="celda-i" style="width: {{ ancho1 }};">
4
- <label>{{ label1 }}</label>
5
- <input type="text" value="{{ valor1 }}">
3
+ <td class="celda-i" style="width: {{ ancho1|default('50%') }};">
4
+ {% if label1 %}
5
+ {% with label=label1 class_label=class_label1 style_label=style_label1 %}
6
+ {% include "assemblerpdf/fields/field_label.html" %}
7
+ {% endwith %}
8
+ {% endif %}
9
+ {% with valor=valor1 name=name1 interactive=interactive1|default(interactive|default(True)) class_control=class_control1 style_control=style_control1 placeholder=placeholder1|default(placeholder|default('')) disabled=disabled1|default(disabled) %}
10
+ {% include "assemblerpdf/fields/field_input.html" %}
11
+ {% endwith %}
6
12
  </td>
7
- <td class="celda-d" style="width: {{ ancho4 }};">
8
- <label>{{ label4 }}</label>
13
+ <td class="celda-d" style="width: {{ ancho4|default('50%') }};">
14
+ {% if label4 %}
15
+ {% with label=label4 class_label=class_label4 style_label=style_label4 %}
16
+ {% include "assemblerpdf/fields/field_label.html" %}
17
+ {% endwith %}
18
+ {% endif %}
9
19
  <div style="position: relative; height: 35px;">
10
20
  <!-- Opción Personal -->
11
21
  <div class="chequeo-i" style="position: absolute; left: 0; min-width: 200px;">
@@ -0,0 +1,44 @@
1
+ <table>
2
+ <tr>
3
+ <td class="celda-i" style="width: {{ ancho1|default('25%') }};">
4
+ {% if label1 %}
5
+ {% with label=label1 class_label=class_label1 style_label=style_label1 %}
6
+ {% include "assemblerpdf/fields/field_label.html" %}
7
+ {% endwith %}
8
+ {% endif %}
9
+ {% with valor=valor1 name=name1 interactive=interactive1|default(interactive|default(True)) class_control=class_control1 style_control=style_control1 placeholder=placeholder1|default(placeholder|default('')) disabled=disabled1|default(disabled) %}
10
+ {% include "assemblerpdf/fields/field_input.html" %}
11
+ {% endwith %}
12
+ </td>
13
+ <td class="celda-c" style="width: {{ ancho2|default('25%') }};">
14
+ {% if label2 %}
15
+ {% with label=label2 class_label=class_label2 style_label=style_label2 %}
16
+ {% include "assemblerpdf/fields/field_label.html" %}
17
+ {% endwith %}
18
+ {% endif %}
19
+ {% with valor=valor2 name=name2 interactive=interactive2|default(interactive|default(True)) class_control=class_control2 style_control=style_control2 placeholder=placeholder2|default(placeholder|default('')) disabled=disabled2|default(disabled) %}
20
+ {% include "assemblerpdf/fields/field_input.html" %}
21
+ {% endwith %}
22
+ </td>
23
+ <td class="celda-c" style="width: {{ ancho3|default('25%') }};">
24
+ {% if label3 %}
25
+ {% with label=label3 class_label=class_label3 style_label=style_label3 %}
26
+ {% include "assemblerpdf/fields/field_label.html" %}
27
+ {% endwith %}
28
+ {% endif %}
29
+ {% with valor=valor3 name=name3 interactive=interactive3|default(interactive|default(True)) class_control=class_control3 style_control=style_control3 placeholder=placeholder3|default(placeholder|default('')) disabled=disabled3|default(disabled) %}
30
+ {% include "assemblerpdf/fields/field_input.html" %}
31
+ {% endwith %}
32
+ </td>
33
+ <td class="celda-d" style="width: {{ ancho4|default('25%') }};">
34
+ {% if label4 %}
35
+ {% with label=label4 class_label=class_label4 style_label=style_label4 %}
36
+ {% include "assemblerpdf/fields/field_label.html" %}
37
+ {% endwith %}
38
+ {% endif %}
39
+ {% with valor=valor4 name=name4 interactive=interactive4|default(interactive|default(True)) class_control=class_control4 style_control=style_control4 placeholder=placeholder4|default(placeholder|default('')) disabled=disabled4|default(disabled) %}
40
+ {% include "assemblerpdf/fields/field_input.html" %}
41
+ {% endwith %}
42
+ </td>
43
+ </tr>
44
+ </table>
@@ -0,0 +1,68 @@
1
+ <table>
2
+ <tr>
3
+ <td class="celda-i" style="width: {{ ancho1|default('25%') }};">
4
+ {% if label1 %}
5
+ {% with label=label1 class_label=class_label1 style_label=style_label1 %}
6
+ {% include "assemblerpdf/fields/field_label.html" %}
7
+ {% endwith %}
8
+ {% endif %}
9
+ {% with valor=valor1 name=name1 interactive=interactive1|default(interactive|default(True)) class_control=class_control1 style_control=style_control1 placeholder=placeholder1|default(placeholder|default('')) disabled=disabled1|default(disabled) %}
10
+ {% include "assemblerpdf/fields/field_input.html" %}
11
+ {% endwith %}
12
+ </td>
13
+ <td class="celda-c" style="width: {{ ancho2|default('25%') }};">
14
+ {% if label2 %}
15
+ {% with label=label2 class_label=class_label2 style_label=style_label2 %}
16
+ {% include "assemblerpdf/fields/field_label.html" %}
17
+ {% endwith %}
18
+ {% endif %}
19
+ {% with valor=valor2 name=name2 interactive=interactive2|default(interactive|default(True)) class_control=class_control2 style_control=style_control2 placeholder=placeholder2|default(placeholder|default('')) disabled=disabled2|default(disabled) %}
20
+ {% include "assemblerpdf/fields/field_input.html" %}
21
+ {% endwith %}
22
+ </td>
23
+ <td class="celda-c" style="width: {{ ancho3|default('25%') }};">
24
+ {% if label3 %}
25
+ {% with label=label3 class_label=class_label3 style_label=style_label3 %}
26
+ {% include "assemblerpdf/fields/field_label.html" %}
27
+ {% endwith %}
28
+ {% endif %}
29
+ {% with valor=valor3 name=name3 interactive=interactive3|default(interactive|default(True)) class_control=class_control3 style_control=style_control3 placeholder=placeholder3|default(placeholder|default('')) disabled=disabled3|default(disabled) %}
30
+ {% include "assemblerpdf/fields/field_input.html" %}
31
+ {% endwith %}
32
+ </td>
33
+ <td class="celda-d" style="width: {{ ancho4|default('25%') }};">
34
+ {% if label4 %}
35
+ {% with label=label4 class_label=class_label4 style_label=style_label4 %}
36
+ {% include "assemblerpdf/fields/field_label.html" %}
37
+ {% endwith %}
38
+ {% endif %}
39
+ <div style="position: relative; height: 35px;">
40
+ <div class="chequeo-i" style="position: absolute; left: 0; min-width: 200px;">
41
+ <div style="position: relative;">
42
+ {% if valor4 == "True" %}
43
+ <i class="fa-regular fa-square-check" style="position: absolute; left: 0; font-size: 30px; color: #888;"></i>
44
+ {% else %}
45
+ <i class="fa-regular fa-square" style="position: absolute; left: 0; font-size: 30px; color: #ccc;"></i>
46
+ {% endif %}
47
+ <p style="position: absolute; left: 35px; top: 5px; font-size: 15px; color: #002857; text-align: left; margin: 0px;">
48
+ Si
49
+ </p>
50
+ </div>
51
+ </div>
52
+
53
+ <div class="chequeo-i" style="position: absolute; left: 100px; min-width: 200px;">
54
+ <div style="position: relative;">
55
+ {% if valor4 == "False" %}
56
+ <i class="fa-regular fa-square-check" style="position: absolute; left: 0; font-size: 30px; color: #888;"></i>
57
+ {% else %}
58
+ <i class="fa-regular fa-square" style="position: absolute; left: 0; font-size: 30px; color: #ccc;"></i>
59
+ {% endif %}
60
+ <p style="position: absolute; left: 35px; top: 5px; font-size: 15px; color: #002857; text-align: left; margin: 0px;">
61
+ No
62
+ </p>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ </td>
67
+ </tr>
68
+ </table>