Skip to main content

Beautiful markdown viewer and renderer for CLI, CI/CD, and automated workflows

Project description

Markdown Viewer

View, export, and translate markdown files โ€” straight from the terminal

License: MIT Python PyPI Security

Open any markdown file in a full browser UI with one command. Supports PDF and Word export, Mermaid diagrams, math equations, syntax highlighting, and content translation.

[TOC]


๐Ÿ“ฆ Installation

Quick Install (For Technical Users)

pip install markdown-viewer-app
playwright install chromium

playwright install chromium is a one-time setup (~140 MB) required for PDF/Word export. Skip it if you don't need export features.

Step-by-Step Guide (For Everyone)

Step 1: Install Python (if you don't have it)

  1. Go to python.org/downloads and download Python 3.9 or newer
  2. Run the installer โ€” check the box "Add Python to PATH" before clicking Install
  3. Verify by opening Terminal (Mac/Linux) or Command Prompt (Windows) and typing: python --version

Step 2: Install Markdown Viewer

Open your Terminal (Mac/Linux) or Command Prompt (Windows):

  • Windows: Press Windows Key + R, type cmd, press Enter
  • Mac: Press Cmd + Space, type "Terminal", press Enter
  • Linux: Press Ctrl + Alt + T

Then type this command and press Enter:

pip install markdown-viewer-app

Wait for it to finish (you'll see "Successfully installed...").

Step 3: Enable PDF & Word Export (Optional)

If you want to export your markdown files to PDF or Word documents, run this one-time command in the same Terminal/Command Prompt:

playwright install chromium

This downloads browser files (~140MB). It might take a few minutes depending on your internet speed.

Step 4: Verify It Works

In the Terminal/Command Prompt, type:

mdview --version

You should see the version number. You're ready to go! ๐ŸŽ‰

Step 5: Open Your First File

mdview path/to/your/file.md

Replace path/to/your/file.md with the actual path to your markdown file. The file will open in your browser automatically.


๐Ÿš€ Quick Start

# Open a file in your browser
mdview README.md

# Export to PDF
mdview README.md --export-pdf

# Export to Word
mdview README.md --export-word

# Export to both at once
mdview README.md --export-pdf --export-word

# Render to HTML only (no browser โ€” useful for CI/CD)
mdview README.md --no-browser

# Save HTML to a specific file
mdview README.md -o output.html

# Use a custom port (default is 5000)
# Note: Some ports like 6000 are blocked by Chrome - use 5001, 8000, 8080, etc.
mdview README.md -p 5001

# Stop the background server on a custom port
mdview --stop -p 5001

When you run mdview <file>, the app:

  1. Starts a background server on port 5000 (silently โ€” no extra window opens)
  2. Opens your browser directly to the rendered file
  3. Returns you to the terminal immediately

The server keeps running in the background. Subsequent mdview calls reuse it instantly. Use -p/--port to run multiple servers on different ports simultaneously.

Port Selection: Chrome and Edge block certain ports for security reasons. For example:

  • Port 6000-6063: Blocked because they're used by the X11 windowing system (Unix/Linux). Chrome prevents malicious websites from using your browser to attack local X11 services, which could allow screen capture, keystroke logging, or connection hijacking.
  • Port 6665-6669: IRC ports, also blocked for security.

If you see ERR_UNSAFE_PORT, choose a safe port like 5001, 8000, 8080, or 3000. Full list of blocked ports.


๐Ÿ–ฅ๏ธ CLI Reference

mdview [file] [options]

Arguments

Argument Description
file Path to the markdown file to render (optional โ€” prompts interactively if omitted in a terminal)

Options

Flag Default Description
-o, --output <path> (temp file) Save rendered HTML to this path instead of a temporary file
--no-browser off Render without opening a browser window
--keep off Keep the HTML output file after rendering (saved as <filename>.html next to the source)
--export-pdf [path] โ€” Export to PDF; optionally specify an output path
--export-word [path] โ€” Export to Word (.docx); optionally specify an output path
--share-pdf โ€” Export to PDF and open your email client with it attached
--share-word โ€” Export to Word and open your email client with it attached
--browser <name-or-path> (system default) Browser to open (e.g. firefox, chrome, msedge, safari, opera, iexplore). Accepts any name recognised by Python's webbrowser module or a full path to the browser executable
-p, --port <port> 5000 Port for the background Flask server. Note: Chrome/Edge block certain ports for security (e.g., 6000-6063 for X11, 6665-6669 for IRC). Use safe ports like 5001, 8000, 8080, 3000
--stop โ€” Stop the background server and release the port
--version โ€” Print the installed version and exit

Examples

# --- Viewing ---
mdview README.md                        # Open in browser (default)
mdview README.md --no-browser           # Render without opening browser
mdview README.md --no-browser --keep    # Render and save README.html next to the source

# --- HTML output ---
mdview README.md -o docs/out.html           # Save rendered HTML to a specific path
mdview README.md --no-browser -o out.html   # Save HTML, no browser

# --- PDF export ---
mdview README.md --export-pdf               # Export to README.pdf (same directory)
mdview README.md --export-pdf ~/docs/out.pdf  # Export to a specific path

# --- Word export ---
mdview README.md --export-word              # Export to README.docx
mdview README.md --export-word ~/docs/out.docx

# --- Export both at once ---
mdview README.md --export-pdf --export-word

# --- Email sharing ---
mdview README.md --share-pdf   # Export PDF and open email client
mdview README.md --share-word  # Export Word and open email client

# --- Browser selection ---
mdview README.md --browser firefox              # Open in Firefox
mdview README.md --browser chrome               # Open in Google Chrome
mdview README.md --browser msedge               # Open in Microsoft Edge
mdview README.md --browser safari               # Open in Safari (macOS)
mdview README.md --browser opera                # Open in Opera
mdview README.md --browser brave                # Open in Brave (if on PATH)
mdview README.md --browser iexplore             # Open in Internet Explorer
# Full executable path (useful when browser is not on PATH)
mdview README.md --browser "C:/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe"
mdview README.md --browser "/usr/bin/google-chrome"

# --- Server / port management ---
mdview README.md -p 5001       # Open using a custom port
mdview --stop                  # Stop the default server (port 5000)
mdview --stop -p 5001          # Stop a server on a custom port

# โš ๏ธ Note: Some ports are blocked by browsers for security reasons
# Chrome/Edge block port 6000-6063 (X11 windowing system - prevents screen capture/keystroke hijacking)
# Also blocked: 6665-6669 (IRC), and others
# Full list: https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/net/base/port_util.cc
# Use safe ports like: 5001, 5050, 8000, 8080, 8888, 9000, 3000, 4000
mdview README.md -p 8080       # Safe alternative port

# --- CI/CD (non-interactive) ---
# When stdout is not a TTY, browser and server are skipped automatically
mdview README.md -o output.html

# --- Version ---
mdview --version

โœจ Features

๐Ÿ“ Rich Markdown Rendering

  • Full GitHub Flavored Markdown (GFM) support
  • Syntax highlighting for 180+ programming languages
  • Tables, task lists, footnotes, blockquotes, and more
  • Emoji support with correct Unicode rendering

๐Ÿ“Š Diagram Support

  • Mermaid: flowcharts, sequence diagrams, pie charts, Gantt charts, state diagrams
  • Diagrams are preserved in all export formats

๐Ÿ”ข Math Equations

  • KaTeX integration for beautiful math rendering
  • Inline: $E = mc^2$
  • Block equations with full LaTeX syntax

๐Ÿ“„ Export

  • PDF โ€” high-quality, print-ready (powered by Playwright/Chromium)
  • Word (.docx) โ€” editable documents with preserved formatting
  • Silent: no popup dialogs, status bar updates on completion

๐ŸŒ Translation

  • Translate content to 15+ languages directly from the UI
  • Preserves markdown formatting and code blocks
  • Powered by MyMemory (free API, no key needed)

๐Ÿ”’ Security

  • CSRF protection on all API endpoints
  • Content Security Policy (CSP) headers
  • Input validation with Marshmallow schemas
  • Path traversal protection
  • Localhost-only server binding (127.0.0.1)

๐Ÿ“š Frontend Asset Policy (No CDN at Runtime)

  • The Electron renderer does not fetch JS/CSS libraries from external CDNs at runtime.
  • Frontend libraries are vendored locally under markdown_viewer/electron/renderer/vendor/.
  • This avoids CSP connect-src violations, improves reliability in restricted networks, and keeps the UI functional offline.
  • Source map references are stripped from vendored assets to prevent blocked .map fetch noise in the console.
  • When upgrading frontend library versions, update the files in renderer/vendor/ and keep index.html script/style references local.

๐Ÿ”— Local File Navigation

  • Both relative and absolute paths to .md files open the target inside the viewer โ€” no 404s:
    [See also](../other-doc.md)                     <!-- relative -->
    [Changelog](docs/CHANGELOG.md)                  <!-- relative -->
    [Notes](C:\Users\me\Documents\notes.md)         <!-- absolute -->
    
  • File transclusion โ€” embed another markdown file's full content inline using the ![[path]] syntax (Obsidian-style). Both relative and absolute paths work:
    ![[../shared/header.md]]                        <!-- relative -->
    ![[snippets/installation.md]]                   <!-- relative -->
    ![[C:\docs\shared\footer.md]]                   <!-- absolute -->
    
    Transclusions are resolved recursively (up to 10 levels). Images inside embedded files are re-resolved relative to their own location, so they always display correctly.

๐Ÿ–ผ๏ธ Local Image Rendering

  • Images referenced by relative or absolute paths are served securely via the built-in /api/image endpoint
  • Both Windows backslash and forward-slash paths are supported:
    ![Logo](./images/logo.png)                      <!-- relative -->
    ![Chart](../assets/chart.png)                   <!-- relative, parent dir -->
    ![Banner](C:\Users\me\Pictures\banner.jpg)      <!-- absolute, backslash -->
    ![Photo](/home/user/photos/shot.jpg)            <!-- absolute, forward-slash -->
    
  • Remote images (https://) pass through unchanged

๐ŸŒ Browser Compatibility

The viewer UI runs in any modern browser. The --browser flag lets you specify exactly which one to use โ€” useful when a corporate proxy or security policy restricts the default browser:

Browser --browser value Notes
Google Chrome chrome Recommended; best Mermaid and PDF support
Mozilla Firefox firefox Fully supported
Microsoft Edge msedge Fully supported (Chromium-based)
Brave brave or full path Fully supported (Chromium-based)
Opera opera Fully supported
Safari safari Fully supported (macOS only)
Internet Explorer iexplore Basic rendering only โ€” IE does not support ES6 modules; a "Browser Not Supported" notice is shown instead of a broken page
Any other browser Full path to executable Pass the absolute path, e.g. "C:/MyBrowser/browser.exe"

Corporate environments: if the system default browser is locked down (e.g. a hardened Internet Explorer), pass --browser firefox or --browser msedge to open in a modern browser instead.

๐Ÿ› ๏ธ Productivity Tools

  • Copy all content with one click
  • Share via email
  • Keyboard shortcuts: Ctrl+O (open), Ctrl+Shift+C (copy), F5 (refresh), F11 (fullscreen)

๐Ÿ“– Markdown Reference

Basic Formatting

# Heading 1
## Heading 2
### Heading 3

**bold**, *italic*, ~~strikethrough~~, ==highlighted==

- Unordered list
  - Nested item

1. Ordered list

[Link text](https://example.com)
![Alt text](https://example.com/image.png)

Local File Links

Both relative and absolute paths to .md files open the target inside the viewer:

[Changelog](CHANGELOG.md)                        <!-- same directory -->
[Installation guide](docs/INSTALLATION.md)       <!-- subdirectory -->
[Parent README](../README.md)                    <!-- parent directory -->
[Notes](C:\Users\me\Documents\notes.md)          <!-- absolute path -->

File Transclusion (Embed)

Embed the full content of another markdown file inline using ![[path]]:

# My Document

![[shared/header.md]]

## Section 1
...

![[shared/footer.md]]
  • Both relative and absolute paths are supported
  • Relative paths resolve from the current file's directory
  • Transclusions are resolved recursively (up to 10 levels deep)
  • Circular includes are detected and skipped
  • Images inside embedded files resolve correctly relative to their own location

Code Blocks

```python
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
```

```sql
SELECT name, COUNT(*) FROM users GROUP BY name;
```

Tables

| Feature        | Markdown Viewer | Typora | VS Code |
|----------------|:---------------:|:------:|:-------:|
| PDF Export     | โœ…              | โœ…     | โŒ      |
| Word Export    | โœ…              | โœ…     | โŒ      |
| Translation    | โœ…              | โŒ     | โŒ      |
| Diagrams       | โœ…              | โœ…     | โœ…      |
| Free & Open    | โœ…              | โŒ     | โœ…      |

Mermaid Diagrams

```mermaid
graph TD
    A[Start] --> B{Working?}
    B -->|Yes| C[Great!]
    B -->|No| D[Debug] --> B
```

```mermaid
sequenceDiagram
    Client->>Server: Request
    Server-->>Client: Response
```

Math Equations

Inline: $x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}$

Block:
$$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$$

Task Lists

- [x] Install Markdown Viewer
- [x] Open first document
- [ ] Try exporting to PDF

๐Ÿ”ง Development Setup

git clone https://github.com/dimpletz/markdown-viewer.git
cd markdown-viewer
poetry install
poetry run playwright install chromium

Run

# Open a file (server auto-reloads on code changes)
poetry run mdview README.md

# Or start the server standalone
poetry run mdview README.md --no-browser

Tests

# Run all tests
poetry run pytest

# With coverage report
poetry run pytest --cov=markdown_viewer --cov-report=html

Project Structure

markdown-viewer/
โ”œโ”€โ”€ markdown_viewer/
โ”‚   โ”œโ”€โ”€ app.py                # Flask application factory
โ”‚   โ”œโ”€โ”€ routes.py             # API endpoints
โ”‚   โ”œโ”€โ”€ server.py             # Server management
โ”‚   โ”œโ”€โ”€ cli.py                # CLI entry point (mdview)
โ”‚   โ”œโ”€โ”€ electron/             # Browser UI (HTML/JS/CSS)
โ”‚   โ”‚   โ””โ”€โ”€ renderer/
โ”‚   โ”‚       โ”œโ”€โ”€ index.html
โ”‚   โ”‚       โ”œโ”€โ”€ scripts/
โ”‚   โ”‚       โ””โ”€โ”€ styles/
โ”‚   โ”œโ”€โ”€ exporters/            # PDF & Word export
โ”‚   โ”œโ”€โ”€ processors/           # Markdown processing
โ”‚   โ”œโ”€โ”€ translators/          # Translation service
โ”‚   โ””โ”€โ”€ utils/                # File handling
โ”œโ”€โ”€ tests/
โ”œโ”€โ”€ docs/
โ””โ”€โ”€ examples/

๐Ÿ› Known Limitations

  • PDF/Word export requires playwright install chromium (one-time ~140 MB download)
  • Translation requires an internet connection
  • Word export has limited support for complex CSS styling

๐Ÿ“š More Documentation


โ“ Troubleshooting

"How do I open Terminal or Command Prompt?"

Windows:

  1. Press Windows Key + R on your keyboard
  2. Type cmd and press Enter
  3. A black window will open โ€” this is Command Prompt

Alternative: Right-click the Start menu โ†’ choose "Terminal" or "Command Prompt"

Mac:

  1. Press Cmd + Space to open Spotlight
  2. Type "Terminal" and press Enter
  3. A window will open with white text on black background

Linux:

  1. Press Ctrl + Alt + T (works on most distributions)
  2. Or search for "Terminal" in your application menu

"The command 'playwright' is not found"

This usually means the Playwright Python package isn't installed. Playwright is included when you run pip install markdown-viewer-app, but the browser binaries are not.

Fix:

  1. First verify Playwright is installed:

    pip show playwright
    

    If you see version information, Playwright is installed.

  2. If not installed, run:

    pip install playwright
    
  3. Then install the browser:

    playwright install chromium
    

"PDF/Word export buttons are missing in the app"

This means Playwright browser binaries are not installed yet.

You'll see a blue banner at the top of the app with installation instructions. If you dismissed it:

  1. Open Terminal/Command Prompt (see above)
  2. Run: playwright install chromium
  3. Wait for the download to finish (~140MB, takes 2-5 minutes)
  4. Refresh the page (F5 or Ctrl+R)
  5. Export buttons will appear

To test if it worked:

mdview yourfile.md --export-pdf

If the PDF is created successfully, it worked! โœ…

"RuntimeError: Failed to initialize browser"

This error means Playwright browser binaries are missing or corrupted.

Fix:

playwright install chromium --force

The --force flag will re-download even if browsers exist.

"Page.goto: Timeout exceeded"

This can happen if:

  • Your internet connection is slow or unstable
  • External fonts or resources are taking too long to load
  • Browser extensions are interfering

Fixes:

  1. Close unnecessary browser tabs (reduces memory pressure)
  2. Disable browser extensions temporarily
  3. Try again โ€” the second attempt is usually faster
  4. Check your internet connection

If it persists, the export might still work โ€” check if the PDF/Word file was created despite the error message.

"How do I find the path to my markdown file?"

Windows:

  1. Open File Explorer and find your file
  2. Hold Shift and right-click the file
  3. Choose "Copy as path"
  4. Paste into the command: mdview <paste here>

Mac:

  1. Find your file in Finder
  2. Right-click โ†’ hold Option key โ†’ choose "Copy ... as Pathname"
  3. Paste into Terminal: mdview <paste here>

Or just drag the file:

  • Type mdview (with a space at the end)
  • Drag your markdown file into the Terminal/Command Prompt window
  • The path will appear automatically
  • Press Enter

"The app says 'mdview' is not recognized"

This means Python scripts are not in your PATH.

Windows Fix:

  1. Reinstall Python from python.org
  2. Check "Add Python to PATH" during installation
  3. After reinstalling, close and reopen Command Prompt
  4. Try mdview --version again

Mac/Linux Fix:

python3 -m pip install --user markdown-viewer-app

Then use: python3 -m markdown_viewer.cli yourfile.md instead of mdview

"Port 5000 is already in use"

Another program is using port 5000.

Solution 1: Use a different port

mdview yourfile.md --port 8080

Solution 2: Stop the background server first

mdview --stop

Then try again.

"ERR_UNSAFE_PORT in browser"

Chrome/Edge block certain ports for security (e.g., 6000-6063, 6665-6669).

Fix: Use a safe port

mdview yourfile.md --port 8080

Safe ports: 5001, 8000, 8080, 3000, 9000

Still having issues?

  1. Check the Installation Guide for detailed setup steps
  2. Open an issue on GitHub with:
    • Your operating system (Windows 10, Mac, Ubuntu, etc.)
    • Python version (python --version)
    • Full error message
    • What you were trying to do

๐Ÿค Contributing

  1. Fork the repository
  2. Create a branch: git checkout -b feature/my-feature
  3. Make your changes and add tests: poetry run pytest
  4. Open a pull request

๐Ÿ“„ License

MIT License โ€” see LICENSE for details.


๐Ÿ™ Acknowledgments

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

markdown_viewer_app-1.3.7.tar.gz (2.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

markdown_viewer_app-1.3.7-py3-none-any.whl (2.3 MB view details)

Uploaded Python 3

File details

Details for the file markdown_viewer_app-1.3.7.tar.gz.

File metadata

  • Download URL: markdown_viewer_app-1.3.7.tar.gz
  • Upload date:
  • Size: 2.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.4 CPython/3.14.3 Windows/11

File hashes

Hashes for markdown_viewer_app-1.3.7.tar.gz
Algorithm Hash digest
SHA256 1a752e3299aaafb73d2aeb1c80f2d483faf6b5a1122e3604cd64b0c2024dd1f2
MD5 4439e9537556723776d59a7bc11c0ad2
BLAKE2b-256 c0120c6d107e02be377a88d6619cc6de7709104ce6b9dbbbef1bf1f3b58f95dc

See more details on using hashes here.

File details

Details for the file markdown_viewer_app-1.3.7-py3-none-any.whl.

File metadata

File hashes

Hashes for markdown_viewer_app-1.3.7-py3-none-any.whl
Algorithm Hash digest
SHA256 e9a244fa769e7b0a8b41f1d32c1a76820bebb7d4b617fb34d772a701f8b172be
MD5 ac72163a8bc4cea74e539f2e93ccd0c6
BLAKE2b-256 efb79312c4229a6fde0d6c86bd7034c2b2c3adb0db763fc92df6ecd409143306

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page