Skip to content

0.1.10 - 2026-10-01

Choose a tag to compare

@github-actions github-actions released this 01 Oct 14:32
738c03c

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 of InteractionState, 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, a wasm-bindgen front 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/web TypeScript package and a pnpm monorepo under web/, 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 fontdef override, and the Han rows appear only for the cjk-type variant in force, offering only the families that cover Han text.
  • A cargo-fuzz harness 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. A fuzz-only prewarm_highlight API 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_progressive from 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-directories feature that is off by default, so a build for a host without a filesystem leaves every std::fs call 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_event and the new tick, 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 SurfaceSource in markview-render instead 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-time instead of std::time, because Instant::now panics on wasm32-unknown-unknown; on every other target it is the same type re-exported.
  • Put texture readback and GPU waits behind a readback feature that is off by default, because both block the calling thread and a browser has no second thread to wait on.
  • Declare wgpu's webgl backend for wasm32-unknown-unknown, so markview-render builds for the Web; winit leaves its dependency tree.

Fixed

  • Prevent malicious HTTP dates and overflowing max-age values 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]: y line 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 baseUrl options 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 ff and fi can 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_device instead 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::spawn panics on wasm32-unknown-unknown and every fenced block went through it.
  • Source ranges after a lone carriage return: comrak ends lines at \r as 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 / denormal scale that produced NaN border 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 | sh

Install 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