Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mdview

Read local Markdown and HTML files in a browser tab that stays open.

A Markdown file open in mdview

Point it at a file or a folder and it opens in your browser. A small background server keeps serving that tab after the terminal — or the editor — is closed, so a document you opened once stays readable at a stable URL.

Python standard library only. The rendering libraries are vendored, so it works offline and there is nothing to pip install.

Install

Requires Python 3.8+ on macOS or Linux.

git clone https://github.com/TeaNguyen/mdview.git ~/.local/share/mdview
ln -s ~/.local/share/mdview/mdview.py ~/.local/bin/mdview

Make sure ~/.local/bin is on your PATH, then:

mdview README.md

Optionally, keep the server running across reboots:

mdview autostart        # macOS launch agent; `mdview autostart off` to undo

Usage

mdview notes.md      # open one file
mdview .             # open a folder: every .md / .html inside
mdview               # home page: every folder you've opened

mdview list          # registered folders
mdview rm <path|id>  # forget one
mdview themes        # list themes; `themes new <name>` scaffolds one
mdview status        # is the server up?
mdview stop          # shut it down
mdview autostart     # start the server at login

-n / --no-open prints the URL instead of opening a tab. --port N moves off the default 4111.

Opening a single file registers the folder around it, and the sidebar shows its neighbours. A file already inside a registered folder reuses that folder.

In the browser

Navigation

  • A sidebar tree mirroring the folders on disk. ⌘K filters it, and matches auto-expand their parents. Clicking a folder opens its index; clicking the chevron collapses it. The button in the sidebar header folds every top-level folder at once.
  • The folder index lists subfolders then files, sorted by modified time, newest first. A folder is dated by the newest file anywhere inside it.
  • Every breadcrumb segment above the current one is clickable.
  • Opening anything — from a link, the breadcrumb, or a pasted URL — expands the tree down to it and scrolls it into view.
  • Collapse state is remembered per folder, and ⌘B hides the sidebar.

Reading

  • Live reload: the open file re-renders on save, keeping your scroll position.
  • A table of contents appears at three or more headings, indented by outline depth.
  • The width button cycles narrow (708px) → wide (1000px) → full.
  • Any list item with a nested list can be collapsed, with a count of what is hidden. Folds are remembered per file.
  • p turns the document into slides: headings become slides, an explicit --- breaks them, long lists spill onto continuation slides, and the deck wears whatever theme you're using. ⌘P from there prints one slide per page.
  • Themes, from the menu behind the circle button. See below.
  • A button hands the file to your default app for that file type.

Markdown

GFM (tables, task lists, strikethrough), YAML frontmatter as a property list, GitHub alerts (> [!NOTE], [!WARNING], …) as callouts, syntax highlighting, ```mermaid diagrams, heading anchors, and a copy button on code blocks.

Relative links between Markdown files navigate in place; relative images and other assets are served from the same folder. .html files are shown in an iframe with the same sidebar around them.

Themes

Built in: Auto / Light / Dark, plus Medieval Parchment (aged paper, Luminari headings, a rubricated drop cap), Typewriter (monospace throughout), Nord and Ember. Pick one from the circle button in the top right. The choice is remembered and applied before the page paints. ?theme=<id> on a URL pins one.

Writing your own

mdview themes new "sea glass"    # scaffolds ~/.mdview/themes/sea-glass.css
mdview themes                    # lists what's installed

Edit the file and reopen the menu — no restart. A theme is a stylesheet loaded after mdview's own, with a header comment giving it a name and a light or dark syntax-highlighting scheme:

/* mdview-theme
   name: Sea Glass
   scheme: light
*/

:root {
  --bg: #eef4f2;
  --text: #22403a;
  --accent: #3f8f7d;
  --font-body: "Iowan Old Style", Georgia, serif;
  --doc-size: 17px;
}

The scaffold lists every variable with a comment. In short:

Group Variables
Surfaces --bg --bg-sidebar --bg-hover --bg-active --bg-code --bg-inline --bg-th
Ink --text --text-soft --text-faint --text-inline --border --border-soft --accent
Callouts --note --tip --warn --danger
Type --font-body --font-head --font-ui --font-mono --doc-size --doc-leading --head-weight --head-case --head-spacing --title-size

A theme is plain CSS and can restyle anything: the parchment theme paints a paper texture on body and a drop cap with .doc > p:first-of-type::first-letter. A file named after a built-in (dark.css, parchment.css) replaces that theme instead of adding one.

Odds and ends

  • Tabs outlive the terminal that opened them, the editor, and — with mdview autostart — a reboot.
  • mdview rm a folder, then reload a tab you left open on it: the folder comes back. Every folder ever opened is remembered.
  • Nothing is fetched at read time. Mermaid alone is 3.2 MB of the 3.9 MB repo and loads only on pages that actually draw a diagram, so diagrams render on a plane.
  • Collapsed bullets are remembered by their text rather than their position, so editing elsewhere in the file doesn't shuffle your folds.
  • mdview . in a repo gives you every README in it, in one tree.
  • The parchment theme opens a page with a red drop cap, the way a scribe would.
  • One command, one URL, no flags to remember — easy to hand to an AI agent: mdview path/to/file.md.

Configuration

Variable Default Effect
MDVIEW_PORT 4111 Port the server binds on 127.0.0.1. Also --port N.
MDVIEW_EDITOR unset App to open files with, instead of the system default.

Both are read by the server process. Set them before it starts:

mdview stop
MDVIEW_EDITOR="Visual Studio Code" mdview .

State lives in ~/.mdview/: roots.json (folders in the home list), known.json (every folder ever opened), themes/ (your themes), and server.log.

Notes and limits

  • Binds 127.0.0.1 only. Nothing is exposed to the network.
  • POSTs that change state — registering a folder, opening a file in an app — are refused when they carry a foreign Origin. Files can only be opened from inside a registered folder, and paths are checked against it.
  • .html files run their own scripts in the iframe, served from the same origin. Don't point mdview at HTML you don't trust.
  • Folder scans skip hidden directories, node_modules, dist, build, venv and similar, and stop at 4000 files or 8 levels deep.
  • mdview autostart is macOS only. Everything else works on Linux; Windows is untested.
  • It renders; it never writes to your files.

License

MIT — see LICENSE.

Vendored libraries under assets/vendor/ keep their own licences: marked (MIT), DOMPurify (Apache-2.0 OR MPL-2.0), highlight.js (BSD-3-Clause), mermaid (MIT).

About

Read local Markdown and HTML files in a browser tab that stays open

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages