Changelog
All notable changes to this project are documented in this file.
The format follows Keep a Changelog, and the project follows Semantic Versioning (while below 1.0, a minor bump may carry breaking changes).
0.10.1 - 2026-10-21
A patch release for a regression in 0.10.0: on the default quickjs backend, a diagram whose text held a
character above U+00FF failed to render.
Fixed
TypeError: Unknown quickjs tag: -6on thequickjsbackend for any label, title or message holding a character above U+00FF (an em dash, a bullet,≥, a circled digit, Persian, CJK, an emoji) (#39, fix by @kamalkraj in #40). QuickJS-ng keeps a long concatenation as a rope string, which thequickjsPython binding cannot convert. Every string that crosses into Python (the rendered SVG, the error text and the arguments of the text-measurement callbacks) is now copied into a flat one first. A long label of that kind used to fail earlier, inside a measurement callback. Thev8engine is unchanged.- The link to the changelog on the installation page of the docs had the wrong letter case, which broke the docs build.
Changed
- Spelling is now US-English throughout the code comments, the docs and the error messages (#42). The one
visible effect: the error for an invalid background color now starts with
Unrecognized background color.
Added
tests/test_unicode_labels.pycovers #39 for ten diagram types, for SVG, PNG and PDF output, for the error path and for the flattening helper itself. Thev8cases are skipped whenmini-raceris not installed.
0.10.0 - 2026-10-17
The theme of this release is browser-faithful output: the DOM/SVG shim now reproduces what Chrome
does (CSSOM serialization, getBBox, float32 path parsing) instead of the SVG being patched afterwards,
and the SVGs are checked against mmdc reference output with a strict structural XML comparison.
It also moves rasterization to novasvg only and adds JPEG, BMP and TGA output.
Added
- JPEG, BMP and TGA output.
Diagram.jpg(),.bmp()and.tga(),.save()by extension (.jpg,.jpeg,.bmp,.tga), and the new top-level functionssvg_to_jpgandsvg_to_image. All encoders come from novasvg, so there is no Pillow dependency. - CLI:
-oaccepts the new extensions, and--quality Nsets the JPEG quality (1-100, default 90). JPEG has no transparency, so the background defaults to white for it. mermaidx/assets/path_bbox.js: a port of Blink's float32 SVG number parser and tight path bounding box (Chrome/Skia behavior), shared by the DOM shim. Used withMath.froundwhen converting units and accumulating positions.- Shared engine code in
mermaidx/engines/_common.py, so thequickjsandv8engines no longer duplicate setup logic. - Structural comparison against
mmdc: 43 reference samples intests/samples/andtests/test_mmdc_structural.py, run on bothquickjsandv8. The comparison is a strict XML structure check (tests/svg_compare.py, built onpygixml); only floating point values have a tolerance. It covers the whole document, including the prolog, comments and CDATA. - New test modules for the DOM shim, selector engine, text and shape bounding boxes, path bbox, label
stacking, deep graphs, sanitization, and the V8 mirror and
foreignObjectpaths.
Changed
- novasvg is now the only rasterizer and the only text and HTML-label measurer.
novasvg>=0.7.5is required (it provides the in-memory image encoders,<foreignObject>soft-wrapping driven by the HTML's ownwhite-space, and GSUB f-ligature handling). mermaid.js's default HTML labels are used again (htmlLabels: true), and the globalhtmlLabelsoverride was removed from the engine base configs. - DOM shim, CSS: style handling now follows Chrome's CSSOM. Rule text is canonicalized (property
names lowercased,
!importanthandled, hex/HSLA colors converted torgb()/rgba(), numbers to six significant figures, barefont-sizenumbers getpx, whitespace after commas normalized). Multi-value declarations that Chrome rejects are skipped,display: noneelements are excluded from layout, and redundant style rewrites are skipped. - DOM shim, selectors and serialization: the selector engine handles descendant, child, adjacent and
general-sibling combinators plus
:notand:first-child.cloneNodematerializes pending styles first, andinnerHTMLsupports XML namespaces. HTML entities are decoded and serialized correctly, andsetAttributeNSandremoveAttributenow track namespaced attributes. - DOM shim, geometry:
getBBoxon<text>uses the ink extent like Chrome,foreignObjectboxes match the sizes novasvg paints (so content near the canvas edge is no longer clipped), and relative CSS units (em,ex,rem,%,pt) resolve to pixels. - V8 engine:
foreignObjectlabels are measured through a JS mirror and rendered in as many passes as needed until sizes settle (an error is raised after a fixed maximum). Timeouts kill the child process rather than a thread. The README no longer quotes specific JIT speedup figures. - Dependencies:
termaidis no longer version-pinned. - Test dependencies now include
pygixml.
Removed (breaking)
- Font embedding.
Diagram.svg(embed_font=...), theembed_font=argument ofsave(), the CLI flag--embed-font, themermaidx[embed]extra (andfonttoolsfrommermaidx[all]), andmermaidx/font_embed.pyare gone. - resvg.
resvg_pyis no longer a dependency, andraster="resvg"now raises aValueErrorwith a migration hint. Drop the argument to use novasvg. - Post-render SVG patching.
mermaidx/engines/_svg_patches.pywas deleted. The shim now produces the expected output directly; the journey/timeline task text color is no longer fixed up on the finished SVG.