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.1.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.1-cp310-abi3-win_amd64.whl (15.2 MB view details)

Uploaded CPython 3.10+Windows x86-64

quillmark-0.92.1-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.1-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.1-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.1.tar.gz.

File metadata

  • Download URL: quillmark-0.92.1.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.1.tar.gz
Algorithm Hash digest
SHA256 eeaf43f3a717eca9561ed0eea3e8e7d6c6a4ba042ed87d5a5b67e7f26be9c27f
MD5 c0eaa767ddd6e6c1511da443f8eb928a
BLAKE2b-256 a89c82b07b251f83f4eb37b5af69bf67269b78fee0405f15a47a296e82d29074

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.1.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.1-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: quillmark-0.92.1-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.1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 4c665f5ab2281e23f37893fbb07176e76f8f00deb5610689b46b2d6009b76069
MD5 88db332763a25827ca0f8a0bc8dbe271
BLAKE2b-256 33801c076a12fa40d1da7420efdcd6e4e7abd5bc1318e0fa1da8b18f33792d1d

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.1-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.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for quillmark-0.92.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c9e06478e755f982a6ebdfba301bdf58a7c0a03c0bcd2d983fc73ef637b04814
MD5 71e475891ddb0ed2f11fc6541f3cff4e
BLAKE2b-256 bdc2606dcdb1d711ef9ec5bdb84dc974f9412de08b944854483567ecfc543004

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.1-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.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for quillmark-0.92.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e8fa958917c1b41a89475b8a85913bcb0a800c27e5775aba323fbde99b16a498
MD5 5c4cb335a8d9db3f4717c2ac36ba5f93
BLAKE2b-256 3bd1f354e733e8f65a4d6f17a18ff267b8f18d21eb50735be7ec76520c51adf8

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.1-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.1-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for quillmark-0.92.1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8b04b94f67ffd11b9c67771e874bd056b997f8133baea1f3e171f68800599478
MD5 2e3ecac1519e716e3a37ff7f6b140c82
BLAKE2b-256 26af92513c01279bd48609c600d25777fb809ec465a69414b835c39f28eb3b15

See more details on using hashes here.

Provenance

The following attestation bundles were made for quillmark-0.92.1-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