Skip to main content

madcatter🎩

PyPI version CI Python 3.12+ License: Apache-2.0 Discord

Rich-based Markdown console renderer (mdcat) and helpers.

Quick Start

uvx madcatter@latest README.md

See Install for additional details.

Example

cat sample.md on the left, mdcat sample.md on the right

If you like reading Markdown in the terminal and want it actually rendered -- emoji, math, tables, syntax highlighting -- instead of dumped raw.

mdcat README.md                  # render a file
mdcat -                          # render stdin
echo '# hi :wave:' | mdcat -     # emoji shortcodes are expanded
echo '$e^{i\pi}+1=0$' | mdcat    # best effort LaTeX: eⁱ⁽π⁾+1=0
mdcat --toc README.md            # render just the table of contents
mdcat foo.md | less -R           # color is on, even through pipes
mdcat --no-color foo.md          # plain text (also --no-c)

Description

madcatter is a Rich-based Markdown renderer for the terminal. It exists because cat-ing a Markdown file dumps raw #/**/``` noise, and most "pretty cat" tools stop at syntax highlighting: madcatter also expands :shortcode: emoji, converts LaTeX math to Unicode, extracts a table of contents or a single section, validates links, diffs two documents, and can tail a growing file the way tail -F tails a log. The package is called madcatter; it installs a CLI called mdcat, also runnable as madcatter.

The same file (docs/assets/sample.md), dumped raw with cat (left) and rendered by mdcat (right): an emoji shortcode, $...$ math, a highlighted code block, and a table.

Features

  • Left-justified headings (Rich's default Markdown centers them; madcatter doesn't).
  • :shortcode: emoji expansion, skipped inside fenced/indented code.
  • LaTeX-to-Unicode math for $...$ and $$...$$, also skipped inside code.
  • Syntax-highlighted fenced code blocks via Pygments themes, plus a code-only extraction mode.
  • Table-of-contents rendering and single-section extraction by heading name.
  • Link extraction and live link validation (HTTP HEAD checks).
  • Unified diff rendering between two Markdown files.
  • --watch (re-render on change) and --follow/-f/-F (tail -F semantics: emit only new lines, survive atomic rewrites).
  • ASCII-only, HTML, and ANSI export.
  • In-place rendering (-i) and --unrender, which reads rendered output back into markdown.
  • YAML frontmatter stripping.

Install

uv tool install madcatter && mdcat README.md
# Later: uv tool upgrade madcatter

If you're missing uvx/uv,

  • Mac
    brew install uv
    
  • Linux
    sudo apt install -y curl
    curl -LsSf https://astral.sh/uv/install.sh | sh
    

To add madcatter to your own project as a library,

uv add madcatter

Or with pip,

python -m pip install madcatter

Usage cookbook

All examples below use real mdcat flags; run mdcat --help for the complete list.

Basic render

mdcat README.md              # render a file
mdcat -                      # render stdin
mdcat a.md b.md --separator  # render several files, with a rule between them

Style profiles (--style, one of dark, light, dracula, solarized)

mdcat --style dracula doc.md

Table of contents

mdcat --toc README.md

Single section by heading name

mdcat --section Install README.md

Links: list or validate

mdcat --links README.md         # list every URL found in the document
mdcat --check-links README.md   # also issue a live HTTP HEAD request to each http(s) link

Code blocks only, optionally filtered by language (--code-lang implies --code-only)

mdcat --code-only README.md
mdcat --code-lang python README.md

Diff two Markdown files

mdcat old.md --diff new.md

Watch vs. follow -- both require a single real file path (stdin - is rejected), and the two are mutually exclusive with each other:

mdcat --watch notes.md   # re-render the whole file whenever its mtime changes
mdcat -f log.md          # tail -F semantics: emit only new lines, re-anchor across rewrites
mdcat -n 20 -f log.md    # on first attach/reopen, show only the last 20 lines

Export

mdcat --export-html out.html README.md
mdcat --export-ansi out.ansi README.md

ASCII-only output (no ANSI codes, no Unicode -- box-drawing, bullets, arrows, etc. are transliterated)

mdcat --ascii README.md

Render in place, and back -- -i writes the colored render over the file, at 80 columns unless -w is given; --unrender turns it back into the exact markdown. The file carries its source in invisible escape codes. If the shown text was edited since, or for other mdcat output, --unrender reads the markdown back from what is shown, which keeps only what the render shows.

mdcat -i notes.md                # notes.md now holds the render
mdcat -i --unrender notes.md     # notes.md is markdown again
mdcat notes.md | mdcat --unrender -   # markdown read back from the render

Strip YAML frontmatter before rendering -- useful for notes that start with a --- metadata block

mdcat --no-frontmatter note-with-frontmatter.md

Library

The preprocessing helpers are importable directly:

from madcatter.markdown import process_math_blocks, strip_frontmatter
from madcatter.latex import latex2unicode
from madcatter.emoji import resolve

process_math_blocks(
    "area is $\\pi r^2$"
)  # -> unicode-rendered math, code blocks left intact
strip_frontmatter(["---", "title: x", "---", "body"])  # -> ["body"]
latex2unicode("x^2 + y_i")  # -> "x² + yᵢ"
resolve("wave")  # -> "👋" (or None if unknown)

Development

Requires Python 3.12 and uv.

uv sync --all-groups
uv run pytest

Tests are organized into tiers via pytest markers (see pyproject.toml). The default run (uv run pytest) excludes the slower/networked tiers -- ci_smoke, cuda, integration, performance, cluster, and slow -- so opt in explicitly when needed, e.g.:

uv run pytest -m ci_smoke        # package/CLI smoke tests
uv run pytest -m integration     # tests needing networking or external CLIs

Before opening a pull request, run the same checks CI runs in package-validation.yml. Lint, type checks, and tests all come from .pre-commit-config.yaml:

uv run pre-commit run --all-files --hook-stage pre-commit
uv run pre-commit run --all-files --hook-stage pre-push
uv build

See also

Sibling projects in the rekursiv-ai family:

  • sagent -- The self-mutating multi-provider coding-agent CLI and typed Python library.
  • trackinizer -- Centralized agent database for tracking inquiries, work, and the evidence behind conclusions.
  • wesearch -- Web search, resilient page fetch, and scholarly-paper lookup without a browser stack.
  • priml -- Composable PyTorch building blocks: models, optimizers, losses, and a step-based training loop.
  • configgle -- Hierarchical experiment configuration in typed pure-Python dataclasses instead of YAML.
  • copybarista -- Bidirectional source sync for publishing OSS-ready trees from a monorepo.

Citing

If you find our work useful, please consider citing:

@misc{rekursivai2026madcatter,
      title={Madcatter - Rich-based Markdown console renderer (mdcat) and helpers.},
      author={Joshua V. Dillon},
      year={2026},
      howpublished={Github},
      url={https://github.com/rekursiv-ai/madcatter},
}

Metadata

Release files for madcatter 0.1.7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for madcatter 0.1.7
File Size Uploaded Provenance Actions
madcatter-0.1.7.tar.gz 422.8 kB With provenance Details for madcatter-0.1.7.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for madcatter 0.1.7
File Interpreter ABI Platform Actions
madcatter-0.1.7-py3-none-any.whl Python 3 none any Details for madcatter-0.1.7-py3-none-any.whl

Total release size: 511.0 kB

Release files / madcatter-0.1.7.tar.gz

Download URL madcatter-0.1.7.tar.gz
Size 422.8 kB
Tags Source
SHA-256 checksum
How to use checksums
ba13c456a1f32800fd9089c6b0dd6fce1600f178c2ac24f58c53df7d7c99797c
BLAKE2b-256 checksum
How to use checksums
615337063d86fa1fb9841c7110739d9282f0bf8d7c9435ba7872568437482eb2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / madcatter-0.1.7-py3-none-any.whl

Download URL madcatter-0.1.7-py3-none-any.whl
Size 88.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bd00c3560d11887d12813c40a3d3df08fba6def0af4b4ce1f13f1131676f1399
BLAKE2b-256 checksum
How to use checksums
d64eaec559ff4a5417efb8be1a81cb3e753939ca4bf2c3fb326f22deec7cd2f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Security for madcatter 0.1.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for madcatter-0.1.7.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page