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.3.tar.gz (63.6 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.3-py3-none-any.whl (71.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: markast-1.0.3.tar.gz
  • Upload date:
  • Size: 63.6 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.3.tar.gz
Algorithm Hash digest
SHA256 6f2c2da7cce4583c5902d55e567bb74391241d2bc5fddd839eff967f97038eb4
MD5 5235b07172b6c391ff90af0478c4222e
BLAKE2b-256 8b632f649364d6839bdf5dddce09a8513752acd057e48d89dd144cc63fe2cf4c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: markast-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 71.6 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 37b296bae3776b86d8219db2c972d34b789cce7406df7c248abd6e9b85ab3426
MD5 5b34049ef8e8d3fb0756fb3e5ac3198d
BLAKE2b-256 3c21fe930023ac724c708bbc75f53a0a466c04d81dfa3562d1218cc6dc7c4aa7

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