A fast, lightweight Markdown formatter that intelligently cleans up your markdown files while preserving structure and content.
mdfmt is a high-performance Rust-based tool that helps you maintain clean and consistent Markdown files by:
- Removing multiple consecutive blank lines while preserving document structure
- Ensuring proper spacing around headings, code blocks, and list markers
- Protecting frontmatter and code blocks from formatting changes
- Deleting empty files (completely empty or containing only frontmatter)
- Processing files recursively across directories with parallel execution
- Providing detailed feedback on all operations
Perfect for maintaining documentation, blog posts, and any Markdown-based content at scale without breaking your carefully crafted code examples or YAML frontmatter.
- π Fast Processing: Built with Rust for maximum performance, using parallel processing with Rayon
- π― Smart Cleanup: Removes multiple consecutive blank lines while preserving document structure
- Proper Spacing: Ensures blank lines around headings, code blocks, and list markers for better readability
- Content Protection: Preserves frontmatter and code fence contents unchanged
- ποΈ Empty File Handling: Automatically detects and removes empty files or files with only frontmatter
- π Recursive Search: Processes all
.mdfiles in a directory tree - π Dry Run Mode: Preview changes before applying them
- π Verbose Output: Optional detailed logging of all operations
- β‘ Error Handling: Robust error reporting with detailed summaries
Make sure you have Rust installed, then:
git clone https://github.com/vew94/mdfmt.git
cd mdfmt
cargo build --releaseThe binary will be available at target/release/mdfmt.
cargo install --git https://github.com/vew94/mdfmt.git# Format all markdown files in current directory
mdfmt
# Format markdown files in a specific directory
mdfmt /path/to/docs
# Format with verbose output
mdfmt --verbose /path/to/docs
# Preview changes without modifying files
mdfmt --dry-run /path/to/docs
# Allow deletion of empty files
mdfmt --delete /path/to/docsA Markdown formatter that removes multiple consecutive blank lines and handles empty files
Usage: mdfmt [OPTIONS] [PATH]
Arguments:
[PATH] Path to a markdown file or directory to process
Options:
-v, --verbose Show verbose output
-n, --dry-run Dry run - show what would be done without making changes
--delete Allow deletion of empty files
-h, --help Print help
-V, --version Print version
mdfmt --verbose ./docsOutput:
Searching for markdown files in: ./docs
Found 15 markdown files
./docs/api.md: no changes needed
./docs/empty-file.md: deleted (empty body with frontmatter or completely empty)
./docs/guide.md: modified (removed multiple blank lines)
./docs/readme.md: no changes needed
Summary:
Files processed: 15
Files modified: 1
Files deleted: 1
Errors: 0
mdfmt --dry-run ./blog-postsOutput:
Found 8 markdown files
Dry run mode - no files will be modified
Would process: ./blog-posts/2023/post1.md
Would process: ./blog-posts/2023/post2.md
Would process: ./blog-posts/2024/draft.md
...
mdfmt intelligently removes excessive blank lines while preserving content structure and protecting special markdown sections. It also ensures proper spacing around markdown elements for better readability.
Before:
# My Document
This is some content.
## Subsection
More content here.
- List item 1
- List item 2
End of document.After:
# My Document
This is some content.
## Subsection
More content here.
- List item 1
- List item 2
End of document.Frontmatter Protection: YAML frontmatter blocks are completely preserved, including their internal spacing:
---
title: "My Post"
author: "John Doe"
tags:
- markdown
- formatting
date: 2024-01-01
---β All spacing within frontmatter is preserved exactly as-is
Code Fence Protection: Code blocks maintain their original formatting:
```rust
fn main() {
println!("Hello, world!");
// Multiple blank lines preserved in code
}
```
~~~python
def hello():
print("Spacing preserved here too!")
return "done"
~~~β All spacing within code fences is preserved exactly as-is
The tool will delete files that are:
- Completely empty
- Contain only whitespace
- Contain only YAML frontmatter with no content body
Example of file that gets deleted:
---
title: "Draft Post"
date: 2024-01-01
---
Note
Files are only deleted if they truly have no meaningful content. Files with any actual content (even just a single character) are preserved.
mdfmt is designed for speed and efficiency:
- Parallel Processing: Uses Rayon for concurrent file processing
- Memory Efficient: Processes files one at a time without loading entire directory structures
- Fast Pattern Matching: Uses optimized glob patterns for file discovery
- Smart Content Analysis: Efficiently detects and preserves frontmatter and code blocks
- Minimal Dependencies: Only essential dependencies for maximum performance
Benchmarks on a typical documentation directory:
- 100 files: ~50ms
- 1,000 files: ~200ms
- 10,000 files: ~1.5s
- Rust 1.85 or later
- Cargo (included with Rust)
git clone https://github.com/vew94/mdfmt.git
cd mdfmt
# Debug build
cargo build
# Release build (optimized)
cargo build --release
# Run tests
cargo test
# Install locally
cargo install --path .mdfmt includes comprehensive safety measures:
- Content Protection: Never modifies frontmatter or code fence contents
- Backup Recommendations: Always backup important files before batch processing
- Dry Run Mode: Preview all changes before applying them
- Error Recovery: Detailed error reporting for any failed operations
- Structure Preservation: Only removes excessive blank lines, never modifies actual content
- Atomic Operations: Each file is processed independently
Warning
While mdfmt is designed to be safe, always backup important files before running it on large directories. Use --dry-run to preview changes first.
Contributions are welcome! Please feel free to submit issues and pull requests.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
If mdfmt doesn't meet your needs, consider these alternatives:
- prettier - Opinionated code formatter with Markdown support
- markdownlint - Linting and style checking for Markdown
- remark - Markdown processor with extensive plugin ecosystem