Filters
Filters are the gate at the front of the pipeline: they decide which symbols enter the documentation corpus at all. MrDocs filters by qualified name, by where the source sits on disk, and by category (undocumented declarations, private members, friends, and so on), and it can hide the implementation details of a type without dropping it from the corpus. Once a symbol has cleared the filters, Extraction decides how MrDocs presents it. The Filters reference lists every option.
Name filters
The most common filter in C++ libraries is by qualified name. include-symbols keeps only the symbols whose names match one of the listed globs. The usual entry point is the library’s top-level namespace. exclude-symbols then drops a glob inside that set. Two patterns are common: the unsafe_* family of functions (faster variants that skip validation, on the assumption the caller has already validated), and a helper namespace like jzon::extra for tracing or debug hooks the public docs do not need.
include/jzon/parser.hppnamespace jzon {
/// A parsed JSON document.
class value;
/** Validate that the document is well-formed JSON.
Parses `source` without constructing a value tree, reporting only
whether the input conforms to RFC 8259.
@param source A null-terminated UTF-8 JSON document.
@return `true` if the document is syntactically valid JSON.
*/
bool validate(char const* source);
/** Parse a JSON document.
Validates `source` and returns the resulting value tree.
@param source A null-terminated UTF-8 JSON document.
*/
value parse(char const* source);
/** Parse a JSON document without validating.
Assumes the caller has already verified `source` with @ref validate.
The behavior is undefined if `source` is not well-formed JSON.
*/
value unsafe_parse(char const* source);
/** Count the number of top-level elements in `source`.
Assumes the caller has already verified `source` with @ref validate.
*/
unsigned long unsafe_element_count(char const* source);
}
include/jzon/extra/utilities.hppnamespace jzon::extra {
/// Turn on parser tracing for the current thread.
void enable_trace();
/// Turn off parser tracing for the current thread.
void disable_trace();
}
mrdocs.ymlinclude-symbols:
- 'jzon::**'
exclude-symbols:
- 'jzon::unsafe_*'
- 'jzon::extra::**'
jzon::value
A parsed JSON document.
Synopsis
Declared in <jzon/parser.hpp>
class value;
Non-Member Functions
Name |
Description |
Parse a JSON document. |
jzon::parse
Parse a JSON document.
Synopsis
Declared in <jzon/parser.hpp>
value
parse(char const* source);
Description
Validates source and returns the resulting value tree.
Return Value
A parsed JSON document.
Parameters
Name |
Description |
source |
A null‐terminated UTF‐8 JSON document. |
jzon::validate
Validate that the document is well‐formed JSON.
Synopsis
Declared in <jzon/parser.hpp>
bool
validate(char const* source);
Description
Parses source without constructing a value tree, reporting only whether the input conforms to RFC 8259.
Return Value
true if the document is syntactically valid JSON.
Parameters
Name |
Description |
source |
A null‐terminated UTF‐8 JSON document. |
Three patterns drive that output:
-
include-symbols: ['jzon::**']keeps the wholejzonnamespace. -
exclude-symbols: ['jzon::unsafe_*']then removesunsafe_parseandunsafe_element_count, so only the safe overloads land in the public docs. -
exclude-symbols: ['jzon::extra::**']removes thejzon::extrahelper functions.
The pattern delimiter is :: instead of /. A single * matches anything that does not cross a ::, so jzon::* matches jzon::parse but not jzon::extra::enable_trace. A double ** matches everything including ::, so jzon::** matches both.
The Doxygen option analogous to exclude-symbols is EXCLUDE_SYMBOLS. Doxygen has no inclusion counterpart. It documents everything by default and narrows the set with the EXTRACT_* family plus EXCLUDE_SYMBOLS.
|
Implementation details
Sometimes a type that lives in the library’s implementation appears in a public signature: a return type, a parameter, an inherited base. Dropping it with exclude-symbols would break cross-references and leave the reference as a bare name. The two options below keep the symbol in the corpus and hide its details from the reader.
implementation-defined drops the page for the matched symbols and renders any reference to them as /* implementation-defined */. see-below is gentler: the symbol keeps its page, but the synopsis collapses to /* see-below */ and the members are not enumerated. Use see-below when the type matters to the reader but its implementation does not. Use implementation-defined when the type’s name should not be advertised.
include/logr/log.hppnamespace logr {
/// The library's private encoder representation.
class encoder_impl;
/** A complete log record.
Carries the message text and the level at which the record was
emitted. Construct one and hand it to @ref emit().
*/
class log_record
{
public:
log_record(char const* message) noexcept;
char const* message() const noexcept;
char const* level_name() const noexcept;
private:
char const* message_;
int level_;
};
/** Attach a key/value pair to every log line in the current scope.
The context stays attached until the returned token is destroyed.
Hold it in `auto`; nested contexts stack and unwind in reverse order.
@param key The context name surfaced on each log line.
@param value The context value surfaced on each log line.
@return An opaque RAII token whose lifetime governs how long the
pair stays attached.
*/
detail::scope_token scoped_context(char const* key, char const* value);
/** Replace the active encoder.
Obtain an encoder via @ref make_json_encoder() or
@ref make_text_encoder() and hand it here.
@par Example
@code
logr::set_encoder(logr::make_json_encoder());
@endcode
*/
void set_encoder(encoder_impl&& enc);
}
include/logr/detail/scope_token.hppnamespace logr::detail {
struct scope_token { ~scope_token(); };
}
mrdocs.ymlimplementation-defined:
- 'logr::detail::**'
- 'logr::*_impl'
see-below:
- 'logr::log_record'
logr::log_record
A complete log record.
Synopsis
Declared in <logr/log.hpp>
class log_record { /* see-below */ };
Description
Carries the message text and the level at which the record was emitted. Construct one and hand it to emit().
logr::scoped_context
Attach a key/value pair to every log line in the current scope.
Synopsis
Declared in <logr/log.hpp>
/* implementation-defined */
scoped_context(
char const* key,
char const* value);
Description
The context stays attached until the returned token is destroyed. Hold it in auto; nested contexts stack and unwind in reverse order.
Return Value
An opaque RAII token whose lifetime governs how long the pair stays attached.
Parameters
Name |
Description |
key |
The context name surfaced on each log line. |
value |
The context value surfaced on each log line. |
logr::set_encoder
Replace the active encoder.
Synopsis
Declared in <logr/log.hpp>
void
set_encoder(/* implementation-defined */&& enc);
Description
Obtain an encoder via make_json_encoder() or make_text_encoder() and hand it here.
Example
logr::set_encoder(logr::make_json_encoder());
Parameters
Name |
Description |
enc |
The library's private encoder representation. |
implementation-defined matches two patterns. 'logr::detail::**' catches the conventional internal namespace, and 'logr::*_impl' catches the _impl-suffixed forward declarations the library uses as opaque customization-point handles. Where either type appears in the signature of scoped_context or set_encoder, the rendered synopsis substitutes /* implementation-defined */. see-below matches logr::log_record: the type keeps its page, but the synopsis on that page collapses to /* see-below */, so the reader sees what the type is rather than how it is laid out.
When the set of implementation symbols is small or awkward to describe with a glob, use the @implementationdefined and @seebelow doc-comment commands instead. Same effect, declared next to the symbol rather than in the config.
|
Doxygen has no direct analogue. Marking a symbol with the \internal command plus INTERNAL_DOCS=NO hides it from the output, but Doxygen does not render references to it as "implementation-defined" or collapse its synopsis to "see-below".
|
Path filters
Reach for path filters when the libraries you want to keep share a naming scheme that a symbol filter cannot separate, or when the source tree contains directories (vendored code, generated headers) that should not appear in the docs at all.
input is the list of directories MrDocs scans for sources. A miniature FFmpeg layout makes the case: every public function across libavcodec, libavformat, and friends sits at global scope under the same av_* prefix, so include-symbols: ['av_*'] would pull them all in. Only the directory tells them apart.
include/libavcodec/avcodec.h/** Allocate a new packet on the heap. */
int av_packet_alloc(void);
/** Release a packet allocated with `av_packet_alloc`. */
void av_packet_free(void);
include/libavformat/avformat.h// Filtered out: `input: include/libavcodec` scopes extraction to that
// directory, so the format-library functions never enter the corpus.
// The directory matters because both libraries put their declarations
// at global scope under the same `av_*` prefix, so a name-based filter
// could not distinguish them.
int av_open_input_file(void);
void av_close_input_file(void);
mrdocs.ymlinput:
- include/libavcodec
av_packet_alloc
Allocate a new packet on the heap.
Synopsis
Declared in <libavcodec/avcodec.h>
int
av_packet_alloc();
av_packet_free
Release a packet allocated with av_packet_alloc.
Synopsis
Declared in <libavcodec/avcodec.h>
void
av_packet_free();
Only include/libavcodec is in input, so the format-library functions never enter the corpus. The default is <source-root>/., which covers the whole project.
recursive decides whether MrDocs walks into subdirectories under each input root. Set it to false when only the top-level files of a directory are public.
The exclusion side of the same axis: exclude drops a specific subdirectory inside input. Use it for code that does not belong in the output, such as a vendored copy of a third-party library or a generated-code tree that lives next to the source. The example below documents the httpd library while skipping a vendored copy of zlib that the project bundles for convenience:
include/httpd/server.hppnamespace httpd {
/** Start the HTTP server on `port`. */
void start(int port);
/** Stop the running server. */
void stop();
}
include/zlib/zlib.h// Vendored copy of zlib's public API. Documented upstream at
// https://zlib.net/, not here. `exclude: include/zlib` keeps the
// vendored library out of the rendered docs so it does not appear
// alongside the httpd API.
/* Compress `src` into `dst` using DEFLATE. */
int compress2(unsigned char* dst, unsigned long* dstLen,
unsigned char const* src, unsigned long srcLen,
int level);
/* Decompress a DEFLATE-compressed buffer. */
int uncompress(unsigned char* dst, unsigned long* dstLen,
unsigned char const* src, unsigned long srcLen);
mrdocs.ymlexclude:
- include/zlib
httpd::start
Start the HTTP server on port.
Synopsis
Declared in <httpd/server.hpp>
void
start(int port);
httpd::stop
Stop the running server.
Synopsis
Declared in <httpd/server.hpp>
void
stop();
exclude-patterns is the glob form of exclude and matches across the tree, so one pattern can drop every directory matching the glob no matter where it sits under input. The classic case is build-generated headers that live next to each component’s hand-written ones under a _generated/ subdirectory:
include/storage/storage.hppnamespace storage {
/** Persist a value under `key`. */
void put(char const* key, char const* value);
}
include/storage/_generated/messages.hpp// Generated by the build (protoc, gRPC, OpenAPI, …); do not edit by
// hand. Every component in this project keeps its generated headers
// next to the hand-written ones under a `_generated/` subdirectory,
// so `exclude-patterns: '**/_generated/**'` drops them all at once.
namespace storage::gen {
struct PutRequest {};
struct PutResponse {};
}
include/payments/payments.hppnamespace payments {
/** Authorize a payment of `amount` against `account`. */
bool authorize(char const* account, double amount);
}
include/payments/_generated/messages.hppnamespace payments::gen {
struct AuthorizeRequest {};
struct AuthorizeResponse {};
}
mrdocs.ymlexclude-patterns:
- '**/_generated/**'
payments::authorize
Authorize a payment of amount against account.
Synopsis
Declared in <payments/payments.hpp>
bool
authorize(
char const* account,
double amount);
storage::put
Persist a value under key.
Synopsis
Declared in <storage/storage.hpp>
void
put(
char const* key,
char const* value);
A single '**/_generated/**' pattern drops both storage/_generated/ and payments/_generated/. With the literal exclude:, you would need one entry per directory.
file-patterns narrows the file set MrDocs scans inside the input directories: only files whose names match one of the globs are read. The default already covers the common C++ header extensions, so you set it only to narrow further (for example, to skip .ipp).
exclude and exclude-patterns are for code that should not appear in the docs at all, such as vendored libraries or generated code. Do not reach for them when the directory holds your own library’s private internals. Dropped symbols leave the corpus entirely, so any reference to one from a kept declaration renders as the literal name (detail::cache_entry) instead of an implementation marker. For your own internals, use the implementation-defined and see-below options covered above. They keep the cross-references intact and render them as /* implementation-defined */ or collapse the synopsis to /* see-below */.
|
The analogous Doxygen options are INPUT, RECURSIVE, EXCLUDE, EXCLUDE_PATTERNS, and FILE_PATTERNS.
|
Category filters
The extract-* family flips MrDocs’s category-level defaults: each option toggles a class of declarations that the default would either include or omit. The two most common are below. The reference page covers the rest (static locals, anonymous and empty namespaces, friends, local classes, implicit template specializations); reach for one when you discover the default is hiding something you wanted documented.
Undocumented symbols
extract-all decides whether MrDocs documents declarations that have no doc comment. The default true pulls them in; set it to false to keep the public docs to the symbols the author has explicitly written prose for:
/// A documented function.
void documented();
// An undocumented function. The default `extract-all: true`
// would pull it in even without a doc comment; setting
// `extract-all: false` hides it.
void undocumented();
mrdocs.ymlextract-all: false
documented
A documented function.
Synopsis
Declared in <extract‐all.cpp>
void
documented();
documented survives; undocumented is dropped because no doc comment is attached.
Private members
extract-private adds private members to a class’s page, with companion switches extract-private-virtual and extract-private-bases for private overrides and private bases:
/// A class with both public and private members.
class widget
{
public:
/// Display the widget.
void show();
private:
/// An internal counter.
int count;
};
mrdocs.ymlextract-private: true
widget
A class with both public and private members.
Synopsis
Declared in <extract‐private.cpp>
class widget;
Member Functions
Name |
Description |
Display the widget. |
Private Data Members
Name |
Description |
An internal counter. |
widget::show
Display the widget.
Synopsis
Declared in <extract‐private.cpp>
void
show();
widget::count
An internal counter.
Synopsis
Declared in <extract‐private.cpp>
int count;
Glob syntax
Symbol and file patterns share the same wildcards (the file form uses / as the path delimiter; the symbol form uses ::):
-
*matches all characters except the delimiter. -
**matches all characters including the delimiter. -
?matches any single character. -
[<chars>]matches one character in the bracket; ranges work as[a-z]; negate with[^<chars>]or[!<chars>]. -
{<glob>,…}matches one of the globs in the list. -
\escapes the next character so it is treated as a literal.
Inclusion rules
Inclusion rules (include-symbols, implementation-defined, see-below) are intentionally looser than exclude-symbols: a symbol counts as included when any of the following hold.
-
The symbol strictly matches one of the patterns.
std::vectormatches bothstd::vectorandstd::*. -
The symbol is a parent namespace of an included symbol.
std::filesystem::*therefore also pulls instdandstd::filesystem. -
The parent symbol is included.
std::*matchesstd::vector::iteratorbecausestd::vectormatches. -
A literal pattern that names a namespace pulls in everything under it.
stdbehaves likestd::**.
Exclusion rules require a strict match: a symbol is excluded only when it (or its scope) is the pattern’s exact target.