Automatizar tareas con Markdown - CI/CD, linting y scripts

Cómo automatizar flujos de trabajo con Markdown usando GitHub Actions, linters, generadores de TOC, verificadores de links y scripts de conversión.

Markdown no es solo para escribir. Puedes automatizar la verificación, conversión, publicación y mantenimiento de tus documentos Markdown con herramientas y scripts que ahorran horas de trabajo manual.

Linting y estilo

markdownlint

markdownlint es el linter estándar para Markdown. Detecta problemas de estilo y consistencia:

Instalación:

npm install -g markdownlint-cli

Uso:

markdownlint "docs/**/*.md"

Configuración (.markdownlint.json):

Puedes ajustar las reglas creando un archivo de configuración en la raíz de tu proyecto. Cada regla tiene un código (MD001, MD013, etc.) y se puede activar, desactivar o configurar con opciones específicas. Esta configuración es un buen punto de partida para la mayoría de proyectos:

{
  "MD013": { "line_length": 120 },
  "MD033": false,
  "MD041": false,
  "MD024": { "siblings_only": true }
}

En este ejemplo se permite un máximo de 120 caracteres por línea, se desactiva la restricción de HTML inline (necesaria si usas <details>, <kbd> u otras etiquetas), se permite que la primera línea no sea un h1 (para archivos con frontmatter) y se aceptan encabezados duplicados siempre que no estén al mismo nivel del mismo padre.

Reglas comunes:

ReglaDescripciónRecomendación
MD001Niveles de encabezado incrementalesActivar
MD013Longitud máxima de línea120 caracteres
MD024Encabezados duplicadosSolo entre hermanos
MD033HTML inlineDesactivar si usas HTML
MD041Primer línea debe ser h1Desactivar con frontmatter

Prettier

Prettier es más conocido como formateador de código JavaScript, pero también funciona con Markdown. A diferencia de markdownlint (que solo detecta problemas), Prettier corrige el formato automáticamente: alinea las columnas de las tablas, normaliza la indentación de las listas y asegura un estilo consistente en todo el proyecto:

npx prettier --write "**/*.md"

Este comando recorre todos los archivos .md del proyecto y los reformatea. Es especialmente útil para tablas, que pueden quedar desalineadas después de varias ediciones.

EditorConfig

Añade un .editorconfig para que todos los editores usen la misma configuración:

[*.md]
indent_style = space
indent_size = 2
trim_trailing_whitespace = false
insert_final_newline = true
max_line_length = 120

Nota: trim_trailing_whitespace = false es importante en Markdown porque dos espacios al final de línea crean un salto de línea.

Verificar enlaces

Los enlaces rotos son uno de los problemas más comunes y más molestos en documentación. Un enlace que lleva a un 404 destruye la confianza del lector y perjudica el SEO. markdown-link-check verifica que todos los enlaces de tus documentos funcionan, tanto internos como externos:

npm install -g markdown-link-check
markdown-link-check README.md

Para verificar todos los archivos de tu directorio de documentación de una sola vez:

find docs -name "*.md" -exec markdown-link-check {} \;

Configuración (.markdown-link-check.json):

Puedes personalizar el comportamiento creando un archivo de configuración. Esto es útil para ignorar URLs locales (como localhost), configurar tiempos de espera y manejar sitios que limitan las peticiones con el código 429:

{
  "ignorePatterns": [
    { "pattern": "^https://localhost" }
  ],
  "timeout": "10s",
  "retryOn429": true,
  "aliveStatusCodes": [200, 206, 301, 302]
}

lychee

Si tu proyecto tiene cientos de archivos Markdown, markdown-link-check puede ser lento. Lychee es una alternativa escrita en Rust que verifica enlaces de forma concurrente, lo que lo hace entre 10 y 50 veces más rápido:

lychee "docs/**/*.md"

Además de la velocidad, lychee ofrece mejor detección de falsos positivos y un formato de salida más claro. Es la opción recomendada para proyectos grandes o para integrar en CI/CD donde el tiempo de ejecución importa.

Generar tabla de contenidos

doctoc

Mantener una tabla de contenidos actualizada manualmente es tedioso y propenso a errores. doctoc la genera automáticamente a partir de los encabezados del documento y la actualiza cada vez que lo ejecutas:

npm install -g doctoc
doctoc README.md

doctoc inserta la TOC entre dos comentarios HTML que actúan como marcadores. Si ya existe una TOC entre esos marcadores, la reemplaza con la versión actualizada:

<!-- START doctoc generated TOC -->
<!-- END doctoc generated TOC -->

markdown-toc

Alternativa que genera la TOC como salida estándar:

npx markdown-toc README.md

Conversión automatizada

Pandoc

Pandoc es la herramienta de referencia para convertir documentos entre formatos. Soporta más de 40 formatos de entrada y salida, y la calidad de la conversión es excelente. Es especialmente útil cuando necesitas generar PDFs, documentos Word o presentaciones a partir de tus archivos Markdown.

Markdown a PDF:

pandoc documento.md -o documento.pdf

Markdown a DOCX:

pandoc documento.md -o documento.docx

Markdown a presentación:

pandoc slides.md -o slides.html -t revealjs

Múltiples archivos a un PDF:

Este es uno de los usos más potentes de Pandoc: combinar varios archivos Markdown en un solo documento PDF con tabla de contenidos generada automáticamente. Ideal para crear manuales, guías o libros a partir de capítulos escritos en archivos separados:

pandoc intro.md capitulo1.md capitulo2.md -o libro.pdf \
  --toc \
  --toc-depth=2 \
  -V geometry:margin=2.5cm

Las opciones --toc genera la tabla de contenidos, --toc-depth=2 limita la profundidad a dos niveles de encabezados, y -V geometry:margin=2.5cm configura los márgenes del PDF.

Conversores online

Si prefieres no instalar nada, puedes usar nuestros conversores online:

GitHub Actions para Markdown

Workflow completo de CI para documentación

Este workflow de GitHub Actions se ejecuta automáticamente en cada pull request que modifique archivos Markdown. Realiza tres verificaciones en paralelo: linting (estilo y formato), verificación de enlaces rotos y corrección ortográfica. Si alguna falla, el PR muestra un error y el autor sabe exactamente qué corregir:

name: Docs CI
on:
  pull_request:
    paths: ['docs/**', '*.md']

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Lint Markdown
        uses: DavidAnson/markdownlint-cli2-action@v19
        with:
          globs: '**/*.md'

  links:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check links
        uses: lycheeverse/lychee-action@v2
        with:
          args: '--verbose docs/**/*.md'
          fail: true

  spelling:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check spelling
        uses: streetsidesoftware/cspell-action@v6
        with:
          files: 'docs/**/*.md'

Deploy automático de documentación

Con este workflow, cada push a main que toque archivos en docs/ reconstruye el sitio con MkDocs y lo publica en GitHub Pages automáticamente. Es el flujo ideal para equipos: escribes Markdown, haces commit, y la documentación se actualiza sola:

name: Deploy Docs
on:
  push:
    branches: [main]
    paths: ['docs/**']

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      pages: write
      id-token: write

    steps:
      - uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install MkDocs
        run: pip install mkdocs-material

      - name: Build
        run: mkdocs build

      - name: Deploy to GitHub Pages
        uses: actions/upload-pages-artifact@v3
        with:
          path: ./site

      - name: Deploy
        uses: actions/deploy-pages@v4

Generar changelog automático

Mantener un changelog a mano es una tarea que nadie quiere hacer. git-cliff analiza los mensajes de tus commits (siguiendo convenciones como Conventional Commits) y genera un CHANGELOG.md formateado automáticamente. Este workflow lo ejecuta cada vez que publicas un release:

name: Generate Changelog
on:
  release:
    types: [published]

jobs:
  changelog:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Generate changelog
        uses: orhun/git-cliff-action@v4
        with:
          config: cliff.toml
          args: --latest
        env:
          OUTPUT: CHANGELOG.md

Scripts útiles

Contar palabras en todos los documentos

find docs -name "*.md" -exec wc -w {} + | sort -n

Encontrar archivos sin frontmatter

for f in docs/**/*.md; do
  head -1 "$f" | grep -q "^---" || echo "Sin frontmatter: $f"
done

Encontrar encabezados duplicados

grep -rh "^#" docs/ | sort | uniq -d

Generar índice de páginas

echo "# Indice"
find docs -name "*.md" -not -name "index.md" | sort | while read f; do
  title=$(head -5 "$f" | grep "^title:" | sed 's/title: //')
  path=${f#docs/}
  echo "- [$title](${path%.md})"
done

Pre-commit hooks

Los pre-commit hooks son la última línea de defensa antes de que un cambio llegue al repositorio. Con el framework pre-commit, puedes configurar verificaciones que se ejecutan automáticamente cada vez que haces git commit. Si alguna falla, el commit se cancela y te muestra qué corregir. Esto garantiza que ningún archivo Markdown con errores llegue al repositorio:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/igorshubovych/markdownlint-cli
    rev: v0.43.0
    hooks:
      - id: markdownlint
        args: ['--fix']

  - repo: https://github.com/tcort/markdown-link-check
    rev: v3.12.2
    hooks:
      - id: markdown-link-check
        args: ['--quiet']

Instalación:

pip install pre-commit
pre-commit install

Ahora cada git commit verifica automáticamente que tus archivos Markdown están bien formateados y sin enlaces rotos.

Consejos finales

  1. Automatiza desde el principio: Es más fácil mantener la calidad si las reglas se aplican desde el primer commit.
  2. No bloquees por estilo: Configura el linter como warning en CI, no como error que bloquea el merge. El estilo importa, pero no debería frenar contribuciones.
  3. Verifica enlaces periódicamente: Los enlaces externos se rompen con el tiempo. Programa una verificación semanal con un cron job.
  4. Usa fix automático: markdownlint --fix y prettier --write corrigen la mayoría de problemas automáticamente.
  5. Documenta tu setup: Añade un CONTRIBUTING.md que explique cómo escribir y verificar documentación en tu proyecto.

👋 Hola! Soy Edu, me encanta crear cosas y he redactado este tutorial. Si te ha resultado útil, el mayor favor que me podrías hacer es el de compatirlo en Twitter.

para estar al día con mi contenido. 😊