A Python-based Markdown-to-ANSI terminal formatter that renders markdown files with color and style directly in your terminal.
- Headers (H1-H6) with distinct color gradients from yellow to purple
- Lists:
- Unordered lists with proper nesting and indentation
- Ordered lists with automatic numbering
- Task lists with checkboxes ([ ] and [x])
- Nested list support with proper indentation
- Code Blocks:
- Fenced with ``` or ~~~ with language detection
- Syntax highlighting for Python, JavaScript, and Bash
- Support for language aliases (py, js, sh, shell)
- Handles multiline strings and comments correctly
- ANSI escape sequence sanitization for clean display
- Tables:
- Pipe-delimited with alignment support (left, center, right)
- Enhanced formatting with mixed styling in cells
- Handles tables with mismatched column counts gracefully
- Blockquotes with dark background highlighting
- Horizontal Rules with full-width terminal rendering
- Inline Formatting:
- Bold text rendering
- Italic text rendering
Strikethroughtext renderingInline code
with distinct styling- Links with underlined styling
with alt text placeholder
- [^1] Footnote references with automatic collection
- Nested formatting support (bold italic, etc.)
- Smart Features:
- Terminal width auto-detection with fallbacks
- ANSI-aware text wrapping that preserves formatting
- File size validation (10MB limit for security)
- Graceful signal handling (Ctrl+C)
- Security:
- ReDoS (Regular Expression Denial of Service) protection with timeouts
- Input sanitization to prevent ANSI injection
- File size limits to prevent DoS attacks
- Safe handling of special characters in filenames
- Developer Tools:
- Debug mode with detailed execution traces
- Comprehensive test suite with 44+ unit tests
- Test fixtures for edge cases and security testing
Use the provided installation script for system-wide installation:
# Download and run the installation script
curl -sL https://raw.githubusercontent.com/Open-Technology-Foundation/md2ansi/main/md2ansi-install.sh | bash
# Or if you've already cloned the repository
cd md2ansi
./md2ansi-install.sh
# To uninstall
./md2ansi-install.sh --uninstall
The installation script will:
- Check prerequisites (git, bash)
- Clone the repository to
/usr/local/share/md2ansi
- Set executable permissions on all scripts
- Create symbolic links in
/usr/local/bin
formd2ansi
andmd
commands - Install bash completion support (if available)
- Generate and install man page (if prerequisites are met)
Clone the repository and make the scripts executable:
git clone https://github.com/Open-Technology-Foundation/md2ansi
cd md2ansi
chmod +x md2ansi.py md2ansi md display-ansi-palette md-link-extract
# Create symbolic links (optional but recommended):
sudo ln -s $(pwd)/md2ansi /usr/local/bin/md2ansi
sudo ln -s $(pwd)/md /usr/local/bin/md
# Install bash completion (optional):
sudo cp .bash_completion /etc/bash_completion.d/md2ansi
Simply clone and run directly:
git clone https://github.com/Open-Technology-Foundation/md2ansi
cd md2ansi
./md2ansi README.md
# View a single markdown file
md2ansi README.md
# View with pager for long files (recommended)
md README.md
# Process multiple files
md2ansi *.md
md2ansi docs/*.md
# Process from stdin
cat README.md | md2ansi
echo "# Hello World" | md2ansi
# Process from URL
curl -s https://raw.githubusercontent.com/user/repo/main/README.md | md2ansi
# Force specific terminal width
md2ansi --width 100 README.md
md2ansi -w 80 README.md
# Enable debug mode for troubleshooting
md2ansi --debug README.md 2>debug.log
md2ansi -D README.md # Debug output to stderr
# Disable specific features
md2ansi --no-syntax-highlight code-heavy.md
md2ansi --no-tables --no-footnotes simple.md
# Plain text mode (all formatting disabled)
md2ansi --plain README.md
md2ansi -t README.md
# View help and version
md2ansi --help
md2ansi --version
# Git diff with markdown formatting
git show HEAD:README.md | md2ansi
# View markdown documentation in man-page style
md2ansi API.md | less -R
# Create a markdown viewer function
mdview() { md2ansi "$1" | less -R; }
# Compare two markdown files side by side
diff -y <(md2ansi --plain old.md) <(md2ansi --plain new.md)
# Search through formatted markdown
md2ansi docs/*.md | grep -i "installation"
# Display ANSI color palette
./display-ansi-palette
# Extract all links from a markdown file
./md-link-extract README.md
# Install/uninstall system-wide
./md2ansi-install.sh --help
Option | Short | Description |
---|---|---|
--help |
-h |
Show help message and exit |
--version |
-V |
Show version information and exit |
--debug |
-D |
Enable debug mode with detailed execution traces |
--width WIDTH |
-w |
Force specific terminal width (default: auto-detect) |
--no-footnotes |
Disable footnotes processing | |
--no-syntax-highlight |
Disable syntax highlighting in code blocks | |
--no-tables |
Disable tables formatting | |
--no-task-lists |
Disable task lists (checkboxes) formatting | |
--no-images |
Disable image placeholders | |
--no-links |
Disable links formatting | |
--plain |
-t |
Plain text mode (disables all formatting) |
Headers are rendered with a distinct color gradient:
# H1 Header (Bright Yellow)
## H2 Header (Orange)
### H3 Header (Green)
#### H4 Header (Blue)
##### H5 Header (Purple)
###### H6 Header (Dark Gray)
All list types are supported with proper nesting:
* Unordered list item
* Nested item
* Deep nested item
* Another nested item
1. Ordered list item
2. Second item
1. Nested ordered item
2. Another nested item
- [ ] Unchecked task
- [x] Checked task
- [ ] Nested task
Tables support alignment and inline formatting:
| Left | Center | Right |
|:-----|:------:|------:|
| Text | **Bold** | *Italic* |
| `Code` | ~~Strike~~ | [Link](url) |
| Plain | ***Bold Italic*** | Mixed |
Tables with mismatched columns are handled gracefully:
| Col1 | Col2 | Col3 |
|------|------|
| Data spans | remaining columns |
Syntax highlighting for multiple languages:
```python
def fibonacci(n: int) -> int:
"""Calculate fibonacci number"""
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
```
```javascript
const greet = (name = 'World') => {
console.log(`Hello, ${name}!`);
return Promise.resolve(name);
};
```
```bash
#!/bin/bash
set -euo pipefail
echo "Setting up environment..."
for file in *.md; do
md2ansi "$file" > "${file%.md}.txt"
done
```
Blockquotes with nested formatting:
> **Important:** This is a blockquote with *emphasis* and `code`.
>
> It can span multiple lines and include:
> - Lists
> - [Links](https://example.com)
> - Even code blocks:
>
> ```python
> print("Hello from a blockquote!")
> ```
Complex nested formatting is supported:
You can **bold**, *italicize*, ~~strike~~, and `code` text.
Combine them: ***bold italic***, **`bold code`**, *`italic code`*.
Links can be [**bold**](url) or [*italic*](url) or [`code`](url).
Footnotes[^1] are collected and displayed at the end[^note].
[^1]: This is the first footnote.
[^note]: This is a named footnote.
MD2ANSI includes a comprehensive test suite to ensure reliability and prevent regressions:
# Run the test suite
./run_tests.sh
# Run with verbose output
./run_tests.sh --verbose
# Run with coverage report (requires pytest-cov)
./run_tests.sh --coverage
# Run tests directly with Python
python3 test_md2ansi.py
# Test specific functionality
python3 -m unittest test_md2ansi.TestSafeRegex
python3 -m unittest test_md2ansi.TestColorizeLine
The test suite includes:
- Safe Regex Operations: ReDoS protection and timeout handling
- Input Sanitization: ANSI escape sequence removal
- Terminal Width Detection: Bounds checking and fallback behavior
- Text Formatting: Bold, italic, code, links, and combined styles
- Table Rendering: Alignment, formatting, and edge cases
- Syntax Highlighting: Multiple language support
- File Processing: Size limits and error handling
- Debug Mode: Logging and trace functionality
Test fixtures are provided in the test_fixtures/
directory:
basic.md
- General markdown featurestables.md
- Table formatting variationscode_blocks.md
- Syntax highlighting testsedge_cases.md
- Special characters and malformed markdownredos_patterns.md
- ReDoS attack patterns for security testing
MD2ANSI is designed as a single-file Python script with zero external dependencies:
- Parser: Line-by-line regex-based parsing for efficiency
- Renderer: ANSI escape sequence generation with careful formatting
- Features: Modular feature flags for customization
- Security: Input validation and sanitization throughout
Element | Color | ANSI Code |
---|---|---|
H1 | Bright Yellow | \x1b[38;5;226m |
H2 | Orange | \x1b[38;5;214m |
H3 | Green | \x1b[38;5;118m |
H4 | Blue | \x1b[38;5;21m |
H5 | Purple | \x1b[38;5;93m |
H6 | Dark Gray | \x1b[38;5;239m |
Code | Gray | \x1b[90m |
Lists | Cyan | \x1b[36m |
Links | Cyan-Blue | \x1b[38;5;45m |
Text | Light Gray | \x1b[38;5;7m |
MD2ANSI works with any terminal that supports:
- 256-color ANSI sequences
- UTF-8 encoding
- Basic ANSI formatting (bold, italic, underline)
Tested on:
- Linux: GNOME Terminal, Konsole, xterm, Alacritty
- macOS: Terminal.app, iTerm2
- Windows: Windows Terminal, Git Bash, WSL
- Memory efficient: Processes files line-by-line
- Fast startup: No external dependencies to load
- File size limit: 10MB for safety (configurable in source)
- Streaming capable: Works with pipes and stdin
Script | Purpose |
---|---|
md2ansi |
Main converter script (Python) |
md2ansi.py |
Symlink to md2ansi for compatibility |
md |
Wrapper that pipes through less -R |
display-ansi-palette |
Shows all 256 ANSI colors |
md-link-extract |
Extracts links from markdown files |
md2ansi-install.sh |
System-wide installation script |
md2ansi-create-manpage.sh |
Generates man page from README.md |
Tab completion is available for both md2ansi
and md
commands:
# Complete .md files only
md2ansi RE<Tab> # Completes to README.md
md <Tab> # Shows all .md files
# Complete options
md2ansi --<Tab> # Shows all available options
# Install completion manually if needed
source .bash_completion
- Python: 3.8 or higher
- Terminal: ANSI color support (most modern terminals)
- Optional:
less
command for themd
wrapper script - Optional:
.bash_completion
package for tab completion - No Python packages required - uses only standard library
MD2ANSI includes comprehensive security features:
- ReDoS Protection: All regex operations have timeouts (1 second default) to prevent catastrophic backtracking
- Input Size Limits:
- Files larger than 10MB are rejected
- Regex input limited to 100KB to prevent memory exhaustion
- Input Sanitization: ANSI escape sequences in input are removed to prevent injection attacks
- Safe File Handling: Proper error messages and validation for all file operations
- Command Injection Prevention: All grep commands use
--
separator - Signal Handling: Graceful exit on Ctrl+C with terminal reset
- Bounds Checking: Terminal width validated to reasonable limits (20-500 columns)
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Follow the coding style (2-space indentation, type hints)
- Add tests for new features
- Update documentation as needed
- Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
See CLAUDE.md for development guidelines.
Copyright © 2022-2025 Indonesian Open Technology Foundation
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
See LICENSE file for details.
Please report any issues on the GitHub repository.
When reporting bugs, please include:
- Your Python version (
python3 --version
) - Your terminal emulator and OS
- The markdown file causing issues (if possible)
- The exact command you ran
- Any error messages
- Security: Added ReDoS protection with timeout-based regex execution
- Feature: Implemented debug mode (
--debug
/-D
) with detailed execution traces - Testing: Added comprehensive test suite with 44+ unit tests
- Testing: Created test fixtures for edge cases and security testing
- Improvement: Added terminal width bounds checking (20-500 columns)
- Improvement: Enhanced error handling with fallback mechanisms
- Fix: Updated all regex operations to use safe wrappers
- Docs: Added testing documentation and security details
- Fixed syntax highlighting issues with ANSI escape sequences
- Improved handling of code blocks for all supported languages
- Fixed handling of multiline strings and comments
- Improved error handling with specific error messages
- Fixed table alignment with mismatched column counts
- Inspired by various markdown terminal viewers
- ANSI color reference from Wikipedia
- Markdown specification from CommonMark
This README.md file serves as both documentation and a test case for MD2ANSI. Try rendering it with the tool to see all formatting features in action!
# Test this README with md2ansi
./md2ansi README.md
# Or use the pager for easier reading
./md README.md