Portable Markdown Viewer with Live-Reload and Multi-Engine Swap
Project description
PMDV (Portable Markdown Viewer)
PMDV (Portable Markdown Viewer) is a self-contained, offline-compatible, and portless Markdown viewer desktop application. It features a native desktop GUI shell with dynamic parser engine hot-swapping, evolutionary math rendering, and direct file modification watching.
1. Scientific Domain & Technical Overview
A. Markdown Abstract Syntax Tree (AST) Formulations
Markdown parsing is modeled as a deterministic sequence transformation translating a raw character stream into a structured Abstract Syntax Tree (AST), which is subsequently compiled into Document Object Model (DOM) nodes:
$$\text{Raw Text Stream} \xrightarrow{\text{Lexical Analysis (Tokenization)}} \mathbf{T} \xrightarrow{\text{Syntactic Analysis (AST Parsing)}} \mathcal{A} \xrightarrow{\text{Compilation}} \text{HTML String}$$
Where the AST $\mathcal{A}$ is a tree hierarchy of nodes:
$$\mathcal{A} = (N, E), \quad N = {n_{\text{root}}, n_{\text{header}}, n_{\text{paragraph}}, n_{\text{code}}, \dots}$$
PMDV hosts multiple parsing engines, allowing runtime functional mapping hot-swapping to guarantee render rendering parity across dialects:
$$\text{Viewport}(\mathbf{x}) = f_{\text{engine}}(\mathbf{x}), \quad \text{engine} \in {\text{Marked.js}, \text{Markdown-it}}$$
B. WebView2 Sandboxing & LocalStorage Virtualization
Operating within an about:blank local sandbox context triggers strict security constraints. Under Chromium and Edge WebView2 security policies, writing or reading from browser-persistent storage throws a blocking SecurityError:
$$\text{Access}(\text{localStorage}) \rightarrow \text{SecurityError} \quad \text{if } \text{Origin} = \text{about:blank}$$
To prevent main-thread execution crashes, PMDV virtualizes the Web Storage API by wrapping accesses using a dynamic in-memory fallback block:
$$\mathcal{S}_{\text{virtual}} = { \text{getItem}(k) \mapsto \mathbf{M}[k], \quad \text{setItem}(k, v) \mapsto \mathbf{M}[k] \leftarrow \text{str}(v) }$$
Where $\mathbf{M}$ is a volatile JavaScript Object map bypassing disk persistence entirely.
C. IPC Bridge & Race Condition Prevention
To prevent script loading racing conditions, PMDV decouples data injection from document instantiation. Staging initial data during DOM parsing when compilation of external scripts (e.g., Prism.js, KaTeX) is incomplete leads to compilation failure:
$$\text{Race Condition: } t_{\text{render}} < t_{\text{script_compile}} \implies \text{TypeError: } \text{marked is not defined}$$
PMDV orchestrates a thread-synchronized load callback:
$$\text{WindowReady} \xrightarrow{\Delta t \ge 300\text{ms}} \text{IPC EvaluateJS} \xrightarrow{} \text{window.updateFromServer}(\text{Payload})$$
2. Core Features
- Serverless & Portless GUI: Eliminates local TCP port bindings. No port conflicts ($10048$) and no background zombie server processes.
- 100% Offline Compatible: Bundles layout (
github-markdown-css), syntax highlight (prism-js), and typesetting (katex) directly inside a single compiled artifact. - Dynamic Watcher Thread: Utilizes native OS filesystem watches (
os.path.getmtime) combined with WebView IPC messaging to dynamically refresh views. - Open Local File & Drag-and-Drop: Load any local markdown document dynamically from the sidebar or by dragging a file directly into the application window.
- Interactive Console Debugging: Double-click or right-click to inspect components using WebKit/Edge Developer Tools directly (
debug=True).
3. Operational Harness
Option A: Local Run (Python Environment)
- Initialize Virtual Environment:
python -m venv .venv .venv\Scripts\activate # On Windows source .venv/bin/activate # On Linux
- Install Dependencies:
pip install -r requirements.txt
- Execute Viewer:
python pmdv/pmdv/viewer.py <path-to-markdown-file>
Shell Alias Auto-Setup (Linux/macOS)
Register pmdv as a global command in your terminal session:
eval $(python3 pmdv/pmdv/viewer.py --init)
Option B: Standalone Binary Compilation (Portable Mode)
If Python is not present on target offline host machines, compile to a native executable beforehand:
- Assemble Embedded Assets:
python downloader.py - Compile with PyInstaller:
python build.py - Execute Standalone Output:
./dist/mdviewer.exe sample.md # Windows ./dist/mdviewer sample.md # Linux
4. Architecture Map
graph TD
CDN[CDN Repositories] -->|downloader.py| V_PY[viewer.py Source]
V_PY -->|build.py + PyInstaller| BIN[mdviewer.exe Portable GUI]
subgraph Runtime_Execution ["Runtime Execution (Portless & Threaded)"]
BIN -->|Option B: Executable| APP[pywebview App Window]
V_PY -->|Option A: Python Script| APP
subgraph Python_Process ["Python Process"]
APP -->|Creates| WIN[WebView2 UI Shell]
Watcher["File Watcher Thread"] -->|Polls getmtime| FS["Local Filesystem"]
Watcher -->|Direct IPC: evaluate_js| WIN
end
end
Directory Structure
.
├── pmdv/ # Core package directory
│ ├── pmdv/
│ │ ├── __init__.py # Package initializer
│ │ └── viewer.py # Main GUI Application Source
│ ├── README.md # Technical User Manual
│ ├── requirements.txt # Runtime dependencies (pywebview)
│ └── setup.py # Setuptools distribution spec
├── build.py # Compiler packaging automation script
└── downloader.py # Assets assembler and bundler script
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 pmdv-1.0.0.tar.gz.
File metadata
- Download URL: pmdv-1.0.0.tar.gz
- Upload date:
- Size: 1.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f9eaf7c2caa0780af702c62d558cf78093e303e0659ed49f7b6b56d58452f9d
|
|
| MD5 |
df5fa27055f812be391e3f90fbe222b0
|
|
| BLAKE2b-256 |
5727d8350642d64c557a7b00ce1c935709fe30bdd9475b113ce00d7a18c6ac01
|
File details
Details for the file pmdv-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pmdv-1.0.0-py3-none-any.whl
- Upload date:
- Size: 1.0 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a977eac6e46c31c944b46f20d02defbdce2fd2153376e53f76a037f0951c3c4
|
|
| MD5 |
0a33c9af2fc7580db1f4f3fecb5df2a8
|
|
| BLAKE2b-256 |
4e7bb601969627bcdcc3a278b085423efbaa61a01ca3aa005fb2823ca126028c
|