rumdl 0.2.66

A fast Markdown linter and formatter written in Rust
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
---
description: "Every rumdl command and flag, including which stream findings are written to, what each exit code means, and the machine readable formats."
icon: lucide/terminal
---

# CLI Commands

Complete reference for rumdl command-line interface.

## Commands

### `check [PATHS...]`

Lint Markdown files and report issues.

```bash
rumdl check .                    # Lint current directory
rumdl check README.md docs/      # Lint specific files/directories
rumdl check --fix .              # Lint and auto-fix issues
```

**Options:**

| Option                       | Description                                               |
| ---------------------------- | --------------------------------------------------------- |
| `--fix`                      | Auto-fix issues (exits 1 if unfixable issues remain)      |
| `--config <PATH>`            | Path to configuration file                                |
| `--disable <RULES>`          | Disable specific rules (e.g., `MD013,MD033`), or `all`    |
| `--enable <RULES>`           | Enable only specific rules                                |
| `--exclude <PATTERNS>`       | Exclude files matching patterns                           |
| `--include <PATTERNS>`       | Include only files matching patterns                      |
| `--no-code-block-tools`      | Skip configured tools; keep checking the outer Markdown   |
| `--only-code-block-tools`    | Run configured tools; skip the outer Markdown             |
| `--stdin-batch`              | Read NUL-delimited path/content pairs from stdin          |
| `--stdin-batch-closed-world` | Resolve batch links only within the supplied document set |
| `--watch`                    | Watch for changes and re-lint                             |
| `--verbose`                  | Show detailed output                                      |
| `--quiet`                    | Print diagnostics, but suppress summaries                 |
| `--silent`                   | Suppress diagnostics and summaries                        |
| `--no-exclude`               | Disable exclude patterns defined in config                |
| `--stderr`                   | Write diagnostics to stderr instead of stdout             |
| `--deny-config-warnings`     | Treat configuration warnings as errors (exit code 2)      |

Findings go to stdout, whether the document came from a path or from `--stdin`,
so `--output-format json` redirects the same way in both. `--stderr` moves them;
config warnings and errors are always on stderr. The exception is a document
rewritten on stdout - `check --fix --stdin` and `fmt --stdin` - where stdout
belongs to the document and diagnostics go to stderr.

The closing summary is written for a person, so a machine-readable format never
carries one and needs no `--quiet` to keep its output parseable.

#### Batch stdin

`--stdin-batch` checks many caller-supplied snapshots in one process. The byte
stream is a repeated `path NUL content NUL` sequence and must end in NUL:

```text
path\0content\0path\0content\0
```

Paths and contents must be UTF-8, paths must be non-empty and unique after path
normalization, and content may be empty. Each path is both the diagnostic name
and the filesystem context used for configuration and relative links.

By default, supplied documents take precedence and links to documents omitted
from the batch fall back to the on-disk workspace. Add
`--stdin-batch-closed-world` to prohibit that fallback. Batch input never reads
or writes the persistent workspace-index cache, because supplied content may
differ from the file saved at the same path.

Batch mode is check-only and cannot be combined with paths, `--stdin`,
`--stdin-filename`, `--fix`, `--diff`, `--check`, or `--watch`.

### `fmt [PATHS...]`

Format Markdown files (applies fixes like `rumdl check --fix`, but keeps formatter-style exit codes).

```bash
rumdl fmt .                      # Format all files
rumdl fmt README.md              # Format specific file
rumdl fmt --silent -             # Format stdin to stdout without diagnostics
```

**Options:**

| Option                    | Description                                                 |
| ------------------------- | ----------------------------------------------------------- |
| `--config <PATH>`         | Path to configuration file                                  |
| `--diff`                  | Show a diff of what would change instead of rewriting files |
| `--check`                 | Exit 1 if formatting changes would be needed                |
| `--stdin`                 | Read from stdin                                             |
| `--stdin-filename <NAME>` | Filename for stdin (for error messages)                     |
| `--no-code-block-tools`   | Skip configured tools; format the outer Markdown            |
| `--only-code-block-tools` | Format configured fenced blocks only                        |
| `--output-format <FMT>`   | Output format for any remaining diagnostics                 |
| `--watch`                 | Re-run formatting when files change                         |
| `--quiet`                 | Print diagnostics, but suppress summaries                   |
| `--silent`                | Suppress diagnostics and summaries                          |
| `--deny-config-warnings`  | Treat configuration warnings as errors (exit code 2)        |

Use `--silent` whenever stdout should contain only formatted Markdown. Plain `rumdl fmt -` may also emit remaining diagnostics.

The code-block-tool mode flags are mutually exclusive and cannot be combined
with `--stdin`, `--stdin-batch`, or the `-` stdin path.
`--only-code-block-tools` drops the outer document's rules and leaves the tool
phases as they are, so `fmt` still runs configured lint tools and reports what a
formatter could not fix.

### `init [OPTIONS]`

Create a configuration file.

```bash
rumdl init                       # Create .rumdl.toml
rumdl init --preset google       # Use Google style preset
rumdl init --output custom.toml  # Custom output path
```

**Options:**

| Option            | Description                                         |
| ----------------- | --------------------------------------------------- |
| `--pyproject`     | Generate configuration for pyproject.toml           |
| `--preset <NAME>` | Use a style preset (`default`, `google`, `relaxed`) |
| `--output <PATH>` | Output file path (default: `.rumdl.toml`)           |

### `import <FILE>`

Import configuration from markdownlint.

```bash
rumdl import .markdownlint.json      # Import from markdownlint config
rumdl import .markdownlint.jsonc     # JSONC comments are supported
rumdl import .markdownlint.yaml      # YAML also works
rumdl import --dry-run .markdownlint.json
rumdl import --format json .markdownlint.yaml --output rumdl-config.json
```

**Options:**

| Option            | Description                               |
| ----------------- | ----------------------------------------- |
| `--dry-run`       | Show the converted config without writing |
| `--format <FMT>`  | Output format: `toml` or `json`           |
| `--output <PATH>` | Output file path (default: `.rumdl.toml`) |

### `rule [<RULE>]`

Show rule documentation.

```bash
rumdl rule                       # List all rules
rumdl rule MD013                 # Show details for specific rule
rumdl rule line-length           # Use rule alias
rumdl rule --list-categories     # Discover rule categories
rumdl rule MD013 --output-format json
rumdl rule MD013 --output-format json --explain
```

**Options:**

| Option                  | Description                                      |
| ----------------------- | ------------------------------------------------ |
| `--list-categories`     | List rule categories and exit                    |
| `--category <NAME>`     | Filter listed rules by category                  |
| `--fixable`             | Show only fixable rules                          |
| `--output-format <FMT>` | Structured output such as `json` or `json-lines` |
| `--explain`             | Include full documentation in JSON-based output  |

### `config [OPTIONS]`

Show effective configuration.

```bash
rumdl config                     # Show merged configuration
rumdl config --defaults          # Show default values only
rumdl config --no-defaults       # Show non-default values only
```

### `server`

Start the LSP server.

```bash
rumdl server                     # Start Language Server Protocol server
```

See [LSP Integration](../lsp.md) for details.

### `vscode`

Install VS Code extension.

```bash
rumdl vscode                     # Install extension
rumdl vscode --status            # Check installation
rumdl vscode --update            # Update the installed extension
rumdl vscode --force             # Force reinstall
```

### `version`

Show version information.

```bash
rumdl --version                  # Short version
rumdl version                    # Detailed version info
```

## Global Options

These options are commonly used with `check` and `fmt`:

| Option                  | Description                                               |
| ----------------------- | --------------------------------------------------------- |
| `--help`, `-h`          | Show help                                                 |
| `--version`, `-V`       | Show version                                              |
| `--verbose`, `-v`       | Verbose output                                            |
| `--quiet`, `-q`         | Print diagnostics, but suppress summaries                 |
| `--color <WHEN>`        | Color output (`auto`, `always`, `never`)                  |
| `--no-config`           | Ignore discovered configuration and use built-in defaults |
| `--output-format <FMT>` | Output format (see [Output Formats]#output-formats)     |

## Exit Codes

| Code | Meaning                        |
| ---- | ------------------------------ |
| `0`  | Success                        |
| `1`  | Lint violations found          |
| `2`  | Configuration or runtime error |

!!! note "fmt vs check --fix"
    - `rumdl fmt` always exits 0 (formatter mode)
    - `rumdl check --fix` exits 1 if unfixable issues remain

!!! note "Failing on configuration problems"
    Configuration problems (an unknown rule or option in a config file or a CLI
    flag, an unknown rule in an inline `rumdl-disable-line` comment, a shadowed
    config file, a subdirectory config that could not be loaded, an
    `.editorconfig` property rumdl cannot apply, or a run in which every Markdown
    file found was filtered out) are non-fatal warnings by default and do not
    affect the exit code. Pass `--deny-config-warnings` to make any of them exit
    with code `2`, so CI catches a typo'd rule name. This
    is distinct from `--fail-on`, which governs the severity of Markdown
    violations (exit `1`); a config problem exits `2` and takes precedence over
    Markdown violations.

!!! note "When nothing gets checked"
    Checking zero files and checking every file cleanly both exit `0` with no
    findings, so rumdl reports which one happened on stderr. A directory holding
    no Markdown says so plainly; a run whose files were all filtered out instead
    reports how many were found and which setting removed them:

    ```text
    No markdown files left to check: 12 files found were filtered out.
      12 by ignore files (.gitignore, .ignore, .markdownlintignore); pass --respect-gitignore=false to keep them
    ```

    The notice never shares a stream with the selected output, so it stays out
    of `--output-format json` and the other machine-readable formats: it goes to
    stderr, or to stdout when `--stderr` routes diagnostics the other way. It
    survives `--quiet`; use `--silent` to suppress it, or
    `--deny-config-warnings` to fail the run instead.

## Usage Examples

### Basic Linting

```bash
# Lint all Markdown files
rumdl check .

# Lint specific directory
rumdl check docs/

# Lint with custom config
rumdl check --config my-config.toml .
```

### Selective Rules

```bash
# Disable specific rules
rumdl check --disable MD013,MD033 .

# Enable only specific rules
rumdl check --enable MD001,MD003 .

# Disable every rule; an --enable list still survives
rumdl check --disable all .
```

### Code block tools

[Code block tools](../code-block-tools.md) run external linters and formatters
over fenced code blocks. They are configured separately from the Markdown rules,
so either side can be run without the other while the rest of the configuration
keeps applying:

```bash
# Markdown rules only, configured tools skipped
rumdl check --no-code-block-tools .
rumdl fmt --no-code-block-tools .

# Configured tools only, outer Markdown left alone
rumdl check --only-code-block-tools .
rumdl fmt --only-code-block-tools .
```

Reach for `--only-code-block-tools` rather than `--disable all` here. The latter
empties the rule set that fenced Markdown configured with `lint = ["rumdl"]` is
linted with, so the built-in tool reports nothing while external tools carry on.

`--no-code-block-tools` is the named form of
`--config 'code-block-tools.enabled = false'`, and the mode flags win over an
inline `--config` that sets the master switch the other way.

### Overriding configuration for one run

`--config` also takes an inline `KEY = VALUE` snippet, which overrides that
setting at the highest precedence while everything else the config files set
still applies. `--no-config` is the blunt alternative: it discards the whole
configuration.

```bash
# One rule option
rumdl check --config 'MD013.line-length = 20' .

# A global option
rumdl check --config 'line-length = 20' .

# A non-rule section: code-block-tools, per-file-ignores, per-file-flavor
rumdl check --config 'code-block-tools.enabled = false' .
rumdl check --config 'per-file-flavor."docs/**/*.md" = "mkdocs"' .
```

An override sets the settings it names to the values given, and settings it does
not name keep what they were configured with. `code-block-tools` holds several
settings, so `--config 'code-block-tools.timeout = 60000'` leaves the configured
languages and tools alone. `per-file-ignores` and `per-file-flavor` are each a
single setting whose value is a map of patterns, so naming one pattern replaces
the map - the same as writing that section in a higher-precedence config file,
and the same as ruff's `--config` for `lint.per-file-ignores`. To keep the
project's other patterns for a run, name them too.

A value the setting cannot hold is reported as a `[config warning]` naming the
key it came from; that value is skipped and the rest of the run proceeds. See
[CLI `--config` overrides](../cli-config-overrides.md#validation-warnings) for
what is and is not checked.

### File Filtering

```bash
# Exclude directories
rumdl check --exclude "node_modules,dist" .

# Include only specific patterns
rumdl check --include "docs/**/*.md" .

# Combine patterns
rumdl check --include "docs/**/*.md" --exclude "docs/drafts" .
```

### Watch Mode

```bash
# Watch for changes
rumdl check --watch docs/
```

### Stdin/Stdout

```bash
# Format from stdin
cat README.md | rumdl fmt --silent -

# With filename context
cat README.md | rumdl check - --stdin-filename README.md

# Format clipboard (macOS)
pbpaste | rumdl fmt --silent - | pbcopy
```

### Output Formats

Control how warnings are displayed with `--output-format`:

```bash
rumdl check --output-format full .
rumdl check --output-format json .
RUMDL_OUTPUT_FORMAT=github rumdl check .
```

**Human-readable formats:**

| Format    | Description                                                     |
| --------- | --------------------------------------------------------------- |
| `text`    | One line per warning: `file:line:col: [RULE] message` (default) |
| `full`    | Source lines with caret underlines highlighting the violation   |
| `concise` | Minimal: `file:line:col rule message`                           |
| `grouped` | Warnings grouped by file with a header per file                 |

**Machine-readable formats:**

| Format       | Description                             |
| ------------ | --------------------------------------- |
| `json`       | JSON array of all warnings (collected)  |
| `json-lines` | One JSON object per warning (streaming) |
| `sarif`      | SARIF 2.1.0 for static analysis tools   |
| `junit`      | JUnit XML for CI test reporters         |

See [Output Formats](../output-formats.md) for the field-level reference for each
machine-readable format.

**CI/CD formats:**

| Format   | Description                                        |
| -------- | -------------------------------------------------- |
| `github` | GitHub Actions annotations (`::warning`/`::error`) |
| `gitlab` | GitLab Code Quality report (JSON)                  |
| `azure`  | Azure Pipelines logging commands                   |
| `pylint` | Pylint-compatible format                           |

**Example: `full` format output:**

```text
MD013 Line length 95 exceeds 80 characters
 --> README.md:42:81
   |
42 | This is a long line that exceeds the configured maximum line length ...
   |                                                                     ^^^
   |
```

**Example: `text` format output (default):**

```text
README.md:42:81: [MD013] Line length 95 exceeds 80 characters
```