CommunityRedacción y edicióngithub.com

tjst-t/boxloom

Escribe presentaciones como Markdown de Boxloom (.bx.md) y conviértelas en archivos PPTX nativos y editables. Úsalo cuando te pidan hacer una presentación / PowerPoint / diapositivas con Boxloom, o al editar un archivo .bx.md. Cubre la sintaxis, cómo elegir un patrón para cada contenido, los límites de densidad medidos por el motor de diseño y el ciclo verificar → corregir.

¿Qué es boxloom?

Boxloom es una herramienta que separa el significado de la apariencia en la creación de presentaciones. Permite escribir el contenido en Markdown con una sintaxis específica, definiendo qué es cada elemento (una lista, una comparación, un plan con fechas) sin preocuparse por colores, fuentes o tamaños, que son manejados automáticamente por la plantilla. Esto es especialmente útil para desarrolladores y profesionales técnicos que desean generar diapositivas consistentes y editables (PPTX) de manera eficiente, manteniendo el flujo de trabajo en un entorno de código. El ciclo de trabajo incluye leer el esquema de la plantilla actual, escribir el contenido, verificar errores y construir la presentación final. Soporta múltiples patrones de contenido como tablas, gráficos, diagramas de Gantt y organigramas, cada uno con reglas claras para su uso. Boxloom está diseñado para ser utilizado con Go 1.24+ desde el directorio `boxloom/` del repositorio, y se integra con plataformas como Claude Code, Cursor y Codex para automatizar la creación de diapositivas.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/tjst-t/boxloom/tree/HEAD/skills/boxloom

Installed? Explore more Redacción y edición skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Vista previa

Del README del skill

texto alternativo
alt

Documentación

Boxloom: escribir presentaciones

Boxloom separa el significado de la apariencia. Solo escribes lo que el contenido es (una lista de puntos, una comparación de opciones, un plan con fechas). La plantilla decide cada color, tamaño de fuente, margen y posición. Nunca escribes un color, un tamaño o una coordenada fuera de la única excepción (shapes, último recurso).

El ciclo es siempre:

  1. boxloom schema — lee lo que las plantillas actuales aceptan (haz esto primero).
  2. Escribe deck.bx.md.
  3. boxloom check -format json deck.bx.md — corrige cada error, luego cada advertencia que puedas.
  4. Repite 3 hasta que "ok": true y no haya advertencia layout-overflow.
  5. boxloom build -o deck.pptx deck.bx.md (las banderas antes del archivo).

Los comandos se ejecutan desde el directorio boxloom/ del repositorio: go run ./cmd/boxloom <schema|check|build|parse> … (Go 1.24+, sin otra dependencia).

1. Lee el esquema primero

boxloom schema [-template light|dark] imprime un documento JSON. Es la fuente de verdad; si este archivo y el esquema no coinciden, el esquema gana.

  • markdown.rules — las reglas de sintaxis (lista corta; obedece todas).
  • markdown.frontMatter — claves permitidas en el encabezado --- (title es obligatorio).
  • templates[].blocks — los bloques delimitados (:::nombre) que esta plantilla conoce, con inside (dónde puede aparecer), contains (qué contiene) y minChildren.
  • templates[].subsystems — los tipos de figuras (bloques de código ```nombre), con markdown (sus reglas adicionales) y schema (un puntero JSON a irSchema que da todas las claves permitidas).
  • Cualquier cosa no listada es un error. No inventes nombres de bloques, atributos o claves.
  • Las plantillas se eligen por nombre (template: light en el front matter, o -template dark). Una plantilla personalizada es un archivo de tabla de valores pasado por ruta: -template ./my.json (funciona para schema, check, build, fonts; ejemplo examples/templates/forest.json). Cuando la presentación se construirá con una plantilla personalizada, ejecuta schema y check con el mismo -template — los nombres de roles y estilos de texto provienen de ese archivo.
  • variant (# Título {variant=…}) existe en la sintaxis, pero las plantillas actuales no declaran variantes (templates[].variants está vacío), así que no lo uses.

La salida es grande. Para ver solo lo que necesitas:

go run ./cmd/boxloom schema -template light > /tmp/schema.json
python3 -c "import json;d=json.load(open('/tmp/schema.json'));print(json.dumps({'rules':d['markdown']['rules'],'blocks':d['templates'][0]['blocks'],'subsystems':[(x['name'],x['markdown']) for x in d['templates'][0]['subsystems']]},ensure_ascii=False,indent=1))"
python3 -c "import json;d=json.load(open('/tmp/schema.json'));print(json.dumps(d['irSchema']['\$defs']['gantt'],ensure_ascii=False,indent=1))"   # todas las claves de gantt

2. Sintaxis en una pantalla

---
title: Trasladar el servicio de informes al nuevo clúster
subtitle: Plan y opciones (ejemplo ficticio)
author: Equipo de plataforma
date: 2026-11-11
confidential: Interno
disclaimer: Todos los nombres y cifras son ficticios
template: light
---

# Soporte del proveedor para el clúster antiguo

:::lead
El clúster antiguo pierde el soporte del proveedor en marzo de 2028, por lo que los 14 servicios que contiene deben migrar antes de esa fecha.
:::

- El soporte del proveedor finaliza las correcciones de seguridad el **2028-03-31**
- 14 servicios aún se ejecutan allí; 9 pueden migrar sin cambios de código
- La migración lleva unas 6 semanas por grupo de servicios

:::source
Aviso de soporte del proveedor de 2026-09; inventario de servicios a octubre de 2026
:::

:::notes
Las notas del orador van aquí. Solo párrafos y viñetas.
:::
  • # Título inicia una diapositiva. Mantén el título como un encabezado breve que quepa en una línea ("Soporte del proveedor para el clúster antiguo"); un título que se envuelve se advierte (title-wrap). Escribe lo que dice la diapositiva — la conclusión — como una oración en :::lead justo después del título (1–2 líneas). La plantilla coloca el lead debajo del título, fuera del cuerpo.

  • --- no es un separador de diapositivas (es un error). ## y encabezados más profundos son errores (un título de grupo se escribe como :::columna Título, no como un subencabezado).

  • Cuerpo: párrafos, viñetas - / 1. (máximo dos niveles), **énfasis** (solo un tipo de énfasis), `código`, [texto](url), \ al final para un salto de línea significativo. Sin cursivas, tachado, notas al pie, HTML.

  • Bloques delimitados: abre con :::nombre y cierra con la misma cantidad de dos puntos. Al anidar, el bloque exterior obtiene un punto más que el interior:

    :::::comparar
    ::::opción Mantener el clúster antiguo
    :::pros
    - Sin trabajo de migración este año
    :::
    :::cons
    - Sin correcciones de seguridad después de marzo de 2028
    :::
    ::::
    ::::opción Migrar al nuevo clúster
    :::pros
    - Con soporte hasta 2033
    :::
    :::cons
    - Seis semanas de trabajo por grupo de servicios
    :::
    ::::
    :::::
    
  • :::lead (el mensaje de la diapositiva), :::notes (notas del orador) y :::source (de dónde provienen los números de la diapositiva) deben estar en el nivel superior de una diapositiva, una vez por diapositiva cada uno. :::lead es solo para diapositivas de contenido.

  • date, confidential y disclaimer en el front matter se escriben una vez para toda la presentación; la plantilla los coloca en la portada (y confidential en el pie de página). Nunca repitas "ficticio" / "confidencial" en una :::note en cada diapositiva.

  • Las figuras son bloques de código delimitados cuyo lenguaje es el nombre del subsistema, el cuerpo en YAML restringido: sin anclas/alias (&, *), sin etiquetas, sin valores multilínea, sin bloques |/>; booleanos solo true/false; las fechas son cadenas YYYY-MM o YYYY-MM-DD; rangos 2027-01 .. 2027-06. Pon entre comillas cualquier valor que comience con *, &, ! o que contenga ": ", por ejemplo, text: ["**Paso más lento**", 5 días en promedio] — un **…** sin comillas al inicio de un elemento de flujo se interpreta como un alias de YAML y se rechaza.

3. Elegir un patrón para cada contenido

Decide el tipo de contenido antes de escribir. Aplica estas reglas en orden y usa la primera que coincida. (Conjunto completo de reglas con ejemplos buenos/malos: docs/patterns.md §4.)

Disponibles ahora (consulta boxloom schema — pueden haberse añadido más):

ContenidoUsarNotas
Un corte de capítulo# Parte 2: Cómo migramos {type=section}El texto del encabezado es el título del capítulo; nada más que :::notes puede seguir. No es una tabla de contenido — cuando la presentación tiene dos o más secciones, la plantilla dibuja la lista de capítulos con el actual resaltado en cada diapositiva de sección por sí misma
La diapositiva dice exactamente una oración; la evidencia está en otras diapositivas# La migración debe adelantarse dos años {type=statement}El texto del encabezado es la oración (este es el único tipo de diapositiva cuyo encabezado es una oración completa); nada más que :::notes y :::source puede seguir. Si agregarías razones, usa una diapositiva normal con un título corto y la conclusión como :::lead
1–4 números para mostrar con fuerza, sin series para comparar::::stat → :::value 3 → 12 {unit=modelos} + etiqueta de una línea dentro5+ números o una serie temporal es un gráfico/tabla, no stat. El valor se escribe tal cual y debe contener un dígito. El valor y la unidad nunca se rompen en el medio, así que mantenlos cortos — 4 tarjetas son estrechas (stat-value)
Una serie de números (3+ puntos): ranking, cambio en el tiempo, parte de un total, distribución, relación de dos cantidades```chartcompare: item / timeSeries / component / frequency / correlation — el tipo de gráfico se elige por ti (nunca escribas barra/línea/pastel). categories: [...], series: [{name, values: [...]}] (un valor por categoría, números sin comillas, máximo 3 series), opcional unit, emphasis: [category] (una serie) o emphasis: true en una serie, stacked: true cuando las series son partes de un total. correlation usa xAxis: {title, unit?}, yAxis y points: [[x, y], …] en lugar de categorías. component (parte) tiene 1 serie y ≤ 6 partes — fusiona partes pequeñas en "Otros"
Palabras de otra persona:::quote Texto fuente + las palabras dentroLa fuente (texto del encabezado) es obligatoria. Nunca cites tu propia conclusión
Una oración para enfatizar dentro de una diapositiva normal:::takeaway + una oraciónComo máximo una por diapositiva, generalmente al final
Filas × columnas de texto simple o númerosTabla GFM: | A | B | + | --- | --- | + filasLa primera fila es el encabezado; cada fila tiene una celda por columna (table-shape). Sin marcadores de alineación (:--, --: son errores); las columnas numéricas se alinean a la derecha por ti. Las celdas son solo en línea. Una línea : leyenda justo después de la tabla es su leyenda. Si la última fila es un total, termina esa línea con {total=last} (: Estimaciones {total=last}, o solo : {total=last}); se dibuja como fila de total. Los totales no se calculan — escribe el valor. Pon la unidad una vez en la leyenda o el encabezado, no en cada celda. Calificaciones en celdas → matrix (abajo)
Filas × columnas donde cada celda es una calificación (compatible / condicional / no / riesgo)```matrixcolumns: [A, B], rows: [{label, cells: [{status, text?}]}], opcional legend: {support: Bueno}. Una celda por columna (matrix-cells). La opción recomendada: emphasis: <texto del encabezado de columna> (exactamente como está escrito en columns, matrix-emphasis) — nunca digas "la columna azul" en prosa. Las celdas que son texto simple o números son una tabla, no una matriz
3–7 pasos sin fechas, en una dirección (la salida de uno es la entrada del siguiente)```processsteps: [{title, detail?, status?, emphasis?}], opcional caption. Los números (1. 2. …) y las flechas se añaden por ti; los procesos largos se envuelven a una segunda fila. Si usas status, di lo que significa en legend: {conditional: Necesita aprobación} (figure-legend)
Dos o más opciones, cada una con pros y contras:::compare → :::option → :::pros / :::consSi 3+ criterios compartidos se aplican a cada opción, una matriz encaja mejor (arriba)
Un padre con hijos (y nietos): configuración de equipo, propiedad```orgchartroot: {title, detail?}, units: [{title, detail?, members: [{title, detail?}]}]. 3 niveles máximo. Un status en una caja necesita legend: {conditional: Se necesitan dos personas más} — la leyenda debajo del gráfico lo explica; no expliques los colores del contorno en una :::note. No para equipos no relacionados uno al lado del otro
Etapas cuyo recuento se reduce (visitas → registros → pagos)```funnelstages: [{label, value, note?}], opcional unit. value es un número o texto; los anchos de las barras son escalonados, no proporcionales. Las tasas de conversión etapa a etapa (↓ 45%) se dibujan por ti a partir de valores numéricos — no las escribas en note; usa note para explicar por qué una etapa disminuye. status necesita legend. Los valores que crecen se advierten (funnel-increase) — usa process para pasos simples
Un plan con fechas, períodos, plazos, estados a lo largo del tiempo```ganttLos estados son support, conditional, none, danger (roles, no colores). Los períodos de hardware/riesgo de soporte son un grupo risk: A .. B. Las anotaciones apuntan a un id de grupo/fila mediante target; el subsistema las coloca
2–3 grupos paralelos leídos uno al lado del otro ("este año / el próximo año / no se hace")::::columns → :::column Título del grupo (2 o 3)Cada grupo contiene párrafos, viñetas, una tabla, una imagen, un ```chart o :::note. Sin columnas anidadas, comparaciones, galerías u otras figuras. Gráfico + su lectura uno al lado del otro: gráfico en un grupo, las conclusiones como viñetas en el otro. Los anchos no son números: marca el grupo principal {role=main} (los otros lo apoyan) o déjalos iguales. 4+ grupos de una línea → viñetas. No para un argumento dividido en dos
Una imagen que muestra el punto (captura de pantalla, foto, dibujo)un párrafo que contiene solo ![texto alternativo](images/x.png "leyenda")El texto alternativo es obligatorio (image-alt). La ruta es relativa al archivo de la presentación; sin URLs, rutas absolutas o .. (image-path). Solo PNG o JPEG (image-format). Se mantiene en proporción, nunca recortada. Imagen + texto uno al lado del otro → ::::columns con la imagen en un grupo
2–6 imágenes comparadas o en secuenciaun párrafo con 2–6 ![alt](ruta "leyenda")Se convierte en una galería (una fila para 2–3, una cuadrícula para 4–6). 7+ es un error: divide la diapositiva
Puntos paralelosviñetas2 niveles máximo
Prosa conectadapárrafo2–3 oraciones
Lo que dice la diapositiva: su conclusión en una o dos oraciones:::lead en el nivel superior de una diapositiva de contenido, un párrafoCada diapositiva de contenido tiene uno. Colocado por la plantilla justo debajo del título, fuera del cuerpo; toma espacio del cuerpo (1 línea ≈ 32 pt, 2 líneas ≈ 57 pt). Cuando necesita dos líneas, el motor lo rompe después del final de una oración (。) o, si no, después de una coma (、) sin agregar una línea — por lo que dos oraciones cortas se leen mejor. No es un resumen de las viñetas — es la afirmación que demuestran
De dónde provienen los números, tabla, figura o cita de la diapositiva (fuente, tamaño de muestra, fecha):::source en el nivel superior de la diapositiva, un párrafoToda diapositiva que muestra números, una tabla, un gráfico o una cita tiene uno. Solo diapositivas de contenido y declaración (no de sección). Colocado por la plantilla debajo del cuerpo, encima del pie de página; toma espacio del cuerpo (layout-overflow lo cuenta). Una por diapositiva: varias fuentes van en un párrafo
Fecha, confidencialidad, descargo de responsabilidad para toda la presentación ("todas las cifras son ficticias")front matter date, confidential, disclaimerEscrito una vez; se muestra en la portada (y confidential en el pie de página)
Una advertencia / comentario similar a una nota al pie:::noteUna línea corta. No para fuentes (:::source), no para el descargo de responsabilidad de toda la presentación (front matter), y nunca para la conclusión o un número clave
Un diagrama cuyas posiciones/conexiones tienen significado y ninguno de los anteriores encaja```shapesÚltimo recurso, ver §3.1

En las cuatro figuras anteriores solo escribes texto, status (support, conditional, none, danger) y emphasis: true; la posición, el tamaño y el color provienen de la plantilla. En chart solo escribes lo que se compara y los números; el gráfico es un gráfico real de PowerPoint cuyos valores permanecen editables. Enfatiza el único punto que el título expresa:

compare: timeSeries
unit: " registros"
categories: [Abr, May, Jun, Jul, Ago, Sep]
emphasis: [Sep]
series:
  - name: Registros
    values: [120, 150, 1

…

[truncado para la traducción]

Skills relacionados