This release is a pre-release and may not be stable for production use.
merman Python Package
Experimental Python bindings for Merman through UniFFI.
Merman renders Mermaid diagrams without a browser. It can parse Mermaid source, return semantic JSON, compute layout JSON, and render SVG through a headless Rust engine. See the project README, Python binding notes, and diagram coverage status for the main library contract.
Compatibility And Release Notes
This package tracks UniFFI ABI 2 and is regenerated from the merman-uniffi cdylib. The
published PyPI page shows this README together with the metadata links in pyproject.toml, so the
package page can point directly to the binding docs, issues, and changelog.
MermanReusableEngine exposes the reusable render path, and MermanTextMeasurer lets Python
hosts provide a callback when they need host-owned text measurement. ascii_capabilities() reports
ASCII support grades and summary fallback metadata; diagram_family_capabilities() reports
parser/render family availability. analyze_document_json() and
analyze_document_facts_json() expose Markdown/MDX-aware diagnostics and facts.
For package-specific release notes, see CHANGELOG.md.
API
import merman
engine = merman.MermanEngine()
assert engine.abi_version() == 2
print(engine.package_version())
source = "flowchart TD\nA[Hello] --> B[World]"
svg = engine.render_svg(source, None)
ascii_text = engine.render_ascii(source, None)
semantic_json = engine.parse_json(source, None)
layout_json = engine.layout_json(source, None)
validation = engine.validate(source, None)
document_json = engine.analyze_document_json("```mermaid\n" + source + "\n```", None, "file:///tmp/example.md")
document_facts_json = engine.analyze_document_facts_json(
"```mermaid\n" + source + "\n```",
None,
"file:///tmp/example.md",
)
diagrams = engine.supported_diagrams()
ascii_capabilities = engine.ascii_capabilities()
themes = engine.supported_themes()
host_presets = engine.supported_host_theme_presets()
family_capabilities = engine.diagram_family_capabilities()
class Measurer(merman.MermanTextMeasurer):
def measure(self, request):
return merman.MermanTextMeasureResult(
width=max(len(request.text) * 8.0, 1.0),
height=max(request.line_height, 1.0),
line_count=1,
)
reusable = engine.reusable_engine_with_text_measurer(None, Measurer())
assert "Hello" in reusable.render_svg(source)
reusable = engine.reusable_engine(None)
document_json = reusable.analyze_document_json(
"```mermaid\n" + source + "\n```",
"file:///tmp/example.md",
)
reusable.set_text_measurer(Measurer())
assert "Hello" in reusable.render_svg(source)
reusable.clear_text_measurer()
try:
engine.render_svg(source, "{")
except merman.MermanError.Binding as error:
print(error.code_name, error.message)
options_json is optional. Pass None for defaults, or a JSON string with parse, layout, and
svg options. The shared schema is documented in
docs/bindings/OPTIONS_JSON.md.
Text Measurement
The current Python package is generated through UniFFI and uses merman's built-in headless text measurer by default. This is suitable for CLI tools, documentation builds, tests, and server-side batch rendering.
If a Python GUI, browser automation host, or WebView application needs geometry that matches its
own font stack, create a MermanReusableEngine with reusable_engine_with_text_measurer(...) or
call set_text_measurer(...) on an existing reusable engine. Call clear_text_measurer() to
restore the engine's original built-in measurer. Return None from the callback when a request is
not handled so merman can fall back to its vendored metrics for that request. Raise MermanError
or another callback exception only for host failures that should make reusable render_svg or
layout_json fail instead of silently returning fallback geometry. See
docs/bindings/HOST_TEXT_MEASUREMENT.md.
Generate Locally
This directory intentionally does not commit generated binding source or native libraries. Generate
them from a local merman-uniffi cdylib:
cargo build -p merman-uniffi --features bindgen-smoke
cargo run -p merman-uniffi --features bindgen-smoke --example generate_python_package -- \
--package-dir platforms/python/merman
The generator writes:
src/merman/merman_uniffi.pysrc/merman/merman_uniffi.dllon Windowssrc/merman/libmerman_uniffi.soon Linuxsrc/merman/libmerman_uniffi.dylibon macOS
The native library must sit beside the generated module because UniFFI's Python loader resolves the library relative to the generated file.
After generation, a local smoke can import the package by putting src on PYTHONPATH:
PYTHONPATH=platforms/python/merman/src python -c "import merman; print(merman.MermanEngine().render_svg('flowchart TD\nA[Hello]', None)[:4])"
Or run the example script:
PYTHONPATH=platforms/python/merman/src python platforms/python/merman/examples/smoke.py
Build a local platform wheel and run an install smoke:
python3 scripts/build-python-uniffi-wheel.py --run-smoke
The wheel is platform-specific because it bundles merman-uniffi as a native .so, .dylib, or
.dll. Tag releases run release-python.yml, attach platform wheels to the GitHub Release, and
publish the merman distribution to PyPI when Trusted Publishing is configured.
License
This package is dual-licensed under either Apache-2.0 or MIT. See LICENSE for the full license
texts. Mermaid compatibility and upstream Mermaid MIT attribution are documented in
THIRD_PARTY_NOTICES.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file merman-0.8.0a3-py3-none-win_amd64.whl.
File metadata
- Download URL: merman-0.8.0a3-py3-none-win_amd64.whl
- Upload date:
- Size: 9.1 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f47b1adfbfc1f5b404f8068384401451f59ae149f0b0eb16f206d7b9df1d4ae8
|
|
| MD5 |
b712a4e4247f1d4f87092316dd76948f
|
|
| BLAKE2b-256 |
16c4fde2b2405b5e8c655617122213f971d6758e47a5bb69d21c6bb7a07e1c7a
|
Provenance
The following attestation bundles were made for merman-0.8.0a3-py3-none-win_amd64.whl:
Publisher:
release-python.yml on Latias94/merman
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
merman-0.8.0a3-py3-none-win_amd64.whl -
Subject digest:
f47b1adfbfc1f5b404f8068384401451f59ae149f0b0eb16f206d7b9df1d4ae8 - Sigstore transparency entry: 2124376931
- Sigstore integration time:
-
Permalink:
Latias94/merman@a165bf6308c1d11cb36cbf31a4f00b7d4d20dc69 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Latias94
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@a165bf6308c1d11cb36cbf31a4f00b7d4d20dc69 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file merman-0.8.0a3-py3-none-manylinux_2_35_x86_64.whl.
File metadata
- Download URL: merman-0.8.0a3-py3-none-manylinux_2_35_x86_64.whl
- Upload date:
- Size: 53.2 MB
- Tags: Python 3, manylinux: glibc 2.35+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db73a6aaed9e92ea5e3a80d3de301a35d3e3c7adf1e5049e3c6dc2b534fec9bf
|
|
| MD5 |
f64799e5b2552c13561b7247376c35c0
|
|
| BLAKE2b-256 |
8003116b1e3e4a530de87d07d3498ce816ea5066b7fc2e092cd0abab8d38d5b7
|
Provenance
The following attestation bundles were made for merman-0.8.0a3-py3-none-manylinux_2_35_x86_64.whl:
Publisher:
release-python.yml on Latias94/merman
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
merman-0.8.0a3-py3-none-manylinux_2_35_x86_64.whl -
Subject digest:
db73a6aaed9e92ea5e3a80d3de301a35d3e3c7adf1e5049e3c6dc2b534fec9bf - Sigstore transparency entry: 2124376972
- Sigstore integration time:
-
Permalink:
Latias94/merman@a165bf6308c1d11cb36cbf31a4f00b7d4d20dc69 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Latias94
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@a165bf6308c1d11cb36cbf31a4f00b7d4d20dc69 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file merman-0.8.0a3-py3-none-macosx_11_0_universal2.whl.
File metadata
- Download URL: merman-0.8.0a3-py3-none-macosx_11_0_universal2.whl
- Upload date:
- Size: 11.9 MB
- Tags: Python 3, macOS 11.0+ universal2 (ARM64, x86-64)
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e585cd4d655afe063112bc1c4bf58d62594b233f1f9b00cebc628e43418ede2a
|
|
| MD5 |
1a5b39219a0afe4ca11c05c695731e1a
|
|
| BLAKE2b-256 |
cdf084d73b1f947e762bfb7347fb7c745210dd163bb4c98050187427c5abc22d
|
Provenance
The following attestation bundles were made for merman-0.8.0a3-py3-none-macosx_11_0_universal2.whl:
Publisher:
release-python.yml on Latias94/merman
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
merman-0.8.0a3-py3-none-macosx_11_0_universal2.whl -
Subject digest:
e585cd4d655afe063112bc1c4bf58d62594b233f1f9b00cebc628e43418ede2a - Sigstore transparency entry: 2124376888
- Sigstore integration time:
-
Permalink:
Latias94/merman@a165bf6308c1d11cb36cbf31a4f00b7d4d20dc69 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Latias94
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@a165bf6308c1d11cb36cbf31a4f00b7d4d20dc69 -
Trigger Event:
workflow_dispatch
-
Statement type: