Professional terminal markdown renderer for streaming LLM responses
Project description
MarkRender
MarkRender is a Python library for rendering Markdown in the terminal. It is designed to be highly customizable and is particularly well-suited for streaming content, such as responses from Large Language Models (LLMs).
Key Features
- Streaming Support: MarkRender can process and render Markdown content as it arrives, providing a smooth and responsive experience for dynamic content.
- Syntax Highlighting: Code blocks are highlighted using the powerful Pygments library, supporting a wide range of languages.
- Theming: Choose from a variety of built-in themes to customize the appearance of your rendered output.
- Table Rendering: Tables are rendered with proper formatting and alignment, powered by the
richlibrary. - Advanced Markdown Support: Highlights, footnotes, definition lists, progress bars, nested lists, and image placeholders.
- CLI Interface: Render markdown files directly from the command line.
- Configuration: Support for TOML configuration files.
- Cross-Platform: Works on Windows, macOS, and Linux.
Installation
You can install MarkRender using pip:
pip install markrender
For development, you can clone the repository and install it in editable mode:
git clone https://github.com/Praneeth-Gandodi/markrender.git
cd markrender
pip install -e .
Basic Usage
To render a Markdown string, create a MarkdownRenderer instance and use its render method:
from markrender import MarkdownRenderer
renderer = MarkdownRenderer()
markdown_text = """
# Example Document
This is a sample Markdown document to demonstrate the capabilities of MarkRender.
## Text Formatting
You can use various text formatting options, such as:
- **Bold text**
- *Italic text*
- `Inline code`
## Code Blocks
```python
def hello_world():
print("Hello, from MarkRender!")
```
## Tables
| Feature | Supported |
| --------------- | :-------: |
| Streaming | Yes |
| Syntax Highlighting | Yes |
| Theming | Yes |
"""
renderer.render(markdown_text)
renderer.finalize()
Streaming Usage
MarkRender is ideal for rendering content that arrives in chunks, such as from an API response. The render method can be called multiple times with partial content.
import time
from markrender import MarkdownRenderer
renderer = MarkdownRenderer()
markdown_stream = [
"# Streaming Example\n\n",
"This text is being rendered in chunks.\n\n",
"```python\n",
"for i in range(5):\n",
" print(i)\n",
"```\n",
]
for chunk in markdown_stream:
renderer.render(chunk)
time.sleep(0.5)
renderer.finalize()
Customization
The MarkdownRenderer can be customized with various options:
from markrender import MarkdownRenderer
renderer = MarkdownRenderer(
theme='monokai',
line_numbers=True,
code_background=True,
force_color=True,
stream_code=True
)
Available Options:
theme: The color theme to use for syntax highlighting.line_numbers: Whether to display line numbers in code blocks.code_background: Whether to add a background color to code blocks.force_color: IfTrue, forces color output even if the terminal does not appear to support it.stream_code: IfFalse, code blocks are rendered all at once at the end, rather than line by line.use_config: IfTrue(default), loads configuration from config file.
Available Themes
github-darkmonokaidraculanordone-darksolarized-darksolarized-light
Advanced Features
Highlighted Text
Use ==text== syntax to highlight text:
from markrender import MarkdownRenderer
renderer = MarkdownRenderer()
markdown_text = """
# Highlighting Example
This is normal text with ==highlighted text== for emphasis.
You can also combine with other formatting: ==**bold highlight**== or ==*italic highlight*==.
"""
renderer.render(markdown_text)
renderer.finalize()
Nested Lists
MarkRender supports deeply nested lists:
from markrender import MarkdownRenderer
renderer = MarkdownRenderer()
markdown_text = """
# Nested Lists Example
## Unordered Lists
- Item 1
- Nested item 1.1
- Deep nested item 1.1.1
- Nested item 1.2
- Item 2
- Nested item 2.1
## Ordered Lists
1. First item
1. Sub-item 1
2. Sub-item 2
2. Second item
1. Sub-item 1
"""
renderer.render(markdown_text)
renderer.finalize()
Progress Bars
Use - [X%] syntax to show task progress with visual progress bars:
from markrender import MarkdownRenderer
renderer = MarkdownRenderer()
markdown_text = """
# Task Progress
- [0%] Not started
- [25%] In progress
- [50%] Halfway done
- [75%] Almost complete
- [100%] Completed
"""
renderer.render(markdown_text)
renderer.finalize()
Progress bars are color-coded:
- Red: 0-24%
- Orange: 25-49%
- Yellow: 50-74%
- Green: 75-99%
- Checkmark: 100%
Image Placeholders
Since terminals cannot display actual images, MarkRender renders image placeholders:
from markrender import MarkdownRenderer
renderer = MarkdownRenderer()
markdown_text = """
# Image Example
Here is an image:

Another image: 
"""
renderer.render(markdown_text)
renderer.finalize()
Images are displayed as bordered boxes with alt text and URL.
Footnotes
Add footnotes to your documents:
from markrender import MarkdownRenderer
renderer = MarkdownRenderer()
markdown_text = """
# Footnotes Example
This is a statement with a footnote reference.[^1]
Here is another statement with a different footnote.[^note]
[^1]: This is the first footnote content. It can contain multiple sentences.
[^note]: This is a named footnote. You can use any identifier here.
"""
renderer.render(markdown_text)
renderer.finalize()
Footnotes are collected and displayed at the end of the document.
Definition Lists
Use Term : Definition syntax for glossaries and definitions:
from markrender import MarkdownRenderer
renderer = MarkdownRenderer()
markdown_text = """
# Definition Lists Example
**Python** : A high-level programming language known for its simplicity.
**API** : Application Programming Interface, allows software components to communicate.
**Markdown** : A lightweight markup language for creating formatted text.
"""
renderer.render(markdown_text)
renderer.finalize()
CLI Interface
MarkRender includes a command-line interface for rendering markdown files:
# Render a markdown file
markrender README.md
# Use a specific theme
markrender --theme dracula file.md
# Disable line numbers
markrender --no-line-numbers file.md
# Enable code background
markrender --code-background file.md
# Force color output
markrender --force-color file.md
# List available themes
markrender --list-themes
# Render from stdin
cat file.md | markrender
CLI Options
| Option | Description |
|---|---|
-t, --theme |
Syntax highlighting theme (default: github-dark) |
--no-line-numbers |
Disable line numbers in code blocks |
--code-background |
Enable background color in code blocks |
--width |
Set terminal width (default: auto-detect) |
--no-stream-code |
Render code blocks all at once |
--force-color |
Force color output |
--list-themes |
List available themes and exit |
-v, --version |
Show version information |
Configuration
MarkRender supports configuration via TOML files. Create a config file at:
~/.markrender/config.toml(home directory).markrender.toml(current directory)
Example Configuration
# MarkRender Configuration
[theme]
name = "github-dark"
[rendering]
code_background = false
line_numbers = true
[output]
# width = 80 # Uncomment to set fixed width
force_color = false
[features]
stream_code = true
Creating Default Config
from markrender import create_default_config
# Create default config file at ~/.markrender/config.toml
create_default_config()
Custom Themes
Register your own custom themes:
from markrender import register_theme, MarkdownRenderer
custom_theme = {
'name': 'my-custom-theme',
'pygments_style': 'monokai',
'heading_colors': {
1: '#ff0000',
2: '#00ff00',
3: '#0000ff',
4: '#ffff00',
5: '#00ffff',
6: '#ff00ff',
},
'inline_code': '#123456',
'link': '#654321',
'blockquote_border': '#aaaaaa',
'table_border': '#bbbbbb',
'checkbox_unchecked': '#cccccc',
'checkbox_checked': '#dddddd',
'hr': '#eeeeee',
'highlight': '#ffffff',
'list_marker': '#111111',
'table_header': '#222222',
}
register_theme('my-custom-theme', custom_theme)
# Use the custom theme
renderer = MarkdownRenderer(theme='my-custom-theme')
Complete Example
Here is a comprehensive example demonstrating multiple features:
from markrender import MarkdownRenderer
renderer = MarkdownRenderer(
theme='github-dark',
line_numbers=True,
code_background=False
)
markdown_content = """
# Complete MarkRender Demo
## Text Formatting
This document demonstrates ==highlighted text==, **bold**, *italic*, and `inline code`.
## Nested Lists
- Main item 1
- Sub-item 1.1
- Deep item 1.1.1
- Sub-item 1.2
- Main item 2
1. Ordered sub-item
2. Another ordered sub-item
## Progress Tracking
- [0%] Planning
- [25%] Design
- [50%] Implementation
- [75%] Testing
- [100%] Deployment
## Code Example
```python
def greet(name):
return f"Hello, {name}!"
print(greet("World"))
```
## Definition List
**MarkRender** : A terminal markdown renderer for Python.
**Rich** : A library for rich terminal output.
## Footnotes
This is an important point.[^1]
[^1]: This footnote provides additional context.
## Image Reference
See the diagram below:

---
End of demo.
"""
renderer.render(markdown_content)
renderer.finalize()
API Reference
MarkdownRenderer
from markrender import MarkdownRenderer
renderer = MarkdownRenderer(
theme='github-dark', # Theme name
code_background=False, # Show code block background
inline_code_color=None, # Custom inline code color
line_numbers=True, # Show line numbers
width=None, # Terminal width (auto-detect if None)
output=None, # Output file (sys.stdout if None)
force_color=False, # Force color output
stream_code=True, # Stream code line by line
use_config=True # Load from config file
)
renderer.render(markdown_text) # Render markdown content
renderer.finalize() # Finalize and flush output
Utility Functions
from markrender import list_themes, get_theme, register_theme, create_default_config
# List available themes
themes = list_themes()
# Get theme configuration
theme = get_theme('github-dark')
# Register custom theme
register_theme('my-theme', theme_config)
# Create default config file
create_default_config()
Contributing
Contributions are welcome! Please feel free to open an issue or submit a pull request on the GitHub repository.
License
MarkRender is distributed under the MIT License. See the LICENSE file for more details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file markrender-1.0.6.tar.gz.
File metadata
- Download URL: markrender-1.0.6.tar.gz
- Upload date:
- Size: 50.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9bd3cb524954d580d993b7ecd7a8273617ec32bb4cb8da11c60129ac0bd949bc
|
|
| MD5 |
3d17af12ffef4fcd0b7acfb272aa6810
|
|
| BLAKE2b-256 |
128dcbc6f2b65f1f41d0d5af8703ae530ab9d09d080462a219d18126910abd3f
|
File details
Details for the file markrender-1.0.6-py3-none-any.whl.
File metadata
- Download URL: markrender-1.0.6-py3-none-any.whl
- Upload date:
- Size: 35.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e063a7235aa7c25ae852d7bb3083a60f6049d32852091513a16b0ade4d40348
|
|
| MD5 |
50b9f22a69b0134327745b3747c49920
|
|
| BLAKE2b-256 |
7880dd85a58d496a4ec006bf979d54585b8eda328b0f314af9922058d75c3488
|