Repository navigation
Releases: stpork/mdvu
Releases · stpork/mdvu
Release list
mdvu v0.4.1
Fixed
- Snapshot mode uses the primary display so changing the active monitor does not change screenshot rasterization.
- TOC and in-document anchor navigation on local files: a
history.pushState/replaceStateSecurityError no longer prevents scrolling. Native navigation history continues to track the jump. - Clicking an already selected TOC item returns to its heading after manually scrolling away; keyboard selection remains supported.
- WebKit regression tests return explicit JavaScript values, avoiding the nil-result async bridge crash observed on the macOS 14 GitHub runner.
- The one-screen fixture test resolves its path relative to the checkout instead of silently skipping outside a developer's machine.
- CLI and About fallback versions match 0.4.1; the About source-tree plist lookup uses the repository root.
Changed
- Both pane headers share an icon/title/close layout; the TOC × button hides its pane through the existing toolbar/menu toggle.
- Left pane now contains only the table of contents; the right file navigator offers Tree / List modes with a shared view and synchronized document selection.
- Opening a folder shows its recursive list on the right and keeps that folder as the navigation root. Removed the duplicate left file table, directory scan and relative-path storage.
- List scanning runs on a shared bounded background queue. Mode changes release inactive models; obsolete scans cancel, and window teardown releases the navigator. Tree and list skip packages and directory symlinks.
- TOC regression coverage verifies actual scroll position for both push and replace navigation and handles missing targets.
- CI preserves test output as an artifact even on failure and limits the job duration.
- README and architecture documentation distinguish measured parser throughput, WebKit's separate processes, advisory cache limits, and hardware-dependent UI performance.
- Drained temporary Foundation buffers after parsing/decompression, captured only dialect metadata in queued UI completion, and consolidated compressed resource loading without removing its LZFSE fallback.
- Retained optimized release flags, WebView prewarming, shared SVG cache, lazy LZMA resources, and all parser/diagram features.
Validation
- 64 tests passed, including navigator selection, scan cancellation, inactive model release and navigator lifetime. Real TOC clicks, including re-clicking after manual scrolling, verified in the installed 0.4.1 build.
- Universal visual regression passed for
test-complete.mdandtest-onescreen.md(normalized RMS 0.00000 / 0.00148); references updated only for the requested TOC icon/title/close header; comparison tolerances unchanged. - arm64, x86_64 and Universal ZIPs plus Universal DMG built; ad-hoc signature and all SHA-256 sidecars verified.
- Native arm64 parser benchmark: five iterations after warmup using repetitions of
test-light.md; medians for 1/5/10/25 MiB were 61.57/309.04/617.67/1556.82 ms. These measure parsing, not DOM rendering, scrolling or diagram execution. - Native executable: 720,240 bytes; native/Universal app disk allocation: 3,488/4,272 KiB. ZIP sizes: arm64 3,114,687 bytes, x86_64 3,145,820 bytes, Universal 3,431,673 bytes; DMG 3,800,779 bytes. Signing and packaging metadata can change subsequent archive sizes.
- Measurements do not establish fixed FPS, zero leaks or the minimum possible size. WebKit uses auxiliary processes and cache limits are advisory.
mdvu v0.4.0
Added
- Obsidian-Style File & Vault Navigator Pane (
⌥⌘D):- Integrated collapsible right-hand file navigation pane with hierarchical tree view (
VaultNavigatorView,VaultOutlineView). - Automatic vault root detection (
VaultScanner.findVaultRoot): intelligently scans up the folder hierarchy for.obsidianor.gitboundaries (up to 20 levels), anchoring the vault tree at the true repository or knowledge base root. - On-demand lazy scanning (
loadChildrenIfNeeded): child directories are scanned only when expanded, keeping memory and CPU footprint near zero even in vaults with thousands of Markdown notes. - Auto-reveal and selection: opening or switching documents automatically expands parent folders and highlights the active file.
- Native keyboard navigation: Return/Enter key opens files or expands/collapses folders; double-click toggles directories; single-click opens notes.
- CLI flag
--navigator: launch directly with the navigator pane open (mdvu --navigator <path>).
- Integrated collapsible right-hand file navigation pane with hierarchical tree view (
- Push-On / Push-Off Toolbar Button States:
- Table of Contents (
Contents) and File Navigator (Navigator) toolbar buttons use textured.pushOnPushOffstyles that stay visually depressed when their corresponding panes are active. - Synchronized across keyboard shortcuts (
^⌘S,⌥⌘D), menu items (View → Show/Hide Table of Contents,View → Show/Hide File Navigator), and toolbar clicks.
- Table of Contents (
- Dynamic Back / Forward Toolbar Button Validation:
- Segmented history navigation control in the toolbar dynamically enables or disables individual segments based on
navigationHistory.canGoBackandnavigationHistory.canGoForward, providing clear visual state and eliminating dead clicks.
- Segmented history navigation control in the toolbar dynamically enables or disables individual segments based on
Changed
- Adaptive 3-Pane Split View Coordinator:
- Unified
rebuildSplitSubviews()managing 1, 2, or 3 panes ([sidebarContainer, webView, vaultNavigatorView]) inside an autoresizingNSSplitView. - Configured split view holding priorities (
.defaultLowfor document web view,.defaultHighfor sidebars) so window resizing gracefully stretches the document reading area. - Available width clamping: prevents navigator or sidebar from squeezing the Markdown document web view below 200px.
- Unified
- CLI Flag Filtering in Application Delegate:
AppDelegate.application(_:openFiles:)filters out CLI flags (e.g.--navigator,--snapshot) so external launch events or drag-and-drop operations do not treat command options as document paths.- Suppressed modal
NSAlertdialogs during--snapshotruns, piping error messages tostderrto prevent headless execution hangs.
- Vault Tree Enumeration Performance:
- Optimized
VaultScanner.scanChildrento consume cached kernel metadata ([.isDirectoryKey]) fromcontentsOfDirectory, eliminating redundantstatsystem calls for every child entry. - Standardized canonical URLs upon initialization in
VaultItem, eliminating repetitive path canonicalization during tree lookups and equality checks.
- Optimized
- Asynchronous Runtime Decompression & Diagram Bridge:
- Moved heavy LZMA decompression of KaTeX, Mermaid, and PlantUML JavaScript bundles off the main UI queue to
DispatchQueue.global(qos: .userInitiated), eliminating UI stutters when loading diagram-rich documents. - Replaced synchronous JavaScript evaluation with
callAsyncJavaScriptwithawait window.__mdvuRenderDiagrams?.(), ensuring WebAssembly/Mermaid rendering completes before declaring render completion or capturing snapshots.
- Moved heavy LZMA decompression of KaTeX, Mermaid, and PlantUML JavaScript bundles off the main UI queue to
- Shared Memory Diagram Cache:
- Unified in-memory diagram SVG cache across all open windows with a shared
NSCacheinstance capped at 16 MB.
- Unified in-memory diagram SVG cache across all open windows with a shared
- Universal Binary Flag Synchronization:
build-universal.shnow consumes release compilation flags directly fromMakefile(print-release-flags), guaranteeing matching optimization levels across native and universal builds.
Fixed
- Window Expansion on Navigator Toggle:
- Replaced Auto Layout constraints on
splitwith frame-based bounds and autoresizing masks (split.frame = dropView.bounds,autoresizingMask = [.width, .height]), eliminating AppKit fitting-size accumulation that previously caused the window to expand horizontally beyond the screen boundaries.
- Replaced Auto Layout constraints on
- Clean Pane Removal & Subview Stretching:
- Added
split.adjustSubviews()upon closing the navigator or sidebar pane, ensuring the remaining views immediately and smoothly reclaim 100% of the window width without leaving empty residual view space.
- Added
- Search & Heading Anchors Unicode Hygiene:
- Fixed Unicode string-length distortion in text search by replacing
toLocaleLowerCase()with Unicode-aware regular expression (RegExp(..., 'giu')) coordinates, accurately highlighting matches in international text (e.g. Turkishİstanbul). - Guaranteed unique heading anchor IDs via duplicate detection set in
app.js, eliminating ambiguous anchor navigation for identically named headings.
- Fixed Unicode string-length distortion in text search by replacing
- File Watcher Reconnection & Recovery:
FileWatcherindefinitely re-arms on.mainqueue every 250 ms until replaced or renamed files reappear, surviving delayed atomic saves and delivering modification events without dropping watch descriptors.
- Window Controller Lifecycle & Teardown Protection:
- Added idempotent
isTornDownguard andrenderGeneration == generationvalidation inDocumentWindowController, stopping background work, cancelling pending find operations, and dropping WebKit navigation delegates upon window closure.
- Added idempotent
- Fenced Code TOC Literal Protection:
- Enclosed GitLab TOC processing in
CodeFenceScanner.processto ensure[TOC]or[[_TOC_]]inside code blocks remain literal examples and are not transformed into HTML placeholders.
- Enclosed GitLab TOC processing in
- Navigation History Scroll Ratio Synchronization:
- Added
recordScrollRatio(_:at:)to record scroll positions into explicit history indices, preventing delayed scroll capture callbacks from pushing duplicate history entries.
- Added
mdvu v0.3.2
Added
- Automatic Dialect Option & Document State Reset:
- Added
Automaticoption toView → Dialectmenu, allowing dynamic frontmatter and comment directive detection while retaining menu fallback. - Switching or opening documents now automatically resets manual dialect overrides to the document's detected default, unless
--dialectwas explicitly passed via CLI.
- Added
Changed
- Linear Callout Scanner & Pipeline Throughput:
- Replaced regular expressions in callout block processing with linear bounded scans and literal string matching, reducing callout postprocessing time by ~8.5x.
- Pipeline throughput boosted to 16.5 – 52 MB/s (~52 MB/s on standard documentation, ~16.5 MB/s on rich multi-extension fixtures).
- Optimized extension pre-checks with hardware-accelerated
FastScan.count(..., atLeast:)using SIMDmemchr, skipping heavy sub/superscript and math passes when fewer than 2 delimiter tokens exist. - Admonition line parser handles CRLF (
\r\n) line breaks cleanly without premature block termination.
- Documentation & Benchmark Comparison:
Fixed
- CriticMarkup Tooltip Attribute Escaping:
- Escaped user comment text in
CriticMarkupExtensiontooltip attribute (HTML.escapeAttribute) to prevent HTML attribute breakouts.
- Escaped user comment text in
- Obsidian 4-Backtick Fence Handling:
- Added fence length and character tracking to prevent 4-backtick code blocks (
````) from being prematurely terminated by inner 3-backtick sequences (```).
- Added fence length and character tracking to prevent 4-backtick code blocks (
- Window Title Markup Leaks:
- Document title extraction from
<h1>elements now strips nested HTML tags and decodes entities, preventing raw markup from leaking into the macOS window title.
- Document title extraction from
- Entity Unescaping with Standalone Ampersands:
- Fixed pointer-advancing logic in
HTML.unescapewhen standalone ampersands are present without valid entity codes.
- Fixed pointer-advancing logic in
mdvu v0.3.1
Added
- Application Menu Dialect Switcher (
View → Dialect):- Integrated
Dialectsubmenu in macOS View menu offering:Generic (CommonMark)GitHub (GFM)Obsidian
- Active dialect displays checkmark state (
NSControl.StateValue.on). - Selecting a dialect immediately re-renders the document and preserves scroll ratio.
- Integrated
- Automated Dialect Detection (YAML Frontmatter & Directives):
- Added
MarkdownDocumentDirectiveparser that scans:- YAML frontmatter keys:
dialect,markdown-dialect,markdown_dialect,mode(supportingobsidian,github,gfm,generic,commonmark). - Top-of-file HTML comment directives (e.g.
<!-- dialect: obsidian -->,Run: mdvu --dialect obsidian,Open in Obsidian dialect).
- YAML frontmatter keys:
- Dynamic hierarchy: explicit CLI
--dialectand explicit user menu selection override document directives; default.genericallows document directives to activate automatically.
- Added
- Preservation of Raw
<style>Elements:<style>...</style>blocks in Markdown are preserved during sanitization instead of being escaped as literal text, allowing custom single-page layouts, showcase templates, and responsive stylesheets to render as intended.<script>elements and event handler attributes remain strictly disarmed.
- Showcase Fixture & High-Resolution Snapshot:
- Added
test-onescreen.mdfixture validating multi-column card presentations, native MathML, embedded base64 wiki-embeds, and diagram pipelines. - Added
Tests/Snapshots/MDVu.jpghigh-resolution showcase screenshot linked inREADME.md.
- Added
Changed
- Compiler Intermediate Hygiene:
- Thin LTO
.bcbitcode files generated during release and benchmark compilation are isolated insideTests/and ignored by git, eliminating root-level workspace clutter.
- Thin LTO
- Temporary Render Lifecycle:
- Unique PID-scoped temporary directory for rendered HTML documents with automatic cleanup on document close and application shutdown.
mdvu v0.3.0
Added
-
Native LaTeX Formula Support (KaTeX + WebKit MathML):
- Full offline rendering for inline (
$...$) and display ($$...$$andmath,latex,katexblocks) mathematical formulas. - Translated client-side via embedded LZMA-compressed KaTeX engine (~64 KB) into native WebKit MathML Core markup.
- 100% offline with zero font download delays, dark/light theme integration, and crisp Retina scaling.
- Full offline rendering for inline (
-
Hardware-Vectorized FastScan:
- Replaced Swift
String.contains("...")pre-checks with POSIXmemchrandmemmembyte-matching routines. - Bypasses grapheme cluster normalization on multi-megabyte documents, delivering a 30x–800x speedup in extension pre-checks.
- Replaced Swift
-
Linear
$O(N)$ Streaming Math & Code Fence Scanner:- Single-pass cursor scanning that natively skips inline code spans (
`...`) and escaped backslashes (\$) without token replacement arrays. - Streaming
CodeFenceScannerreplaces memory-heavy string splitting for fenced code blocks.
- Single-pass cursor scanning that natively skips inline code spans (
-
Startup Pipelining (
EagerDocumentLoader):- Detached background reading and parsing launched immediately upon CLI invocation, running concurrently with AppKit runloop and window initialization.
- Continuous WebKit prewarming keeps subsequent document windows instant.
-
Zero-Leak Memory & Lifecycle Hygiene:
-
WeakScriptMessageHandlertrampoline breaks the hiddenWKUserContentControllerretain cycle. - Decoupled background rendering in
DocumentWindowControllercaptures only immutableMarkdownPipelinestate, eliminating controller retain across background parse tasks. - Deterministic
tearDown()andFileWatcher.invalidate()cancel GCD dispatch sources, debounce timers, and close file descriptors immediately upon window close. -
DiagramCachememory cache bounded strictly to 16 MB.
-
-
Corporate & Non-Admin Installation:
-
make installand Homebrew cask automatically detect write permissions on/Applications, installing withoutrootor falling back seamlessly to~/Applications.
-
-
GitHub Actions CI Pipeline:
- Automated continuous integration on native Apple Silicon
macos-14(M1) runners with Xcode 16. - Validates full test suites, release builds, binary stripping and sizes, streaming throughput benchmarks, universal lipo binaries, and artifact generation.
- Automated continuous integration on native Apple Silicon
-
Full Fixture Coverage & Torture Testing:
- Audited and activated 100% of test fixtures in
Tests/Fixtures/:test-light.md(109 KB),test-medium.md(174 KB),test-complete.md(228 KB), andtest-heavy.md(1.65 MB). - Added torture test verifying
test-heavy.md(13,916 lines, 324 Mermaid diagrams, 1,100 headings, multi-script Unicode) parses end-to-end in 0.35 seconds. - Expanded
test-complete.mdwith sections 19–23 covering 120 content-cases: formulas inside tables, blockquotes, callouts, CriticMarkup, false-positive currency protection, and isolated security fixtures (Tests/Fixtures/runtime/). - Programmatic verification suite (
testAllMathCasesInFixture) asserting all 42 LaTeX formula cases. - Extended math code fence scanner to support CommonMark tildes (
~~~math) and multi-backtick (math) fences with variable indentation. - Unit and integration suite expanded to 43 tests executing in < 0.8 seconds with > 92% line coverage on core rendering modules.
- Audited and activated 100% of test fixtures in
Changed
- Compiler Optimization:
- Updated release build configuration to
-O -cross-module-optimization -disable-reflection-metadata -disable-reflection-names -dead_strip -dead_strip_dylibs. - Stripped single-arch binary is 638 KB; entire
.appbundle is 3.3 MB (including KaTeX, Mermaid, PlantUML).
- Updated release build configuration to
- Throughput & Latency Gains:
- Parsing throughput boosted from 3.0 MB/s to 14.3+ MB/s (~4.8x faster on large documents; 1 MB in 70 ms, 25 MB in 1.77 s, 44 KB real-world documents in 4.97 ms).
mdvu v0.2.0
Added
- Ultra-Fast Native Architecture: Built with pure AppKit and WebKit. Zero Electron, zero Node runtime, zero telemetry, and 100% offline. Cold start in ~150 ms, first paint in ~300 ms, with an ultra-compact 3.2 MB app bundle (4.2 MB Universal, ~2.2 MB compressed release archive). Stripped Mach-O binary is 572 KB.
-
High-Throughput Markdown Engine: Powered by Apple/GitHub's reference
cmark-gfmwith full CommonMark and GitHub Flavored Markdown support (tables, task lists, autolinks, and strikethrough). High throughput of 4.5+ MB/s (~35 ms for 4,600+ line documents). -
Comprehensive Markdown Ecosystem Support:
-
Obsidian: Callouts (
[!NOTE],[!TIP],[!WARNING],[!DANGER],[!CAUTION],[!INFO],[!SUCCESS], etc.), expandable/foldable callouts ([!...]+/[!...]-),[[wikilinks]]with aliases and block references, and media embeds (![[embed]]). -
Admonitions & Containers: MkDocs syntax (
!!!,???,???+) and Docusaurus/VuePress colon containers (:::note,:::tip,:::warning,:::danger,:::) mapped cleanly to native callouts. -
CriticMarkup: Full editorial review syntax for additions (
{++add++}), deletions ({--del--}), substitutions ({~~old~>new~~}), highlights ({==mark==}), and reviewer comments ({>>comment<<}). -
Subscript, Superscript & Underline:
~sub~(strictly guarded against GFM~~strikethrough~~),^sup^, and^^underline^^. -
GitLab Markdown: Table of Contents tokens (
[[_TOC_]]and[TOC]). - YAML FrontMatter: Extracted into clean, readable document metadata tables.
-
Safe HTML & XSS Prevention: Built-in
tagfilterdisarming malicious elements while preserving presentation tags (<details>,<summary>,<b>,<u>,<sub>,<sup>). -
Code Fence Protection:
CodeFenceProtectorshields all 3-backtick, 4-backtick, and tilde blocks from transformation.
-
Obsidian: Callouts (
-
Offline Diagrams (Mermaid 11.17.2, ZenUML 0.2.3 & PlantUML 1.2026.7):
- Bundled Mermaid 11.17.2 supporting all standard and beta grammars (including all five C4 models, fishbone, swimlanes, and ZenUML sequence diagrams).
- Bundled PlantUML Core 1.2026.7 with WebAssembly Graphviz (Viz.js 3.24.0) via TeaVM—100% offline with zero Java requirement, supporting both
plantuml`` andpuml`` code fences. - Frame-budgeted diagram batching (16 ms time slices) preventing UI lockup on documents with hundreds of diagrams.
- Automatic error recovery and syntax resilience (including unquoted hyphen handling in
requirementDiagram). - On-demand lazy decompression and SHA-256 SVG disk caching.
-
Standardized 120 FPS Zoom Subsystem: Compound
[-][ 100% ][+]toolbar control featuring:- Smooth, real-time continuous trackpad pinch (
.magnify) via hardware-accelerated CoreAnimation layer scaling. - Magnetic snapping (
$\pm 2.5%$ ) eliminating jitter and presentation rounding errors (e.g.201%$\to$ 200%). - Bounce-back settling engine via trailing spring timers (50 ms, 150 ms, 300 ms) ensuring clean return to exact 1.0 (100%).
- Discrete 10% stepping with automatic snapping from fractional gesture levels.
- Manual percentage input field bounded strictly between 10% and 500%.
- Double-click to instantly reset zoom to 100% (
⌘0). - Persistent window zoom across document reloads, navigation history, and link jumps.
- Smooth, real-time continuous trackpad pinch (
-
Document Titlebar Quick-Open: Click directly on the filename in the window title to summon an
NSOpenPanelmodal sheet to switch files or folders within the current window, while preserving macOS proxy icon dragging and⌘-clickfolder hierarchy popups. -
Two-Finger Navigation & Content Panning: Intelligent trackpad gesture routing—two-finger horizontal swipes navigate Back and Forward when history is available, and automatically transition to smooth horizontal panning when zoomed in (
> 105%) over wide tables and code blocks. -
In-Page Search (
⌘F): Instant keyword search with live match counters, highlighting, and smooth cycling (⌘G/⇧⌘G). -
Full Width Mode (
⇧⌘W): One-key toggle between readable typographic measure (920px max-width) and fluid edge-to-edge layout. - Atomic File Watching: Live automatic reload on document save, supporting atomic file replacements in Vim, Xcode, and VS Code while preserving scroll position.
-
Headless PNG Snapshot (
--snapshot): Fast command-line renderer for automation and visual regression testing. -
Homebrew Cask Distribution: Prepared automated tap packaging for
stpork/homebrew-tap(Casks/mdvu.rb).