pmd — Print Markdown
Terminal Markdown renderer. Zero dependencies. One command.
pmd renders Markdown files directly in your terminal with ANSI colors and Unicode box-drawing characters. No browser, no GUI, no npm install. Just Python 3.9+ and pip install pmd-cli.
Quick start
pip install pmd-cli # or: pipx install pmd-cli
pmd README.md
cat doc.md | pmd # stdin works too
Features
Headings — 6 levels with colors
| Level | Style | Marker |
|---|---|---|
| H1 | White on magenta | ■ |
| H2 | White on blue | ▸ |
| H3 | Black on cyan | ▸ |
| H4–H6 | Green / Yellow / Gray | ▸ |
No underlines, no # prefixes — just color and shape.
Inline formatting
- Bold
**text** - Italic
*text* - Bold-italic
***text*** Strikethrough~~text~~Code— bold green for visibility- Links — blue underlined
Code blocks — bordered, language-tagged
┌ python ──────────────────
│ def hello():
│ print("world")
└──────────────────────────
Clean box borders, language label in the top frame. No syntax highlighting — just readable code.
Tables — autofit, cell wrapping, inline formatting
┌──────────┬───────┬─────────────────┐
│ Name │ Age │ City │
├──────────┼───────┼─────────────────┤
│ Alice │ 30 │ Beijing │
│ Bob │ 25 │ Shanghai │
└──────────┴───────┴─────────────────┘
- Unicode box-drawing glyphs
- Columns autofit to content — compact by default
- Long cells wrap within their column
- Inline formatting (
`code`,**bold**) preserved inside cells
Task lists
● Completed task
○ Pending task
GFM-style - [x] / - [ ] rendered as green filled / gray empty circles. Mix with regular list items freely.
Blockquotes
▎ Cyan bar + dimmed text
▎ Clean and compact
CJK / Emoji support
Chinese, Japanese, Korean characters measured at correct display width (2 columns). Table alignment and text wrapping work properly for mixed-script documents.
Why pmd?
| Tool | Language | Dependencies |
|---|---|---|
| pmd | Python 3 | Zero |
glow |
Go | Requires Go toolchain or prebuilt binary |
rich-cli |
Python | rich + 10+ transitive deps |
mdcat |
Rust | Requires Rust or prebuilt binary |
mdr |
Ruby | Requires Ruby + gem install |
pmd is the lightest option when you need markdown rendering on a server, container, CI runner, or air-gapped machine where installing compilers or heavy packages isn't practical.
Alternatives vs. built-in less / cat
These show raw markdown source:
# Heading ← looks like a comment
**bold** *italic* ← noise characters everywhere
| table | columns | ← misaligned without rendering
pmd shows the rendered document — the way it was meant to be read.
Install
pip install pmd-cli # system-wide
pip install --user pmd-cli # user only
pipx install pmd-cli # isolated CLI (recommended)
Python 3.9 or later. No other dependencies.
Usage
# File
pmd README.md
# Stdin
curl -s https://example.com/doc.md | pmd
# From clipboard (macOS)
pbpaste | pmd
# From clipboard (Linux)
xclip -o | pmd
Project structure
src/pmd/
__init__.py # version
__main__.py # parser + renderer (~850 lines)
pyproject.toml # pip metadata
Single-file core — easy to vendor, fork, or embed.
License
MIT
Release files for pmd-cli 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pmd_cli-1.0.2.tar.gz | 13.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pmd_cli-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.8 kB
Release files / pmd_cli-1.0.2.tar.gz
| Download URL | pmd_cli-1.0.2.tar.gz |
|---|---|
| Size | 13.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cdcd578cf41b44b91df018206331c34a96457e11b2ca8d19c003bce6dd8ae6a8
|
|
BLAKE2b-256 checksum How to use checksums |
0b20d4f45b7c5dc9369902da3ca0648d2bc8341ab7fd5e353b32f205556d8e3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / pmd_cli-1.0.2-py3-none-any.whl
| Download URL | pmd_cli-1.0.2-py3-none-any.whl |
|---|---|
| Size | 12.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9c5d7ffb80cb4be7f438ddd13826f4571781fa8241c53d832c4c0dba7d93dbb0
|
|
BLAKE2b-256 checksum How to use checksums |
a99b385de6a31bb31242ba1338b35c1318f3f7d202f7bfab18c23696e2fd33ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|