True
Saltar a contenido

Herramientas de Lint y Format para Markdown

Note

No te pierdas la continuación de este artículo hablando de la herramienta rumdl

Llevo bastante tiempo usando markdownlint-cli2 y prettier para linting y formatting de Markdown, pero no tenía un análisis de las herramientas disponibles, para ver si había mejores opciones.

Requisitos Deseables

  • Integración con el IDE. Una buena extensión para VSCode y derivados
  • Integración con pre-commit (oficial en el repo, no sólo ejecución local)
  • Una sola herramienta mejor que varias herramientas. En todo caso el linter y el formatter deben ser compatibles.
  • Bien mantenida, popular, ...
  • Rápida
  • Rust > Python > Javascript
  • Prefiero herramientas en lenguajes que generan binarios como Rust porqué son más fáciles de instalar y mantener. Luego en Python porqué conozco mejor el ecosistema
  • Formato:
  • Mucho Markdown es para LLMs o producido por LLMs. Así que prefiero un estilo que concuerde.
  • Que se lleve bien con MkDocs, que tiene su propio sabor (python-markdown, y python-markdown-extensions)

Aunque preparando el artículo me entero de que MkDocs está deprecated y Zensical del mismo equipo usará en el futuro (1) CommonMark

  1. 🙏 !Gracias!

Herramientas

mdformat

mdformat es un formatter escrito en Python.

  • Usa markdown-it-py cómo parser.
  • 643 estrellas
  • Soporta CommonMark, GFM, MysT
  • Tiene plugins para soportar casos particulares como Admonitions, formatear código dentro de fenced blocks, ...
  • Opinionated. Pocas opciones de configuración
  • Soporta MkDocs a través de plugin:
  • Aunque hay que probar bien.
  • Plugin no oficial para vscode.
  • Tiene soporte para pre-comit

No me acaba de convencer.

prettier

Prettier es el estándar para formatear en el ecosistema JavaScript.

  • Usa remark-parser como parser
  • 50k estrellas
  • Soporte para CommonMark, GFM y MDXv1
  • Muy buena integración con el IDE
  • Es opinionated. La única opción específica markdown es prose-wrap
  • No hay soporte oficial para pre-commit, ni para prek

Una opción que nunca es mala, aunque puede no ser la mejor.

markdownlint

Bajo este nombre encontramos varias herramientas de lint:

La que nos interesa es markdownlint-cli2.

  • Markdown/CommonMark
  • pre-commit, github action, extensión para vscode.
  • Distintos formatos de salida (xml, json, consola, con colores, ...)
  • La configuración es algo confusa, pero los ficheros .markdownlint-cli2.* permiten configurar tanto la CLI, cómo la extensión para code, cómo la librería
  • El linter usa por debajo el parse markdown-it.

Un artículo sobre la herramienta.

A pesar de las confusiones de nombres, y la documentación dispersa no es una mala opción.

remark

Remark no es una herramienta si no un ecosistema en torno a Markdown que a su vez forma forma parte de unifiedjs.

Por defecto trabaja con ConmmonMark pero tiene plugins para otras versiones.

Es muy configurable, tanto, que entender bien cómo funciona, escoger los plugins y configurar las opciones adecuadas se vuelve complicado.

Sin soporte oficial para pre-commit.

La extensión de remark-lint para vscode que aparece en el README no se actualiza desde 2018. Hay otra extensión que parece oficial que en el momento de escribir esto lleva más de año y medio (Abril/2024) sin actualizarse.

  • remark-parse es la librería que convierte markdown a AST. Es usada también por prettier.
  • remark-stringify. Es la librería que se encarga de convertir el AST a Markdown. Cuando formateamos Markdown remark-parse lo convierte a AST, y remark-stringify lo convierte de nuevo a Markdown. Las reglas que queremos para el formatter son las que admita esta librería más plugins.
  • remark-lint. Es un monorepo que contiene la librería básica de linting y un montón de reglas que están por separadas o en conjuntos llamados "presets". Pero no es una herramienta, el uso de la librería es a través de remark-cli. Cuando instalamos un preset el paquete base remark-lint va cómo dependencia. Los presets más habituales:
  • remark-preset-lint-consistent — rules that enforce consistency
  • remark-preset-lint-markdown-style-guide — rules that enforce the markdown style guide
  • remark-preset-lint-recommended — rules that prevent mistakes or stuff that fails across vendors.
  • remark-cli, es la herramienta de línea de comandos para llevar a cabo operaciones.
  • plugins para casi todo lo que podamos imaginar. Otras versiones de markdown cómo remark-gfm, manipulaciones cómo remark-toc, linting cómo remark-lint, ...

Un ejemplo de instalación y uso

# Instalar la línea de comandos genérica
npm install --save-dev remark-cli

# Instalar plugins cómo remark-toc o un conjunto de reglas
npm install --save-dev remark-preset-lint-markdown-style-guide remark-toc

# Format de un fichero
remark --output readme.md

# Format de un fichero añadiendo el TOC
remark --output --use remark-toc readme.md

# Lint de todos los ficheros acorde a remark-preset-lint-markdown-style-guide
remark --use remark-preset-lint-markdown-style-guide .

# Format de todos los ficheros markdown en el directorio actual
remark . --output

# Lint de todos los ficheros markdown en el directorio actual
remark .

Un ejemplo de configuración

// .remarkrc.yaml
plugins:
  # Check that markdown is consistent.
  - remark-preset-lint-consistent
  # Few recommended rules.
  - remark-preset-lint-recommended
  # Generate a table of contents in `## Contents`
  - - remark-toc
    - heading: contents
settings:
  bullet: "*"
  emphasis: "_"
  strong: "*"

Herramientas Descartadas

Biome

Biome es la alternativa a prettier y eslint escrita en rust, pero todavía no implementa todas las reglas ni todos los lenguajes que soporta prettier. No soporta Markdown por ahora.

PyMarkdown

PyMarkdown es un linter escrito en Python que cumple pocos de los requisitos.

  • Usan su propio parser.
  • 109 estrellas
  • Soporta CommonMark y GFM
  • Tiene soporte para pre-commit
  • No parece tener extensión para vscode, ni ningún otro IDE
  • Tienen muchas opciones y reglas y es muy configurable

dprint

dprint no es un proyecto al que le hubiera prestado mucha atención si no fuera porqué lo usan Deno y Helix.

Es un "framework" para formatting escrito en Rust que soporta muchos lenguajes a través de plugins, entre ellos Markdown. Por ejemplo tienen un plugin para ruff para formatear Python.

Para markdown usa un parser centrado en CommonMark con soporte parcial para GFM. Las reglas de formato son poco configurables. Parece tener integración con pre-commit (no oficial) y vscode, pero no muy mantenida:

Bugs a los que prestar atención:

Otras referencias

Conclusiones

Prettier y Markdownlint son las mejores opciones en este momento. Habrá que estar atentos a la evolución de otras herramientas cómo dprint, biome u Oxc, y también a lo que salga de Zensical.

Si manipular el Markdown mediante línea de comandos también es de interés remark es una opción a estudiar.