Skip to main content

Parse Doxygen-documented C++ with libclang and generate MyST Markdown API docs for Sphinx

Project description

clangquill

ClangQuill Logo

image

Parse Doxygen-documented C++ with libclang and generate MyST Markdown API docs for Sphinx.

clangquill reads your C++ headers with libclang, extracts classes, functions, namespaces, enums and their documentation comments into a SQLite intermediate representation, and renders MyST Markdown pages. Every symbol becomes a real Sphinx C++ domain object ({cpp:class}, {cpp:function}, …) — so the generated API appears in objects.inv and cross-references like any hand-written page, with inter-symbol links resolved through {cpp:any}.

Features

  • libclang-based parsing of real C++ (c++20 / c++23 / c++26), including Doxygen comments and compile_commands.json support.
  • First-class Sphinx integration — output is MyST Markdown backed by the Sphinx C++ domain, so symbols cross-reference and show up in the search index.
  • Three front-ends for the same pipeline: a Sphinx extension, a clangquill CLI, and a Python API.
  • Incremental builds — a persistent SQLite IR plus a hash cache skip re-parsing unchanged inputs, rewrite only pages whose content changed, and delete pages for symbols that disappeared.
  • Customizable output via per-kind Jinja2 templates you can override one file at a time.
  • Pluggable comment parsers (Doxygen by default).

Installation

clangquill is published on PyPI. Install it with uv:

uv pip install clangquill

(Plain pip install clangquill works too.)

The Linux wheels bundle a self-contained libclang 22 from the official LLVM release, so parsing works out of the box with no system LLVM required. That bundled libclang needs glibc ≥ 2.34 (manylinux_2_34); on older distributions, build from source against your own libclang instead.

Quick start

Sphinx extension

For the common case you do not need to drive the parser yourself: enable the bundled extension and it runs the whole pipeline — parse → SQLite → MyST — at build time, regenerating pages into your source tree before Sphinx reads them.

# conf.py
extensions = ["clangquill.sphinx_ext"]  # pulls in myst_parser automatically

clangquill_input = ["../include/**/*.hpp"]
clangquill_output_dir = "api"          # written under the Sphinx srcdir
clangquill_std = "c++20"
clangquill_include_dirs = ["../include"]

Then reference the generated toctree from your root document:

```{toctree}
api/index
```

Every knob is a clangquill_* config value mirroring a field of clangquill.config.Config — including clangquill_compile_commands, clangquill_template_dirs, clangquill_include_undocumented, clangquill_comment_parser and clangquill_group_by. See the configuration guide for the full reference.

Command line

The same pipeline is available standalone, handy for previewing output or wiring clangquill into a non-Sphinx build:

$ clangquill build include/geo.hpp -o docs/api --std c++20 -I include
Parsed 7 symbol(s) from 1 file(s).
Wrote 1 page(s) to /path/to/docs/api.

Run clangquill build --help for the full set of options, which mirror the clangquill_* config values.

Python API

Once a project has been parsed into the SQLite IR, the generator renders it into MyST Markdown: one page per top-level symbol plus an index.md toctree.

from clangquill.generator import Generator
from clangquill.store import Store

with Store.open("api.sqlite") as store:
    Generator(store).generate("docs/api")

Incremental builds

Set clangquill_cache_dir (or the matching CLI/API option) to make rebuilds incremental. clangquill keeps the SQLite IR and a small bookkeeping cache between runs and:

  • skips the parse when no input — or transitively #included header — changed, reusing the cached IR instead of invoking libclang again;
  • rewrites only the pages whose content changed; and
  • deletes pages whose symbols disappeared.

Without a cache directory the build is stateless: it re-parses into a throwaway database and rewrites every page each time.

Templates

Templates are the customization point. The Jinja environment looks up {kind}.md.jinja (e.g. class.md.jinja, function.md.jinja) in your own template directories before the bundled defaults, so dropping in a file of the same name overrides just that kind:

Generator(store, template_dirs=["my_templates"]).generate("docs/api")

See the templates guide for the available templates and context variables.

Building from source

clangquill ships a compiled C++ core (clangquill._core) built with scikit-build-core, CMake and nanobind. A standard install builds it:

uv pip install .
uv run python -c "from clangquill import _core; print(_core.have_libclang())"

The core optionally links libclang; when libclang-dev (or an LLVM prefix via LibClang_ROOT) is available at build time the extraction backend is enabled. Pass -DCLANGQUILL_WITH_LIBCLANG=ON to require it.

Documentation

Contributing

Contributions are welcome — see CONTRIBUTING.md. In short:

uv sync --extra dev
uvx pre-commit install
uv run pytest      # Python test suite
make cpp-test      # C++ (Catch2) unit tests

License

clangquill is released under the BSD 2-Clause License — see LICENSE. The Linux wheels additionally bundle libclang, distributed under the Apache-2.0 WITH LLVM-exception license.

Credits

This package was created with Cookiecutter and the renefritze/python_cookiecutter project template.

Project details


Download files

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

Source Distribution

clangquill-0.2.3.tar.gz (1.5 MB view details)

Uploaded Source

Built Distributions

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

clangquill-0.2.3-cp313-cp313-manylinux_2_34_x86_64.whl (60.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

clangquill-0.2.3-cp313-cp313-manylinux_2_34_aarch64.whl (56.9 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ ARM64

File details

Details for the file clangquill-0.2.3.tar.gz.

File metadata

  • Download URL: clangquill-0.2.3.tar.gz
  • Upload date:
  • Size: 1.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for clangquill-0.2.3.tar.gz
Algorithm Hash digest
SHA256 1713ec22f7da8b5b562d26257b79da28641599bf78e4e2cbb4dd0f0a3af8676c
MD5 1159aa9fc9e0174a95b2eab20074c315
BLAKE2b-256 90ade9af300b971ae8cdfc64c3816bb8f3b17c1e874b49b4439a0165a39dffaa

See more details on using hashes here.

Provenance

The following attestation bundles were made for clangquill-0.2.3.tar.gz:

Publisher: deploy.yml on renefritze/clangquill

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

File details

Details for the file clangquill-0.2.3-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for clangquill-0.2.3-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 dec06fcbbacd8339d245fd11c342958aa10cd8bdfa4b734b5dd21ce5f227bd50
MD5 4c903619d26a0f29c78372beaface8ef
BLAKE2b-256 dd6b578f1ee9b0c255968580bae24f60012b98a3aa9b8a5addd0af95ca9c0b01

See more details on using hashes here.

Provenance

The following attestation bundles were made for clangquill-0.2.3-cp313-cp313-manylinux_2_34_x86_64.whl:

Publisher: deploy.yml on renefritze/clangquill

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

File details

Details for the file clangquill-0.2.3-cp313-cp313-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for clangquill-0.2.3-cp313-cp313-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 5c7cd33f30730fa525aa7a777c931210f4a3a3e0b83c0d65c7ddc57cbdef07a8
MD5 21a28774380692de9699b2ee0ee1af3f
BLAKE2b-256 53a52115a613d0b2839f8139af8f9d30f745d89e8ccddfa09b7b43c87ee15def

See more details on using hashes here.

Provenance

The following attestation bundles were made for clangquill-0.2.3-cp313-cp313-manylinux_2_34_aarch64.whl:

Publisher: deploy.yml on renefritze/clangquill

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 Pingdom Monitoring Sentry Error logging StatusPage Status page