Diagramas
Última actualización: 06-01-2026 09:01 PM
Objetivo
Section titled “Objetivo”En pDOCS usamos D2 solo para lo básico y útil:
- Cajas con nombres (bloques)
- Cajas dentro de cajas (contenedores / módulos)
- Flechas con intención (normal, punteada, “principal”, etc.)
Todo lo demás (diagramas raros, overkill visual) no se usa aquí.
Por qué D2 (y por qué nos sirve)
Section titled “Por qué D2 (y por qué nos sirve)”D2 es texto declarativo que se renderiza a SVG, perfecto para documentación:
- Vive en Markdown (diff/review en Git).
- No dependes de archivos binarios (draw.io / figma export).
- El resultado por defecto suele verse más “bonito” que Mermaid sin pelearte con CSS.
- Tiene control real de layout/estilo/temas.
Referencia oficial y playground:
Estándar pDOCS: D2 visible + Mermaid oculto para LLM
Section titled “Estándar pDOCS: D2 visible + Mermaid oculto para LLM”El problema real
Section titled “El problema real”En la página final, D2 se renderiza como SVG. Ese SVG puede no conservar el source original de forma legible/recuperable desde el HTML final. En consecuencia, un LLM no puede “leer” el diagrama desde la web con fiabilidad si solo existe el SVG.
La solución (estándar pDOCS)
Section titled “La solución (estándar pDOCS)”- Diagrama visible: bloque Markdown
```d2(lo normal, lo que ve el usuario). - Fallback oculto para LLM: un bloque Mermaid (explícito y estable) justo debajo del diagrama, dentro de:
<pre class="llm-only" data-diagram="llm" data-format="mermaid" aria-hidden="true"><code>...</code></pre>Reglas obligatorias
Section titled “Reglas obligatorias”- NO usar el atributo HTML
hidden. (Algunos extractores lo ignoran.) - Ocultar solo con CSS
.llm-only(presente en el HTML, invisible visualmente). - El Mermaid debe ser mínimo y explícito: nodos, contención, conexiones, etiquetas e intención.
- Si el diagrama tiene fórmula (LaTeX), incluirla en el nodo (o label) para que quede inequívoca.
- Mantener el contrato de fallback versionado:
pdocs.diagram.mermaid.v1. - El fallback Mermaid debe incluir como “firma” (primera línea de comentario):
%% pdocs.diagram.mermaid.v1.
Regla crítica (precisión de contenedores):
- Si en D2 un nodo aparece dentro de un contenedor
{ ... }, entonces en Mermaid ese nodo DEBE vivir dentro de unsubgraphequivalente.
Nota de seguridad HTML: si dentro del Mermaid o labels necesitas el carácter
<, escápalo como<para no romper el HTML.
Contrato Mermaid (fallback para LLM)
Section titled “Contrato Mermaid (fallback para LLM)”Usa siempre esta estructura base:
flowchart TD%% pdocs.diagram.mermaid.v1
%% nodosa["A"]b["B"]
%% contenedores (si en D2 usas `{ ... }`)subgraph example_container["Example Container"] example_node["Example Node"]end
%% conexionesa --> bexample_node -.->|opcional| ba -->|principal| bConvenciones
Section titled “Convenciones”-
Dirección:
direction: right(D2) →flowchart LR(Mermaid)direction: down(D2) →flowchart TD(Mermaid)
-
Nodos:
- IDs sin espacios (snake_case recomendado).
- Caja:
id["Label"] - Decisión (diamond):
id{"Label"} - Texto multilínea: usa
<br/>.
-
Contenedores (equivalente a
{ ... }en D2):subgraph contenedor["Label"] ... end- Si un nodo vive dentro de un contenedor en D2, en Mermaid debe ir dentro del
subgraph.
-
Conexiones:
-
Normal:
a --> b -
Con etiqueta:
a -->|texto| b -
Relación “débil/opcional” (equivalente a dashed):
a -.-> b -
Relación “principal/crítica” (recomendado por compatibilidad):
a -->|principal| b- Si tu renderer soporta
==>, puedes usara ==> bcomo aproximación visual.
- Si tu renderer soporta
-
Nota (importante): no todos los renderers permiten “apuntar” directamente a un
subgraph. Si quieres representar “flecha hacia el contenedor”, crea un nodo ancla dentro delsubgraphy conecta contra ese ancla (ver ejemplo 3).
Nota de seguridad HTML: si dentro de labels necesitas el carácter
<, escápalo como<para no romper el HTML.
Links: abrir en pestaña nueva
Section titled “Links: abrir en pestaña nueva”Ya está configurado en astro.config.mjs para que todo link externo abra en otra pestaña (target="_blank").
Cómo escribir un diagrama (mínimo)
Section titled “Cómo escribir un diagrama (mínimo)”direction: right= izquierda → derecha (equivalente a “LR”).direction: down= arriba → abajo (equivalente a “TD”).- Conexiones válidas D2:
--,->,<-,<->.
Estética “PRO” sin complicarte
Section titled “Estética “PRO” sin complicarte”Reglas simples
Section titled “Reglas simples”- Un diagrama = una idea.
- Etiquetas cortas (2–4 palabras).
- Prefiere
direction: downsi se te pone muy ancho (evita scroll horizontal). - Usa contenedores
{ ... }para “caja dentro de caja”. - Usa pocos estilos: 2–3 como máximo.
Nota sobre dark mode
Section titled “Nota sobre dark mode”Si fijas style.fill con colores claros, en modo oscuro el fondo cambia pero tu fill se queda igual.
Solución: cuando uses fills claros, fija también style.font-color y style.stroke con un “ink” oscuro.
Ejemplos canónicos (solo lo que vas a usar)
Section titled “Ejemplos canónicos (solo lo que vas a usar)”1) Diagrama de bloques simple (cajas + decisión)
Section titled “1) Diagrama de bloques simple (cajas + decisión)”2) Cajas dentro de cajas (contenedores) — “módulos” / “capas”
Section titled “2) Cajas dentro de cajas (contenedores) — “módulos” / “capas””3) Flechas con significado + estilos que NO se dañan en dark mode
Section titled “3) Flechas con significado + estilos que NO se dañan en dark mode”Leyenda mental:
->flujo normal--relación sin direcciónstyle.stroke-dash= “opcional / débil / depende”style.stroke-width= “principal / crítico”
4) Etiquetas en flechas + fórmula
Section titled “4) Etiquetas en flechas + fórmula”Checklist antes de dejar un diagrama “listo”
Section titled “Checklist antes de dejar un diagrama “listo””- ¿Se entiende en 5–10 segundos?
- ¿Es una sola idea (no un mural)?
- ¿Usaste contenedores
{}si hay “cajas dentro de cajas”? - Si usaste contenedores
{}, ¿el Mermaid coloca los nodos internos dentro desubgraph? - ¿Tus flechas tienen intención (normal vs punteada vs principal)?
- ¿No hay texto largo dentro de nodos?
- ¿Incluiste el Mermaid oculto
pdocs.diagram.mermaid.v1debajo del diagrama?
CSS: llm-only (Starlight)
Section titled “CSS: llm-only (Starlight)”Crea (o mantén) este archivo:
/* Visualmente oculto, pero presente en el HTML. (No usar atributo HTML `hidden`.) */.llm-only { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: pre !important; border: 0 !important;}Y agrégalo a customCss:
// dentro de starlight({ ... })customCss: [ "./src/styles/beoe-diagrams.css", "./src/styles/llm-only.css",],Con esto: la página queda limpia (solo SVG D2 visible) y el “source” semántico (Mermaid) queda embebido para LLM sin depender de clicks ni <details>.