Skip to content

ydah/mdlint

Repository files navigation

mdlint

Ruby VersionLicenseCIGem Version

A pure Ruby Markdown linter and formatter with zero external dependencies

FeaturesQuickstartInstallationUsageConfigurationLint RulesFormatting

Features

  • Pure Ruby, no C/Rust extensions or external dependencies
  • Linting with configurable rules and clear violations
  • Auto-formatting that follows mdformat conventions
  • CLI for CI-friendly workflows and local formatting
  • Simple YAML configuration file

Quickstart

gem install mdlint

# format in place
mdlint README.md docs/

# check-only (CI)
mdlint --check README.md

# show diffs
mdlint --diff README.md

Installation

With Bundler:

bundle add mdlint

Without Bundler:

gem install mdlint

Usage

Command line:

mdlint README.md docs/
mdlint --check README.md
mdlint --diff README.md

Options:

Usage: mdlint [options] [paths...]

Options:
    -c, --check              Check if files are formatted, exit with error if not
    -d, --diff               Show diff of changes
    -q, --quiet              Suppress output
    -e, --exclude PATTERN    Exclude files matching pattern
    -w, --wrap MODE          Paragraph wrapping: keep (default), no, or INTEGER
        --number             Use consecutive numbering for ordered lists
        --end-of-line MODE   End of line: lf (default), crlf, keep
    -v, --version            Show version
    -h, --help               Show help

Ruby API:

require "mdlint"

formatted = Mdlint.format("# Hello World")
Mdlint.format_file("README.md")

tokens = Mdlint.parse("# Hello World")

violations = Mdlint.lint("# Heading\n\n\n\nParagraph")
violations.each { |v| puts v }

violations = Mdlint.lint_file("README.md")

Configuration

Create a .mdlint.yml file in your project root:

# Check mode (don't modify files)
check: false

# Quiet mode (suppress output)
quiet: false

# Exclude patterns
exclude:
  - "vendor/**/*.md"
  - "node_modules/**/*.md"

Lint Rules

Key rules:

  • Heading levels should increment by one
  • Heading style should be consistent (ATX)
  • No trailing spaces
  • No multiple consecutive blank lines
  • First line should be a top-level heading

Formatting Style

Element Style
Headings ATX style only (#)
Bullet lists Hyphen (-), alternating for nested
Ordered lists All items use 1. (minimizes diffs)
Code blocks Fenced style (```)
Horizontal rules 70 underscores
Hard breaks Backslash (\)
Line endings LF (configurable)
Reference links Converted to inline links

Supported Markdown Elements

Block elements:

  • ATX headings (# Heading)
  • Setext headings (converted to ATX)
  • Paragraphs
  • Bullet lists (-, *, +)
  • Ordered lists (1., 2.)
  • Blockquotes (>)
  • Fenced code blocks (```)
  • Indented code blocks (converted to fenced)
  • Horizontal rules (---, ***, ___)
  • HTML blocks
  • Reference definitions

Inline elements:

  • Bold (**text**, __text__)
  • Italic (*text*, _text_)
  • Inline code (`code`)
  • Links ([text](url))
  • Reference links ([text][ref])
  • Images (![alt](src))
  • Autolinks (<https://example.com>)
  • Hard breaks (backslash + newline)

Development

bin/setup
bundle exec rspec

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/ydah/mdlint.

License

MIT License. See LICENSE.txt for details.

About

A Pure Ruby Markdown linter and formatter.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages