Skip to main content

sphinx-rustdoc-postprocess

Post-process sphinxcontrib-rust RST output, converting leftover markdown fragments (code fences, tables, links, headings, inline code) to proper RST via pandoc.

The problem

sphinxcontrib-rust generates RST files from Rust crates, but rustdoc doc-comments are written in markdown. The generated RST ends up with markdown fragments embedded verbatim inside directive bodies, which Sphinx cannot render correctly.

For a real-world example, see rgpot (source), which uses this extension to document its Rust core library alongside C++ API docs.

Before (raw sphinxcontrib-rust output)

Given Rust doc-comments like these in lib.rs:

//! ## Module Overview
//!
//! | Module | Purpose |
//! |--------|---------|
//! | [`types`] | `#[repr(C)]` data structures for force/energy I/O |
//! | [`tensor`] | DLPack tensor helpers |

sphinxcontrib-rust produces RST with the markdown still intact inside directives:

.. py:module:: rgpot_core

   ## Module Overview

   | Module | Purpose |
   |--------|---------|
   | [`types`] | `#[repr(C)]` data structures for force/energy I/O |
   | [`tensor`] | DLPack tensor helpers |

This renders incorrectly in Sphinx: headings inside directives break the document structure, markdown tables appear as literal pipe characters, and single-backtick code is not valid RST.

After (postprocessed output)

After this extension runs, the same file becomes:

.. py:module:: rgpot_core

   **Module Overview**

   +------------+----------------------------------------------------+
   | Module     | Purpose                                            |
   +============+====================================================+
   | ``types``  | ``#[repr(C)]`` data structures for force/energy IO |
   +------------+----------------------------------------------------+
   | ``tensor`` | DLPack tensor helpers                              |
   +------------+----------------------------------------------------+

Similarly, markdown code fences:

```c
rgpot_status_t s = rgpot_potential_calculate(pot, &input, &output);
if (s != RGPOT_SUCCESS) {
    fprintf(stderr, "rgpot error: %s\n", rgpot_last_error());
}
```

become proper RST code-block directives:

.. code-block:: c

   rgpot_status_t s = rgpot_potential_calculate(pot, &input, &output);
   if (s != RGPOT_SUCCESS) {
       fprintf(stderr, "rgpot error: %s\n", rgpot_last_error());
   }

And markdown links like [metatensor](https://docs.metatensor.org/) become `metatensor <https://docs.metatensor.org/>`_, while rustdoc intra-doc links like [`types`] become types .

Installation

pip install sphinx-rustdoc-postprocess

Pandoc must be available on your PATH. See pandoc.org for installation instructions.

Usage

Add to your Sphinx conf.py:

extensions = [
    "sphinxcontrib_rust",
    "sphinx_rustdoc_postprocess",
]

The extension hooks into builder-inited at priority 600 (after sphinxcontrib-rust's default 500), so it automatically runs on the generated RST files before Sphinx reads them.

Configuration

Config value Default Description
rustdoc_postprocess_rst_dir "crates" Subdirectory of srcdir to scan for RST files
rustdoc_postprocess_toctree_target "" RST file to inject a toctree snippet into (empty = skip)
rustdoc_postprocess_toctree_rst "" RST snippet to append to the target file (empty = skip)

Full configuration example

# conf.py
import os

extensions = [
    "sphinxcontrib_rust",
    "sphinx_rustdoc_postprocess",
]

# sphinxcontrib-rust settings
rust_crates = {
    "my_crate": os.path.abspath("../../my-crate/"),
}
rust_doc_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "crates")
rust_rustdoc_fmt = "rst"

# Inject a toctree entry for the Rust docs into an existing index page
rustdoc_postprocess_toctree_target = "api/index.rst"
rustdoc_postprocess_toctree_rst = """

Rust API
--------

.. toctree::
   :maxdepth: 2

   ../crates/my_crate/lib
"""

What gets converted

Markdown construct RST output
```lang code fences .. code-block:: lang directives
\vert table \vert pipe tables RST grid tables (via pandoc)
[text](url) links `text <url>`_
[`Name`] intra-doc links ``Name``
`code` inline code ``code``
## Heading ATX headings **Heading** (bold, since RST headings can't nest in directives)

Development

pixi install
pixi run test

A pre-commit job is setup on CI to enforce consistent styles, so it is best to set it up locally as well (using uvx for isolation):

# Run before committing
uvx pre-commit run --all-files

License

MIT

Metadata

Release files for sphinx-rustdoc-postprocess 0.1.1

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

Source distribution (sdist)

Source distribution for sphinx-rustdoc-postprocess 0.1.1
File Size Uploaded
sphinx_rustdoc_postprocess-0.1.1.tar.gz 88.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sphinx-rustdoc-postprocess 0.1.1
File Interpreter ABI Platform
sphinx_rustdoc_postprocess-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 97.1 kB

Release files / sphinx_rustdoc_postprocess-0.1.1.tar.gz

Download URL sphinx_rustdoc_postprocess-0.1.1.tar.gz
Size 88.8 kB
Tags Source
SHA-256 checksum
How to use checksums
091cf42f660049e17c8632390a16267006800747b86635063fda02dbc5df6a94
BLAKE2b-256 checksum
How to use checksums
29b5fbf07cd42648bad3f6c8026a724d4099230373b1bc2633e5b27137aef101
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 9, 2026.

Transparency log

Release files / sphinx_rustdoc_postprocess-0.1.1-py3-none-any.whl

Download URL sphinx_rustdoc_postprocess-0.1.1-py3-none-any.whl
Size 8.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f650713d35c89e87d78022bc4d598f9786ac8e5a6c699e1f3ab47ab54f23abbe
BLAKE2b-256 checksum
How to use checksums
269bd12031e1dc3aadb5123629a83688bf088539d69f2a6850729aca2464c204
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 Jul 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

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