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.2.tar.gz (63.9 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.2-py3-none-any.whl (72.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: markast-1.0.2.tar.gz
  • Upload date:
  • Size: 63.9 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.2.tar.gz
Algorithm Hash digest
SHA256 8f138d6c92cac5bef6b4aaaf177090839ef28e029719ddb127ac2773fdf1bb47
MD5 a701cd9017e2e5a7e60f4c0b916ca300
BLAKE2b-256 b3417d5fe100d1616950db8cfbf305103eb957fc48b6f4636317bbe6d4792089

See more details on using hashes here.

File details

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

File metadata

  • Download URL: markast-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 72.1 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 89a169d691ee95c1a35db8d49f6ac66889d9d5fdc2c080d9e28d8b1ddd9bd437
MD5 ad76367ea2992392d80ab974c766fe51
BLAKE2b-256 be53ccebad1f7e1e0455ba77800a67723696bba416f3772b4b105bf0fd4c4b56

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