Refactor code structure for improved readability and maintainability

This commit is contained in:
2026-10-13 10:18:48 -03:00
parent 5612ad3eed
commit 5786e9cde0
4 changed files with 240 additions and 15 deletions
+61
View File
@@ -0,0 +1,61 @@
---
name: book-pdf
description: Generar o regenerar los PDF de los capítulos del libro de C en dist/, con diseño consistente (resaltado de sintaxis, fuente mono para código, notas con fondo de color). Trigger - pdf, generar pdf, exportar capítulo, dist, md-to-pdf, print.css, "convertir a pdf", "rehacer pdf".
---
# Skill: book-pdf — Generación de PDF de los capítulos
Todos los PDF del libro se generan **siempre** con este procedimiento, para que mantengan
exactamente el mismo diseño. Fuente de diseño única: `assets/pdf/print.css`.
## Herramienta
Usar el MCP **`md-to-pdf`** → herramienta **`md-to-pdf_markdown_to_pdf`**.
(NO escribir un pipeline propio con Node/Puppeteer ni instalar pandoc/LaTeX: ya existe este MCP.)
## Pasos
1. **Leer** `assets/pdf/print.css` (con la tool `read`).
2. **Invocar** `md-to-pdf_markdown_to_pdf` con estos parámetros fijos:
| Parámetro | Valor |
| ----------------- | -------------------------------------------------------------- |
| `inputPath` | ruta absoluta del capítulo, p. ej. `book\12-arenas.md` |
| `outputPath` | `dist\<mismo-nombre>.pdf`, p. ej. `dist\12-arenas.pdf` |
| `css` | **el contenido completo** de `assets/pdf/print.css` |
| `format` | `A4` |
| `printBackground` | `true` (obligatorio: pinta los fondos de código y notas) |
| `pageNumbers` | `true` |
| `headerText` | `Programación en C — Libro de ejercicios` |
| `footerText` | el capítulo, p. ej. `12 — Arenas` |
3. Comprobar que la respuesta diga `PDF generated: ... (<n> KB)`.
## Reglas de diseño (no romper)
- **Fuente del cuerpo**: serif (`Georgia` / `Palatino` / `Times`). Definida en `print.css`.
- **Fuente de código**: mono distinta de la del cuerpo (`Cascadia Code` / `JetBrains Mono` /
`Consolas`). **Todo bloque de código debe declarar su lenguaje** en el fence
(```` ```c ````, ```` ```bash ````, ```` ```text ````). Sin lenguaje, `highlight.js` lo trata como
`plaintext` y **no hay resaltado**. Para trazas de consola usar ```` ```text ````.
- **Notas / advertencias**: se escriben como **blockquote** (`>`). En el PDF se dibujan **todas**
igual: caja con fondo azul claro (`#eef4fb`) y borde izquierdo acentuado. No inventar estilos
distintos de nota.
- **Resaltado**: `md-to-pdf` usa `highlight.js` y emite clases `.hljs-*`; los colores están en
`print.css`. No cambiar colores fuera de `print.css`.
## Cambiar el diseño
Si hay que cambiar fuentes, colores o el estilo de las notas, **editar solo
`assets/pdf/print.css`** (es la fuente única) y regenerar **todos** los capítulos para que no
queden PDF con diseños distintos.
## Regenerar todo
Generar cada `book\*.md` a `dist\<nombre>.pdf` con los parámetros de arriba, uno por uno.
## Notas de compatibilidad
- Verificado en esta máquina: `md-to-pdf` 5.2.5 con `marked` 4.3.0 y `highlight.js` 11.12.0;
el highlighter de `md-to-pdf` **sí** resalta (emite `.hljs-keyword/string/comment`).
- El MCP corre headless Chromium vía `md-to-pdf`; no requiere instalación adicional.
+51 -13
View File
@@ -82,19 +82,28 @@ El libro vive bajo un directorio raíz de contenido. Se propone:
c-programming/
├─ AGENTS.md # este archivo (reglas del proyecto)
├─ README.md # presentación del libro e índice general
└─ book/
├─ 00-introduccion.md
├─ 01-conceptos-basicos.md
├─ 02-variables-y-tipos.md
├─ 03-operadores-y-expresiones.md
├─ 04-estructuras-de-control.md
├─ 05-funciones.md
├─ 06-arreglos-y-cadenas.md
├─ 07-punteros.md
├─ 08-structs-y-uniones.md
├─ 09-memoria-dinamica.md
├─ 10-archivos.md
└─ 11-estructuras-de-datos.md
├─ book/ # FUENTE: capítulos en Markdown
│ ├─ 00-introduccion.md
│ ├─ 01-conceptos-basicos.md
│ ├─ 02-variables-y-tipos.md
│ ├─ 03-operadores-y-expresiones.md
│ ├─ 04-estructuras-de-control.md
│ ├─ 05-funciones.md
│ ├─ 06-arreglos-y-cadenas.md
│ ├─ 07-punteros.md
│ ├─ 08-structs-y-uniones.md
│ ├─ 09-memoria-dinamica.md
│ ├─ 10-archivos.md
│ ├─ 11-estructuras-de-datos.md
│ └─ 12-arenas.md
├─ dist/ # SALIDA: un PDF por cada capítulo trabajado
│ └─ 12-arenas.pdf
├─ assets/
│ └─ pdf/
│ └─ print.css # hoja de estilo canónica de los PDF
└─ .opencode/
└─ skills/
└─ book-pdf/SKILL.md # procedimiento para generar los PDF
```
- **Un archivo por tema/concepto principal.**
@@ -163,3 +172,32 @@ Checklist al crear o editar un ejercicio:
10. Actualizar el índice del `README.md` si se agregó un capítulo.
> Recordatorio permanente: se entrega el **problema**, nunca la **respuesta**.
---
## 9. Generación de PDF (`dist/`)
Cada capítulo trabajado se publica como **PDF** en `dist/`, con el **mismo nombre** que su
Markdown: `book/12-arenas.md` → `dist/12-arenas.pdf`.
- Los PDF se generan con el MCP **`md-to-pdf`** (herramienta `md-to-pdf_markdown_to_pdf`).
**No** instalar pandoc/LaTeX ni armar un pipeline propio: ya existe.
- El diseño es **único y compartido**: vive en `assets/pdf/print.css`. No se estiliza capítulo
por capítulo.
- El procedimiento completo y los **parámetros fijos** de generación están en la skill del
proyecto: `.opencode/skills/book-pdf/SKILL.md`. Hay que **seguirla siempre** para que todos los
PDF tengan el mismo diseño.
Reglas de diseño (resumen):
- **Fuente de código:** monoespaciada, distinta de la fuente del cuerpo (serif). Todo bloque de
código declara su lenguaje en el fence (```` ```c ````, ```` ```bash ````, ```` ```text ````);
así `highlight.js` aplica **resaltado de sintaxis**. Un bloque sin lenguaje no se resalta
(las trazas de consola van como ```` ```text ````).
- **Notas / advertencias:** se escriben como **blockquote** (`>`). En el PDF **todas** se dibujan
igual, con un **fondo de color** que resalta del blanco de la hoja.
- `printBackground` debe estar **activo** (si no, no se pintan los fondos de código y notas).
- Encabezado, pie de página y **numeración de páginas** fijos.
> Si se modifica `assets/pdf/print.css`, hay que **regenerar todos** los capítulos para que ningún
> PDF quede con un diseño distinto.
+126
View File
@@ -0,0 +1,126 @@
/* =====================================================================
print.css — Hoja de estilo canónica para los PDF del libro.
Usada por el MCP `md-to-pdf` (herramienta markdown_to_pdf) como `css`.
Reglas de diseño: ver AGENTS.md y .opencode/skills/book-pdf/SKILL.md
NO editar los colores/fuentes sin actualizar también esas referencias.
===================================================================== */
/* --- Garantiza que los colores de fondo se impriman --- */
html {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
:root {
--ink: #1f2733;
--muted: #5b6673;
--accent: #2f6fb3; /* azul del libro */
--rule: #dfe4ea;
--note-bg: #eef4fb; /* fondo de las notas (resalta del blanco) */
--note-border: #2f6fb3;
--code-bg: #f4f6f8;
--code-border: #dfe4ea;
--code-accent: #2f6fb3;
}
/* --- Tipografía del cuerpo: SERIF (distinta de la mono del código) --- */
body {
font-family: "Georgia", "Iowan Old Style", "Palatino Linotype", "Times New Roman", serif;
font-size: 11.5pt;
line-height: 1.6;
color: var(--ink);
}
/* --- Títulos: sans, para diferenciar de la prosa --- */
h1, h2, h3, h4 {
font-family: "Segoe UI", "Calibri", system-ui, sans-serif;
color: #16202b;
line-height: 1.25;
}
h1 { font-size: 22pt; border-bottom: 3px solid var(--accent); padding-bottom: .25em; }
h2 { font-size: 16pt; margin-top: 1.7em; border-bottom: 1px solid var(--rule); padding-bottom: .2em; }
h3 { font-size: 13pt; margin-top: 1.3em; }
h4 { font-size: 11.5pt; margin-top: 1.1em; }
/* --- Código inline: MONO, distinta de la serif del texto --- */
code {
font-family: "Cascadia Code", "JetBrains Mono", "Consolas", "Courier New", monospace;
font-size: .88em;
background: var(--code-bg);
border: 1px solid var(--code-border);
border-radius: 4px;
padding: .08em .35em;
}
/* --- Bloques de código: MONO + resaltado de sintaxis (highlight.js) --- */
pre {
font-family: "Cascadia Code", "JetBrains Mono", "Consolas", "Courier New", monospace;
font-size: 9.5pt;
line-height: 1.5;
background: var(--code-bg);
border: 1px solid var(--code-border);
border-left: 4px solid var(--code-accent);
border-radius: 6px;
padding: .85em 1.1em;
white-space: pre-wrap; /* evita que el código se salga de la hoja */
word-break: break-word;
overflow-wrap: anywhere;
}
pre code {
background: none;
border: none;
padding: 0;
font-size: inherit;
color: inherit;
}
/* --- Paleta de resaltado de sintaxis (clases de highlight.js) --- */
pre code.hljs { background: transparent; }
.hljs-comment, .hljs-quote { color: #6a737d; font-style: italic; }
.hljs-keyword, .hljs-selector-tag,
.hljs-built_in, .hljs-name { color: #c0392b; font-weight: 600; }
.hljs-string, .hljs-meta-string,
.hljs-regexp { color: #1a7f37; }
.hljs-number, .hljs-literal,
.hljs-boolean { color: #0550ae; }
.hljs-function, .hljs-title,
.hljs-title.function_, .hljs-params { color: #6f42c1; }
.hljs-type, .hljs-class .hljs-title { color: #953800; }
.hljs-meta, .hljs-preprocessor { color: #7a5af8; }
.hljs-variable, .hljs-attr,
.hljs-property, .hljs-template-variable { color: #0a3069; }
.hljs-symbol, .hljs-bullet,
.hljs-operator { color: #e36209; }
/* --- Notas: TODO blockquote se dibuja igual, con fondo que resalta --- */
blockquote {
margin: 1.2em 0;
padding: .8em 1.1em;
background: var(--note-bg);
border-left: 5px solid var(--note-border);
border-radius: 6px;
color: #24303d;
}
blockquote > :first-child { margin-top: 0; }
blockquote > :last-child { margin-bottom: 0; }
blockquote p { font-size: 10.5pt; }
/* --- Tablas (escenarios de prueba) --- */
table {
border-collapse: collapse;
width: 100%;
font-size: 10pt;
margin: 1em 0;
}
th, td {
border: 1px solid #d7dde3;
padding: .4em .6em;
text-align: left;
}
th { background: #eef1f4; font-family: "Segoe UI", "Calibri", sans-serif; }
/* --- Separadores y enlaces --- */
hr { border: none; border-top: 1px solid var(--rule); margin: 1.6em 0; }
a { color: var(--accent); text-decoration: none; }
BIN
View File
Binary file not shown.