Skip to content

feat: honor cond and endcond in doc comments - #1367

Open
gennaroprota wants to merge 3 commits into
cppalliance:developfrom
gennaroprota:feat/honor_cond_and_endcond_in_doc_comments
Open

gennaroprota wants to merge 3 commits into
cppalliance:developfrom
gennaroprota:feat/honor_cond_and_endcond_in_doc_comments

Conversation

@gennaroprota

Copy link
Copy Markdown
Collaborator

MrDocs dropped Doxygen's \cond <label> and \endcond markers and rendered everything between them, so the internals that a project migrating from Doxygen had hidden with them ended up in its documentation: the text inside a doc comment and, in the common form that wraps code, whole declarations such as a detail namespace.

This PR honors them. Within a file, everything between a \cond and its matching \endcond is hidden, doc-comment text and declarations alike, unless the new enabled-sections option (Doxygen's ENABLED_SECTIONS) names the section's label. The label is the first word after \cond, as in Doxygen; a section with no label is always hidden. Sections nest, and they can span several doc comments and the code between them. The issue suggested only warning about the form that wraps declarations, assuming it needs a preprocessor-level view; it doesn't, because Clang keeps every doc comment of a file, attached to a declaration or not, so the source range between the markers is known.

A hidden declaration is treated like one matched by exclude-symbols: it gets no page, its members go with it, and its name is still printed where a visible declaration refers to it. @implementationdefined and @seebelow take precedence, as they do over exclude-symbols. A symbol stays visible if one of its declarations lies outside every hidden section, such as a public forward declaration, while an out-of-line definition (S::f) follows the declaration it defines. Macros, friend declarations and using-directives inside a hidden section are left out too. A doc comment with nothing left to show once its hidden sections are removed counts as undocumented.

A \cond with no matching \endcond hides everything to the end of its file, so that a missing marker can never leak what it was meant to hide, and a stray \endcond is ignored. Both now produce a warning naming the file and line, once per run. Only the project's own files are reported: markers in system headers never are, and those in files outside the inputs only at the debug level (libstdc++, for one, has @cond sections that its preprocessor conditionals leave unmatched). The warnings count as errors under warn-as-error and drop to the debug level with warnings: false. Markers inside a \code block or a Markdown code span are not markers.

Label expressions (\cond (A && !B)), \if/\ifnot/\else/\endif and \internal/\endinternal are not supported. An expression is taken as a label that is never enabled, so its section is hidden.

Changes

  • Source: src/mrdocs/AST/ConditionalSections.cpp computes, per file, the disabled sections and the malformed markers from the file's doc comments, using Clang's comment parser. ASTVisitor uses it to give hidden declarations the exclude-symbols extraction mode, to skip hidden macros, friends and using-directives, to decide whether a comment still documents its symbol, and to report malformed markers; the doc-comment extractor leaves out the blocks of a hidden section.
  • Tests: golden fixtures under config/enabled-sections cover in-comment sections, the enabled label, nesting, unlabeled and unbalanced sections, sections spanning comments, hidden declarations of every kind, forward declarations and out-of-line definitions, @implementationdefined in a section, undocumented comments, and code blocks and code spans (including unpaired and escaped backticks). New CTests under tests/diagnostics check the warnings: reported once each, failing the run under --warn-as-error, lowered by --warnings=false, and never reported for a system header or a file outside the inputs.
  • Build: the generated config schema gains the enabled-sections entry.
  • Breaking changes: content between \cond and \endcond, which used to be published, is now hidden unless its label is listed in enabled-sections.

Testing

The enabled-sections fixtures pin the hiding of text and declarations and the documented status of what remains, and the diagnostics CTests pin the warnings, their level and the files they are restricted to. Both run on every build.

Documentation

The command reference describes @cond ... @endcond, the commands page points to it, and the migration notes recommend configuration (exclude-symbols, implementation-defined, see-below, separate runs per audience) as the way to keep internals out of the documentation, while noting that \cond is honored so that a migration doesn't leak them.

Fixes #1343.

In Doxygen, `\cond <label>` ... `\endcond` hides a part of the
documentation unless the label is enabled. We dropped the two markers
and rendered everything between them, so the internals that a project
migrating from Doxygen had hidden ended up in its documentation.

We now leave out the text of each section, unless the corresponding
label is named by the new `enabled-sections` option. The label is the
first word after `\cond`, as in Doxygen, and a `\cond` with no label is
never enabled. Sections nest, and they are matched across all the doc
comments of a file, so a section can open in one comment and close in a
later one. A `\cond` with no matching `\endcond` runs to the end of its
file, so that a missing marker can never leak what it was meant to hide.
The markers are found with Clang's comment parser, so the same words
inside a `\code` block are left alone.
A `\cond` section can span several doc comments and the code between
them, which is how a Doxygen project usually hides a `detail` namespace
or an internal function. Those declarations still got pages of their
own.

We now give a declaration that begins inside a disabled section the
extraction mode that `exclude-symbols` gives: it gets no page, its
members go with it, and its name is still printed where a visible
declaration refers to it. As with `exclude-symbols`,
`@implementationdefined` and `@seebelow` take precedence. A symbol stays
visible if one of its declarations is outside every disabled section,
such as a public forward declaration, but an out-of-line definition
(`S::f`) follows the declaration it defines, so it can't bring back what
was hidden where it was declared. Macros defined in a disabled section
are left out too.

A doc comment that has nothing left to show once its disabled sections
are removed now counts as no documentation, so `warn-if-undocumented`
and `extract-all: false` treat its symbol as undocumented.
A `\cond` with no matching `\endcond` hides everything up to the end of
its file, and a stray `\endcond` is ignored. Both are almost always
mistakes, and the first one can silently take most of a header out of
the documentation.

We now warn about each of them, naming the file and line of the marker,
once per run however many translation units include the file. Only the
project's own files are concerned: markers in system headers are never
reported, and those in files outside the inputs only at the debug level,
since someone else maintains them (libstdc++, for one, has `@cond`
sections that its preprocessor conditionals leave unmatched). The
warnings count as errors under `warn-as-error` and drop to the debug
level with `warnings: false`.

A `\cond` written in a Markdown code span is no longer taken as a
marker, so a comment that merely mentions the command no longer hides
the rest of its file.

Friend declarations and using-directives written in a disabled section
are now left out too, as other declarations already were. A command such
as `\ingroup`, which renders nothing, no longer keeps a comment
documented when everything else in it is hidden.

The command reference and the migration notes now describe the sections,
and the migration notes recommend configuration (`exclude-symbols`,
`implementation-defined`, `see-below`) as the way to keep internals out
of the documentation.

Fixes cppalliance#1343.
@github-actions

Copy link
Copy Markdown
Contributor

✨ Highlights

  • 🧪 New golden tests added

🧾 Changes by Scope

Scope Lines Δ% Lines Δ Lines + Lines - Files Δ Files + Files ~ Files ↔ Files -
🥇 Golden Tests 78% 4547 4547 - 76 76 - - -
🛠️ Source 17% 975 954 21 9 2 7 - -
📦 Other 4% 259 259 - 11 10 1 - -
📄 Docs 1% 40 40 - 4 - 4 - -
Total 100% 5821 5800 21 100 88 12 - -

Legend: Files + (added), Files ~ (modified), Files ↔ (renamed), Files - (removed)

🔝 Top Files

  • src/mrdocs/AST/ConditionalSections.cpp (Source): 536 lines Δ (+536 / -0)
  • tests/golden/fixtures/config/enabled-sections/in-code-span.xml (Golden Tests): 299 lines Δ (+299 / -0)
  • tests/golden/fixtures/config/enabled-sections/standalone-namespace-enabled.xml (Golden Tests): 279 lines Δ (+279 / -0)

Generated by 🚫 dangerJS against d7d15a1

@codecov

codecov Bot commented Oct 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.21%. Comparing base (9faf2d7) to head (d7d15a1).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #1367   +/-   ##
========================================
  Coverage    83.21%   83.21%           
========================================
  Files           35       35           
  Lines         3670     3670           
  Branches       845      845           
========================================
  Hits          3054     3054           
  Misses         410      410           
  Partials       206      206           
Flag Coverage Δ
bootstrap 83.21% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cppalliance-bot

Copy link
Copy Markdown

An automated preview of the documentation is available at https://1367.mrdocs.prtest2.cppalliance.org/index.html

If more commits are pushed to the pull request, the docs will rebuild at the same URL.

2026-10-29 11:54:46 UTC

This branch has not been deployed

No deployments
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.

feat: honor \cond / \endcond in doc comments

2 participants