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.4.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.4-py3-none-any.whl (72.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: markast-1.0.4.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.4.tar.gz
Algorithm Hash digest
SHA256 1fe91b8aa3b825adde8ba02fee530e23c136339aa7e7068c54e44f69c41c5043
MD5 7c31a727d8a1a0338d7f3505bb2e75fa
BLAKE2b-256 2f8268a01afd08331f683a67170af9376fbb7c729cec659f0f1d5fa97161ec23

See more details on using hashes here.

File details

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

File metadata

  • Download URL: markast-1.0.4-py3-none-any.whl
  • Upload date:
  • Size: 72.0 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.4-py3-none-any.whl
Algorithm Hash digest
SHA256 a72d7d6e2661a0ad8bc109c5dc388e0ee210172c0b53f43452d6aa6f8d14b238
MD5 26d32f9e2e00b7a594859333a47f405c
BLAKE2b-256 a0ea531839f1b766e995101fbb59a281b4a419278fd3de5658aec5c153815f41

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