Variable MD - Document Viewer
Variable MD is a multi-format document viewer following the Navigator-Viewer pattern. It displays Markdown, JSON, code, diffs, and Git views in a tabbed interface.Copy
┌─────────────────────────────────────────────────────────────────┐
│ VARIABLE MD ARCHITECTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ File Explorer (Left Panel) │ │
│ │ │ │
│ │ Projects │ │
│ │ └─ monolex │ │
│ │ ├─ README.md │ │
│ │ ├─ CLAUDE.md │ │
│ │ └─ package.json │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ │ File Click │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Tab Bar │ │
│ │ [README.md] [config.json] [diff-view] [+] │ │
│ │ ↑ active │ │
│ ├─────────────────────────────────────────────────────────┤ │
│ │ Content Area │ │
│ │ │ │
│ │ md Markdown rendered to HTML │ │
│ │ json Syntax highlighted JSON │ │
│ │ diff Side-by-side comparison │ │
│ │ code Syntax highlighted source │ │
│ │ git-* Git viewers (commit, branch, stash) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Supported Viewer Types
Copy
┌─────────────────────────────────────────────────────────────────┐
│ VIEWER TYPES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Basic Viewers │
│ ────────────── │
│ ┌─────────┬─────────────────────────────────────────┐ │
│ │ md │ Markdown to HTML rendering │ │
│ │ json │ JSON with syntax highlighting │ │
│ │ code │ Source code with highlighting │ │
│ │ html │ HTML preview │ │
│ │ diff │ Side-by-side file comparison │ │
│ └─────────┴─────────────────────────────────────────┘ │
│ │
│ Git Viewers │
│ ──────────── │
│ ┌────────────────────┬──────────────────────────────┐ │
│ │ git-diff │ Show file changes │ │
│ │ git-file-history │ File commit history │ │
│ │ git-file-blame │ Line-by-line blame │ │
│ │ git-commit │ Commit details │ │
│ │ git-commit-search │ Search commits │ │
│ │ git-branch │ Branch list │ │
│ │ git-branch-diagram│ Visual branch graph │ │
│ │ git-stash │ Stash management │ │
│ │ git-author-timeline│ Author contributions │ │
│ │ git-project-summary│ Project overview │ │
│ └────────────────────┴──────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Tab Lifecycle
Tabs are created, activated, and closed through a managed lifecycle.Copy
┌─────────────────────────────────────────────────────────────────┐
│ TAB LIFECYCLE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Create Tab │
│ ────────── │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 1. Check max tabs (10) │ │
│ │ 2. Generate unique tab ID │ │
│ │ 3. Create content container │ │
│ │ 4. Set metadata (path, title, type) │ │
│ │ 5. Activate if first tab │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Activate Tab │
│ ──────────── │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 1. Save current tab state │ │
│ │ 2. Hide current container │ │
│ │ 3. Show new container │ │
│ │ 4. Restore new tab state │ │
│ │ 5. Update tab UI │ │
│ │ 6. Emit "tab-activated" event │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Close Tab │
│ ───────── │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 1. Remove container from DOM │ │
│ │ 2. Delete from tabs collection │ │
│ │ 3. Activate last remaining tab │ │
│ │ 4. Update UI │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Smart Tab Reuse
Intelligent logic prevents tab explosion while preserving context.Copy
┌─────────────────────────────────────────────────────────────────┐
│ SMART TAB REUSE LOGIC │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Open File Request │
│ │ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ Force new tab requested? │ │
│ └───────────┬───────────────────┘ │
│ │ │
│ YES ────┴──── NO │
│ │ │ │
│ ▼ ▼ │
│ New Tab ┌───────────────────────────────┐ │
│ │ Same file already open? │ │
│ └───────────┬───────────────────┘ │
│ │ │
│ YES ────────┴──── NO │
│ │ │ │
│ ▼ ▼ │
│ Activate ┌───────────────────────────────┐ │
│ existing │ Active tab is editor mode? │ │
│ └───────────┬───────────────────┘ │
│ │ │
│ YES ────────┴──── NO │
│ │ │ │
│ ▼ ▼ │
│ New Tab ┌─────────────────┐ │
│ (preserve │ Same extension? │ │
│ editor) └────────┬────────┘ │
│ │ │
│ YES ────────┴──── NO │
│ │ │ │
│ ▼ ▼ │
│ Reuse tab Find same- │
│ type tab │
│ or create │
│ new │
│ │
│ Benefits: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Prevents tab explosion │ │
│ │ Groups same-type files │ │
│ │ Preserves editor contexts │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Tab Width Auto-Adjustment
Tabs resize automatically based on available space.Copy
┌─────────────────────────────────────────────────────────────────┐
│ TAB WIDTH ADJUSTMENT │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Constants: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Minimum Tab Width: 80px │ │
│ │ Maximum Tab Width: 200px │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Few Tabs (wide): │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ [ README.md ] [ config.json ] [+] │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ Many Tabs (compressed): │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ [README] [config] [index] [styles] [test] [+] │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ Triggers: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Window resize (debounced 100ms) │ │
│ │ Panel resize (debounced 50ms) │ │
│ │ Tab add/remove │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Terminal Tab Comparison
Variable MD tabs share patterns with terminal tabs.Copy
┌─────────────────────────────────────────────────────────────────┐
│ TAB PATTERN COMPARISON │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Terminal Tab MD Viewer Tab │
│ ──────────── ────────────── │
│ │
│ Manager TerminalTabManager MDViewerTabManager │
│ │
│ Storage Map of tabs Map of tabs │
│ │
│ Active activeTabId activeTabId │
│ │
│ Limit configurable 10 tabs │
│ │
│ Content Live PTY session Static DOM content │
│ │
│ Link sessionId to daemon filePath to filesystem │
│ │
│ ═══════════════════════════════════════════════════════════ │
│ │
│ Key Difference: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Terminal = Real-time process │ │
│ │ MD Viewer = Static content │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Summary
Copy
┌─────────────────────────────────────────────────────────────────┐
│ VARIABLE MD IN ONE PICTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ File Click │
│ │ │
│ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Smart │───▶│ Tab │───▶│ Content │ │
│ │ Reuse │ │ Manager │ │ Render │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │
│ Prevent Track Format- │
│ explosion active specific │
│ state viewer │
│ │
│ Supported Formats: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Markdown JSON Code HTML Diff │ │
│ │ Git: diff, history, blame, commit, branch, stash │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Design Principles Applied: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ SMPC: Tab = id + container + metadata │ │
│ │ OFAC: DOM preserved on tab switch │ │
│ │ Event-driven communication │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘