Skip to content

Feature: Run per-language linters in rumdl check and per-language formatters in rumdl fmt and rumdl check --fix for fenced code blocks #331

Description

@pygarap

Summary

Add an optional feature that runs user-configured tools on the contents of fenced code blocks based on the code block's syntax highlighting language.

Behavior split:

  • rumdl check: run configured linters for fenced code blocks
  • rumdl fmt and rumdl check --fix: run configured formatters for fenced code blocks and rewrite the block contents

This should be configured per language using GitHub Linguist languages.yml for language and alias resolution, similar in spirit to mdsf but implemented directly in rumdl.

Source of truth:

Motivation

rumdl already formats and lints Markdown structure well, but docs often embed real code snippets. Projects want those snippets to be:

  • linted during rumdl check
  • formatted automatically during rumdl fmt and rumdl check --fix

Doing this in rumdl would keep CI consistent and reduce the need for extra tooling around Markdown.

Proposed behavior

Language identification

For each fenced code block with an info string:

  • Use the first token after the opening fence as the language label.
  • Resolve it via Linguist languages.yml (language name or alias), so aliases map to the same configured language group.

rumdl check runs linters

When enabled:

  • For each fenced code block whose resolved language has lint tools configured, run those tools against the block content.
  • Report diagnostics as rumdl findings, including file and code block location.
  • Do not modify files.

rumdl fmt and rumdl check --fix run formatters

When enabled:

  • For each fenced code block whose resolved language has format tools configured, run those tools and replace the code block contents with the formatted output.
  • Preserve the opening and closing fences and the info string, and only change the content inside the fence.
  • Do not run linters here unless explicitly requested later. The core request is linters in check, formatters in fmt and check --fix.

Failure handling

Configurable per language:

  • on_error = "fail" (default) or on_error = "skip"

If a tool is missing or exits non-zero, follow on_error, and include a clear message pointing to the language and tool that failed.

Configuration sketch

Example naming only:

[code-block-tools]
enabled = true
normalize-language = "linguist"

[code-block-tools.languages.python]
lint = ["ruff:check"]
format = ["ruff:format"]

[code-block-tools.languages.json]
format = ["prettier"]

[code-block-tools.languages.shell]
lint = ["shellcheck"]
format = ["shfmt"]
on_error = "skip"

Notes:

  • Language keys should match Linguist language names (recommended) and can optionally accept aliases, since resolution is done via Linguist anyway.
  • Tools can be defined via a small built-in registry (like mdsf) or via explicit command definitions.

Scope and safety

  • Off by default.
  • Only runs tools explicitly configured by the user.
  • Apply only to fenced code blocks with an explicit language label.

Acceptance criteria

  • rumdl check runs configured linters for fenced code blocks and reports failures without modifying files.
  • rumdl fmt and rumdl check --fix run configured formatters for fenced code blocks and rewrite block contents.
  • Language matching and alias handling are based on GitHub Linguist languages.yml.
  • Output is stable: running rumdl fmt twice produces no additional diffs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions