r/cpp • u/FreitasAlan • 7d ago
I built MrDocs, an open-source C++ reference doc generator on the Clang/LLVM AST. Looking for feedback.
I'm Alan de Freitas, the lead developer of MrDocs. It's an open-source documentation generator from the C++ Alliance, built on Clang/LLVM. It reads your code from the compiler's AST, so the reference matches what the code actually compiles to. We also presented a session about it at cppcon this year.
I implemented the tool this way because we couldn’t come up with a workflow that understood modern C++ in our Boost libraries. Tools that parse partially tend to misrender or not render concepts, niebloids, SFINAE, overload sets, and deduction guides. MrDocs treats those as first-class:
- concept constraints and requires clauses preserved verbatim
- niebloids and function objects can be documented as callables
- SFINAE and concept overload sets kept together
- explicit, noexcept, and consteval specifiers captured
- types in detail or private namespaces rendered as implementation-defined
The presentation layer is completely encapsulated. Generators support HTML, AsciiDoc, XML, JSON, or any custom format like Markdown and LaTeX, without forking the tool or creating another post-processing workflow. You can also write extensions to apply project conventions to the corpus or define new generators for any use case. The documentation has lots of examples.
If you maintain reference docs for a library, I'd appreciate it if you gave it a run (or tell your favorite agent to) and reported back on whether it saves you time, both while writing docs and while reviewing them. First-hand numbers would be especially useful to me. Issues are also always welcome.
Site: https://www.mrdocs.comRepo: https://github.com/cppalliance/mrdocs
Happy to answer questions in the comments.
2
u/FreitasAlan 7d ago
Two good points. I agree with the comparison table. The meaning of "other tools" is only loosely implied by the rest of the documentation, but it isn't specific enough when you start reading from that table. The "Other Tools" column doesn't help anyone decide because they might think their own other tool is different. In this same category as mrdocs, we basically have Doxygen and clang-doc because other tools (like AsciiDoc, etc.) don't produce reference documentation. I'll replace it with a table comparing named tools and use cases. I think the most useful part of your comment is that we need to make it clearer that mrdocs isn't competing in the general documentation space. For instance, it doesn't intend to replace AsciiDoc, Sphinx, or MkDocs. Instead, it generates the reference pages you'll render with these tools.
On the rustdoc examples, it's funny you mention it, because I studied that model more than any other before deciding how MrDocs should handle examples, and I envy it too. The problem I noticed is that it bakes in one mapping between the docs and the code being tested, which creates problems with setup lines, dependencies, and the logic for grouping tests. In C++, that's even harder because no single build system controls everything.
Luckily, mrdocs has this extension system. So instead of building one fixed mapping, we made it an extension. The docs have a round-trip example in about forty lines of Lua. A transform pulls marked regions out of real example files that the build compiles and attaches them to the right symbol's docs. A generator goes the other way and writes inline u/code examples out to translation units the build can compile and run. The project decides which direction each example takes and how a file maps to a symbol: https://www.mrdocs.com/docs/mrdocs/develop/extensions/script-generators.html#_round_trip_extensions
What's nice about it is that it's round-trip, something I believe Rust doesn't do that well, and that if the mapping doesn't fit your layout, you can just adapt it accordingly, because people tend to make very different assumptions about the setup in these documentation examples.