# Resumen

Un SVG autocontenido para un README de perfil, dibujado con los mismos puntos que reciben las bases de datos.

Source: https://jmrplens.github.io/ghchronicle/es/card/

```sh
ghchronicle -config config.yaml -card card.svg -card-only
```

> **Esto es una función secundaria**
>
> El objetivo del proyecto es la ingesta. La tarjeta existe porque los números
> ya estaban ahí, y se dibuja exactamente con los mismos puntos que reciben las
> bases de datos, así que la tarjeta y el dashboard no pueden contradecirse.

## Las opciones

| Opción                                  | Hace                                                                  |
| --------------------------------------- | --------------------------------------------------------------------- |
| `-card <ruta>`                          | Ejecuta una pasada y escribe el SVG ahí                               |
| `-card-only`                            | Escribe el SVG y nada más, así que no hace falta base de datos        |
| `-card-layout <nombre>`                 | Uno de los trece [diseños](/ghchronicle/es/card/layouts/)             |
| `-card-theme <dark\|light\|auto\|both>` | Both escribe la tarjeta clara y una gemela `_dark` en una sola pasada |
| `-card-motion <once\|loop\|off>`        | Cómo se mueve un diseño animado; los demás la ignoran                 |
| `-card-fields <lista>`                  | Separados por comas, en orden de dibujo                               |
| `-card-width <píxeles>`                 | Sin ella, el ancho propio del diseño; en `activity-heatmap` compra semanas |
| `-card-speed <0 a 1>`                   | A qué velocidad se reproduce un diseño animado; `0.5`, el valor por omisión, es el ritmo de siempre |
| `-card-layouts`                         | Imprime los diseños con sus campos y sus anchos y termina             |

Sin `-card-only` la tarjeta se escribe **además de** todo lo que recibirían
normalmente los destinos, que es la disposición para una máquina que ya está
recogiendo y quiere además una imagen.

## La pasada de la tarjeta y el fichero de estado

Una pasada con `-card` recoge **todas las familias**, digan lo que digan las
cadencias, porque cada número de la tarjeta sale de los puntos de esa única
pasada y una familia saltada por no tocarle sería un cero en la imagen.

Con `-card-only` además deja el [fichero de
estado](/ghchronicle/es/configuration/#state_file) tal y como lo encontró. Nada
de lo que recogió esa pasada llegó a un almacén, así que nada de lo que aprendió
puede decirle a la siguiente recogida que una familia ya está hecha. Sí lo lee,
que es lo que le permite saltarse el recorrido único del historial de estrellas:
lo que el estado recuerda abarata la pasada, nunca encoge la tarjeta.

Así que una tarjeta, una segunda tarjeta y una recogida pueden compartir un
`state_file`, y cada una de ellas es la cuenta entera.

## Qué dibuja

Estrellas, forks, seguidores y número de repositorios; contribuciones del último
año; visitas y visitantes únicos de la ventana de tráfico de catorce días de
GitHub; un sparkline del calendario de contribuciones; y los repositorios con
más estrellas junto a su lenguaje.

Las estrellas y los forks se **suman de los repositorios que recogió la pasada**,
porque el endpoint de cuenta de GitHub no informa de ninguno de los dos totales.
Eso significa que excluir forks o archivados en `targets` se nota también en la
tarjeta, que es la lectura honesta y no una discrepancia oculta.

## Los campos

`-card-fields` acepta una lista separada por comas, en orden de dibujo, entre:

`stars`, `forks`, `followers`, `repos`, `contributions`, `views`, `visitors`,
`clones`, `commits`, `pull_requests`, `reviews`, `issues`, `languages`,
`top_repos`, `sparkline`.

Un diseño se salta un campo que no sabe dibujar. Un nombre desconocido es un
error que lista los válidos, en vez de un salto silencioso: de lo contrario,
una errata quitaría un número y nadie se daría cuenta hasta tener la tarjeta ya
subida.

```sh
ghchronicle -config config.yaml -card card.svg -card-only \
  -card-layout github-stats -card-theme dark \
  -card-fields repos,stars,forks,followers,commits,pull_requests,languages
```

Vacío significa el conjunto por defecto del diseño.

## Temas

- **dark y light**

  Una paleta cada uno, y la opción para un README. `-card-theme both` (o
  `card-theme: both` en la Action) escribe la tarjeta clara en la ruta dada y
  la oscura a su lado con `_dark` antes de la extensión, en la misma pasada,
  así que las dos no pueden contradecirse nunca. Pon las dos en un
  `<picture>`, que es como GitHub documenta mostrar una imagen distinta según
  el tema:

  ```html
  <picture><source media="(prefers-color-scheme: dark)" srcset="card_dark.svg"><img src="card.svg" alt="Mi tarjeta de GitHub"></picture>
  ```

  El README de este mismo proyecto lo hace así con sus tarjetas.

- **auto**

  Ambas paletas en un fichero, tras una consulta `prefers-color-scheme`
  dentro de la imagen. Esa consulta sigue al sistema operativo de quien lee y
  no al tema que eligió en la página, y un navegador no la vuelve a evaluar de
  forma fiable dentro de una imagen: en GitHub se vieron tarjetas auto cambiar
  de paleta en una página oscura al salir de la pestaña y volver. Sirve en una
  página sin tema propio. Para un README, usa los dos ficheros.

## Tres restricciones que respeta

**Autocontenida.** Sin hoja de estilos externa, sin webfont, sin `<image>`
apuntando a una URL, sin script. El proxy camo de GitHub sirve las imágenes de
un README desde su propio dominio y bloquea todo eso, así que cualquier cosa
externa sencillamente no se dibujaría.

**Determinista.** La misma entrada produce un fichero idéntico byte a byte, así
que un job programado que haga commit de la tarjeta no produce un diff en cada
ejecución.

**Escrita atómicamente.** Se dibuja en un fichero temporal y se renombra, así
que quien esté mirando la ruta nunca ve medio documento.

## Movimiento

La animación, en los diseños que la tienen, es CSS dentro del SVG, y nunca hay
script. Toda animación termina en la tarjeta estática completa, así que un
renderizador que ignora la animación muestra el estado final, y
`prefers-reduced-motion` la desactiva en todos los modos.

| `-card-motion` | Qué hace la tarjeta                                                           |
| -------------- | ----------------------------------------------------------------------------- |
| `once`         | Se reproduce al cargar y se queda quieta. Es el valor por defecto             |
| `loop`         | Lo mismo, y lo que el diseño tenga que no termine sigue moviéndose para siempre |
| `off`          | Sin animación, y un fichero más pequeño                                       |

### Un bucle nunca repite

La animación aquí revela contenido: una cifra cuenta hasta lo que vale, una
barra crece hasta su porcentaje, una línea se dibuja sola. Reproducir eso otra
vez sería quitarle a quien lee algo que ya se le había mostrado, y una tarjeta
que esconde sus propias cifras cada pocos segundos es peor que una quieta.

Así que `loop` no significa "y otra vez". La revelación se reproduce una sola
vez y se asienta en los dos modos, y lo único que puede seguir para siempre es
el movimiento que no pone nada en la tarjeta ni se lo lleva. Dos diseños tienen
algo así:

- `terminal`, cuyo cursor parpadea en el prompt desde que se dibuja la ventana.
  Las cifras se siguen tecleando una sola vez. Con `once`, en cambio, el cursor
  espera a la última, parpadea un par de veces y se queda encendido.
- `ticker`, cuya banda de píldoras sigue desplazándose. No desaparece nada; las
  mismas píldoras vuelven a pasar.

En cualquier otro diseño `loop` dibuja exactamente la tarjeta que dibuja `once`,
byte a byte. Se acepta en vez de rechazarse, así que un workflow puede fijarlo
una vez y cambiar `card-layout` con libertad.

`once` sigue siendo la opción respetuosa para un perfil, y más que antes. Una
tarjeta en bucle se mueve para todo el que abre el README, y ninguno de los dos
que pueden hacerlo tiene pausa: el cursor parpadea y la banda se desplaza sin
descanso entre pasadas, donde las tarjetas en bucle que esto sustituye se
quedaban quietas siete segundos entre reproducciones. Un README no le da a quien
lee ninguna forma de pararla. Su única salida es `prefers-reduced-motion`, que
se la desactiva, pero que es un ajuste de toda su máquina y no un control sobre
tu tarjeta. Es la misma razón por la que la página de diseños nunca muestra una
tarjeta en bucle hasta que se pulsa el botón (WCAG 2.2.2, Pausar, detener,
ocultar).

![El diseño terminal reproducido una vez: una ventana de terminal cuyas líneas de salida tienen cada una un número que se teclea solo, con un cursor de bloque encendido en el prompt de abajo que parpadea cuando aterriza la última cifra, y la página también puede reproducirlo en bucle, donde el tecleo sigue ocurriendo una vez y solo sigue el cursor, parpadeando desde el principio](../../../../assets/card-terminal.svg)

- **Binario**

  ```sh
  ghchronicle -card-layout terminal -card-theme both -card-only -card card.svg -config config.yaml
  ```

  La imagen en bucle:

  ```sh
  ghchronicle -card-layout terminal -card-theme both -card-only -card card.svg -config config.yaml -card-motion loop
  ```

- **GitHub Action**

  ```yaml
  - uses: jmrplens/ghchronicle@v1
    with:
      token: ${{ secrets.GHCHRONICLE_TOKEN }}
      mode: card
      card: generated/card.svg
      card-layout: terminal
      card-theme: both
  ```

  La imagen en bucle:

  ```yaml
  - uses: jmrplens/ghchronicle@v1
    with:
      token: ${{ secrets.GHCHRONICLE_TOKEN }}
      mode: card
      card: generated/card.svg
      card-layout: terminal
      card-theme: both
      card-motion: loop
  ```

### A qué velocidad se reproduce

`-card-speed` es un decimal de 0 a 1, y 0.5 es el valor por omisión. Es un solo
número para toda la tarjeta: todos los diseños animados se escalan con él, los
dos movimientos continuos junto con las revelaciones, así que una tarjeta más
lenta tiene a la vez una banda que tarda más en dar la vuelta y un cursor que
parpadea más despacio.

| `-card-speed` | Qué hace la tarjeta                                                          |
| ------------- | ---------------------------------------------------------------------------- |
| `0`           | La animación más lenta, el doble de larga que la de por omisión              |
| `0.5`         | Exactamente la tarjeta que este renderizador dibujó siempre, byte a byte. Es el valor por omisión |
| `1`           | La más rápida, la mitad de larga que la de por omisión                       |

Hay un mando y no uno por diseño por la misma razón que hay un ancho y no uno
por diseño: los ciclos de aquí se calibraron unos contra otros, y escalarlos
juntos es lo que conserva el ritmo con el que se diseñó el movimiento. Una
velocidad fuera del rango se rechaza antes de la pasada, nombrando los dos
extremos.

> **0 es la animación más lenta, no la ausencia de animación**
>
> Un rango que empieza en cero parece un interruptor, y este no lo es. Una
> tarjeta dibujada en `0` se sigue animando, tan despacio como este renderizador
> la dibuje. La que no dibuja animación ninguna es `-card-motion off`, que es
> además la que hace el fichero más pequeño.

`prefers-reduced-motion` no se ve afectado por nada de esto: a quien le ha
pedido a su máquina menos movimiento no le queda animación que frenar ni que
acelerar.

## En un README

```html
<picture><source media="(prefers-color-scheme: dark)" srcset="generated/card_dark.svg"><img src="generated/card.svg" alt="Mis estadísticas de GitHub"></picture>
```

El workflow que la mantiene al día, para un README de perfil o cualquier otro,
está en
[Una tarjeta en el README de tu perfil](/ghchronicle/es/install/actions/#una-tarjeta-en-el-readme-de-tu-perfil).

## No hay biblioteca Go

El renderizador vive en `internal/render`, y Go rechaza esa importación desde
fuera del módulo, así que no hay manera de dibujar una tarjeta desde un
programa propio llamando a este. Un programa que quiera un SVG ejecuta el
binario con `-card` y lee el fichero, igual que ejecutaría cualquier otra
orden: ver [llamarlo desde un programa](/ghchronicle/es/reference/subprocess/).
