API Reference

Complete reference for every CMX module, generated from the source with autodoc.

The API splits into four groups. Core is what you import and call day to day. Backends turn the document tree into output. Utilities support both. Server is optional, for serving live documents.

Core

You interact with CMX through the cmx module: the global doc object, its md alias, and the re-exported cmx.data helpers.

Backends

A backend renders the accumulated document blocks into a concrete format. Markdown is the primary, fully supported backend; the others cover narrower cases.

Markdown

Renders the document tree to Markdown. This is the default backend.

The CommonMark document – the object exported as cmx.doc.

A CommonMark is an Article (so it inherits the component factories: table, image, figure, row, video, savefig) plus the live-document machinery: the @ / | / call operators for adding markdown, with doc: source capture, and flush to write out.

class cmx.backends.markdown.CommonMark(filename=None, overwrite=True, root=None, prefix=None)[source]

Bases: Article

counter = 0
property hide

with doc.hide: runs its body but does not capture the source as a code block – handy for boilerplate you want to execute but not show.

property skip

with doc.skip: skips execution of its body entirely.

Implemented via frame tracing (see SkipContextManager); this can interfere with debuggers such as PyCharm’s pydev.

on_mount(*, filename, wd, figdir, doc, **kw)[source]

Fires once in config() after paths resolve. Return a dest (base key / URL / id) or None for the local filesystem.

on_save(*, data, path, kind, dest, doc, **kw)[source]

Fires per binary asset. Write the bytes locally and return the link.

kind is one of "image" / "video" / "figure". The bytes land under self.wd at path (with any ?query stripped); the returned link (the full path, query intact) is what gets rendered into ![]( ).

on_flush(*, text, path, dest, doc, **kw)[source]

Fires per flush(). Append the rendered text to the md file.

on_close(*, full_text, path, dest, doc, **kw)[source]

Fires once via doc.close() / atexit. Default: no-op.

on_error(*, exc, block, doc, **kw)[source]

Fires in the with doc: exception path. Default: no-op (returns a falsy value so the exception still propagates).

on_block(*, kind, node, doc, **kw)[source]

Fires when a block is appended. kind is one of text / code / table / image / figure / video.

on_hide(*, doc, **kw)[source]

Fires from with doc.hide:. Default: no-op.

on_skip(*, doc, **kw)[source]

Fires from with doc.skip:. Default: no-op.

config(file=None, *, wd=None, figdir=None, overwrite=True, filename=None, src_prefix=None)[source]

Configure where script output lands.

Parameters:
  • file – EITHER a script path (doc.config(__file__), ends with .py) OR an explicit output path (ends with .md). Outputs resolve relative to the script/output, not the cwd.

  • wd – working directory; overrides the default derived from file/filename (or the cwd when neither is given).

  • figdir – a template string for the figure directory. {fname} expands to the markdown stem. When omitted, the default is the per-document "{fname}" folder if the script/output name is known (e.g. doc.config(__file__)), and a shared "figures" directory otherwise.

  • overwrite – clear the file on configure instead of appending.

  • filename – explicit output path (back-compat keyword).

property figdir
new(filename=None, **kwargs)[source]
property filename
write(text, overwrite=None)[source]
clear()[source]
md(*snippets, dedent=True, **kwargs)

Add markdown text: doc("# Title").

pre(text, lang=None, **kwargs)[source]
yaml(data=None, file=None, **kwargs)[source]

Render YAML as a code block.

Pass data to dump a Python object, or file= to read a .yaml file straight from disk (its contents are shown verbatim, comments and all).

csv(csv, show_index=False, **kwargs)[source]
print(*args, sep=' ', end='\n')[source]
flush(*args)[source]
close()[source]

Render/send the document’s full text once (idempotent).

Fires on_close exactly once across explicit close() calls and the registered atexit guard. full_text is the file’s full content for the local case, falling back to the accumulated document text.

class cmx.backends.markdown.Github(filename=None, overwrite=True, root=None, prefix=None)[source]

Bases: CommonMark

Uses tables for the layout.

class cmx.backends.markdown.Gist(filename=None, overwrite=True, root=None, prefix=None)[source]

Bases: CommonMark

Saves everything inside a folder.

Components

The block types (Text, Pre, Table, Image, Figure, Row, Video) shared across backends.

Render components for the CMX markdown backend.

Each component knows how to render itself as Markdown (_md) and HTML (_html). Components form a tree: an Article holds children, some of which (Table, FigureRow, Row) hold children of their own.

This module is dependency-inverted the simple way: there is no class registry or __getattribute__ proxy. Parents create their children by calling the component classes directly. Components are pure render objects – they no longer write files; the document’s lifecycle hooks (on_save and friends, see cmx.backends.markdown.CommonMark) own all I/O and hand each component the final src link to render. Anything that needs heavy third-party libraries (numpy, PIL, pyyaml) imports them lazily so import cmx stays cheap.

cmx.backends.components.read_table(file, sep=None, **kwargs)[source]

Load a tabular file into a pandas DataFrame, inferred by extension.

Supports .csv / .tsv (text), .json, .parquet, and Excel (.xls / .xlsx); .yaml / .yml are parsed and fed to the DataFrame constructor. Extra kwargs are forwarded to the matching pandas reader. sep overrides the delimiter for text files (defaulting to a tab for .tsv and a comma otherwise). Unknown extensions are read as CSV.

cmx.backends.components.attrs(class_name=None, **kwargs)[source]
cmx.backends.components.styles(**kwargs)[source]
class cmx.backends.components.Component(tag=None, children=None, **kwargs)[source]

Bases: object

Base node in the document tree.

A component renders to Markdown via _md and to HTML via _html. The default implementation emits a generic <tag>...children...</tag>; most subclasses override one or both properties.

data = None
class_name = None
tag = None
now(fmt=None)[source]
class cmx.backends.components.Container(tag=None, children=None, **kwargs)[source]

Bases: Component

A holder that is rendered by its parent, never on its own.

class cmx.backends.components.Div(tag=None, children=None, **kwargs)[source]

Bases: Component

tag = 'div'
class cmx.backends.components.Span(*args, sep=' ', dedent=None, end='\n', **kwargs)[source]

Bases: Component

tag = 'span'
cmx.backends.components.Text

alias of Span

class cmx.backends.components.Bold(*args, sep=' ', dedent=None, end='\n', **kwargs)[source]

Bases: Span

tag = 'b'
class cmx.backends.components.Pre(text, lang=None, **kwargs)[source]

Bases: Component

tag = 'pre'

Bases: Component

tag = 'span'
class cmx.backends.components.Img(src=None, zoom=None, alt=None, **kwargs)[source]

Bases: Component

tag = 'img'
zoom = None
class cmx.backends.components.Image(image=None, src=None, normalize=False, **kwargs)[source]

Bases: Img

An image that either references a src link or inlines base64 data.

Components no longer perform any file I/O – the document’s on_save hook writes the bytes and returns the link, which is passed here as src.

  • src given -> reference that link (already resolved by on_save).

  • image only -> inline the array as a base64 data: URI.

data = None
property base64
class cmx.backends.components.Video(src=None, width=320, height=240, controls=True, **kwargs)[source]

Bases: Component

cmx.backends.components.video(frames=None, *, src, **kwargs)[source]

Return the component matching src.

.gif sources render as an Image; everything else as a Video. Frame data is saved by the document’s on_save hook, not here.

class cmx.backends.components.Figure(image=None, src=None, title=None, caption=None, **kwargs)[source]

Bases: Component

tag = 'div'
class cmx.backends.components.Savefig(key, caption=None, width=None, height=None, zoom=None, **kwargs)[source]

Bases: Figure

Save the current matplotlib figure to key and reference it inline.

key is the destination path (an optional ?... query suffix is stripped before writing, so it can double as a cache-buster in the src). title/caption/width/height/zoom control how the figure is displayed; every other keyword (dpi, bbox_inches, transparent, facecolor, format …) is forwarded untouched to matplotlib’s savefig (through the document’s on_save hook) and is not leaked into the <img> tag.

class cmx.backends.components.Row(wrap=False, styles=None, **kwargs)[source]

Bases: Component

styles = {'display': 'flex', 'flex_direction': 'row', 'item_align': 'center'}
class cmx.backends.components.FigureRow(header=None, n_cols=None, doc=None, **kwargs)[source]

Bases: Container

A horizontal band of figures rendered by its parent Table as up to three Markdown rows: titles, images, and captions (empty bands are dropped).

figure(image=None, src=None, title=None, caption=None, **kwargs)[source]
video(frames=None, src=None, title=None, caption=None, **kwargs)[source]
column(title=None, text=None, footer=None)[source]
savefig(key, title=None, caption=None, **kwargs)[source]
property rows
class cmx.backends.components.Table(table=None, file=None, show_index=None, format='github', sep=',*', doc=None, **kwargs)[source]

Bases: Component

A Markdown/HTML table.

Pass tabular data (a DataFrame, CSV string, or anything pandas accepts) for a data table, or build a figure grid with figure_row().

data: pd.DataFrame | None = None
figure_row(**kwargs)[source]
class cmx.backends.components.Html(tag=None, children=None, **kwargs)[source]

Bases: _Factory, Component

tag = 'body'
class cmx.backends.components.Article(tag=None, children=None, **kwargs)[source]

Bases: Html

tag = 'article'
class_name = 'commonmark'
class cmx.backends.components.Print(*args, sep=' ', end='\n', **kwargs)[source]

Bases: Pre

Table renderer

Pure-Python renderer for the default github table format. It needs no tabulate and matches to_markdown(tablefmt="github") byte for byte.

Pure-Python GitHub-flavored Markdown table renderer.

This module reproduces, byte-for-byte, the output of pandas.DataFrame.to_markdown(tablefmt="github", index=<bool>) for the slice of behavior CMX relies on – WITHOUT importing tabulate at runtime.

It is a faithful, narrow re-implementation of tabulate’s GitHub format. The algorithm mirrors tabulate’s internals:

  • Per-column type detection (least-generic type over the column’s values). bool/str/bytes/datetime columns are STRING (left-aligned); int and float columns are NUMERIC (decimal-point aligned, which collapses to right-alignment).

  • Number formatting matches tabulate defaults: ints via str/format(""); floats via the g format. Missing values (None / NaN) render as "".

  • Width = max(len(header) + MIN_PADDING, max cell width); cells get one space of padding on each side; the separator row is plain dashes (no colons).

  • index=True prepends the DataFrame index as a leading column (with the index name – or an empty string – as its header).

Only pandas/numpy are used, and only to introspect the frame’s values; they are already dependencies of the tables feature.

The reference for this implementation is tabulate 0.x’s __init__.py (functions _type, _column_type, _format, _align_column, _align_header, _format_table and the "github" TableFormat).

cmx.backends.md_table.render(df, index=False)[source]

Render a pandas DataFrame as a GitHub-flavored Markdown table string.

Reproduces df.to_markdown(tablefmt="github", index=index) exactly (without any trailing newline). Only pandas/numpy are used to read the frame; tabulate is never imported.

HTML

HTML output support.

LaTeX

LaTeX output support for academic papers and publications.

Utilities

Utils

Helper functions used across the package.

class cmx.utils.F(fn=None)[source]

Bases: object

Functional notation wrapper - allows using @ operator for function composition

Usage: - F @ function - wraps a function - (F @ function)(args) - calls the wrapped function

cmx.utils.is_empty(line)[source]
cmx.utils.get_indent(text)[source]
cmx.utils.dedent(text)[source]
cmx.utils.get_block(filename, line_number)[source]
cmx.utils.is_subclass(obj, cls)[source]
cmx.utils.to_snake(name)[source]
cmx.utils.write_image(image, path, *, wd=None, normalize=False)[source]

Write an image array (or PIL image) to path under wd.

cmx.utils.write_video(frames, path, *, wd=None)[source]

Write video frames to path under wd (.gif only for now).

cmx.utils.write_savefig(path, *, wd=None, **kwargs)[source]

Save the current matplotlib figure to path under wd.

cmx.utils.append_text(text, path, *, wd=None, overwrite=False)[source]

Append (or overwrite) text to path under wd (mkdir -p).

Data

Data-processing helpers, re-exported as cmx.data.

Context managers

The frame-tracing machinery behind with doc:, doc.hide, and doc.skip.

exception cmx.with_hack.SkipException[source]

Bases: Exception

class cmx.with_hack.SkipContextManager(skip)[source]

Bases: object

trace(frame, event, arg)[source]

Server

Optional components for serving live documents.

async cmx.server.echo(request, ws)
Parameters:
  • request (sanic.Request)

  • ws (sanic.Websocket)

async cmx.server.log(request, ws)
Parameters:
  • request (sanic.Request)

  • ws (sanic.Websocket)

Next steps

  • Development — set up a dev environment, run tests, and build these docs.