Skip to content

release: 0.6.0 — SVG output + crisp gallery - #31

Merged
scottvr merged 9 commits into
mainfrom
feature/render-svg
Aug 24, 2026
Merged

release: 0.6.0 — SVG output + crisp gallery#31
scottvr merged 9 commits into
mainfrom
feature/render-svg

Conversation

@scottvr

@scottvr scottvr commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Combined pass: the --format svg feature plus the crisp-gallery swap it enables, cut as 0.6.0.

SVG image output

-o *.svg (or render --format svg) emits a crisp, scalable SVG of RLE colour rectangles — shape-rendering="crispEdges", razor-sharp at any zoom, renders natively in browsers/Markdown. Now supported by render (all paths: -m, -t/--pipe, --rgb), contact, and diff, via a shared _write_image helper. Sized by colour transitions, not pixels — compact for structured renders, larger for noise (keep BMP for those).

Crisp gallery (the payoff)

The gallery images were upscale-blurry. Now gen-docs-images.sh renders each tile to SVG and rasterizes it to a small PNG — razor-sharp, and ~40x smaller than embedding raw SVGs would be. The data that drove keeping PNG-in-gallery:

tile as SVG rasterized PNG
byteclass 205 KB 6 KB
text 3.0 MB 42 KB

So SVG is the crispness engine, not the delivered file. Whole gallery is now 208 KB and sharp.

Release

__version__ 0.5.2 → 0.6.0 (MINOR — additive); CHANGELOG [0.6.0]. Preflight: version/metadata/twine ✅; ruff+mypy clean; 172 tests green.

After merge: git tag v0.6.0 && git push origin v0.6.0 → gated publish → approval.

🤖 Generated with Claude Code

Add an SVG render target beside BMP and --term: canvas.to_svg emits the raster as run-length-encoded <rect> runs with a viewBox and shape-rendering=crispEdges, so pixels stay razor-sharp at any zoom (no upscaling blur) and render natively in a browser or Markdown page.

Triggered by --format svg or an -o path ending .svg; default stays BMP. Works across every render path (-m, -t/--pipe, --rgb) via _emit_render. Sized by colour transitions, not pixels -- compact and crisp for structured renders (region maps, byte classes), larger for high-entropy noise (docs say keep BMP for those). 7 new tests (RLE, viewBox, fidelity, --format, extension sniff, bmp default). 170 total.

The vizbin-native, zero-dependency answer to 'output straight to a shareable, non-blurry image file' -- the GHFM rule idea done in a format every browser renders.
Extend SVG output beyond render to contact and diff via a shared _write_image helper (BMP, or SVG when -o ends .svg). Regenerate the gallery crisp: gen-docs-images.sh now renders each tile to SVG and rasterizes it to a small PNG (rsvg-convert/magick), so the images are razor-sharp instead of upscale-blurry -- and ~40x smaller than embedding the SVGs would be (data-driven: e.g. the text tile is 3MB as SVG vs 42KB rasterized).

Bump __version__ to 0.6.0; roll CHANGELOG [Unreleased] into [0.6.0]. 4 new tests (contact/diff svg + the render svg tests from earlier). 172 total.
@scottvr scottvr changed the title feat(render): --format svg (crisp, scalable vector output) release: 0.6.0 — SVG output + crisp gallery Aug 24, 2026
…wcase)

Make demo.sh a good asciinema/terminal-video script for the 0.6.0 release: add the SVG output, weave in a colourful --term showcase (entropy, byteclass, --rgb, xor,entropy magma pipeline, text mode via --find), and a visual diff --term. Runs clean end-to-end; covers every headline feature.
Add a pause() gated on an interactive terminal (and a NOPAUSE=1 override): demo.sh now waits for a keypress before each section, so you can pace a screen recording. Auto-skips when stdin isn't a TTY (piped/redirected/CI), so non-interactive runs never hang.
…ing)

Add a run() wrapper that prints each command as you'd type it (bold '$ vizbin ...') before executing, plus cyan section headers; keep the keypress pause but stop hiding its prompt. demo.sh now reads like a real terminal session -- command, then output -- which is what you want on screen while recording.
A width sweep produces frames of differing sizes, and many viewers (kitty, some image apps) won't animate a GIF whose frames vary in size -- they show the first frame and stop. The NETSCAPE loop flag was already correct; pad each frame to the max canvas size (like the mp4 path already did).

Also: document animate --fps (lower it for short sweeps to watch the snap), slow the demo sweep to --fps 3 over 7 widths. +1 regression test. 173 tests.
The old payload was flat-random: infer found the 188 stride via its sync
marker, but suggest could not rank 188 (adjacent records were dissimilar),
and rendering at the true stride showed only a thin sync band, not a clean
vertical snap.

Make each record's 179-byte payload random-WALK from its predecessor
(+-40/column/step). Adjacent records now look alike -> suggest ranks 188
first (0.87, 'strong adjacent-row coherence') and infer locks the stride;
each column still wanders its full range over 400 records -> infer reads one
clean blob (magic/counter/reserved/blob; struct '<5sH2x179s'). Visually the
walk paints a vertical wood-grain at 188 that shears to diagonals at any
other width, so the width sweep snaps cleanly -- the find->verify story the
demo is meant to show.
render --term / diff --term emitted 24-bit SGR (38;2;r;g;b) unconditionally.
Terminals without truecolor support -- macOS Terminal.app, and kitty/others
when $COLORTERM isn't exported -- don't recognise the 38;2 introducer and
reparse it as separate SGR codes: the background never sets (only the top
half of each half-block cell renders) and colour bytes leak in as text
attributes, so a byte of value 5 becomes SGR 5 (blink). That is the observed
'top halves only + blinking rows' bug.

Detect truecolor from $COLORTERM (auto) with a --color {auto,truecolor,256}
override, and add canvas.rgb_to_256 (6x6x6 cube + 24-step gray ramp, nearest
of the two) to quantise for the 256 path. VSCode's terminal sets COLORTERM
and stays 24-bit; Terminal.app/kitty fall back to 256, which they support.
Add the recorded terminal tour (docs/images/demo.sh.gif) to the README beside
the gallery link, with a short invite to clone and run scripts/demo.sh.

Also commit the demo.sh edits that recording used: sections reordered, the
width sweep slowed to --fps 1, and two terminal renders contrasting the true
188-byte stride (vertical band) against a close-but-wrong 180 (no band), so
the committed script matches what the GIF shows.

Un-ignore docs/images/** (the repo ignores generated *.gif under output/, but
committed documentation images are tracked).
@scottvr
scottvr merged commit 58302e1 into main Aug 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant