Skip to content

doc: port the documentation to Antora + MrDocs (experiment — not for merge) - #494

Draft
jll63 wants to merge 10 commits into
boostorg:developfrom
jll63:antora-mrdocs-opus5-high_effort
Draft

doc: port the documentation to Antora + MrDocs (experiment — not for merge)#494
jll63 wants to merge 10 commits into
boostorg:developfrom
jll63:antora-mrdocs-opus5-high_effort

Conversation

@jll63

@jll63 jll63 commented Aug 1, 2026

Copy link
Copy Markdown

This PR is not a merge request. It exists so the converted documentation renders on
GitHub and the diff is reviewable in the normal UI. Please do not merge it; I will close it
once it has served that purpose.

It is the output of an experiment in using Claude Opus 5 to port the Boost.Test documentation from
QuickBook/BoostBook to Antora + MrDocs, following the setup Boost.URL uses:

  • doc/antora.yml, doc/local-playbook.yml, doc/mrdocs.yml, doc/build_antora.sh
  • 76 pages under doc/modules/ROOT/pages, examples under doc/modules/ROOT/examples
    included via tag::example_code / tag::example_output markers
  • the API reference generated by MrDocs from an umbrella translation unit
    (-D BOOST_TEST_MRDOCS_BUILD=ON)
  • 222 redirect aliases mapping every old BoostBook URL onto its new page
  • an antora CI job that fails on an unresolved xref or include
  • the QuickBook toolchain removed

Ten commits on top of develop, each self-contained; the conversion commit and the polish
pass are separate so the mechanical and the hand-edited changes can be told apart.

I rendered the documentation locally, and the result is encouraging.

jll63 and others added 10 commits July 30, 2026 11:25
First step of the QuickBook -> Antora + MrDocs port. Adds the component
descriptor, a local playbook, the npm dependency set and the build script,
all modelled on libs/openmethod/doc. MrDocs is not wired up yet: the
ext.cpp-reference stanza in antora.yml stays commented out until
doc/mrdocs.yml exists.

doc/html/ becomes Antora's output directory, so its two tracked inputs move
out: images/ to modules/ROOT/images/, and boostbook.css is dropped along with
the BoostBook stylesheet it served.

build_antora.sh carries one addition over openmethod's: Antora's git backend
requires <content-source>/.git to be a directory, and inside a Boost
superproject checkout libs/test is a submodule whose .git is a file. When that
is detected, an equivalent playbook rooted at the superproject is derived.
A standalone clone, which is what CI checks out, is unaffected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
doc/tools/qbk2adoc.py converts the 76 .qbk sources to Antora pages. It is a
migration tool, not something to maintain: it runs once in the next commit and
is deleted at the end of the port, recoverable from this branch's history.

Pass 1 walks test.qbk following [include] and builds the section tree, the
[#anchor]/[hN:id] targets and the 85 [def] macros. Pass 2 renders one .adoc per
page and resolves the 556 [link]s against that map. 551 of them resolve; the
five that do not are targets that do not exist in the QuickBook either, so they
are already broken on the current site. They are emitted as `// FIXME` markers
rather than dropped, along with the other things a human still has to look at.

Two things in the sources needed care. QuickBook code fences here are backtick
*runs* -- both ``...`` and ```...``` occur, and a closing run must match the
opening one exactly -- and there are three stray unpaired backticks, one of
which otherwise swallows the remainder of its file. An unpaired inline backtick
is therefore treated as literal text and reported.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Antora can only include files from modules/<name>/examples, so doc/examples
and doc/snippet move there. The QuickBook //[name ... //] region markers become
AsciiDoc // tag::name[] ... // end::name[] markers; only comment lines change
in the .cpp files.

doc/examples is compiled and run by the test suite, so the paths in
test/Jamfile.v2, test/CMakeLists.txt and the CI depinst arguments move with it,
as do the source paths embedded in three .output files -- those are what the
example prints at runtime, and they are shown in the docs.

The snippets were never compiled and were not compilable: they contained
QuickBook [def] macros (__BOOST_TEST__ and friends) in place of the real macro
names. Those are now spelled out, which also makes them candidates for the
example test harness later.

modules/ROOT/partials/bt_example.adoc replaces the QuickBook `bt_example`
template used at 118 call sites.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Generated by doc/tools/qbk2adoc.py: 210 QuickBook sections become 76 Antora
pages under modules/ROOT/pages, one per chapter or per included .qbk file,
with deeper sections as in-page headings carrying their original ids.

The 85 [def] macros become AsciiDoc attributes in antora.yml rather than ~2000
expanded xrefs, so a reference page can still be renamed in one place.
nav.adoc mirrors the old chapter tree.

Every page also carries :page-aliases: with its old BoostBook path, which
gets deep links to the right page. The #fragment is lost through a redirect;
Antora has no mechanism to preserve it.

Two defects in the sources are fixed rather than reproduced: one table row
carried an extra cell that DocBook silently dropped, and two different tables
shared the id id_range_parameter_table -- the second, which lists the random
generator's parameters, becomes id_random_parameter_table.

doc/Jamfile.v2 now drives build_antora.sh; the doxygen, quickbook and boostbook
targets are gone. boostdoc/boostrelease still work for the superproject. The
.qbk sources are now unreferenced and are deleted at the end of the port.

Antora builds the site with no warnings beyond MrDocs not being wired up yet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the Doxygen target the QuickBook build used. doc/CMakeLists.txt is a
standalone project that gives MrDocs a compilation database for doc/mrdocs.cpp,
an umbrella translation unit including the same ~50 public headers the Doxygen
target curated. The library's own CMakeLists.txt cannot serve: it is a modular
Boost library that only configures from the superproject.

BOOST_TEST_DOXYGEN_DOC__ is deliberately not defined, although the Doxygen
target set it. It exists for a tool that does not compile what it reads, and
MrDocs does: with it set, data/monomorphic/fwd.hpp hides the forward
declarations that make_delayed() needs and the header does not compile, and
data/config.hpp defines BOOST_TEST_NO_{RANDOM_DATASET,GRID_COMPOSITION,
ZIP_COMPOSITION}_AVAILABLE, which would drop those datasets from the reference.
The macros it reveals carry no doc comments and are documented by hand.

mrdocs-addons overrides one template. Antora ignores files whose name starts
with an underscore, and MrDocs names a page after its symbol, so the unnamed
enum behind `enum { type = TUT_CASE };` in tree/test_unit.hpp produced links to
pages Antora never published. The override drops the link and keeps the row.

The [def]-derived attributes are restructured at the same time. They used to
hold a whole xref including its label, which renders the backticks visible:
Asciidoctor substitutes quotes before attributes, and an API attribute -- which
is what antora.yml sets -- is inserted without further substitution. They now
hold only the link target, with the label at the call site.

The site builds with no warnings: 1665 pages, of which 1520 are reference.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
All 556 QuickBook links now resolve. What it took:

The Program Execution Monitor chapter comes back into the book. It had been
commented out of test.qbk with a [/TOFIX] marker while a live [def] still
linked into it, so __auto_linking__ has been dangling on the published site.
The component still ships. Its bt_example named example24 with the run-fail
rule, but the file is example24.run.cpp, which is why nobody noticed: the
chapter was never built.

Links written against `boost_test.components.*`, a chapter that no longer
exists, still name a real section by their last component, so the resolver
falls back to that. The one with no successor at all, the Execution Monitor,
now points at the class MrDocs generates.

Four links target a plain [hN] heading by the id QuickBook derived from its
title. Those ids are emitted now -- but only where something links to them.
Emitting them everywhere collides, since each of the 25 runtime parameters has
an "Acceptable values" heading and they share one page.

BOOST_TEST_NO_{RANDOM_DATASET,ZIP_COMPOSITION,GRID_COMPOSITION}_AVAILABLE were
referenced by [macroref] but documented nowhere, and MrDocs cannot emit them.
They are now written up in the build-scenarios reference alongside
BOOST_TEST_DISABLE_ALT_STACK.

Also fixes three stray unpaired backticks in the sources, and a `[boost test]`
that QuickBook rendered as a literal bracket.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A rendering pass over the built site: no QuickBook markup, attribute reference,
xref or include survives unrendered anywhere in the narrative pages, and no
paragraph starts indented, which AsciiDoc would turn into a literal block.

Three things the converter could not decide:

- test_module_runner_overview had a [link] inside a code span, which QuickBook
  rendered literally too, so the sentence read `--[link ...]=no`. It now points
  at the result_code parameter and says what the value does.
- The "Notation" table in the floating point chapter had an empty header row.
- The SVG behind --list_content was linked as a bare relative path, which is
  not a link macro and rendered as text. The file moves to attachments, where
  Antora publishes and resolves it.

All 118 example blocks resolve to files that exist; example20 remains
unreferenced, as it was in the QuickBook.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The CI workflow gains an `antora` job. It clones Boost, because MrDocs compiles
an umbrella translation unit against it, and uploads the built site as an
artifact. It does not deploy to Pages: boost.org builds the published docs, and
the point here is to catch a broken build. build_antora.sh passes
--log-failure-level=warn when CI is set, so an unresolved xref or include fails
the job -- Antora exits zero otherwise -- and the explicit `[ -d html ]` check
stays as a second net.

Every page already carried the alias of the section it came from. BoostBook
chunked to depth 4, so sections that are now in-page headings had their own
HTML file as well; 145 further aliases point those at the page that absorbed
them. That is 222 redirects in total. The #fragment does not survive a
meta-refresh, so a deep link lands on the right page but not the right heading;
Antora offers no way around that.

libs/test/index.html and the new documentation key in meta/libraries.json point
at doc/html/test/index.html, where Antora writes the site.

doc/README.md is rewritten for the new toolchain: no more Docbook, xsltproc or
Doxygen, and it now covers the prose-only fast path, the CI failure level and
how to add an example.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Deletes the 76 .qbk sources, the stale doc/doxygen/Doxyfile that nothing had
referenced for years, and doc/tools/qbk2adoc.py. The transpiler was a migration
tool, not something to maintain; it is recoverable from this branch's history
along with the sources it read.

The IDE-only CMake target that globbed the .qbk files now globs the pages, and
is renamed from `quickbook` to `documentation`.

Verified after the deletion: Antora builds the site with no warnings at the CI
failure level, and the documentation examples still compile and run under b2 --
including example24, which the Program Execution Monitor chapter uses and which
had never been built before this branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The BoostBook reference had a "Header <boost/test/...>" section per header.
MrDocs organises purely by namespace and has no header grouping, so the port
dropped it without noticing. utf_reference/ref_headers.adoc puts it back as a
curated page: every public header, grouped by area, with what it brings in and
a link to its source. That answers "which header do I include for what", which
is what the old listing was mostly used for; the reverse direction is already
covered, since every generated page names the header its symbol comes from.

Writing it surfaced four things that were quietly broken:

- boost::math::fpc was not extracted at all, so the three references to
  close_at_tolerance, small_with_tolerance and the tolerance_based
  customisation point rendered as plain text. It is Boost.Test's own
  namespace, and the floating point chapter links straight into it.
- Normalising the include path in CMakeLists.txt -- so the "Declared in" links
  stop going through a GitHub redirect for `doc/../include` -- activated an
  exclusion of boost/test/detail that had been inert because it never matched.
  That directory holds global_typedef.hpp, which the Doxygen target listed
  explicitly and which declares output_format; the exclusion is gone.
- One reference named boost::unit_test::data::monomorphic::make_delayed, which
  is declared in boost::unit_test::data.
- Footnotes containing a cross-reference were mangled: the converter escaped
  `]` in content it had already rendered, which broke the nested macro.
  Asciidoctor matches balanced brackets inside footnote:[] by itself.

Eleven QuickBook code blocks nested inside list items had been flattened into
multi-line inline code spans, with blank lines turned into list continuation
markers. They are listing blocks again, with the indentation the sources had.

All 102 cpp: references now resolve to a reference page, and all 470 fragment
links point at an id that exists.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant