docs: Update CLAUDE.md with complete project documentation
- Full API documentation with examples - Roadmap phases 1-5 - Architecture details - Zig 0.15 compatibility notes - Related projects table - Next session tasks 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
0e17e8790b
commit
59c155331f
1 changed files with 304 additions and 132 deletions
432
CLAUDE.md
432
CLAUDE.md
|
|
@ -1,167 +1,286 @@
|
||||||
# zpdf - Generador PDF para Zig
|
# zpdf - Generador PDF para Zig
|
||||||
|
|
||||||
> **Fecha creación**: 2025-12-08
|
> **Ultima actualizacion**: 2025-12-08
|
||||||
> **Versión Zig**: 0.15.2
|
> **Lenguaje**: Zig 0.15.2
|
||||||
> **Estado**: En desarrollo inicial
|
> **Estado**: v0.1 - Core funcional, en desarrollo activo
|
||||||
|
> **Inspiracion**: gofpdf (Go), fpdf (PHP)
|
||||||
|
|
||||||
## Descripción del Proyecto
|
## Descripcion del Proyecto
|
||||||
|
|
||||||
Librería pura Zig para generación de documentos PDF. Sin dependencias externas, compila a un binario único.
|
**zpdf** es una libreria pura Zig para generacion de documentos PDF. Sin dependencias externas, compila a un binario unico.
|
||||||
|
|
||||||
**Filosofía**:
|
**Filosofia**:
|
||||||
- Zero dependencias (100% Zig)
|
- Zero dependencias (100% Zig puro)
|
||||||
- API simple y directa
|
- API simple y directa
|
||||||
- Enfocado en generación de facturas/documentos comerciales
|
- Enfocado en generacion de facturas/documentos comerciales
|
||||||
- Soporte para texto, tablas, imágenes y formas básicas
|
- Soporte para texto, tablas, imagenes y formas basicas
|
||||||
|
- Calidad open source (doc comments, codigo claro)
|
||||||
|
|
||||||
|
**Objetivo**: Ser el pilar para generar PDFs en Zig con codigo 100% propio, replicando funcionalidad de librerias maduras como gofpdf.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estado Actual del Proyecto
|
||||||
|
|
||||||
|
### Implementacion v0.1 (Core Funcional)
|
||||||
|
|
||||||
|
| Componente | Estado | Archivo |
|
||||||
|
|------------|--------|---------|
|
||||||
|
| **Document** | | |
|
||||||
|
| Document init/deinit | ✅ | `src/root.zig` |
|
||||||
|
| addPage (standard sizes) | ✅ | `src/root.zig` |
|
||||||
|
| addPageCustom | ✅ | `src/root.zig` |
|
||||||
|
| render() to buffer | ✅ | `src/root.zig` |
|
||||||
|
| saveToFile() | ✅ | `src/root.zig` |
|
||||||
|
| **Page** | | |
|
||||||
|
| Page init/deinit | ✅ | `src/root.zig` |
|
||||||
|
| setFont | ✅ | `src/root.zig` |
|
||||||
|
| drawText | ✅ | `src/root.zig` |
|
||||||
|
| setFillColor | ✅ | `src/root.zig` |
|
||||||
|
| setStrokeColor | ✅ | `src/root.zig` |
|
||||||
|
| setLineWidth | ✅ | `src/root.zig` |
|
||||||
|
| drawLine | ✅ | `src/root.zig` |
|
||||||
|
| drawRect | ✅ | `src/root.zig` |
|
||||||
|
| fillRect | ✅ | `src/root.zig` |
|
||||||
|
| drawFilledRect | ✅ | `src/root.zig` |
|
||||||
|
| **Types** | | |
|
||||||
|
| PageSize enum (A4, Letter, etc.) | ✅ | `src/root.zig` |
|
||||||
|
| Font enum (14 Type1 fonts) | ✅ | `src/root.zig` |
|
||||||
|
| Color struct (RGB) | ✅ | `src/root.zig` |
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
| Categoria | Tests | Estado |
|
||||||
|
|-----------|-------|--------|
|
||||||
|
| Create empty document | 1 | ✅ |
|
||||||
|
| Add page | 1 | ✅ |
|
||||||
|
| Render minimal document | 1 | ✅ |
|
||||||
|
| Font names | 1 | ✅ |
|
||||||
|
| Color conversion | 1 | ✅ |
|
||||||
|
| Graphics operations | 1 | ✅ |
|
||||||
|
| **Total** | **6** | ✅ |
|
||||||
|
|
||||||
|
### Ejemplos
|
||||||
|
|
||||||
|
| Ejemplo | Descripcion | Estado |
|
||||||
|
|---------|-------------|--------|
|
||||||
|
| hello.zig | PDF minimo con texto y formas | ✅ |
|
||||||
|
| invoice.zig | Factura completa realista | ✅ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
### Fase 1 - Core (COMPLETADO)
|
||||||
|
- [x] Estructura documento PDF 1.4
|
||||||
|
- [x] Paginas (A4, Letter, A3, A5, Legal, custom)
|
||||||
|
- [x] Texto basico (14 fuentes Type1 built-in)
|
||||||
|
- [x] Lineas y rectangulos
|
||||||
|
- [x] Colores RGB
|
||||||
|
- [x] Serializacion correcta
|
||||||
|
|
||||||
|
### Fase 2 - Texto Avanzado (PENDIENTE)
|
||||||
|
- [ ] Multiples fuentes en mismo documento
|
||||||
|
- [ ] Alineacion (izquierda, centro, derecha)
|
||||||
|
- [ ] Word wrap automatico
|
||||||
|
- [ ] Interlineado configurable
|
||||||
|
- [ ] Texto multilinea
|
||||||
|
|
||||||
|
### Fase 3 - Imagenes (PENDIENTE)
|
||||||
|
- [ ] JPEG embebido
|
||||||
|
- [ ] PNG embebido (con alpha)
|
||||||
|
- [ ] Escalado y posicionamiento
|
||||||
|
- [ ] Aspect ratio preservation
|
||||||
|
|
||||||
|
### Fase 4 - Utilidades (PENDIENTE)
|
||||||
|
- [ ] Helper para tablas
|
||||||
|
- [ ] Numeracion de paginas
|
||||||
|
- [ ] Headers/footers automaticos
|
||||||
|
- [ ] Margenes de pagina
|
||||||
|
- [ ] Links/URLs
|
||||||
|
|
||||||
|
### Fase 5 - Avanzado (FUTURO)
|
||||||
|
- [ ] Fuentes TTF embebidas
|
||||||
|
- [ ] Compresion de streams
|
||||||
|
- [ ] Metadatos documento (autor, titulo)
|
||||||
|
- [ ] Bookmarks/outline
|
||||||
|
- [ ] Forms (campos rellenables)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Arquitectura
|
## Arquitectura
|
||||||
|
|
||||||
|
### Estructura de Archivos
|
||||||
|
|
||||||
```
|
```
|
||||||
zpdf/
|
zpdf/
|
||||||
├── CLAUDE.md # Este archivo
|
├── CLAUDE.md # Este archivo - estado del proyecto
|
||||||
├── build.zig # Sistema de build
|
├── build.zig # Sistema de build
|
||||||
├── src/
|
├── src/
|
||||||
│ ├── root.zig # Exports públicos
|
│ └── root.zig # Libreria principal (todo en uno por ahora)
|
||||||
│ ├── document.zig # Documento PDF principal
|
|
||||||
│ ├── page.zig # Páginas
|
|
||||||
│ ├── stream.zig # Content streams
|
|
||||||
│ ├── text.zig # Renderizado de texto
|
|
||||||
│ ├── graphics.zig # Líneas, rectángulos, etc.
|
|
||||||
│ ├── image.zig # Imágenes embebidas
|
|
||||||
│ ├── fonts.zig # Fuentes Type1 básicas
|
|
||||||
│ └── writer.zig # Serialización PDF
|
|
||||||
└── examples/
|
└── examples/
|
||||||
├── hello.zig # PDF mínimo
|
├── hello.zig # Ejemplo basico
|
||||||
└── invoice.zig # Factura ejemplo
|
└── invoice.zig # Factura ejemplo
|
||||||
```
|
```
|
||||||
|
|
||||||
## Formato PDF
|
### Formato PDF
|
||||||
|
|
||||||
Usamos PDF 1.4 (compatible con todos los lectores). Estructura básica:
|
Generamos PDF 1.4 (compatible con todos los lectores):
|
||||||
|
|
||||||
```
|
```
|
||||||
%PDF-1.4
|
%PDF-1.4
|
||||||
|
%[binary marker]
|
||||||
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
|
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
|
||||||
2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 >> endobj
|
2 0 obj << /Type /Pages /Kids [...] /Count N >> endobj
|
||||||
3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R >> endobj
|
3 0 obj << /Type /Page ... >> endobj
|
||||||
4 0 obj << /Length ... >> stream ... endstream endobj
|
4 0 obj << /Length ... >> stream ... endstream endobj
|
||||||
xref
|
xref
|
||||||
0 5
|
0 N
|
||||||
0000000000 65535 f
|
trailer << /Size N /Root 1 0 R >>
|
||||||
...
|
|
||||||
trailer << /Size 5 /Root 1 0 R >>
|
|
||||||
startxref
|
startxref
|
||||||
...
|
...
|
||||||
%%EOF
|
%%EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
## API Objetivo
|
### Fuentes Type1 Built-in
|
||||||
|
|
||||||
```zig
|
PDF incluye 14 fuentes estandar que no necesitan embeber:
|
||||||
const std = @import("std");
|
- **Helvetica**: helvetica, helvetica_bold, helvetica_oblique, helvetica_bold_oblique
|
||||||
const pdf = @import("zpdf");
|
- **Times**: times_roman, times_bold, times_italic, times_bold_italic
|
||||||
|
- **Courier**: courier, courier_bold, courier_oblique, courier_bold_oblique
|
||||||
|
- **Otros**: symbol, zapf_dingbats
|
||||||
|
|
||||||
pub fn main() !void {
|
### Tamanos de Pagina
|
||||||
var allocator = std.heap.page_allocator;
|
|
||||||
|
|
||||||
var doc = pdf.Document.init(allocator);
|
| Nombre | Puntos | Milimetros |
|
||||||
defer doc.deinit();
|
|--------|--------|------------|
|
||||||
|
| A4 | 595 x 842 | 210 x 297 |
|
||||||
var page = try doc.addPage(.a4);
|
| A3 | 842 x 1191 | 297 x 420 |
|
||||||
|
| A5 | 420 x 595 | 148 x 210 |
|
||||||
// Texto
|
| Letter | 612 x 792 | 216 x 279 |
|
||||||
try page.setFont(.helvetica_bold, 24);
|
| Legal | 612 x 1008 | 216 x 356 |
|
||||||
try page.drawText(50, 750, "Factura #001");
|
|
||||||
|
|
||||||
try page.setFont(.helvetica, 12);
|
|
||||||
try page.drawText(50, 700, "Cliente: Empresa S.L.");
|
|
||||||
|
|
||||||
// Línea
|
|
||||||
try page.setLineWidth(0.5);
|
|
||||||
try page.drawLine(50, 690, 550, 690);
|
|
||||||
|
|
||||||
// Rectángulo
|
|
||||||
try page.setFillColor(.{ .r = 240, .g = 240, .b = 240 });
|
|
||||||
try page.fillRect(50, 600, 500, 20);
|
|
||||||
|
|
||||||
// Tabla (helper)
|
|
||||||
try page.drawTable(.{
|
|
||||||
.x = 50,
|
|
||||||
.y = 580,
|
|
||||||
.columns = &.{ 200, 100, 100, 100 },
|
|
||||||
.headers = &.{ "Descripción", "Cantidad", "Precio", "Total" },
|
|
||||||
.rows = &.{
|
|
||||||
&.{ "Producto A", "2", "10.00", "20.00" },
|
|
||||||
&.{ "Producto B", "1", "25.00", "25.00" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Guardar
|
|
||||||
try doc.save("factura.pdf");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Funcionalidades Planificadas
|
|
||||||
|
|
||||||
### Fase 1 - Core (Actual)
|
|
||||||
- [ ] Estructura documento PDF 1.4
|
|
||||||
- [ ] Páginas (A4, Letter, custom)
|
|
||||||
- [ ] Texto básico (fuentes Type1 built-in)
|
|
||||||
- [ ] Líneas y rectángulos
|
|
||||||
- [ ] Serialización correcta
|
|
||||||
|
|
||||||
### Fase 2 - Texto Avanzado
|
|
||||||
- [ ] Múltiples fuentes en mismo documento
|
|
||||||
- [ ] Colores (RGB, CMYK, grayscale)
|
|
||||||
- [ ] Alineación (izquierda, centro, derecha)
|
|
||||||
- [ ] Word wrap automático
|
|
||||||
|
|
||||||
### Fase 3 - Imágenes
|
|
||||||
- [ ] JPEG embebido
|
|
||||||
- [ ] PNG embebido (con alpha)
|
|
||||||
- [ ] Escalado y posicionamiento
|
|
||||||
|
|
||||||
### Fase 4 - Utilidades
|
|
||||||
- [ ] Helper para tablas
|
|
||||||
- [ ] Numeración de páginas
|
|
||||||
- [ ] Headers/footers
|
|
||||||
|
|
||||||
## Fuentes Type1 Built-in
|
|
||||||
|
|
||||||
PDF incluye 14 fuentes estándar que no necesitan embeber:
|
|
||||||
- Helvetica, Helvetica-Bold, Helvetica-Oblique, Helvetica-BoldOblique
|
|
||||||
- Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic
|
|
||||||
- Courier, Courier-Bold, Courier-Oblique, Courier-BoldOblique
|
|
||||||
- Symbol, ZapfDingbats
|
|
||||||
|
|
||||||
## Tamaños de Página
|
|
||||||
|
|
||||||
```zig
|
|
||||||
pub const PageSize = enum {
|
|
||||||
a4, // 595 x 842 points (210 x 297 mm)
|
|
||||||
letter, // 612 x 792 points (8.5 x 11 inches)
|
|
||||||
legal, // 612 x 1008 points
|
|
||||||
a3, // 842 x 1191 points
|
|
||||||
a5, // 420 x 595 points
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Referencias
|
|
||||||
|
|
||||||
- [PDF Reference 1.4](https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.4.pdf)
|
|
||||||
- [pdf-nano (Zig)](https://github.com/GregorBudweiser/pdf-nano) - Referencia minimalista
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Equipo y Metodología
|
## API Actual
|
||||||
|
|
||||||
### Normas de Trabajo
|
### Crear Documento
|
||||||
|
|
||||||
**IMPORTANTE**: Todas las normas de trabajo están en:
|
```zig
|
||||||
|
const pdf = @import("zpdf");
|
||||||
|
|
||||||
|
var doc = pdf.Document.init(allocator);
|
||||||
|
defer doc.deinit();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Agregar Paginas
|
||||||
|
|
||||||
|
```zig
|
||||||
|
// Tamano estandar
|
||||||
|
var page = try doc.addPage(.a4);
|
||||||
|
|
||||||
|
// Tamano personalizado (en puntos, 1pt = 1/72 inch)
|
||||||
|
var page = try doc.addPageCustom(500, 700);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Texto
|
||||||
|
|
||||||
|
```zig
|
||||||
|
try page.setFont(.helvetica_bold, 24);
|
||||||
|
page.setFillColor(pdf.Color{ .r = 0, .g = 0, .b = 255 });
|
||||||
|
try page.drawText(50, 750, "Titulo");
|
||||||
|
|
||||||
|
try page.setFont(.times_roman, 12);
|
||||||
|
page.setFillColor(pdf.Color.black);
|
||||||
|
try page.drawText(50, 700, "Texto normal");
|
||||||
|
```
|
||||||
|
|
||||||
|
### Graficos
|
||||||
|
|
||||||
|
```zig
|
||||||
|
// Linea
|
||||||
|
try page.setLineWidth(1);
|
||||||
|
page.setStrokeColor(pdf.Color.gray);
|
||||||
|
try page.drawLine(50, 600, 500, 600);
|
||||||
|
|
||||||
|
// Rectangulo solo borde
|
||||||
|
try page.drawRect(50, 500, 200, 100);
|
||||||
|
|
||||||
|
// Rectangulo relleno
|
||||||
|
page.setFillColor(pdf.Color.light_gray);
|
||||||
|
try page.fillRect(50, 400, 200, 100);
|
||||||
|
|
||||||
|
// Rectangulo con borde y relleno
|
||||||
|
page.setFillColor(pdf.Color{ .r = 200, .g = 220, .b = 255 });
|
||||||
|
page.setStrokeColor(pdf.Color.blue);
|
||||||
|
try page.drawFilledRect(50, 300, 200, 100);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Guardar
|
||||||
|
|
||||||
|
```zig
|
||||||
|
// A archivo
|
||||||
|
try doc.saveToFile("documento.pdf");
|
||||||
|
|
||||||
|
// A buffer (para enviar por red, etc.)
|
||||||
|
const data = try doc.render(allocator);
|
||||||
|
defer allocator.free(data);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Colores Predefinidos
|
||||||
|
|
||||||
|
```zig
|
||||||
|
pdf.Color.black // (0, 0, 0)
|
||||||
|
pdf.Color.white // (255, 255, 255)
|
||||||
|
pdf.Color.red // (255, 0, 0)
|
||||||
|
pdf.Color.green // (0, 255, 0)
|
||||||
|
pdf.Color.blue // (0, 0, 255)
|
||||||
|
pdf.Color.gray // (128, 128, 128)
|
||||||
|
pdf.Color.light_gray // (200, 200, 200)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Comandos
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Zig path
|
||||||
|
ZIG=/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig
|
||||||
|
|
||||||
|
# Compilar
|
||||||
|
$ZIG build
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
$ZIG build test
|
||||||
|
|
||||||
|
# Ejecutar ejemplos
|
||||||
|
$ZIG build hello && ./zig-out/bin/hello
|
||||||
|
$ZIG build invoice && ./zig-out/bin/invoice
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Equipo y Metodologia
|
||||||
|
|
||||||
|
### Normas de Trabajo Centralizadas
|
||||||
|
|
||||||
|
**IMPORTANTE**: Todas las normas de trabajo estan en:
|
||||||
```
|
```
|
||||||
/mnt/cello2/arno/re/recode/TEAM_STANDARDS/
|
/mnt/cello2/arno/re/recode/TEAM_STANDARDS/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Archivos clave a leer**:
|
||||||
|
- `LAST_UPDATE.md` - **LEER PRIMERO** - Cambios recientes en normas
|
||||||
|
- `NORMAS_TRABAJO_CONSENSUADAS.md` - Metodologia fundamental
|
||||||
|
- `QUICK_REFERENCE.md` - Cheat sheet rapido
|
||||||
|
|
||||||
|
### Estandares Zig Open Source (Seccion #24)
|
||||||
|
|
||||||
|
- **Claridad**: Codigo autoexplicativo, nombres descriptivos
|
||||||
|
- **Doc comments**: `///` en todas las funciones publicas
|
||||||
|
- **Idiomatico**: snake_case, error handling explicito
|
||||||
|
- **Sin magia**: Preferir codigo explicito sobre abstracciones complejas
|
||||||
|
|
||||||
### Control de Versiones
|
### Control de Versiones
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -169,18 +288,71 @@ pub const PageSize = enum {
|
||||||
git remote: git@git.reugenio.com:reugenio/zpdf.git
|
git remote: git@git.reugenio.com:reugenio/zpdf.git
|
||||||
|
|
||||||
# Branches
|
# Branches
|
||||||
main # Código estable
|
main # Codigo estable
|
||||||
develop # Desarrollo activo
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Zig Path
|
---
|
||||||
|
|
||||||
```bash
|
## Referencias
|
||||||
ZIG=/mnt/cello2/arno/re/recode/zig/zig-0.15.2/zig-x86_64-linux-0.15.2/zig
|
|
||||||
```
|
### gofpdf (Referencia principal)
|
||||||
|
- Repo: https://github.com/go-pdf/fpdf
|
||||||
|
- Objetivo: Replicar funcionalidad core en Zig
|
||||||
|
|
||||||
|
### PDF Reference
|
||||||
|
- PDF 1.4 Spec: https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.4.pdf
|
||||||
|
|
||||||
|
### Otros (Referencia)
|
||||||
|
- pdf-nano (Zig): https://github.com/GregorBudweiser/pdf-nano
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Historial de Desarrollo
|
||||||
|
|
||||||
|
### 2025-12-08 - v0.1 (Core Funcional)
|
||||||
|
- Estructura inicial del proyecto
|
||||||
|
- Document, Page, Color, Font, PageSize types
|
||||||
|
- Texto con 14 fuentes Type1 standard
|
||||||
|
- Graficos: lineas, rectangulos (stroke, fill, both)
|
||||||
|
- Colores RGB
|
||||||
|
- Serializacion PDF 1.4 correcta
|
||||||
|
- 6 tests unitarios pasando
|
||||||
|
- Ejemplos: hello.zig, invoice.zig funcionales
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Notas de Desarrollo
|
## Notas de Desarrollo
|
||||||
|
|
||||||
*Se irán añadiendo conforme avance el proyecto*
|
### Proxima Sesion
|
||||||
|
1. Implementar word wrap automatico para texto largo
|
||||||
|
2. Agregar helper para tablas (simplificar invoice.zig)
|
||||||
|
3. Soporte para imagenes JPEG
|
||||||
|
4. Alineacion de texto (center, right)
|
||||||
|
|
||||||
|
### Lecciones Aprendidas
|
||||||
|
- PDF es formato relativamente simple para generacion basica
|
||||||
|
- Content streams usan operadores PostScript-like
|
||||||
|
- Coordenadas PDF son desde bottom-left (Y aumenta hacia arriba)
|
||||||
|
- Las 14 fuentes Type1 estan garantizadas en todos los lectores PDF
|
||||||
|
|
||||||
|
### Zig 0.15 Notas
|
||||||
|
- `std.ArrayList` cambio a `std.ArrayListUnmanaged` con allocator explicito
|
||||||
|
- `writer()` ahora requiere allocator como parametro
|
||||||
|
- `toOwnedSlice()` requiere allocator
|
||||||
|
- `deinit()` requiere allocator
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Proyectos Relacionados
|
||||||
|
|
||||||
|
| Proyecto | Descripcion | Repo |
|
||||||
|
|----------|-------------|------|
|
||||||
|
| **zcatui** | TUI library (ratatui-style) | git.reugenio.com/reugenio/zcatui |
|
||||||
|
| **zsqlite** | SQLite wrapper | git.reugenio.com/reugenio/zsqlite |
|
||||||
|
| **zpdf** | PDF generator (este) | git.reugenio.com/reugenio/zpdf |
|
||||||
|
| **service-monitor** | Monitor de servicios | git.reugenio.com/reugenio/service-monitor |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**© zpdf - Generador PDF para Zig**
|
||||||
|
*2025-12-08 - En desarrollo activo*
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue