mdriver - Streaming Markdown Printer
A streaming markdown printer for the terminal that renders GitHub Flavored Markdown with ANSI escape codes. The key feature is incremental emission: blocks are emitted immediately once parsed, not waiting for the entire document.
Warning: I wrote this code as an experiment in LLM development. I do not speak fluent rust and I have not read the markdown parser. I'm pretty sure it cannot do anything dangerous, but you've been warned.
Features
- Reasonably attractive, colorful display
- Parses some HTML
- Renders links as OSC8 terminal hyperlinks
- This sounds fancy, but just means you can click on links if your terminal supports it
Installation
Using Homebrew (macOS)
From crates.io
From Pre-built Binaries
Download the latest release for your platform from the GitHub Releases page:
- Linux:
mdriver-x86_64-unknown-linux-gnu.tar.gz - macOS:
mdriver-x86_64-apple-darwin.tar.gz(Intel) ormdriver-aarch64-apple-darwin.tar.gz(Apple Silicon)
Extract and add to your PATH:
From Source
The binary will be available at target/release/mdriver.
Usage
# Read from file
# Pipe markdown from a file
|
# Pipe from echo
|
# Redirect from file
# Use a specific syntax highlighting theme
# Set default theme via environment variable
MDRIVER_THEME="Solarized (dark)"
# List available themes
# Render images using kitty graphics protocol
# Control color output (auto, always, never)
|
# Show help
Example
|
Output (with ANSI colors in your terminal):
- # Demo (in blue and bold)
- This is bold and italic
Features
- ✅ Streaming: Renders markdown incrementally as it arrives
- ✅ ATX Headings:
# Headingwith blue/bold formatting - ✅ Paragraphs: Text blocks with inline formatting
- ✅ Code Blocks: Fenced blocks with
```and syntax highlighting - ✅ Lists: Unordered (
-) and ordered (1.) lists - ✅ Inline Formatting:
**bold**,*italic*,`code`with nested support - ✅ Hyperlinks:
[text](url)converted to clickable OSC8 terminal links - ✅ Image Rendering:
with kitty graphics protocol support - ✅ Syntax Highlighting: 100+ languages supported with customizable themes
- ✅ ANSI Colors: Beautiful terminal output with 24-bit true color
- ✅ Color Control: Auto-detect, always, or never modes for flexible output
- ✅ Zero Warnings: Strict clippy linting, no compiler warnings
Syntax Highlighting Themes
mdriver uses the syntect library for syntax highlighting, supporting 100+ languages with customizable color themes.
Available Themes
Use mdriver --list-themes to see all available themes. Popular options include:
- InspiredGitHub - Bright, vibrant colors inspired by GitHub's syntax highlighting
- Solarized (dark) - The classic Solarized dark color scheme
- Solarized (light) - Solarized optimized for light backgrounds
- base16-ocean.dark - Calm oceanic colors (default)
- base16-mocha.dark - Warm mocha tones
- base16-eighties.dark - Retro 80s aesthetic
Setting a Theme
There are three ways to configure the theme (in order of precedence):
- Command-line flag:
mdriver --theme "InspiredGitHub" file.md - Environment variable:
export MDRIVER_THEME="Solarized (dark)" - Default:
base16-ocean.dark
Example
# Use InspiredGitHub theme
# Set environment variable for persistent default
# Combine with piping
MDRIVER_THEME="base16-mocha.dark" |
Image Rendering
mdriver can render images inline in your terminal using the kitty graphics protocol. This feature works with any terminal that supports the kitty graphics protocol (kitty, WezTerm, Ghostty, etc.).
Enabling Image Rendering
Use the --images kitty flag to enable image display:
# Render local images
# Works with remote URLs
|
# Combine with theme selection
Image Features
- Auto-resize: Images automatically resize to fit terminal width while preserving aspect ratio
- Remote URLs: Fetches and displays images from HTTP/HTTPS URLs
- Graceful fallback: Shows alt text when image fails to load
- Backward compatible: Without
--imagesflag, images render as plain text - Extensible: Architecture supports future protocols (sixel, iTerm2, etc.)
Example
Here's a screenshot:

And a remote image:

# Render with images
Note: Image rendering requires a terminal that supports the kitty graphics protocol. In terminals without support, images will display as alt text.
Color Output Control
By default, mdriver automatically detects whether to use ANSI colors based on whether stdout is a terminal. You can override this behavior with the --color flag.
Color Modes
| Mode | Description |
|---|---|
auto |
Use colors only when stdout is a terminal (default) |
always |
Always emit ANSI color codes, even when piping |
never |
Never use colors; pass markdown through unchanged |
Usage Examples
# Default behavior (auto-detect)
|
# Force colors when piping to a pager
|
# Disable colors entirely
# Alternative syntax (space instead of =)
Common Use Cases
Piping to a pager with colors:
|
The -R flag tells less to interpret ANSI escape sequences.
Saving colored output to a file:
The file will contain ANSI codes that display colors when cated to a terminal.
Plain text output:
Passes the markdown through without any formatting.
HTML Entity Support
mdriver decodes HTML entities in markdown text, supporting both named entities and numeric character references.
Supported Named Entities
| Entity | Character | Description |
|---|---|---|
| Essential (XML) | ||
& |
& |
Ampersand |
< |
< |
Less than |
> |
> |
Greater than |
" |
" |
Quotation mark |
' |
' |
Apostrophe |
| Whitespace | ||
|
Non-breaking space | |
| Typographic | ||
– |
– |
En dash |
— |
— |
Em dash |
… |
… |
Horizontal ellipsis |
‘ |
' |
Left single quote |
’ |
' |
Right single quote |
“ |
" |
Left double quote |
” |
" |
Right double quote |
• |
• |
Bullet |
· |
· |
Middle dot |
| Symbols | ||
© |
© |
Copyright |
® |
® |
Registered |
™ |
™ |
Trademark |
° |
° |
Degree |
± |
± |
Plus-minus |
× |
× |
Multiplication |
÷ |
÷ |
Division |
| Fractions | ||
¼ |
¼ |
One quarter |
½ |
½ |
One half |
¾ |
¾ |
Three quarters |
| Currency | ||
¢ |
¢ |
Cent |
£ |
£ |
Pound |
€ |
€ |
Euro |
¥ |
¥ |
Yen |
| Arrows | ||
← |
← |
Left arrow |
→ |
→ |
Right arrow |
↑ |
↑ |
Up arrow |
↓ |
↓ |
Down arrow |
Numeric Character References
In addition to named entities, mdriver supports numeric references for any Unicode character:
- Decimal:
©→© - Hexadecimal:
©→©
Example
|
&
Conformance Test Suite
This project uses a comprehensive conformance test suite to verify streaming behavior, markdown parsing, and ANSI formatting.
Test Structure
Tests are written as TOML fixture files that specify:
- Input chunks: Markdown arriving incrementally (simulating streaming)
- Expected emissions: What should be output after each chunk (empty string if block incomplete)
- Raw ANSI codes: Actual escape sequences for exact terminal output matching
Test Format Example
= "heading-basic"
= "Heading should emit after newline is received"
[[]]
= "#"
= ""
[[]]
= " Hello"
= ""
[[]]
= "\n"
= "\u001b[1;34m# Hello\u001b[0m\n"
Key Points:
- Each
[[chunks]]represents a piece of markdown fed to the parser input: The markdown chunkemit: Expected terminal output (empty""means no emission yet)- ANSI codes use
\u001bformat (TOML Unicode escape)
Test Categories
Tests are organized in tests/fixtures/:
blocks/- Individual block types (headings, paragraphs, code blocks, lists)streaming/- Incremental emission and block boundary detectionansi/- ANSI escape sequence formatting (bold, italic, colors)complex/- Real-world documents with mixed block types
Running Tests
# Run all conformance tests
# Run specific test category
# Run with verbose output
Test Output
When tests fail, you see clear diagnostics:
Running 4 tests from blocks...
✗ heading-basic
Heading should emit after newline is received
Chunk 4 failed:
Input: "\n"
Expected: "\u{1b}[1;34m# Hello\u{1b}[0m\n"
Actual: ""
Writing New Tests
- Create a
.tomlfile in the appropriatetests/fixtures/subdirectory - Define test name and description
- Add chunks with input and expected emissions
- Use
\u001bfor ESC character in ANSI codes
Example ANSI codes:
- Bold:
\u001b[1m...\u001b[0m - Italic:
\u001b[3m...\u001b[0m - Color:
\u001b[1;34m...\u001b[0m(bold blue) - Background:
\u001b[48;5;235m...\u001b[0m
Current Status
All Systems Operational ✅
- ✅ Parser Implementation: Complete with full streaming support
- ✅ Test Suite: 8 conformance tests - all passing
- ✅ CLI: Working binary for command-line usage
- ✅ Code Quality: Zero compiler warnings, zero clippy errors
- ✅ Documentation: Comprehensive CLAUDE.md for AI assistants
Test Coverage:
- Block types: heading, paragraph, code block, list
- Streaming: incremental emission, block boundaries
- Formatting: inline ANSI codes (bold, italic, code)
- Complex: mixed document scenarios
Future Enhancements
Potential areas for expansion:
- Additional GFM features (tables, task lists)
- Additional image protocols (sixel, iTerm2)
- Terminal width awareness and text wrapping
- Performance benchmarks for large documents
Project Structure
mdriver/
├── Cargo.toml
├── README.md
├── CLAUDE.md # AI assistant context and guidelines
├── gfmspec.md # GitHub Flavored Markdown specification
├── .clippy.toml # Clippy linting configuration
├── src/
│ ├── lib.rs # StreamingParser implementation
│ └── main.rs # CLI binary
└── tests/
├── conformance.rs # Test runner
├── common/
│ ├── mod.rs
│ └── fixture_loader.rs
└── fixtures/
├── blocks/ # 4 tests: heading, paragraph, code_block, list
├── streaming/ # 2 tests: incremental_emit, block_boundaries
├── ansi/ # 1 test: inline_formatting
└── complex/ # 1 test: mixed_document
Design Philosophy
- Streaming First: Blocks emit immediately when complete, enabling real-time rendering
- Test-Driven: Comprehensive test suite defines expected behavior before implementation
- Exact Output: Tests verify exact ANSI codes, not just content
- Incremental Testing: Tests verify streaming property, not just final output
- Zero Tolerance: No compiler warnings, no clippy errors - strict code quality standards
Development
Code Quality Standards
This project maintains strict code quality requirements:
# All must pass before committing:
See CLAUDE.md for comprehensive development guidelines and best practices.
Contributing
- Fork the repository
- Create a feature branch
- Write tests first (TDD approach)
- Implement feature to pass tests
- Ensure all quality checks pass
- Submit pull request
Key Files
CLAUDE.md: Comprehensive guide for AI assistants and developersgfmspec.md: GitHub Flavored Markdown specification (authoritative source).clippy.toml: Linting configurationtests/fixtures/: Conformance test cases in TOML format
License
MIT