Repository navigation
0.1.10 - 2026-10-01
Release Notes
This is a hardening release: hostile-input fuzzing removed panics in parsing, incremental reparse, download date/max-age handling and raw HTML scanning, and shaping no longer hangs on an extreme font size. Desktop readers also get a full-size image viewer, wheel-scrolled option lists and per-role font selection, while the WebAssembly front end stays in-progress groundwork.
Added
- Add host-managed asynchronous MVaaC image requests with viewport priorities, cancellable RGBA delivery, progressive reflow and opt-in browser URL/decode helpers.
- Keep an open option list inside the panel that owns it and cap its width at the panel's, so a list never overflows the window.
- Scroll an open option list with the wheel: wherever the pointer rests, one notch of travel moves the highlight one option, a trackpad's pixel travel accumulates to that notch, and a list longer than its window draws its own scrollbar.
- Open a full-size viewer over any image: click to open, wheel or glide to zoom about the pointer, drag to pan, click or Escape to close.
- Add
markview-selection, the pointer-driven selection machine taken out ofInteractionState, so a second front end can drive the same grains, click counting and drag rules. - Cover the selection paths that had no test: what a copy takes, the drag-past-edge auto-scroll tick, the deferred
Ctrl+A, and carrying a selection across an update. - Let a host with no filesystem supply its own faces as bytes through
FontConfig::from_faces, so the shaper can be driven from a front end that has no directory to scan. - Add
markview-web, awasm-bindgenfront end that lays Markdown out with the engine and paints it into a<canvas>, with pointer selection, clipboard copy and layout budgeted across frames. - Add the MVaaC canvas demo under
web/: a textarea feeds Markdown to the WebAssembly module, with a Playwright acceptance suite that checks rendering, incremental re-layout and copy. - Add
scripts/check_web_font_coverage.py, which reports the characters of a document that none of the bundled subset faces can draw. - Add
ProgressiveLayout, a layout pass that suspends between blocks and resumes without re-measuring what it already laid out, so a front end can bound each step by a time budget. - Add the
@markview/webTypeScript package and a pnpm monorepo underweb/, bundling the WebAssembly front end into a reusable component with a progressive layout handle and a very thin demo app. - Choose the family of each font role — serif, sans-serif, monospace and the same three for Han text — from a Set fonts step beside the Fonts page's catalogue filters, one chooser row per role: a pick reflows the document at once and persists as a per-role
fontdefoverride, and the Han rows appear only for thecjk-typevariant in force, offering only the families that cover Han text. - A
cargo-fuzzharness for the library crates (fuzz/, not part of the root workspace): eleven targets covering parse, incremental reparse, MVSS, layout, progressive layout, math, highlight, shaping, fonts, PDF export, and render geometry, with structure-aware mutators, calibrated per-input wall and allocation budgets, and spec-derived seed corpora. Afuzz-onlyprewarm_highlightAPI lets the harness pay the syntax-highlight warm-up before its input budgets start.
Changed
- Point the Comrak patch at upstream again, now carrying the fence-offset fix and the multiline inline source-position fix.
- Align publishable web package versions with Markview and synchronize them during releases.
- Load MVaaC text fonts from host URLs or bytes during initialization; the esbuild demo emits separate font assets, while KaTeX stays embedded in wasm.
- Share document hover, cursor, scrolling and gesture inertia between desktop and Web; Web adds host activation callbacks, anchors, details and selectable scroll motion ownership, defaulting to internal wheel easing.
- Route Windows fractional wheel events through ordinary wheel easing, removing the touchpad-specific packet momentum path pending a new adaptation.
- Share one cancellable native download service and CPU budget across images and fonts, with owned progress events and transactional installation.
- Version pixel lookups and frame demand, move eviction outside cache locks, and wake layout through a shared latest-request mailbox.
- Bound background CPU work by queue size and retained inputs; cancel obsolete highlight epochs and wake owners after completion.
- Own diagram face metrics under one lock and share reclaimable font names; reject chooser selections from retired catalogues.
- Drive
layout_progressivefrom the resumable pass, so the engine has one block loop instead of two and a cancelled prefix costs nothing to resume. - Split the font module into validation, directory scanning and diagram selection, so a front end reuses the parts it has and leaves the rest behind.
- Put directory scanning behind a
font-directoriesfeature that is off by default, so a build for a host without a filesystem leaves everystd::fscall out of the binary. - Focus security documentation on policy and the threat model, with implementation details and verification work in separate references.
- Name the loop generically in
handle_user_eventand the newtick, so the event and timer paths run without a window server. - Separate the reading text a copy takes from the clipboard write that stores it.
- Take a
SurfaceSourceinmarkview-renderinstead of a window, so the renderer never names a windowing toolkit and a canvas front end can drive it the way the desktop window does. - Take the library crates' clock from
web-timeinstead ofstd::time, becauseInstant::nowpanics onwasm32-unknown-unknown; on every other target it is the same type re-exported. - Put texture readback and GPU waits behind a
readbackfeature that is off by default, because both block the calling thread and a browser has no second thread to wait on. - Declare wgpu's
webglbackend forwasm32-unknown-unknown, somarkview-renderbuilds for the Web;winitleaves its dependency tree.
Fixed
- Prevent malicious HTTP dates and overflowing
max-agevalues from panicking during downloads or redirect cache calculations. - Take multiline inline source positions from the block rather than the inline, so formulas and code spans keep the same range across differing indents, containers and line endings.
- Keep the line ending that closes an incremental parse window, so a multiline formula or code span at the window's edge gets the same source range as in a full parse.
- Prevent shaping from hanging when an extreme font size overflows Parley's line height, including sizes supplied by a valid MVSS rule.
- Keep thematic-break source ranges on their marker line, so trailing blank lines no longer change block IDs or make incremental and full parses disagree.
- A raw HTML attribute scan no longer splits a multi-byte space that stripping a leading
/exposed (<details /\u{a0}open>), which panicked on an 18-byte document. - A merged inline's source range only ever grows, so the out-of-order positions comrak reports after a link reference definition can no longer invert a range.
- Treat a
[x]: yline that continues a paragraph as text, not as a reference definition, so a prefix parse or a<details>body no longer resolves a link the document never had. - A prefix parse no longer cuts through YAML front matter or an open raw HTML block, and keeps the line ending a trailing list marker needs.
- Remove deprecated TypeScript
baseUrloptions and resolve web package aliases relative to each configuration file. - Apply horizontal overflow transforms and clipping to MVaaC image priorities, and infer SVG MIME types for byte decoding.
- Keep scanned glyph fallback choices independent of preceding characters, reuse fallback faces when caches fill, and preserve the cached text length limit.
- Preserve Web selections and held drag bases until a replacement reflow has laid out their blocks.
- Honor a corrected MVaaC wasm URL on retry when an early font failure leaves the previous binary request pending and that request later fails.
- Preserve the displayed Web scroll offset when changing motion mode or pressing the pointer during an animation over incomplete layout.
- Toggle Web disclosures using the document behind the published prefix, and stop internal scroll animation when external input pans a wide block.
- Apply external scroll travel from the displayed animation offset, preserve absolute requests through growing Web layouts, and defer End navigation until the final document height is known.
- Move image cache writes and eviction off the shared I/O runtime so disk work does not stall transfers or cancellation.
- Cancel pending save selections during shutdown, keep highlight preparation linear, and finish queued file creation before cancellation cleanup.
- Persist restoring the last font role to Default by removing its saved override.
- Offer Han font choosers only for definitions resolved by the selected CJK variant.
- Draw open language menus once to preserve translucent backgrounds and avoid redundant shaping.
- Fix image viewer activation without selectable text, capture covered controls' input, and cancel or latch drags correctly across focus loss and pointer movement.
- Refresh open image viewers after decoding and keep very thin images within the window's fit bounds.
- Cover the WebAssembly front end's publication bookkeeping and selection-length cache with native tests, replacing the Playwright wall-clock timing assertion that could flake on a loaded runner.
- Keep the last completed pass's block geometry when a later pass is cancelled, so typing past a document no longer flushes the warm cache.
- Keep a block's completed-pass membership separate from the pass that last used it, so a pass that resumes geometry and is then abandoned cannot cost the warm cache.
- Let a selection stop between the letters of a ligature, so
ffandfican be picked apart instead of only taken whole, while a single grapheme is still never parted. - Re-derive the selection when the view scrolls under a held press, so scrolling with the wheel extends what the pointer covers.
- Take a formula or a drawn image whole, since its source text is not what is displayed, instead of selecting an arbitrary slice of it.
- Mark the selected part of a ligature from the glyph's own advance, so a horizontally scrolled line never lights the letter that is still onscreen in place of the one selected.
- Keep selection painting linear in the paragraph length by scanning only the cluster's own grapheme boundaries.
- Ask a WebGL2 device only for the limits it has, so the browser backend gets past
request_deviceinstead of failing it on the desktop storage-buffer and compute defaults. - Color a document's code blocks without spawning a thread where the target has none, since
thread::spawnpanics onwasm32-unknown-unknownand every fenced block went through it. - Source ranges after a lone carriage return: comrak ends lines at
\ras well as\n, and the line-offset table followed only\n, shifting every range after the break (and desynchronizing the incremental parser). - The incremental parser's line and blank-line model now follows the parser's: a lone carriage return breaks a line, so a list marker hidden after a mid-line carriage return can no longer take the fast path with a window cut through the list's range.
- An indented
</details>closing tag no longer drags the element's source range past the tag, which could index out of bounds. - The incremental parser falls back to a full parse when its change window starts on a mid-document byte-order mark, which the parser only strips at the start of a document.
- Code blocks and HTML source split their lines on the parser's line structure (a lone carriage return ends a line), so a carriage return inside a code line can no longer reach the shaper inside a run.
- Border fitting on a box with a non-positive extent no longer runs a
0 / denormalscale that producedNaNborder widths. - A quoted
<details>body and the reference definitions a prefix parse appends now split their lines on the parser's line structure, so a lone carriage return no longer quotes a body line twice or hides a[x]: ...definition from the prefix. - Draw a cluster no configured face covers from a scan of the whole collection's character maps before handing it to the platform, so rare symbols like the long double arrow render instead of tofu even where the per-script fallback knows no family, and the fallback warning now means the glyph is genuinely absent.
Install markview 0.1.10
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/szdytom/markview/releases/download/v0.1.10/markview-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/szdytom/markview/releases/download/v0.1.10/markview-installer.ps1 | iex"Download markview 0.1.10
| File | Platform | Checksum |
|---|---|---|
| markview-aarch64-apple-darwin.tar.gz | Apple Silicon macOS | checksum |
| markview-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| markview-x86_64-pc-windows-msvc.msi | x64 Windows | checksum |
| markview-x86_64-unknown-linux-gnu.tar.gz | x64 Linux | checksum |