CMX
Generate live Markdown documentation from Python scripts — you choose exactly what appears.
CMX runs your script and captures the parts you mark, turning code and its output into a Markdown file. It works like a notebook, but you control what shows up: source, printed results, tables, images, and more. The core has zero third-party dependencies; richer blocks pull in small, opt-in extras.
Installation
Install the core from PyPI. It needs no third-party packages:
pip install cmx
Add extras only for the features you use:
| Install | Pulls in | Enables |
|---|---|---|
pip install cmx |
nothing | text, operators, doc.print, doc.pre, capture, flush |
pip install 'cmx[tables]' |
pandas | doc.table, doc.csv |
pip install 'cmx[images]' |
pillow, numpy | array images, doc.image / figure / video |
pip install 'cmx[figures]' |
matplotlib | doc.savefig |
pip install 'cmx[yaml]' |
pyyaml | doc.yaml |
pip install 'cmx[all]' |
all of the above | everything |
CMX requires Python 3.11 or later.
Quick start
Configure an output file, capture a block of code, then write it to disk. Create report.py:
from cmx import doc
doc.config(__file__)
with doc:
doc @ "# Daily Report"
total = sum(range(100))
doc.print(f"Sum of 0-99: {total}")
doc.flush()
Run it with python report.py. CMX writes report.md next to the script:
# Daily Report
```python
total = sum(range(100))
doc.print(f"Sum of 0-99: {total}")
```
```
Sum of 0-99: 4950
```
The with doc: block captures its own source as a code fence and runs it; doc.print echoes to your terminal and appends the output. Code outside a with doc: block still runs — it just doesn't appear in the document.
Common patterns
Add text three equivalent ways. Each appends a text block and returns doc:
doc("## Results", end="\n") # call form (end="\n" is the default)
doc @ "## Results" # prefix @ operator
"## Results" | doc # postfix | operator
Render a DataFrame (needs cmx[tables]):
import pandas as pd
with doc:
doc.table(pd.DataFrame({"model": ["a", "b"], "acc": [0.95, 0.87]}))
Save and link an image (needs cmx[images]). A bare filename lands in the document's figure folder; a path with a slash is used as written:
import numpy as np
with doc:
doc.image(np.random.rand(64, 64, 3), src="sample.png")
Render a config dict as YAML (needs cmx[yaml]):
with doc:
doc.yaml({"model": "ResNet50", "epochs": 100})
Hide setup, keep results. doc.hide runs a block without showing it; variables it defines stay in scope:
with doc.hide:
data = load_results()
with doc:
doc @ "## Analysis"
doc.print(f"Best: {data['accuracy'].max():.2%}")
Documentation
Full documentation: https://cmx-python.readthedocs.io
- Get started — the config → capture → flush workflow.
- Configuration — where Markdown and assets are written.
- Adding text, Tables, Images.
- API reference.
Runnable examples live in examples/core/ — see its README.
Development
git clone https://github.com/cmx/cmx-python.git
cd cmx-python
pip install -e '.[dev,docs]' # editable install with test + docs tooling
make test # run the pytest suite
make preview # live-reload docs at http://localhost:8000
make docs # build the HTML docs
See the Development guide for the full workflow.
Claude Code plugin
CMX ships a Claude Code plugin with two skills that guide Claude through CMX's API and component usage when you work on a CMX project. To set it up, run inside Claude Code:
/plugin marketplace add cmx/cmx-python
/plugin install cmx@cmx
Claude then loads the skills automatically whenever a task touches CMX; you can also invoke them directly:
/cmx:cmx-basics— configuration (doc.config,figdir), context managers, output methods, and lifecycle hooks/cmx:cmx-components— tables andfigure_rowmedia grids, images, figures, videos, and troubleshooting
The skill sources live in skills/; plugin and marketplace metadata live in .claude-plugin/.
Project structure
cmx-python/
├── src/cmx/
│ ├── backends/ # markdown, components, md_table, html, latex
│ └── server/ # optional server stub
├── docs/ # Sphinx + MyST documentation
├── examples/core/ # numbered tutorial examples
├── tests/ # pytest suite + golden-file harness
├── skills/ # Claude Code plugin skills (SKILL.md per skill)
├── .claude-plugin/ # Claude Code plugin + marketplace metadata
├── pyproject.toml # project configuration
└── Makefile # build automation
Contributing
Contributions are welcome. See the Development guide for setup, tests, and the publishing flow.
Authors
- Ge Yang
- Tom Tao
License
MIT — see LICENSE.
Links
- Documentation: https://cmx-python.readthedocs.io
- GitHub: https://github.com/cmx/cmx-python
- PyPI: https://pypi.org/project/cmx/
- Issues: https://github.com/cmx/cmx-python/issues
Release files for cmx 0.0.52
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cmx-0.0.52.tar.gz | 38.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cmx-0.0.52-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 63.7 kB
Release files / cmx-0.0.52.tar.gz
| Download URL | cmx-0.0.52.tar.gz |
|---|---|
| Size | 38.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8047462705dfffa474657e0a0b76eff847679a0aae196d01756da36a3f6e2f6f
|
|
BLAKE2b-256 checksum How to use checksums |
cdc8f8b6c2917359d6c4175b97546c180b6a9f6aa082602c71317abe54c1d584
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / cmx-0.0.52-py3-none-any.whl
| Download URL | cmx-0.0.52-py3-none-any.whl |
|---|---|
| Size | 25.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ca81066981682cbdd5ea4eec7e89c9d75de0ea77e515fd3c50e33da7a033569e
|
|
BLAKE2b-256 checksum How to use checksums |
240d4f4811ec1905e809361ecbd1f9ea2b6e1d5a2a2894ff31dda098b5499d5d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|