Skip to main content

Markdown → typed AST → JSON / Markdown / HTML, with a pluggable widget system.

Project description

markast

markast

Markdown → typed AST → JSON / Markdown / HTML

Parse Markdown into a structured, typed tree your front-end can render — natively, server-side, or as JSON.

Version Python License Docs

Docs · Documentación (ES) · Examples


from markast import parse

doc = parse("# Hello\n\nA paragraph with **bold** and a [link](https://example.com).")

doc.to_json()       # str — ship to any client renderer
doc.to_markdown()   # str — roundtrip
doc.to_html()       # str — server-side render

Why a tree, not HTML?

HTML is a one-way street. Once your content is rendered, the structure is gone — clients can't restyle headings per platform, can't swap a :::video for a native player, can't extract a TOC without re-parsing.

markast keeps the meaning intact. Parse once, render anywhere:

  • Native mobile renders headings with platform typography.
  • The web renders :::video as a custom player; the terminal renders it as a link.
  • Search indexes the same structured nodes that drive the UI.
  • One source of content powers a docs site, a CMS preview, and a CLI.

What you get

Layer What it gives you
🌳 AST Typed nodes (TypedDict), walker/visitor, JSON-Schema export, factory helpers
🧱 Widgets :::widget containers with typed params, named slots, validation — and a per-parser registry, no global state
🛡️ Rules Validation diagnostics that never crash — bad content is repaired and a warning is emitted
⚙️ Transforms AST → AST passes: normalize, slugify, TOC, autolink
🔀 Renderers Markdown (full roundtrip) and HTML (server-side) — both subclassable
🧰 Parser CommonMark + GFM (tables, strikethrough, tasklists, autolinks) + footnotes + custom containers
⌨️ CLI markast parse file.md --format json

Install

pip install markast

30-second tour

from markast import Parser
from markast.widgets import BaseWidget, WidgetParam

class CalloutWidget(BaseWidget):
    name = "callout"
    params = {
        "level": WidgetParam(str, default="info", choices=["info", "warn", "error"]),
        "title": WidgetParam(str, default=None),
    }

parser = Parser(widgets=[CalloutWidget], transforms=["normalize", "slugify"])

doc = parser.parse("""
# Welcome

:::callout level=warn title="Heads up"
This is **important** content.
:::
""")

print(doc.to_json(indent=2))
print(doc.to_html())

parser.parse(...) always returns a valid Document. Invalid input is repaired and reported on doc.warnings — the parser never raises on user content.

Documentation

Full docs live at cursland.github.io/markast (English / Español, light & dark).

🚀 Getting started Install, parse, render
🌳 AST reference Every node type and field
🧱 Widgets Built-ins and authoring your own
⚙️ Transforms Built-in passes and custom transforms
🔀 Renderers Markdown, HTML, and subclassing
🧭 Walker & utilities Traverse and mutate the AST safely
🌐 Client integration Patterns for any front-end
🧩 Extending Custom rules, plugins, tokenizers

Examples

Runnable scripts in examples/:

Status

1.0.0 — first stable release. Backwards-compatible changes follow semver.

License

MIT © cursland

Project details


Download files

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

Source Distribution

markast-1.0.1.tar.gz (63.2 kB view details)

Uploaded Source

Built Distribution

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

markast-1.0.1-py3-none-any.whl (71.2 kB view details)

Uploaded Python 3

File details

Details for the file markast-1.0.1.tar.gz.

File metadata

  • Download URL: markast-1.0.1.tar.gz
  • Upload date:
  • Size: 63.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for markast-1.0.1.tar.gz
Algorithm Hash digest
SHA256 d30be63b8829944ab7854070f52b1389667e693228b9a3785ee7c9ce10502465
MD5 11daee5aab176498f74490f91c117ac1
BLAKE2b-256 a8930a6070a20d39dbd9d86bdb56f55a9ecd5cb151fdad04d1de47876bb0ff31

See more details on using hashes here.

File details

Details for the file markast-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: markast-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 71.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for markast-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 686fae335dabdcb7e7881e55e919976e3b9d089be51455c5f4efd3888e860f11
MD5 68183314c12b57ab619ea0b757bd1b5a
BLAKE2b-256 719eb3f63719b633ea69002040857e7ab2f1f4a32f16f316aa316d582f8742ff

See more details on using hashes here.

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