Skip to main content

QMDC Parser (Python)

QMDC ↔ JSON parser for Markdown with lossless round-trip support.

Installation

cd qmdc-py
uv pip install -e .

CLI Usage

Parse (QMD.md → JSON)

# File → stdout
qmdc parse -i doc.qmd.md

# Stdin → stdout
echo "## Test [[test]]" | qmdc parse

# File → file
qmdc parse -i doc.qmd.md -o output.json

# Without metadata
qmdc parse -i doc.qmd.md --no-comments --no-syntax

# Compact JSON
qmdc parse -i doc.qmd.md --no-pretty

Rebuild (JSON → QMD.md)

# File → stdout
qmdc rebuild -i data.json

# Stdin → stdout
echo '[{"__id":"test","name":"Test"}]' | qmdc rebuild

# File → file
qmdc rebuild -i data.json -o doc.qmd.md

Formatting (parse → rebuild)

There is no separate lint command. Canonical formatting (like ruff/prettier) is the lossless round-trip through parse → rebuild:

# Canonical formatting
qmdc parse -i doc.qmd.md | qmdc rebuild

Programmatic API

from qmdc.parser import parse, rebuild

# Parse QMD.md → JSON
markdown = """
## User [[user]]

- name: Alice
- age: 30
"""
result = parse(markdown)
# [{"__id": "user", "__label": "User", "name": "Alice", "age": 30, ...}]

# Rebuild JSON → QMD.md
qmdc = rebuild(result)
# "## User [[user]]\n\n- name: Alice\n- age: 30\n"

Testing

# From the project root
make test

# Python tests only
make py-test

# pytest directly
cd qmdc-py
uv run pytest tests/ -v

Workspace (multi-file parsing)

QMDC Parser supports workspaces — a set of related QMD.md files with cross-file reference validation.

Workspace CLI

# Parse a workspace into JSON
qmdc workspace parse ./my-project -o workspace.json

# Validate a workspace
qmdc workspace validate ./my-project

# Rebuild files from JSON
qmdc workspace rebuild workspace.json -o ./output

Query (SQL queries against a workspace)

# SQL query against a workspace (loads all workspaces recursively)
qmdc query ./my-project "SELECT __id, __kind, __label FROM objects WHERE __kind = 'Service'"

# With JSON output
qmdc query ./my-project "SELECT * FROM objects LIMIT 10" --format json

# Query via a Query object (reference to a [[id:Query]] object in the workspace)
qmdc query ./my-project "#all_services"

# Count objects and edges
qmdc query ./my-project "SELECT COUNT(*) as total FROM objects"
qmdc query ./my-project "SELECT COUNT(*) as edges FROM edges"

The query command automatically:

  • Recursively finds every QMDC workspace under the given folder
  • Parses all files and loads objects into SQLite
  • Extracts graph edges from references between objects
  • Runs the SQL query against the database

Available tables:

  • objects — all objects with __id, __kind, __label, __file, __line, data (JSON)
  • edges — all graph edges with source_id, target_id, field_name

Workspace API

from qmdc.workspace import (
    scan_workspace,
    parse_workspace,
    validate_workspace,
    query_workspace,
    get_refs_to,
)

# Scan files
files = scan_workspace("/path/to/workspace")
# ['readme.qmd.md', 'users.qmd.md', 'database/tables.qmd.md']

# Parse the whole workspace
result = parse_workspace("/path/to/workspace")
# WorkspaceResult with objects, index, errors

# Query objects
tables = query_workspace(result, kind="Table")
users = query_workspace(result, object_id="users")

# Find references to an object
refs = get_refs_to(result, "database/tables.qmd.md#users")
# [("api.qmd.md", "get_users", "returns"), ...]

See the format specification for the full spec.

Status

Fully implemented:

  • Tokenizer (markdown-it-py)
  • Header parser (all variants: [[id]], [[id:Kind]], [[:Kind]])
  • Field parser (primitives: string, number, boolean, null)
  • Nested objects (H1–H6)
  • Arrays (YAML notation, Markdown lists, object arrays)
  • Tables
  • Comments (__comments)
  • Syntax metadata (__syntax)
  • Types metadata (__types)
  • YAML multiline syntax (|)
  • Rebuild (canonical form)
  • YAML blocks
  • JSON blocks
  • Document title (H1 without [[id]])
  • Lossless round-trip (__level, __has_explicit_id)
  • CLI: parse, rebuild
  • Workspace: multi-file parsing with reference validation

License

AGPL-3.0-or-later © mikilabs

Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

qmdc-1.0.6-py3-none-win_arm64.whl (4.1 MB view details)

Uploaded Python 3Windows ARM64

qmdc-1.0.6-py3-none-win_amd64.whl (4.4 MB view details)

Uploaded Python 3Windows x86-64

qmdc-1.0.6-py3-none-musllinux_1_1_x86_64.whl (4.6 MB view details)

Uploaded Python 3musllinux: musl 1.1+ x86-64

qmdc-1.0.6-py3-none-manylinux_2_28_aarch64.whl (4.2 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

qmdc-1.0.6-py3-none-manylinux_2_17_x86_64.whl (4.6 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

qmdc-1.0.6-py3-none-macosx_11_0_arm64.whl (4.4 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

qmdc-1.0.6-py3-none-macosx_10_12_x86_64.whl (4.7 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file qmdc-1.0.6-py3-none-win_arm64.whl.

File metadata

  • Download URL: qmdc-1.0.6-py3-none-win_arm64.whl
  • Upload date:
  • Size: 4.1 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for qmdc-1.0.6-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 098a27be7f24165e25a897912db561c93848231946a58a4c206805694399c574
MD5 dcb5b9cdaae0dff0ab1f8fbf6d7caa49
BLAKE2b-256 7b12af0b118316457a2bf3dd77bde6333a69db0148450e3a0259d3b98771a50c

See more details on using hashes here.

File details

Details for the file qmdc-1.0.6-py3-none-win_amd64.whl.

File metadata

  • Download URL: qmdc-1.0.6-py3-none-win_amd64.whl
  • Upload date:
  • Size: 4.4 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for qmdc-1.0.6-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 e5f57fbeba1a6d44bec9636dc0dff1f3b00f51eba60313fa5579687f88ffdcdb
MD5 4a89694133aebb1650ecd081b174fefa
BLAKE2b-256 301bf21ec20c0e6fd5b5ddb261c465b3184ecb7fd3d6abf5592a5ddf8f0760d2

See more details on using hashes here.

File details

Details for the file qmdc-1.0.6-py3-none-musllinux_1_1_x86_64.whl.

File metadata

  • Download URL: qmdc-1.0.6-py3-none-musllinux_1_1_x86_64.whl
  • Upload date:
  • Size: 4.6 MB
  • Tags: Python 3, musllinux: musl 1.1+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for qmdc-1.0.6-py3-none-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 429ba550a873c8f29221a3bee3bd0d6e39828b79ca5ad5b8055845b23866caf7
MD5 203d6dd10989fb36dbf6ce5dd2127ead
BLAKE2b-256 091c3239314e75d2b0b6dae5099cf3a82fbf6f36213944b22a3cbe57a6fba856

See more details on using hashes here.

File details

Details for the file qmdc-1.0.6-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for qmdc-1.0.6-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9e70497a258964b65ca863bbc6f015e3aa879a46a3dbe5e03cb25f9ca100d8c9
MD5 71647efe5b4055fedef121e75a7b19bc
BLAKE2b-256 2e92cf9d6e45e4eed1b95cc5840e30f3257eb795c1e4d51d9ab27c069c16c37d

See more details on using hashes here.

File details

Details for the file qmdc-1.0.6-py3-none-manylinux_2_17_x86_64.whl.

File metadata

  • Download URL: qmdc-1.0.6-py3-none-manylinux_2_17_x86_64.whl
  • Upload date:
  • Size: 4.6 MB
  • Tags: Python 3, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for qmdc-1.0.6-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 1b75c021ec5448b8b72118d0ebee8323fc033e860177d2e37e39e007d899a54f
MD5 c916d4526756a3945bc2122344e6ad75
BLAKE2b-256 f25b870a331fd4c93449b582253af64d30366e5e73b9c83724a3ea7f062939a3

See more details on using hashes here.

File details

Details for the file qmdc-1.0.6-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: qmdc-1.0.6-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 4.4 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for qmdc-1.0.6-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e1b946fa975f69199f1084faf33d9bf94bf9c0e13ff1dae0f1939de5bc398326
MD5 7c4320a7cf2ecc1f1f6becad90fb5f58
BLAKE2b-256 a79034fddd9d05ddd4f53179ad43e20341158ac0737e0d25102d3e53e408452f

See more details on using hashes here.

File details

Details for the file qmdc-1.0.6-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for qmdc-1.0.6-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5d6fd4b54ffd27c8f24c79360a90d6b16eb0574e51fe773ccb80ea5f765c99da
MD5 ee740d28d5e381469e395fd75dfe6460
BLAKE2b-256 a172da3de6a15758b02285a6ed9306793e51147204b2091588a0eece9e0fbcb1

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.6 This release

7 files

1.0.5

7 files

1.0.3

7 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page