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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sphinx_rustdoc_postprocess-0.1.1.tar.gz (88.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sphinx_rustdoc_postprocess-0.1.1-py3-none-any.whl (8.2 kB view details)

Uploaded Python 3

File details

Details for the file sphinx_rustdoc_postprocess-0.1.1.tar.gz.

File metadata

File hashes

Hashes for sphinx_rustdoc_postprocess-0.1.1.tar.gz
Algorithm Hash digest
SHA256 091cf42f660049e17c8632390a16267006800747b86635063fda02dbc5df6a94
MD5 4ff340cc8dc37bfab8c7876b2a41f021
BLAKE2b-256 29b5fbf07cd42648bad3f6c8026a724d4099230373b1bc2633e5b27137aef101

See more details on using hashes here.

Provenance

The following attestation bundles were made for sphinx_rustdoc_postprocess-0.1.1.tar.gz:

Publisher: publish.yml on HaoZeke/sphinx-rustdoc-postprocess

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sphinx_rustdoc_postprocess-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for sphinx_rustdoc_postprocess-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f650713d35c89e87d78022bc4d598f9786ac8e5a6c699e1f3ab47ab54f23abbe
MD5 e81241e27b499bf4dc2174ba8572695e
BLAKE2b-256 269bd12031e1dc3aadb5123629a83688bf088539d69f2a6850729aca2464c204

See more details on using hashes here.

Provenance

The following attestation bundles were made for sphinx_rustdoc_postprocess-0.1.1-py3-none-any.whl:

Publisher: publish.yml on HaoZeke/sphinx-rustdoc-postprocess

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page