Fast popup Markdown viewer with sidebar TOC, search, multi-file tabs, css themes, mermaid, katex, obsidian yaml show/hide, keyboard-based, stdio pipes
Project description
openmd - by Rufus Lin
Markdown viewer for humans (not AI models).
I got tired of reading raw Markdown with less or opening VS Code/Cursor just to see it nicely rendered. So I built openmd.
Run openmd *.md (or any Markdown file) from the shell and a window pops up instantly. Independent Qt window, ESC closes it. Think of it as "less" but for markdown files.
GitHub: RufusLin/openmd
Warning - Lazy Maintainer: Yeah, not a fan of reading PRs, but will pay attention to issues to fix bugs. Feel free to fork, but remember to give credit, please.🙏🏻
X: @rufuslinjapan
What it looks like
###openmd renders markdown
###CSS themes (customizable)
###Mermaid, KaTeX too!
Usage
# Open a single file
openmd README.md
# Open multiple files (each in its own tab)
openmd doc1.md doc2.md doc3.md
# No arguments — interactive picker (choose from .md files in current directory)
openmd
# Glob expansion
openmd docs/*.md
# Pipe stdio
tail -100 x.md | openmd
# on MacOS, render selected markdown
Select text, right click, Services, "Open in openmd"
Remote preview via SSH (optional)
remotemd() {
local remote_path="$1"
local filename=$(basename "$remote_path")
local tmp_file="/tmp/remote_preview_${filename}.md"
scp "home:$remote_path" "$tmp_file" && openmd "$tmp_file"
}
Features
- Meta panel — shows YAML front‑matter in a hidden-by-default div; toggle via the META button or the M shortcut key
- Quick Help — access a concise help dialog with navigation and shortcuts via the HELP button or the H shortcut key
- Instant launch — the shell prompt returns immediately; openmd runs as a fully detached GUI app (no
&needed, no blocking) - GitHub-dark theme by default — comfortable reading in low-light environments
- 16 built-in themes — dark and light, switch instantly via the swatch bar at the bottom of the sidebar; fully customizable via
.openmd.css - Live reload — the display pane updates instantly when the file is saved; no manual refresh needed
- Mermaid diagrams — fenced mermaid blocks render automatically via CDN
- KaTeX math — inline
$…$and display$$…$$expressions render out of the box - Sidebar TOC — hierarchical (H1 → H2 → H3); click or press Return to jump to any heading. The sidebar takes up 20% of your screen, and you can easily jump between the sidebar and display using the left/right arrow keys.
- Dynamic Pane Focus — unselected panes automatically dim to 60% opacity so you always know exactly where your keyboard focus is.
- Multi-file tabs — pass multiple
.mdfiles (even*.mdglobs) and each opens in its own tab, max 6 - Unix pipes - accepts markdown from stdin, e.g.
echo 'markdown string here' | openmd - Interactive file picker — run with no arguments and choose from
.mdfiles in the current directory via a curses-based picker - Remote image caching — remote images in your Markdown are downloaded to a local temp cache so they render correctly in the Qt WebEngine view
- External link handling — clicking any
http/httpslink opens it in your default browser; the display window never navigates away - Update notifications — on startup, openmd quietly checks PyPI (at most once every 6 hours) and shows a non-intrusive popup if a newer version is available
- Version in title bar — the window title shows the running version for quick reference
- Keyboard shortcuts —
Esccloses the window; Up/Down arrows and Return navigate the sidebar, Left/Right switch panes, and Cmd+Left/Right switch tabs
Theming with .openmd.css
Preview: Open openmd-preview-themes.html in a browser to see what the 16 themes look like.
Customization: Copy openmd-default.css to your home directory ($HOME/.openmd.css #note the dot), then edit it to your liking.
openmd ships with 16 built-in themes (8 dark, 8 light) selectable from the swatch bar. Automatically loaded from openmd-default.css. To customize further, create an .openmd.css file — it is appended after the built-in CSS so any rule you write overrides the default via normal CSS cascade.
Lookup order (first match wins):
| Priority | Location |
|---|---|
| 1 | Current working directory (./) |
| 2 | openmd install directory |
| 3 | Home directory (~/) |
To make your own CSS themes, add body.theme-yourname { ... } blocks to your .openmd.css. The swatch bar automatically discovers and displays the first 16 themes defined there.
Requirements
- macOS or Linux (POSIX)
- Python 3.10+
- PySide6 + PySide6-WebEngine
- Markdown
- BeautifulSoup4
- PyYAML
Note: Mermaid and KaTeX require an internet connection to load from CDN.
Installation
The easiest way to install openmd (recommended, just two steps):
- Install uv (the fastest Python tool manager):
curl -LsSf https://astral.sh/uv/install.sh | sh
(Windows users: use the same curl command in PowerShell or run winget install astral-sh.uv)
- Install openmd:
uv tool install openmd
That’s it! You can now run openmd like this:
openmd <filename(s)>
###From source
git clone https://github.com/RufusLin/openmd.git
cd openmd
pip install -e .
After this, the openmd command will be available in your shell.
Keyboard shortcuts
| Key | Action |
|---|---|
Esc |
Close the preview window |
↑ / ↓ |
Navigate the sidebar TOC |
← / → |
Move focus between sidebar and display |
Cmd + ← / → |
Navigate among tabs |
Cmd + Shift + < / > |
Change font size |
Return |
Jump to selected heading |
M |
Toggle Meta Panel (YAML front-matter) |
H |
Show Quick Help dialog |
License
MIT
Project details
Release history Release notifications | RSS feed
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 openmd-1.5.2.tar.gz.
File metadata
- Download URL: openmd-1.5.2.tar.gz
- Upload date:
- Size: 24.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
20b6daae32a0519f2768e533b38957e4781a57bde0f13ddb9c8adb400e2f9ae0
|
|
| MD5 |
5fddaa8353eca3894bfa36a149d6375d
|
|
| BLAKE2b-256 |
89be6ef60c234a129f1acf8547953b39feb38f11f7d906f9d622fc9855164b0a
|
File details
Details for the file openmd-1.5.2-py3-none-any.whl.
File metadata
- Download URL: openmd-1.5.2-py3-none-any.whl
- Upload date:
- Size: 25.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fded14dd4eec8f5f4277999e4683218d8b0ebf05eff57b3110d9d8199b58c430
|
|
| MD5 |
cd10dd21cd9f1639a04bf88263d65b0e
|
|
| BLAKE2b-256 |
51229f600c2abf0b827d9059d6880344b46225d8ca96f7ec52081bb949ccc57f
|