Markdown rendering for CLI applications with syntax highlighting.
clickmd provides beautiful terminal output with:
- π¨ Syntax highlighting for code blocks (Python, TypeScript, JSON, YAML, Bash, etc.)
- π Markdown rendering with headers, bold, links, and more
- π§ Zero dependencies for core functionality
- π±οΈ Optional Click integration for CLI decorators
# Core package (no dependencies)
pip install clickmd
# With Click support
pip install clickmd[click]from clickmd import md, echo
# Render markdown with syntax highlighting
md("""
# Hello World
This is **bold** and this is a [link](https://example.com).
```python
def greet(name: str) -> str:
return f"Hello, {name}!"""")
echo("## Status Update") echo("Regular text without markdown")
### With Click Integration
```python
import clickmd as click
@click.group()
def cli():
"""My awesome CLI tool"""
pass
@cli.command()
@click.option("--name", "-n", default="World")
def hello(name: str):
"""Say hello"""
click.md(f"""
## π Hello, {name}!
Welcome to **clickmd** - making CLIs beautiful.
""")
if __name__ == "__main__":
cli()
clickmd provides syntax highlighting for multiple languages:
| Language | Extensions | Highlight Features |
|---|---|---|
| Python | .py |
Keywords, strings, comments, decorators |
| TypeScript/JavaScript | .ts, .js |
Keywords, strings, template literals |
| JSON | .json |
Keys, strings, numbers, booleans |
| YAML | .yaml, .yml |
Keys, values, comments |
| Bash/Shell | .sh, .bash |
Commands, comments |
| Markdown | .md |
Headers, bold, links |
| Log | .log |
Errors (red), warnings (yellow), success (green) |
from clickmd import md
md("""
# Heading 1
## Heading 2
### Heading 3
**Bold text** and regular text.
[Links](https://example.com) are supported.
```python
# Code blocks with syntax highlighting
print("Hello, World!")- List items
- Are rendered
- Correctly """)
### MarkdownRenderer Class
For more control, use the `MarkdownRenderer` class directly:
```python
from clickmd import MarkdownRenderer
import sys
renderer = MarkdownRenderer(use_colors=True, stream=sys.stdout)
renderer.heading(1, "My Title")
renderer.codeblock("python", 'print("Hello!")')
from clickmd import md
# Log-style output with automatic coloring
md("""
```log
π Starting process...
π¦ Installing dependencies...
β
Build successful!
β οΈ Warning: deprecated API
π Error: connection failed""")
## API Reference
### Core Functions
#### `md(text: str) -> None`
Render markdown text with syntax highlighting.
#### `echo(message, file=None, nl=True, err=False, color=None) -> None`
Smart echo that auto-detects markdown and renders it.
#### `render_markdown(text, text_lang="markdown", stream=None, use_colors=True) -> None`
Low-level markdown rendering function.
#### `get_renderer(stream=None, use_colors=True) -> MarkdownRenderer`
Get a `MarkdownRenderer` instance.
### Click Decorators (requires `click` package)
When `click` is installed, these decorators are available:
- `@clickmd.group()` - Create a command group
- `@clickmd.command()` - Create a command
- `@clickmd.option()` - Add an option
- `@clickmd.argument()` - Add an argument
- `@clickmd.pass_context` - Pass Click context
- `clickmd.Choice` - Choice type
- `clickmd.Path` - Path type
### Constants
- `CLICK_AVAILABLE: bool` - Whether Click is installed
## Additional Features
### Interactive Menus
```python
import clickmd
choice = clickmd.menu("## Choose Provider", [
("groq", "Groq β fast & free tier"),
("openrouter", "OpenRouter β multi-model"),
("ollama", "Ollama β local, no API key"),
])
from clickmd import table, panel
table(
headers=["Name", "Version", "Status"],
rows=[
["clickmd", "1.1.0", "β
OK"],
["click", "8.1.7", "β
OK"],
],
)
panel("Deployment complete!", title="Success", style="green")from clickmd import get_logger
log = get_logger("myapp")
log.info("Starting process...")
log.success("Build complete!")
log.warning("Deprecated API")
log.error("Connection failed")from clickmd import set_theme, list_themes
list_themes() # Show available themes
set_theme("monokai") # Switch themefrom clickmd import debug, inspect_obj, diff, tree
debug(my_variable) # Pretty-print with type info
inspect_obj(my_object) # Show object attributes
diff("old text", "new text") # Side-by-side diff
tree("/path/to/dir") # Directory treeSee the examples/ directory for 17 demo scripts:
basic.pyβ Basic markdown renderingcli_app.pyβ Full CLI application with Clickcustom_renderer.pyβ Custom renderer configurationcolored_logging.pyβ Log-style colored outputphase1_features.pyβ Tables, panels, blockquotes, checklistsphase3_progress.pyβ Progress bars, spinners, live updatesphase4_themes.pyβ Theming systemphase5_devtools.pyβ Debug, inspect, diff, tree toolslogger_usage.pyβ Structured loggingmarkdown_help.pyβ Markdown help formatter for Click
clickmd/
βββ src/clickmd/ # Package source (src layout)
β βββ __init__.py # Public API: md(), echo(), menu(), select()
β βββ renderer.py # Core markdown renderer & syntax highlighting
β βββ decorators.py # Click decorator re-exports
β βββ help.py # Markdown help formatter for Click
β βββ logger.py # Markdown-aware structured logger
β βββ progress.py # Progress bars, spinners, live updates
β βββ themes.py # Color themes & NO_COLOR support
β βββ devtools.py # Debug, inspect, diff, tree tools
β βββ rich_backend.py # Optional Rich integration
β βββ py.typed # PEP 561 type marker
βββ tests/ # Test suite (69 tests)
βββ examples/ # 17 demo scripts
βββ docs/ # API reference & contributing guide
βββ scripts/ # Build & version tools
βββ tools/ # Markdown-to-HTML converter
βββ pyproject.toml # Project config (hatchling)
βββ Makefile # Dev commands
# Clone the repository
git clone https://github.com/wronai/clickmd.git
cd clickmd
# Install development dependencies
pip install -e ".[dev,click]"
# Run tests
make test
# Run linter & format
make lint
make format
# Build & publish
make build
make publishLicensed under Apache-2.0.
Licensed under Apache-2.0.
Licensed under Apache-2.0.
Licensed under Apache-2.0.
Apache License 2.0 - see LICENSE for details.
Tom Sapletta
Tom Sapletta
Tom Sapletta
Tom Sapletta
Created by Tom Sapletta - tom@sapletta.com
Contributions are welcome! Please read our Contributing Guide first.