Skip to content

A powerful Python-based Markdown to ANSI terminal formatter that renders markdown files with color and style directly in your terminal.

License

Notifications You must be signed in to change notification settings

Open-Technology-Foundation/md2ansi

Repository files navigation

MD2ANSI

A Python-based Markdown-to-ANSI terminal formatter that renders markdown files with color and style directly in your terminal.

Version License Python Dependencies Tests

Features

  • 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
    • Strikethrough text rendering
    • Inline code with distinct styling
    • Links with underlined styling
    • Image 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

Installation

Method 1: Automatic Installation (Recommended)

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 for md2ansi and md commands
  • Install bash completion support (if available)
  • Generate and install man page (if prerequisites are met)

Method 2: Manual Installation

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

Method 3: Local Usage (No Installation)

Simply clone and run directly:

git clone https://github.com/Open-Technology-Foundation/md2ansi
cd md2ansi
./md2ansi README.md

Usage

Basic Usage

# 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

Advanced Usage

# 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

Integration Examples

# 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"

Utility Scripts

# 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

Command Line Options

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)

Formatting Examples

Headers

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)

Lists

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

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 |

Code Blocks

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

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!")
> ```

Inline Formatting

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.

Testing

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

Test Coverage

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

Test fixtures are provided in the test_fixtures/ directory:

  • basic.md - General markdown features
  • tables.md - Table formatting variations
  • code_blocks.md - Syntax highlighting tests
  • edge_cases.md - Special characters and malformed markdown
  • redos_patterns.md - ReDoS attack patterns for security testing

Technical Details

Architecture

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

ANSI Color Scheme

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

Terminal Compatibility

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

Performance

  • 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

Included Scripts

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

Bash Completion

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

Requirements

  • Python: 3.8 or higher
  • Terminal: ANSI color support (most modern terminals)
  • Optional: less command for the md wrapper script
  • Optional: .bash_completion package for tab completion
  • No Python packages required - uses only standard library

Security Considerations

MD2ANSI includes comprehensive security features:

  1. ReDoS Protection: All regex operations have timeouts (1 second default) to prevent catastrophic backtracking
  2. Input Size Limits:
    • Files larger than 10MB are rejected
    • Regex input limited to 100KB to prevent memory exhaustion
  3. Input Sanitization: ANSI escape sequences in input are removed to prevent injection attacks
  4. Safe File Handling: Proper error messages and validation for all file operations
  5. Command Injection Prevention: All grep commands use -- separator
  6. Signal Handling: Graceful exit on Ctrl+C with terminal reset
  7. Bounds Checking: Terminal width validated to reasonable limits (20-500 columns)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Follow the coding style (2-space indentation, type hints)
  4. Add tests for new features
  5. Update documentation as needed
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

See CLAUDE.md for development guidelines.

License

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.

Bug Reports

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

Changelog

Version 0.9.6 (2025-09-01)

  • 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

Version 0.9.5 (Previous)

  • 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

Acknowledgments

  • 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

About

A powerful Python-based Markdown to ANSI terminal formatter that renders markdown files with color and style directly in your terminal.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published