Skip to main content

Python bindings for Quillmark - format-first Markdown rendering

Project description

Quillmark — Python bindings

Python bindings for Quillmark's format-first Markdown rendering engine.

Maintained by TTQ.

Installation

pip install quillmark

Quick Start

from quillmark import Quillmark, Quill, Document, OutputFormat

engine = Quillmark()                       # backend registry + render dispatcher
quill = Quill.from_path("path/to/quill")   # engine-free, validated config data

markdown = """~~~
$quill: my_quill
$kind: main
title: Hello World
~~~

# Hello
"""

parsed = Document.from_markdown(markdown)
result = engine.render(quill, parsed, OutputFormat.PDF)
result.artifacts[0].save("output.pdf")

API surface

The Python surface mirrors the @quillmark/wasm package for the shared document model. Names follow snake_case conventions; the underlying concepts (and shapes of return values) are the same. Python renders in one shot via engine.render; the iterative render-session and canvas-preview surface is WASM-only (see prose/canon/PREVIEW.md).

Capability principle: a Quill is engine-free, validated config data — quill.metadata is a pure, infallible snapshot of the quill: section. The format probe (supported_formats) and rendering (render) are resolved by the engine, against a quill; they raise QuillmarkError (UnsupportedBackend) only if the declared backend isn't registered.

Quillmark

engine = Quillmark()
engine.registered_backends()              # ['typst']
engine.render(quill, parsed, OutputFormat.PDF)   # ppi=, pages=, producer= optional
engine.supported_formats(quill)           # [OutputFormat.PDF, ...] (raises if backend unregistered)

Quill

quill = Quill.from_path("path/to/quill")  # pure config load — no backend resolved here

quill.backend_id            # "typst" (declared backend)
quill.blueprint             # auto-generated annotated Markdown blueprint
quill.schema                # structured dict of the quill's document schema
quill.metadata              # pure config snapshot of the quill: section (never raises)
quill.quill_ref             # "name@version"

diags   = quill.validate(parsed)          # list of validation::* diagnostic dicts ([] = valid)
seed    = quill.seed_document()           # starter Document seeded from `example:` values
main    = quill.seed_main()               # just the $kind: main card (dict, like doc.main)
card    = quill.seed_card("note")         # one starter composable card (dict), None if kind undeclared

RenderResult / Artifact

result.artifacts            # [Artifact, ...]
result.warnings             # [Diagnostic, ...]
result.format               # OutputFormat
result.render_time_ms       # float

artifact.format             # OutputFormat
artifact.bytes              # bytes
artifact.mime_type          # 'application/pdf', 'image/svg+xml', ...
artifact.save("out.pdf")

Document

doc = Document.from_markdown(markdown)
emitted = doc.to_markdown()

stored   = doc.to_json()
restored = Document.from_json(stored)
maybe    = Document.try_from_json(blob)          # None when not a DTO

Document.schema_version_of(blob)                 # raw tag (incl. unknown futures)
Document.current_schema_version()                # what this build writes

Document.format_rules()                          # card-yaml authoring rules (static text)
Document.quill_ref_hint()                        # $quill reference grammar (static text)
Document.blueprint_instruction("taro")           # LLM/MCP blueprint header for a quill

doc.clone()
doc.equals(other)
doc.card_count
doc.main; doc.cards; doc.body; doc.warnings

doc.set_field("title", "New")
doc.push_card(Document.make_card("note", {"x": 1}, "..."))  # or pass a Card from cards/remove_card/seed_card
# insert_card, remove_card, move_card, set_card_kind,
# update_card_field, remove_card_field, update_card_body, ...

Schema model

A field's cell is inferred from whether the schema declares a default::

  • Unendorsed (no default:) — the blueprint renders <must-fill>. An absent Unendorsed field is a non-fatal signal (validation::field_absent) — the render path zero-fills it silently. A surviving <must-fill> sentinel is fatal (validation::must_fill_sentinel). Partial documents are first-class; engine.render(quill, doc) only raises for malformed input.
  • Endorsed (with default:) — the blueprint renders the default value with a ; delete-ok annotation, and the default is used when the document omits the field.

There is no required: axis on FieldSchema.

Error contract

A single exception type — QuillmarkError — is raised for every failure mode. Every raised exception carries a non-empty .diagnostics list of Diagnostic objects. This matches the WASM binding's contract.

try:
    Document.from_markdown(bad_md)
except QuillmarkError as exc:
    for d in exc.diagnostics:
        print(d.severity, d.code, d.message, d.path)
        print(str(d))   # canonical pretty-printed text (matches CLI / WASM)

EditError-shaped failures (invalid field names, kind names, out-of-range indices) prefix the message with [EditError::<Variant>] — the same format WASM uses — so callers can pattern-match on the message when they need to.

Changelog

See the changelog and the GitHub Releases page for release notes and version history.

Development

uv venv
uv pip install -e ".[dev]"
uv run pytest

License

Apache-2.0

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quillmark-0.92.0.tar.gz (2.5 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

quillmark-0.92.0-cp310-abi3-win_amd64.whl (15.2 MB view details)

Uploaded CPython 3.10+Windows x86-64

quillmark-0.92.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.3 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

quillmark-0.92.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (15.7 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

quillmark-0.92.0-cp310-abi3-macosx_11_0_arm64.whl (14.4 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file quillmark-0.92.0.tar.gz.

File metadata

  • Download URL: quillmark-0.92.0.tar.gz
  • Upload date:
  • Size: 2.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for quillmark-0.92.0.tar.gz
Algorithm Hash digest
SHA256 985333571c08635d3bfea69aa5ba6ae36fc5652f6d8fcfbdaa3f4cca95c289c9
MD5 05abf3b8b7ea66a70823aba5e0d58b25
BLAKE2b-256 d62cec85d7a51b32e5ce38099b7990f4c44fb5be306ade36b2b67d9f70190bbc

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.0.tar.gz:

Publisher: release.yml on quillmark-org/quillmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quillmark-0.92.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: quillmark-0.92.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 15.2 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for quillmark-0.92.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 c27b5abf66d0f1a2078fefade4a1c538edb490b71af5f539b71545039c832680
MD5 6beabc96bc9a6f2dc4297ccc004d6da6
BLAKE2b-256 a2841b452ca31ca8cd88068c3b8f372c3b31702bc6e4b05e819435a431c844fb

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.0-cp310-abi3-win_amd64.whl:

Publisher: release.yml on quillmark-org/quillmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quillmark-0.92.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for quillmark-0.92.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b4636c6eeb39115c7f8aa773e489c65f3c0007f2b15861ff30647e37b7f464df
MD5 a84e5358ee6b7b3805a6703db1026310
BLAKE2b-256 222b9096002f9fb6b46d54e99c92ec0048bc74d4dae991ff83e37694b7de2458

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on quillmark-org/quillmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quillmark-0.92.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for quillmark-0.92.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b2d51117fe0b76a190353a95b9a1cbc48dc5f121fba5e1fb70bae3e79a1594b5
MD5 7b6722c33a0cfba2dc4e50b1d6a86137
BLAKE2b-256 8df404e655b0a057a870d4d03e77242f77aa818d053af455a5fb7532514ad464

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on quillmark-org/quillmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quillmark-0.92.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for quillmark-0.92.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 66d306e3b2bd272054ba4b722ed98018aed12f3b7f478e04ab8682eedad3fa43
MD5 0680a6e7a1882fb6d01e6ee1ab9355e8
BLAKE2b-256 3fc97939afa9822360d200da4e669815551ebfd17483e7e40463490e0a05cd98

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on quillmark-org/quillmark

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page