{"id":29938024,"url":"https://github.com/open-technology-foundation/md2ansi","last_synced_at":"2026-04-12T15:53:29.814Z","repository":{"id":202563720,"uuid":"707187452","full_name":"Open-Technology-Foundation/md2ansi","owner":"Open-Technology-Foundation","description":"A powerful Python-based Markdown to ANSI terminal formatter that renders markdown files with color and style directly in your terminal.","archived":false,"fork":false,"pushed_at":"2025-07-23T04:18:40.000Z","size":328,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-23T05:32:27.054Z","etag":null,"topics":["ansi","bash","markdown","shell"],"latest_commit_sha":null,"homepage":"https://yatti.id/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Open-Technology-Foundation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-10-19T11:52:00.000Z","updated_at":"2025-07-23T04:18:44.000Z","dependencies_parsed_at":"2024-12-29T04:17:52.790Z","dependency_job_id":"8371bd04-038a-449c-8ae3-c45114380abc","html_url":"https://github.com/Open-Technology-Foundation/md2ansi","commit_stats":null,"previous_names":["open-technology-foundation/md2ansi"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Open-Technology-Foundation/md2ansi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Open-Technology-Foundation%2Fmd2ansi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Open-Technology-Foundation%2Fmd2ansi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Open-Technology-Foundation%2Fmd2ansi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Open-Technology-Foundation%2Fmd2ansi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Open-Technology-Foundation","download_url":"https://codeload.github.com/Open-Technology-Foundation/md2ansi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Open-Technology-Foundation%2Fmd2ansi/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268470799,"owners_count":24255391,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansi","bash","markdown","shell"],"created_at":"2025-08-02T23:16:32.047Z","updated_at":"2026-04-12T15:53:29.789Z","avatar_url":"https://github.com/Open-Technology-Foundation.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# MD2ANSI\n\nA Python-based Markdown-to-ANSI terminal formatter that renders markdown files with color and style directly in your terminal.\n\n![Version](https://img.shields.io/badge/version-0.9.6-blue.svg)\n![License](https://img.shields.io/badge/license-GPL--3.0-green.svg)\n![Python](https://img.shields.io/badge/python-3.8+-blue.svg)\n![Dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)\n![Tests](https://img.shields.io/badge/tests-44%20passing-green.svg)\n\n(For pure Bash version, see [md2ansi.bash](https://github.com/Open-Technology-Foundation/md2ansi.bash))\n\n## Features\n\n- **Headers** (H1-H6) with distinct color gradients from yellow to purple\n- **Lists:**\n  - Unordered lists with proper nesting and indentation\n  - Ordered lists with automatic numbering\n  - Task lists with checkboxes ([ ] and [x])\n  - Nested list support with proper indentation\n- **Code Blocks:**\n  - Fenced with ``` or ~~~ with language detection\n  - Syntax highlighting for Python, JavaScript, and Bash\n  - Support for language aliases (py, js, sh, shell)\n  - Handles multiline strings and comments correctly\n  - ANSI escape sequence sanitization for clean display\n- **Tables:**\n  - Pipe-delimited with alignment support (left, center, right)\n  - Enhanced formatting with mixed styling in cells\n  - Handles tables with mismatched column counts gracefully\n- **Blockquotes** with dark background highlighting\n- **Horizontal Rules** with full-width terminal rendering\n- **Inline Formatting:**\n  - **Bold** text rendering\n  - *Italic* text rendering\n  - ~~Strikethrough~~ text rendering\n  - `Inline code` with distinct styling\n  - [Links](https://example.com) with underlined styling\n  - ![Image](url) with alt text placeholder\n  - [^1] Footnote references with automatic collection\n  - Nested formatting support (***bold italic***, etc.)\n- **Smart Features:**\n  - Terminal width auto-detection with fallbacks\n  - ANSI-aware text wrapping that preserves formatting\n  - File size validation (10MB limit for security)\n  - Graceful signal handling (Ctrl+C)\n- **Security:**\n  - ReDoS (Regular Expression Denial of Service) protection with timeouts\n  - Input sanitization to prevent ANSI injection\n  - File size limits to prevent DoS attacks\n  - Safe handling of special characters in filenames\n- **Developer Tools:**\n  - Debug mode with detailed execution traces\n  - Comprehensive test suite with 44+ unit tests\n  - Test fixtures for edge cases and security testing\n\n## Installation\n\n### Method 1: Automatic Installation (Recommended)\n\nUse the provided installation script for system-wide installation:\n\n```bash\n# Download and run the installation script\ncurl -sL https://raw.githubusercontent.com/Open-Technology-Foundation/md2ansi/main/md2ansi-install.sh | bash\n\n# Or if you've already cloned the repository\ncd md2ansi\n./md2ansi-install.sh\n\n# To uninstall\n./md2ansi-install.sh --uninstall\n```\n\nThe installation script will:\n- Check prerequisites (git, bash)\n- Clone the repository to `/usr/local/share/md2ansi`\n- Set executable permissions on all scripts\n- Create symbolic links in `/usr/local/bin` for `md2ansi` and `md` commands\n- Install bash completion support (if available)\n- Generate and install man page (if prerequisites are met)\n\n### Method 2: Manual Installation\n\nClone the repository and make the scripts executable:\n\n```bash\ngit clone https://github.com/Open-Technology-Foundation/md2ansi\ncd md2ansi\nchmod +x md2ansi.py md2ansi md display-ansi-palette md-link-extract\n\n# Create symbolic links (optional but recommended):\nsudo ln -s $(pwd)/md2ansi /usr/local/bin/md2ansi\nsudo ln -s $(pwd)/md /usr/local/bin/md\n\n# Install bash completion (optional):\nsudo cp .bash_completion /etc/bash_completion.d/md2ansi\n```\n\n### Method 3: Local Usage (No Installation)\n\nSimply clone and run directly:\n\n```bash\ngit clone https://github.com/Open-Technology-Foundation/md2ansi\ncd md2ansi\n./md2ansi README.md\n```\n\n## Usage\n\n### Basic Usage\n\n```bash\n# View a single markdown file\nmd2ansi README.md\n\n# View with pager for long files (recommended)\nmd README.md\n\n# Process multiple files\nmd2ansi *.md\nmd2ansi docs/*.md\n\n# Process from stdin\ncat README.md | md2ansi\necho \"# Hello World\" | md2ansi\n\n# Process from URL\ncurl -s https://raw.githubusercontent.com/user/repo/main/README.md | md2ansi\n```\n\n### Advanced Usage\n\n```bash\n# Force specific terminal width\nmd2ansi --width 100 README.md\nmd2ansi -w 80 README.md\n\n# Enable debug mode for troubleshooting\nmd2ansi --debug README.md 2\u003edebug.log\nmd2ansi -D README.md  # Debug output to stderr\n\n# Disable specific features\nmd2ansi --no-syntax-highlight code-heavy.md\nmd2ansi --no-tables --no-footnotes simple.md\n\n# Plain text mode (all formatting disabled)\nmd2ansi --plain README.md\nmd2ansi -t README.md\n\n# View help and version\nmd2ansi --help\nmd2ansi --version\n```\n\n### Integration Examples\n\n```bash\n# Git diff with markdown formatting\ngit show HEAD:README.md | md2ansi\n\n# View markdown documentation in man-page style\nmd2ansi API.md | less -R\n\n# Create a markdown viewer function\nmdview() { md2ansi \"$1\" | less -R; }\n\n# Compare two markdown files side by side\ndiff -y \u003c(md2ansi --plain old.md) \u003c(md2ansi --plain new.md)\n\n# Search through formatted markdown\nmd2ansi docs/*.md | grep -i \"installation\"\n```\n\n### Utility Scripts\n\n```bash\n# Display ANSI color palette\n./display-ansi-palette\n\n# Extract all links from a markdown file\n./md-link-extract README.md\n\n# Install/uninstall system-wide\n./md2ansi-install.sh --help\n```\n\n## Command Line Options\n\n| Option | Short | Description |\n|--------|-------|-------------|\n| `--help` | `-h` | Show help message and exit |\n| `--version` | `-V` | Show version information and exit |\n| `--debug` | `-D` | Enable debug mode with detailed execution traces |\n| `--width WIDTH` | `-w` | Force specific terminal width (default: auto-detect) |\n| `--no-footnotes` | | Disable footnotes processing |\n| `--no-syntax-highlight` | | Disable syntax highlighting in code blocks |\n| `--no-tables` | | Disable tables formatting |\n| `--no-task-lists` | | Disable task lists (checkboxes) formatting |\n| `--no-images` | | Disable image placeholders |\n| `--no-links` | | Disable links formatting |\n| `--plain` | `-t` | Plain text mode (disables all formatting) |\n\n## Formatting Examples\n\n### Headers\n\nHeaders are rendered with a distinct color gradient:\n\n```markdown\n# H1 Header (Bright Yellow)\n## H2 Header (Orange)\n### H3 Header (Green)\n#### H4 Header (Blue)\n##### H5 Header (Purple)\n###### H6 Header (Dark Gray)\n```\n\n### Lists\n\nAll list types are supported with proper nesting:\n\n```markdown\n* Unordered list item\n  * Nested item\n    * Deep nested item\n  * Another nested item\n\n1. Ordered list item\n2. Second item\n   1. Nested ordered item\n   2. Another nested item\n\n- [ ] Unchecked task\n- [x] Checked task\n  - [ ] Nested task\n```\n\n### Tables\n\nTables support alignment and inline formatting:\n\n```markdown\n| Left | Center | Right |\n|:-----|:------:|------:|\n| Text | **Bold** | *Italic* |\n| `Code` | ~~Strike~~ | [Link](url) |\n| Plain | ***Bold Italic*** | Mixed |\n```\n\nTables with mismatched columns are handled gracefully:\n\n```markdown\n| Col1 | Col2 | Col3 |\n|------|------|\n| Data spans | remaining columns |\n```\n\n### Code Blocks\n\nSyntax highlighting for multiple languages:\n\n````markdown\n```python\ndef fibonacci(n: int) -\u003e int:\n    \"\"\"Calculate fibonacci number\"\"\"\n    if n \u003c= 1:\n        return n\n    return fibonacci(n-1) + fibonacci(n-2)\n```\n\n```javascript\nconst greet = (name = 'World') =\u003e {\n    console.log(`Hello, ${name}!`);\n    return Promise.resolve(name);\n};\n```\n\n```bash\n#!/bin/bash\nset -euo pipefail\n\necho \"Setting up environment...\"\nfor file in *.md; do\n    md2ansi \"$file\" \u003e \"${file%.md}.txt\"\ndone\n```\n````\n\n### Blockquotes\n\nBlockquotes with nested formatting:\n\n```markdown\n\u003e **Important:** This is a blockquote with *emphasis* and `code`.\n\u003e \n\u003e It can span multiple lines and include:\n\u003e - Lists\n\u003e - [Links](https://example.com)\n\u003e - Even code blocks:\n\u003e\n\u003e ```python\n\u003e print(\"Hello from a blockquote!\")\n\u003e ```\n```\n\n### Inline Formatting\n\nComplex nested formatting is supported:\n\n```markdown\nYou can **bold**, *italicize*, ~~strike~~, and `code` text.\n\nCombine them: ***bold italic***, **`bold code`**, *`italic code`*.\n\nLinks can be [**bold**](url) or [*italic*](url) or [`code`](url).\n\nFootnotes[^1] are collected and displayed at the end[^note].\n\n[^1]: This is the first footnote.\n[^note]: This is a named footnote.\n```\n\n## Testing\n\nMD2ANSI includes a comprehensive test suite to ensure reliability and prevent regressions:\n\n```bash\n# Run the test suite\n./run_tests.sh\n\n# Run with verbose output\n./run_tests.sh --verbose\n\n# Run with coverage report (requires pytest-cov)\n./run_tests.sh --coverage\n\n# Run tests directly with Python\npython3 test_md2ansi.py\n\n# Test specific functionality\npython3 -m unittest test_md2ansi.TestSafeRegex\npython3 -m unittest test_md2ansi.TestColorizeLine\n```\n\n### Test Coverage\n\nThe test suite includes:\n- **Safe Regex Operations**: ReDoS protection and timeout handling\n- **Input Sanitization**: ANSI escape sequence removal\n- **Terminal Width Detection**: Bounds checking and fallback behavior\n- **Text Formatting**: Bold, italic, code, links, and combined styles\n- **Table Rendering**: Alignment, formatting, and edge cases\n- **Syntax Highlighting**: Multiple language support\n- **File Processing**: Size limits and error handling\n- **Debug Mode**: Logging and trace functionality\n\n### Test Fixtures\n\nTest fixtures are provided in the `test_fixtures/` directory:\n- `basic.md` - General markdown features\n- `tables.md` - Table formatting variations\n- `code_blocks.md` - Syntax highlighting tests\n- `edge_cases.md` - Special characters and malformed markdown\n- `redos_patterns.md` - ReDoS attack patterns for security testing\n\n## Technical Details\n\n### Architecture\n\nMD2ANSI is designed as a single-file Python script with zero external dependencies:\n\n- **Parser**: Line-by-line regex-based parsing for efficiency\n- **Renderer**: ANSI escape sequence generation with careful formatting\n- **Features**: Modular feature flags for customization\n- **Security**: Input validation and sanitization throughout\n\n### ANSI Color Scheme\n\n| Element | Color | ANSI Code |\n|---------|-------|-----------|\n| H1 | Bright Yellow | `\\x1b[38;5;226m` |\n| H2 | Orange | `\\x1b[38;5;214m` |\n| H3 | Green | `\\x1b[38;5;118m` |\n| H4 | Blue | `\\x1b[38;5;21m` |\n| H5 | Purple | `\\x1b[38;5;93m` |\n| H6 | Dark Gray | `\\x1b[38;5;239m` |\n| Code | Gray | `\\x1b[90m` |\n| Lists | Cyan | `\\x1b[36m` |\n| Links | Cyan-Blue | `\\x1b[38;5;45m` |\n| Text | Light Gray | `\\x1b[38;5;7m` |\n\n### Terminal Compatibility\n\nMD2ANSI works with any terminal that supports:\n- 256-color ANSI sequences\n- UTF-8 encoding\n- Basic ANSI formatting (bold, italic, underline)\n\nTested on:\n- Linux: GNOME Terminal, Konsole, xterm, Alacritty\n- macOS: Terminal.app, iTerm2\n- Windows: Windows Terminal, Git Bash, WSL\n\n### Performance\n\n- **Memory efficient**: Processes files line-by-line\n- **Fast startup**: No external dependencies to load\n- **File size limit**: 10MB for safety (configurable in source)\n- **Streaming capable**: Works with pipes and stdin\n\n## Included Scripts\n\n| Script | Purpose |\n|--------|---------|\n| `md2ansi` | Main converter script (Python) |\n| `md2ansi.py` | Symlink to md2ansi for compatibility |\n| `md` | Wrapper that pipes through `less -R` |\n| `display-ansi-palette` | Shows all 256 ANSI colors |\n| `md-link-extract` | Extracts links from markdown files |\n| `md2ansi-install.sh` | System-wide installation script |\n| `md2ansi-create-manpage.sh` | Generates man page from README.md |\n\n## Bash Completion\n\nTab completion is available for both `md2ansi` and `md` commands:\n\n```bash\n# Complete .md files only\nmd2ansi RE\u003cTab\u003e  # Completes to README.md\nmd \u003cTab\u003e          # Shows all .md files\n\n# Complete options\nmd2ansi --\u003cTab\u003e   # Shows all available options\n\n# Install completion manually if needed\nsource .bash_completion\n```\n\n## Requirements\n\n- **Python**: 3.8 or higher\n- **Terminal**: ANSI color support (most modern terminals)\n- **Optional**: `less` command for the `md` wrapper script\n- **Optional**: `.bash_completion` package for tab completion\n- **No Python packages required** - uses only standard library\n\n## Security Considerations\n\nMD2ANSI includes comprehensive security features:\n\n1. **ReDoS Protection**: All regex operations have timeouts (1 second default) to prevent catastrophic backtracking\n2. **Input Size Limits**: \n   - Files larger than 10MB are rejected\n   - Regex input limited to 100KB to prevent memory exhaustion\n3. **Input Sanitization**: ANSI escape sequences in input are removed to prevent injection attacks\n4. **Safe File Handling**: Proper error messages and validation for all file operations\n5. **Command Injection Prevention**: All grep commands use `--` separator\n6. **Signal Handling**: Graceful exit on Ctrl+C with terminal reset\n7. **Bounds Checking**: Terminal width validated to reasonable limits (20-500 columns)\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Follow the coding style (2-space indentation, type hints)\n4. Add tests for new features\n5. Update documentation as needed\n6. Commit your changes (`git commit -m 'Add amazing feature'`)\n7. Push to the branch (`git push origin feature/amazing-feature`)\n8. Open a Pull Request\n\nSee [CLAUDE.md](CLAUDE.md) for development guidelines.\n\n## License\n\nCopyright © 2022-2025 [Indonesian Open Technology Foundation](https://yatti.id)\n\nThis 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.\n\nSee [LICENSE](LICENSE) file for details.\n\n## Bug Reports\n\nPlease report any issues on the [GitHub repository](https://github.com/Open-Technology-Foundation/md2ansi/issues).\n\nWhen reporting bugs, please include:\n- Your Python version (`python3 --version`)\n- Your terminal emulator and OS\n- The markdown file causing issues (if possible)\n- The exact command you ran\n- Any error messages\n\n## Changelog\n\n### Version 0.9.6 (2025-09-01)\n- **Security**: Added ReDoS protection with timeout-based regex execution\n- **Feature**: Implemented debug mode (`--debug`/`-D`) with detailed execution traces\n- **Testing**: Added comprehensive test suite with 44+ unit tests\n- **Testing**: Created test fixtures for edge cases and security testing\n- **Improvement**: Added terminal width bounds checking (20-500 columns)\n- **Improvement**: Enhanced error handling with fallback mechanisms\n- **Fix**: Updated all regex operations to use safe wrappers\n- **Docs**: Added testing documentation and security details\n\n### Version 0.9.5 (Previous)\n- Fixed syntax highlighting issues with ANSI escape sequences\n- Improved handling of code blocks for all supported languages\n- Fixed handling of multiline strings and comments\n- Improved error handling with specific error messages\n- Fixed table alignment with mismatched column counts\n\n## Acknowledgments\n\n- Inspired by various markdown terminal viewers\n- ANSI color reference from [Wikipedia](https://en.wikipedia.org/wiki/ANSI_escape_code)\n- Markdown specification from [CommonMark](https://commonmark.org/)\n\n---\n\n*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!*\n\n```bash\n# Test this README with md2ansi\n./md2ansi README.md\n\n# Or use the pager for easier reading\n./md README.md\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-technology-foundation%2Fmd2ansi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopen-technology-foundation%2Fmd2ansi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-technology-foundation%2Fmd2ansi/lists"}