Skip to main content

QMDC parser — convert QMD.md to a queryable object graph (JSON) and back

Project description

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

Project details


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.3-py3-none-win_arm64.whl (4.1 MB view details)

Uploaded Python 3Windows ARM64

qmdc-1.0.3-py3-none-win_amd64.whl (4.5 MB view details)

Uploaded Python 3Windows x86-64

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

Uploaded Python 3musllinux: musl 1.1+ x86-64

qmdc-1.0.3-py3-none-manylinux_2_28_aarch64.whl (4.3 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

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

Uploaded Python 3manylinux: glibc 2.17+ x86-64

qmdc-1.0.3-py3-none-macosx_11_0_arm64.whl (4.5 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

qmdc-1.0.3-py3-none-macosx_10_12_x86_64.whl (4.8 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: qmdc-1.0.3-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.8

File hashes

Hashes for qmdc-1.0.3-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 f7fb139c71b0d5f2153a104c5e22027c958192980e9dc214a6bffa6f3c2921b8
MD5 8cdddc59ef0770c5f33668865ab73fb8
BLAKE2b-256 1d8ba921a25a972156d665f3c217e8d09ab02e7417acc352b2619a7357123218

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for qmdc-1.0.3-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 ddd189ee997debdceec599d3e01258930a631c9e5f76be45acecdae1f3b8a230
MD5 954ea782d1466bec672d2da3ec55d74c
BLAKE2b-256 c98792d79c7645cc56712bbfcf7889273b90ac48366623649c73b6b4b996beb9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: qmdc-1.0.3-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.8

File hashes

Hashes for qmdc-1.0.3-py3-none-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 dc1554ea875cc2a5cde156f1c72344d9124ec8d22a55e83d63349fcadb32eeec
MD5 3d8c75d0baf631858018e29a92ac8379
BLAKE2b-256 a609020c51cdb3baac594f908454bd44c27407b1fd1375ebdbb0152132796e7f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for qmdc-1.0.3-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9181f93f22ad555786804d3fe24c90990bae6fb53822f77b927ddf0e4b9c9e7b
MD5 69a68b707e9e2ebc2959c27d2f73619a
BLAKE2b-256 55b0f96f215f1813d858a3199542a478730fcaef8f6cb80e2f643f00bab5b21f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: qmdc-1.0.3-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.8

File hashes

Hashes for qmdc-1.0.3-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 21357c406684d5041866f5978c24fceca26f6ab707d47543692e55fe4b0ed45b
MD5 9a73cee5a224c6add19c986395373f59
BLAKE2b-256 697399a281de2d5ec0a49f5a45d6a4c1b828fef574a807ab72caacf68feb8e81

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for qmdc-1.0.3-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b23d049320d9861928a9de3ff10dcee6999ec30b9f1b9eaca0d15603454bf8bd
MD5 814ad5b588ba8d0c25700d5ec4a3d5fe
BLAKE2b-256 e29941c459bd6bbb1d133cae59cc7546e8f3e657548b3a82b6362575bb872d9e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for qmdc-1.0.3-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0fda095b4d8a5bc37a00713f98d18047031574a81992d6e1274e0464d4e61b4b
MD5 f79e700a3b3b262678ce945eddcad386
BLAKE2b-256 8f819def7c4dbab0df051553ade34ec27473e2f615683f35d4925930a039613e

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