refactor: migrar reportes a Typst con plantilla compartida y scripts
- Reemplazar plantillas Markdown por template/report.typ y template/main.typ - Agregar primer reporte: respuesta-observaciones-avance-1 - Agregar scripts build.sh, preview.sh y common.sh con salida en pdf/ - Actualizar README y AGENTS.md; simplificar .gitignore
This commit is contained in:
+1
-24
@@ -1,33 +1,10 @@
|
|||||||
# Sistemas operativos
|
# Sistemas operativos
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
desktop.ini
|
|
||||||
|
|
||||||
# Editores e IDEs
|
# Editores
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
*.swp
|
*.swp
|
||||||
*~
|
*~
|
||||||
|
|
||||||
# Python
|
|
||||||
__pycache__/
|
|
||||||
*.py[cod]
|
|
||||||
.venv/
|
|
||||||
venv/
|
|
||||||
.pytest_cache/
|
|
||||||
.mypy_cache/
|
|
||||||
|
|
||||||
# Node
|
|
||||||
node_modules/
|
|
||||||
|
|
||||||
# Salidas y archivos temporales de generación de reportes
|
|
||||||
*.tmp
|
|
||||||
*.bak
|
|
||||||
.cache/
|
|
||||||
build/
|
|
||||||
dist/
|
|
||||||
output/
|
|
||||||
|
|
||||||
# Binarios grandes que no deben versionarse
|
|
||||||
*.zip
|
|
||||||
*.tar.gz
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Agent instructions
|
||||||
|
|
||||||
|
- Do not use Graphify in this repository or generate Graphify artifacts. Inspect
|
||||||
|
files directly with tools such as `rg` instead.
|
||||||
|
- Do not commit or push unless the user explicitly requests that action. A request
|
||||||
|
to edit, fix, build, or test does not authorize a commit or push. Permission to
|
||||||
|
commit does not imply permission to push, and permission to push does not imply
|
||||||
|
permission to create a commit.
|
||||||
|
- Preserve existing uncommitted changes. Do not stage unrelated work.
|
||||||
|
- Work on the current branch. Create or switch branches only when explicitly asked.
|
||||||
|
- Keep the README concise and in Spanish.
|
||||||
|
- Keep templates and reports separate: shared styling in `template/report.typ`
|
||||||
|
and the reusable scaffold in `template/main.typ`; actual reports belong in
|
||||||
|
`reports/<slug>/main.typ`, with images in `figures/`. Use short, descriptive,
|
||||||
|
lowercase hyphenated folder names; keep the full internal title in the document.
|
||||||
|
- Do not generate PDFs for files in `template/`; compile actual reports only.
|
||||||
|
- Use `./scripts/build.sh` to validate changes against the first report, or pass the affected report
|
||||||
|
path. Existing PDFs must be preserved unless `--force` is explicitly supplied.
|
||||||
|
To validate source changes, use `./scripts/build.sh --force [path]`.
|
||||||
|
Save generated PDFs in the repository's root `pdf/` directory, named after the
|
||||||
|
report folder for `main.typ`, or the source filename for other `.typ` files.
|
||||||
|
Generated PDFs are local artifacts and must not be committed.
|
||||||
|
- Use `./scripts/preview.sh [path]` to open the saved PDF (creating it only if
|
||||||
|
missing). With `--force`, it regenerates and watches until Ctrl+C.
|
||||||
@@ -1,42 +1,45 @@
|
|||||||
# Reportes
|
# Reportes FONDEF IT24I0091 Manito
|
||||||
|
|
||||||
Repositorio central de reportes del equipo. Cada reporte se genera a partir de una
|
Reportes en [Typst](https://typst.app) con una plantilla compartida en
|
||||||
plantilla y se archiva según su tipo, de modo que el historial quede ordenado y sea
|
`template/report.typ`. Requiere Typst (probado con 0.15.1) y Bash; para la vista
|
||||||
fácil encontrar versiones anteriores.
|
previa, un visor de PDF predeterminado.
|
||||||
|
|
||||||
## Estructura
|
`template/` contiene solo la plantilla y el documento base reutilizable.
|
||||||
|
Los scripts no generan PDF de las plantillas; cópielas a `reports/` para usarlas.
|
||||||
|
`reports/` contiene los reportes, cada uno en su propia carpeta.
|
||||||
|
El primero es `reports/respuesta-observaciones-avance-1/main.typ`, con el título
|
||||||
|
interno «RESPUESTA OBSERVACIONES INF. DE AVANCE 1».
|
||||||
|
|
||||||
```text
|
## Compilar y ver
|
||||||
.
|
|
||||||
├── README.md # esta guía
|
```bash
|
||||||
├── .gitignore # archivos ignorados por Git
|
./scripts/build.sh # compila solo si no existe el PDF
|
||||||
├── plantillas/ # plantillas para crear nuevos reportes
|
./scripts/preview.sh # abre el PDF existente; lo crea si falta
|
||||||
│ └── plantilla-reporte.md
|
./scripts/build.sh --force # regenera el PDF aunque exista
|
||||||
├── reportes/ # reportes archivados, uno por carpeta
|
./scripts/preview.sh --force # regenera, abre y recompila al guardar
|
||||||
│ ├── semanal/
|
./scripts/build.sh reports/respuesta-observaciones-avance-1
|
||||||
│ ├── mensual/
|
./scripts/preview.sh reports/respuesta-observaciones-avance-1/main.typ
|
||||||
│ ├── hito/
|
|
||||||
│ └── final/
|
|
||||||
└── assets/ # imágenes y binarios embebidos en los reportes
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Tipos de reporte
|
Ambos scripts aceptan un archivo `.typ` o una carpeta con `main.typ`. Los PDF se
|
||||||
|
guardan en `pdf/` en la raíz, con el nombre del reporte: por ejemplo,
|
||||||
|
`pdf/respuesta-observaciones-avance-1.pdf`. Para `main.typ` se usa el nombre de
|
||||||
|
su carpeta; para otros archivos, el nombre del archivo sin `.typ`.
|
||||||
|
El PDF se conserva aunque cambien los fuentes. Para
|
||||||
|
actualizarlo, use `--force` (o `-f`). Las rutas relativas parten del directorio
|
||||||
|
actual; los scripts configuran la raíz de Typst automáticamente. Use Ctrl+C para
|
||||||
|
detener la vista previa con `--force`.
|
||||||
|
|
||||||
| Tipo | Carpeta | Descripción |
|
## Crear un reporte
|
||||||
| --- | --- | --- |
|
|
||||||
| Semanal | `reportes/semanal/` | Avance de la semana: tareas, bloqueos, próximos pasos. |
|
|
||||||
| Mensual | `reportes/mensual/` | Resumen del mes con métricas y estado general. |
|
|
||||||
| Hito | `reportes/hito/` | Cierre de un hito o entregable del proyecto. |
|
|
||||||
| Final | `reportes/final/` | Informe final del proyecto. |
|
|
||||||
|
|
||||||
## Cómo agregar un reporte
|
```bash
|
||||||
|
mkdir -p reports/nombre-corto/figures
|
||||||
|
cp template/main.typ reports/nombre-corto/main.typ
|
||||||
|
```
|
||||||
|
|
||||||
1. Copia `plantillas/plantilla-reporte.md` a la carpeta de su tipo.
|
Edite los datos de `report.with(...)` y el contenido de `main.typ`. Guarde las
|
||||||
2. Nombra el archivo `AAAA-MM-DD-<slug>.md`, por ejemplo `2026-10-28-semana-44.md`.
|
imágenes en `figures/` y use nombres de carpeta cortos, en minúsculas y con guiones.
|
||||||
3. Completa la tabla de metadatos (frontmatter) y el contenido.
|
Los PDF no se versionan; las entregas se guardan en Google Drive.
|
||||||
4. Guarda las imágenes en `assets/` y referéncialas desde el reporte.
|
|
||||||
|
|
||||||
## Agregar un nuevo tipo de reporte
|
Las reglas para agentes están en [AGENTS.md](AGENTS.md): los commits y pushes
|
||||||
|
requieren una solicitud explícita del usuario.
|
||||||
Crea una carpeta en `reportes/<nuevo-tipo>/` con su propio `README.md` describiendo
|
|
||||||
el formato, y copia la carpeta de un tipo existente como base.
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
# Assets
|
|
||||||
|
|
||||||
Imágenes, diagramas y binarios embebidos (`![[...]]`) desde los reportes.
|
|
||||||
Organiza por reporte o fecha cuando haya muchos archivos.
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
---
|
|
||||||
titulo: "Título del reporte"
|
|
||||||
tipo: semanal # semanal | mensual | hito | final
|
|
||||||
fecha: AAAA-MM-DD
|
|
||||||
autor: Cristhian
|
|
||||||
estado: borrador # borrador | revisado | entregado
|
|
||||||
---
|
|
||||||
|
|
||||||
# Título del reporte
|
|
||||||
|
|
||||||
## Resumen
|
|
||||||
|
|
||||||
Un párrafo con lo esencial del periodo.
|
|
||||||
|
|
||||||
## Avance
|
|
||||||
|
|
||||||
- Tarea o resultado 1.
|
|
||||||
- Tarea o resultado 2.
|
|
||||||
|
|
||||||
## Bloqueos y riesgos
|
|
||||||
|
|
||||||
- Nada bloqueante, o descripción del bloqueo.
|
|
||||||
|
|
||||||
## Próximos pasos
|
|
||||||
|
|
||||||
- [ ] Acción siguiente.
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# Reportes finales
|
|
||||||
|
|
||||||
Informe final del proyecto: resultados completos, conclusiones y lecciones aprendidas.
|
|
||||||
|
|
||||||
- Nombre de archivo: `AAAA-MM-DD-informe-final.md`.
|
|
||||||
- Plantilla base: `../../plantillas/plantilla-reporte.md`.
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# Reportes de hito
|
|
||||||
|
|
||||||
Cierre de un hito o entregable del proyecto: objetivos cumplidos, entregables y
|
|
||||||
evidencia asociada.
|
|
||||||
|
|
||||||
- Nombre de archivo: `AAAA-MM-DD-hito-<n>.md`.
|
|
||||||
- Plantilla base: `../../plantillas/plantilla-reporte.md`.
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# Reportes mensuales
|
|
||||||
|
|
||||||
Resumen mensual con métricas, estado general del proyecto y decisiones tomadas.
|
|
||||||
|
|
||||||
- Nombre de archivo: `AAAA-MM-<slug>.md` (primer día del mes).
|
|
||||||
- Plantilla base: `../../plantillas/plantilla-reporte.md`.
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# Reportes semanales
|
|
||||||
|
|
||||||
Reportes de avance de una semana: tareas realizadas, bloqueos y próximos pasos.
|
|
||||||
|
|
||||||
- Nombre de archivo: `AAAA-MM-DD-<slug>.md` (fecha del lunes de la semana).
|
|
||||||
- Plantilla base: `../../plantillas/plantilla-reporte.md`.
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#import "/template/report.typ": report
|
||||||
|
|
||||||
|
#show: report.with(
|
||||||
|
title: "RESPUESTA OBSERVACIONES INF. DE AVANCE 1",
|
||||||
|
kind: "Respuesta a observaciones",
|
||||||
|
date: datetime(year: 2026, month: 10, day: 28),
|
||||||
|
version: "0.1",
|
||||||
|
)
|
||||||
|
|
||||||
|
= Antecedentes
|
||||||
|
|
||||||
|
Pendiente: indicar los antecedentes del informe de avance 1 y las observaciones recibidas.
|
||||||
|
|
||||||
|
= Respuesta a observaciones
|
||||||
|
|
||||||
|
== Observación 1
|
||||||
|
|
||||||
|
*Observación recibida:* pendiente de incorporar.
|
||||||
|
|
||||||
|
*Respuesta:* pendiente de elaborar.
|
||||||
|
|
||||||
|
*Respaldo:* pendiente de indicar los documentos o evidencias correspondientes.
|
||||||
|
|
||||||
|
= Anexos
|
||||||
|
|
||||||
|
Pendiente: incorporar los antecedentes de respaldo que correspondan.
|
||||||
Executable
+3
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source "$(dirname -- "${BASH_SOURCE[0]}")/common.sh"
|
||||||
|
build_pdf
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Shared setup; sourced by build.sh and preview.sh.
|
||||||
|
set -euo pipefail
|
||||||
|
repo_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 [--force|-f] [document.typ | report-directory]"
|
||||||
|
echo "Defaults to reports/respuesta-observaciones-avance-1/main.typ. Relative paths use the current directory."
|
||||||
|
echo "Existing PDFs are preserved unless --force is given. Preview watches only with --force."
|
||||||
|
}
|
||||||
|
force=false
|
||||||
|
input=""
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--force|-f) force=true ;;
|
||||||
|
--help|-h) usage; exit 0 ;;
|
||||||
|
-*) echo "Error: unknown option: $1" >&2; usage >&2; exit 2 ;;
|
||||||
|
*)
|
||||||
|
if [[ -n "$input" ]]; then usage >&2; exit 2; fi
|
||||||
|
input="$1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
input="${input:-$repo_root/reports/respuesta-observaciones-avance-1/main.typ}"
|
||||||
|
if [[ -d "$input" ]]; then input="$input/main.typ"; fi
|
||||||
|
if [[ ! -f "$input" || "$input" != *.typ ]]; then
|
||||||
|
echo "Error: expected an existing .typ file: $input" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
input="$(realpath -- "$input")"
|
||||||
|
case "$input" in
|
||||||
|
"$repo_root/template/"*)
|
||||||
|
echo "Error: las plantillas no generan PDF; copie el documento base a reports/ primero." >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
name="$(basename -- "$input" .typ)"
|
||||||
|
if [[ "$name" == main ]]; then
|
||||||
|
name="$(basename -- "$(cd -- "$(dirname -- "$input")" && pwd)")"
|
||||||
|
fi
|
||||||
|
output="$repo_root/pdf/$name.pdf"
|
||||||
|
|
||||||
|
require_typst() {
|
||||||
|
command -v typst >/dev/null 2>&1 || {
|
||||||
|
echo "Error: install Typst and make it available on PATH." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build_pdf() {
|
||||||
|
if [[ -e "$output" && "$force" == false ]]; then
|
||||||
|
printf 'PDF existente: %s (use --force para regenerar)\n' "$output"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
require_typst
|
||||||
|
mkdir -p -- "$repo_root/pdf"
|
||||||
|
typst compile --root "$repo_root" "$input" "$output"
|
||||||
|
printf 'PDF: %s\n' "$output"
|
||||||
|
}
|
||||||
Executable
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source "$(dirname -- "${BASH_SOURCE[0]}")/common.sh"
|
||||||
|
if [[ "$force" == true ]]; then
|
||||||
|
require_typst
|
||||||
|
mkdir -p -- "$repo_root/pdf"
|
||||||
|
exec typst watch --root "$repo_root" "$input" "$output" --open
|
||||||
|
fi
|
||||||
|
build_pdf
|
||||||
|
# Use an absolute path so the viewer also handles names starting with a dash.
|
||||||
|
pdf_path="$(cd -- "$(dirname -- "$output")" && pwd)/$(basename -- "$output")"
|
||||||
|
if command -v xdg-open >/dev/null 2>&1; then
|
||||||
|
exec xdg-open "$pdf_path"
|
||||||
|
elif command -v open >/dev/null 2>&1; then
|
||||||
|
exec open "$pdf_path"
|
||||||
|
else
|
||||||
|
echo "Error: no PDF opener found (xdg-open or open). PDF: $pdf_path" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#import "/template/report.typ": report, project
|
||||||
|
|
||||||
|
#show: report.with(
|
||||||
|
title: "Título del reporte",
|
||||||
|
subtitle: "Subtítulo opcional",
|
||||||
|
kind: "Informe técnico",
|
||||||
|
date: datetime(year: 2026, month: 10, day: 28),
|
||||||
|
version: "0.1",
|
||||||
|
authors: (
|
||||||
|
(name: "Nombre Apellido"),
|
||||||
|
),
|
||||||
|
history: (
|
||||||
|
(version: "0.1", date: "2026-10-28", author: "Nombre Apellido", changes: "Versión inicial."),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
= Introducción
|
||||||
|
|
||||||
|
Contexto del reporte, objetivo y alcance. Los datos del proyecto están disponibles como
|
||||||
|
`project`, por ejemplo #project.code.
|
||||||
|
|
||||||
|
= Desarrollo
|
||||||
|
|
||||||
|
== Metodología
|
||||||
|
|
||||||
|
Describa los procedimientos, materiales y criterios utilizados.
|
||||||
|
|
||||||
|
== Resultados
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
table(
|
||||||
|
columns: 3,
|
||||||
|
[Métrica], [Versión anterior], [Versión actual],
|
||||||
|
[Métrica A], [—], [—],
|
||||||
|
[Métrica B], [—], [—],
|
||||||
|
),
|
||||||
|
caption: [Ejemplo de tabla comparativa.],
|
||||||
|
)
|
||||||
|
|
||||||
|
= Conclusiones
|
||||||
|
|
||||||
|
Síntesis de los resultados y próximos pasos.
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
// Plantilla general de reportes del proyecto FONDEF IT24I0091 Manito.
|
||||||
|
|
||||||
|
#let project = (
|
||||||
|
code: "IT24I0091",
|
||||||
|
name: "Manito: Potenciando el aprendizaje inicial con IA y robótica colaborativa",
|
||||||
|
program: "FONDEF IT 2024 · ANID",
|
||||||
|
institution: "Universidad San Sebastián",
|
||||||
|
partner: "Servicio Local de Educación Pública Llanquihue",
|
||||||
|
)
|
||||||
|
|
||||||
|
// Typst no traduce los nombres de los meses al formatear fechas.
|
||||||
|
#let months = (
|
||||||
|
"enero", "febrero", "marzo", "abril", "mayo", "junio",
|
||||||
|
"julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre",
|
||||||
|
)
|
||||||
|
|
||||||
|
#let format-date(date) = [#date.day() de #months.at(date.month() - 1) de #date.year()]
|
||||||
|
|
||||||
|
#let title-page(title, subtitle, kind, date, version, authors) = page(header: none, footer: none)[
|
||||||
|
#set par(justify: false)
|
||||||
|
|
||||||
|
#text(size: 10pt, fill: luma(90))[#project.program #h(1fr) Proyecto #project.code]
|
||||||
|
#line(length: 100%, stroke: 0.5pt + luma(160))
|
||||||
|
#text(size: 12pt)[#project.name]
|
||||||
|
|
||||||
|
#v(1fr)
|
||||||
|
|
||||||
|
#text(size: 11pt, fill: luma(90), tracking: 0.08em)[#upper(kind)]
|
||||||
|
#v(0.4em)
|
||||||
|
#text(size: 24pt, weight: "bold")[#title]
|
||||||
|
#if subtitle != none {
|
||||||
|
v(0.2em)
|
||||||
|
text(size: 15pt)[#subtitle]
|
||||||
|
}
|
||||||
|
|
||||||
|
#v(1fr)
|
||||||
|
|
||||||
|
#table(
|
||||||
|
columns: (auto, 1fr),
|
||||||
|
stroke: none,
|
||||||
|
inset: (x: 0pt, y: 4pt),
|
||||||
|
column-gutter: 1.5em,
|
||||||
|
[*Versión*], [#version],
|
||||||
|
[*Fecha*], [#format-date(date)],
|
||||||
|
[*Autores*], [#authors.map(author => author.name).join(linebreak())],
|
||||||
|
[*Institución*], [#project.institution],
|
||||||
|
[*Entidad asociada*], [#project.partner],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
#let report(
|
||||||
|
title: "Título del reporte",
|
||||||
|
subtitle: none,
|
||||||
|
kind: "Informe técnico",
|
||||||
|
date: datetime.today(),
|
||||||
|
version: "1.0",
|
||||||
|
authors: (),
|
||||||
|
history: (),
|
||||||
|
body,
|
||||||
|
) = {
|
||||||
|
set document(title: title, author: authors.map(author => author.name), date: date)
|
||||||
|
set page(paper: "us-letter", margin: (x: 2.5cm, top: 2.8cm, bottom: 2.5cm))
|
||||||
|
set text(font: "New Computer Modern", size: 11pt, lang: "es", region: "cl")
|
||||||
|
set par(justify: true, leading: 0.65em)
|
||||||
|
set heading(numbering: "1.1")
|
||||||
|
show heading.where(level: 1): set block(above: 1.8em, below: 1em)
|
||||||
|
set table(stroke: 0.5pt + luma(150), inset: 6pt)
|
||||||
|
show figure.where(kind: table): set figure.caption(position: top)
|
||||||
|
|
||||||
|
title-page(title, subtitle, kind, date, version, authors)
|
||||||
|
|
||||||
|
show table.cell.where(y: 0): set text(weight: "bold")
|
||||||
|
|
||||||
|
set page(
|
||||||
|
header: {
|
||||||
|
set text(size: 9pt, fill: luma(90))
|
||||||
|
grid(columns: (1fr, auto), [FONDEF #project.code · #kind], [#title])
|
||||||
|
line(length: 100%, stroke: 0.4pt + luma(160))
|
||||||
|
},
|
||||||
|
footer: context {
|
||||||
|
set text(size: 9pt, fill: luma(90))
|
||||||
|
align(center)[Página #counter(page).display() de #counter(page).final().first()]
|
||||||
|
},
|
||||||
|
)
|
||||||
|
counter(page).update(1)
|
||||||
|
|
||||||
|
if history.len() > 0 {
|
||||||
|
heading(numbering: none, outlined: false)[Control de versiones]
|
||||||
|
table(
|
||||||
|
columns: (auto, auto, auto, 1fr),
|
||||||
|
[Versión], [Fecha], [Autor], [Cambios],
|
||||||
|
..history.map(entry => (entry.version, entry.date, entry.author, entry.changes)).flatten(),
|
||||||
|
)
|
||||||
|
v(1.5em)
|
||||||
|
}
|
||||||
|
|
||||||
|
outline(title: [Índice], indent: auto)
|
||||||
|
pagebreak()
|
||||||
|
|
||||||
|
body
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user