mdsmith

module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2026 License: MIT

README ΒΆ

πŸ”¨ mdsmith

A fast, auto-fixing Markdown linter and formatter for docs, READMEs, and AI-generated content. Checks style, readability, and structure. Written in Go.

✨ Why mdsmith

πŸ“‹ Progressive disclosure with catalogs. The catalog rule generates summary tables from file front matter and keeps them in sync. Link each row to the full document β€” readers see the overview first and drill down on demand. Run mdsmith fix and the table updates itself.

πŸ€– Keep AI verbosity in check. AI tools produce walls of text. max-file-length caps document size, paragraph-readability enforces a reading-grade ceiling, and paragraph-structure limits sentence count and length. token-budget adds a token-aware budget with heuristic and tokenizer modes. Set the thresholds in .mdsmith.yml and let CI enforce them.

πŸ“– AI-ready rule specs β€” no remote calls. mdsmith help rule lists every rule with its ID and description. mdsmith help rule <name> prints the full spec: settings, examples, diagnostics. All docs are compiled into the binary β€” works offline, works in CI, works as a source for .cursor/rules or AGENTS.md. mdsmith help metrics and mdsmith help metrics <name> do the same for shared file metrics.

πŸ”§ Auto-fix. mdsmith fix corrects most rules in place. Whitespace, heading style, code fences, bare URLs, list indentation, table alignment, and generated sections β€” all handled. Multi-pass fixing resolves cascading changes automatically.

πŸ“¦ Installation

go install github.com/jeduden/mdsmith/cmd/mdsmith@latest

πŸš€ Usage

mdsmith <command> [flags] [files...]
Commands
Command Description
check Lint files (default command)
fix Auto-fix issues in place
help Show help for docs and topics
metrics List and rank Markdown metrics
merge-driver Git merge driver for regenerable sections
init Generate .mdsmith.yml
version Print version, exit

Files can be paths, directories (walked recursively for *.md), or glob patterns. With no arguments and no piped input, mdsmith exits 0.

When walking directories, mdsmith respects .gitignore files by default. Files matched by .gitignore patterns are skipped, including patterns from nested .gitignore files in subdirectories and ancestor directories. Explicitly named file paths are never filtered by gitignore. Use --no-gitignore to disable this behavior and lint all files.

Flags
Flag Description
-c, --config Config path
-f, --format text or json
--no-color Plain output
--no-gitignore Skip gitignore
-q, --quiet Quiet mode
Examples
mdsmith check docs/            # lint a directory
mdsmith fix README.md          # auto-fix in place
mdsmith check -f json docs/    # JSON output
mdsmith metrics rank --by bytes --top 10 .
Output

Diagnostics are printed to stderr:

README.md:10:1 MDS001 line too long (135 > 80)

Pattern: file:line:col rule message

Exit codes
Code Meaning
0 No lint issues found
1 Lint issues found
2 Runtime or configuration error

βš™οΈ Configuration

Create a .mdsmith.yml in your project root, or run mdsmith init to generate one with every rule and its default settings. Without a config file, rules run with their built-in defaults.

rules:
  line-length:
    max: 120
  fenced-code-language: false

ignore:
  - "vendor/**"

overrides:
  - files: ["CHANGELOG.md"]
    rules:
      no-duplicate-headings: false

Rules can be true (enable with defaults), false (disable), or an object with settings. The overrides list applies different rules per file pattern. Later overrides take precedence.

Config is discovered by walking up from the current directory to the repo root. Use --config to override.

Bootstrapping with mdsmith init

Run mdsmith init to generate a .mdsmith.yml with every rule and its default enablement and settings. This pins the config to the current defaults so that future mdsmith upgrades (which may change defaults) do not silently alter your lint results. Review the generated file and adjust settings to match your project's conventions.

mdsmith init
# creates .mdsmith.yml with all rule defaults

Commit the generated file to version control. This ensures every contributor uses the same rule settings. Upgrades become an explicit, reviewable change.

πŸ“š Guides

Guide Description
Choosing Readability, Conciseness, and Token Budget Metrics Trade-offs and threshold guidance for readability, structure, length, and token budgets.

πŸ“ Rules

Rule Name Status Description
MDS001 line-length ready Line exceeds maximum length.
MDS002 heading-style ready Heading style must be consistent.
MDS003 heading-increment ready Heading levels should increment by one. No jumping from # to ###.
MDS004 first-line-heading ready First line of the file should be a heading.
MDS005 no-duplicate-headings ready No two headings should have the same text.
MDS006 no-trailing-spaces ready No trailing whitespace at the end of lines.
MDS007 no-hard-tabs ready No tab characters. Use spaces instead.
MDS008 no-multiple-blanks ready No more than one consecutive blank line.
MDS009 single-trailing-newline ready File must end with exactly one newline character.
MDS010 fenced-code-style ready Fenced code blocks must use a consistent delimiter.
MDS011 fenced-code-language ready Fenced code blocks must specify a language.
MDS012 no-bare-urls ready URLs must be wrapped in angle brackets or as a link, not left bare.
MDS013 blank-line-around-headings ready Headings must have a blank line before and after.
MDS014 blank-line-around-lists ready Lists must have a blank line before and after.
MDS015 blank-line-around-fenced-code ready Fenced code blocks must have a blank line before and after.
MDS016 list-indent ready List items must use consistent indentation.
MDS017 no-trailing-punctuation-in-heading ready Headings should not end with punctuation.
MDS018 no-emphasis-as-heading ready Don't use bold or emphasis on a standalone line as a heading substitute.
MDS019 catalog ready Catalog content must reflect selected front matter fields from files matching its glob.
MDS020 required-structure ready Document structure and front matter must match its template.
MDS021 include ready Include section content must match the referenced file.
MDS022 max-file-length ready File must not exceed maximum number of lines.
MDS023 paragraph-readability ready Paragraph readability grade must not exceed a threshold.
MDS024 paragraph-structure ready Paragraphs must not exceed sentence and word limits.
MDS025 table-format ready Tables must have consistent column widths and padding.
MDS026 table-readability ready Tables must stay within readability complexity limits.
MDS027 cross-file-reference-integrity ready Links to local files and heading anchors must resolve.
MDS028 token-budget ready File must not exceed a token budget.
MDS029 conciseness-scoring not-ready Paragraph conciseness score must not fall below a threshold.
MDS030 empty-section-body ready Section headings must include meaningful body content.
MDS031 unclosed-code-block ready Fenced code blocks must have a closing fence delimiter.
MDS032 no-empty-alt-text ready Images must have non-empty alt text for accessibility.

πŸ› οΈ Development

Requires Go 1.24+. See docs/development/index.md for the full contributor guide (build commands, project layout, workflow, code style, and PR conventions).

πŸ“‚ Documentation

πŸ“„ License

MIT

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL