Skip to main content

Module roxygen

Module roxygen 

Source
Expand description

Roxygen tag extraction and processing for R wrapper generation.

This module extracts roxygen2-style tags (e.g., @param, @examples) from Rust doc comments and propagates them to generated R wrapper code.

§Usage

In Rust doc comments, use roxygen2 tags:

ⓘ
/// @param x A numeric input.
/// @return The squared value.
/// @examples
/// square(4)
#[miniextendr]
pub fn square(x: f64) -> f64 { x * x }

§How doc lines carry over

Every reader here (explicit_roxygen_tags_from_attrs, leading_prose_from_attrs, strip_roxygen_from_attrs) walks the same lines (doc_lines) with the same roles (classify):

  • Text before the first @tag line is leading prose. It becomes @description (when the block has none) with its lines, blank lines and indentation kept, and it stays in rustdoc. Its [...] links lose their brackets unless the crate sets roxygen_prose_links = "keep" (ProseLinks). Under "keep", and in the text of every explicit tag but the code ones (CODE_TAGS), only a link roxygen2 can never resolve loses them (is_rustdoc_only_target). An inline link whose destination is such a Rust path ([text](crate::x)) keeps only its text under either setting (inline_rustdoc_destination); other [text](url) links stay. A block that renders no help page (its own @noRd, or a caller’s RdPage::Suppressed: noexport, a class without a page) loses every link in its prose and its non-code tag text, whatever the setting.
  • A tag runs from its @tag line to the next one. A multi-line tag (@description, @return, @examples, …) keeps its blank lines (a roxygen2 paragraph break; a blank line in an example) and the indentation of its continuation lines, less the one space rustdoc’s /// puts there. Trailing blank lines are dropped. roxygen2 markdown reads a continuation indented 4 or more spaces after a blank line as a code block, as rustdoc does.
  • A joined tag (@title, @keywords, @concept, @aliases) folds its wrapped lines onto one line.
  • A single-line tag (@export, @noRd, @rdname topic, …) ends at its line. Lines after it, up to the next tag, are rustdoc only.
  • Rustdoc keeps the leading prose and the rustdoc-only lines, and drops every tag with its text.

§R Package Configuration

For roxygen2 to process multiline tags correctly, add this to your DESCRIPTION file:

Roxygen: list(markdown = TRUE)

Structs§

DocLine 🔒
One line of a string-literal doc attribute.

Enums§

LineRole 🔒
What a doc line is to roxygen extraction and rustdoc stripping.
Neutralize 🔒
Which [...] links sanitize_roxygen_links reduces to their text.
OpenTag 🔒
How the tag that is open takes the lines that follow it.
ProseLinks 🔒
What leading prose does with [...] link syntax on its way to @description: the crate’s roxygen_prose_links setting in [package.metadata.miniextendr].
RdPage 🔒
Whether a doc block’s roxygen text can reach a rendered help page, as far as the caller knows, which decides what happens to its [...] links.

Constants§

CODE_TAGS 🔒
Tags whose text is R code or raw Rd, not markdown: their [...] is never a link, so neutralize_tag_links leaves them as written.
JOINED_TAGS 🔒
Tags whose wrapped continuation lines are joined back onto one line with a space instead of a newline: roxygen2 wants these on a single line (or reads them as one whitespace-separated list), but a long title, keyword list, concept, or alias list in a Rust doc comment can be wrapped by the author.
METHOD_ONLY_TAGS 🔒
Roxygen tags that only make sense on individual methods, not on impl blocks.
METHOD_ONLY_TAGS_R6 🔒
Tags stripped from impl-block docs for R6 classes — same as METHOD_ONLY_TAGS minus "param", since roxygen2 8.0.0 inherits class-level @param tags into all R6 methods and strips them from the rendered method entries automatically. This means /// @param breed … on an R6 impl block is valid and intentional, not a misplaced method-only tag. Keeping them avoids both the compile warning and the resulting (no documentation available) placeholder on subclass ctors.
MULTILINE_TAGS 🔒
Tags that allow multi-line content (continuation lines appended). All other tags are treated as single-line.
ORDER_AFTER_TOPIC_BLOCKS 🔒
The @order tag that sorts a generated block after every block without one, so the topic’s own block claims a merged page regardless of R file order (#1590).
PARAM_FILLER_MARKER 🔒
Prefix of a generated @param line in a standalone function’s wrapper (#' .__MX_PARAM_FILLER__ @param x (no documentation available)), for the wrapper registry to resolve when it writes the file (resolve_standalone_pages in miniextendr-api/src/registry.rs, which spells the same prefix). Whether an author @rdname topic names the function’s own page or its file’s stem page (the opt-in group page, #1289), and whether another function on the page documents the argument, is only known then. The registry keeps the line (without the prefix) when the function stays on its own or file-stem page and no other function there documents the argument, and drops it otherwise. roxygen2 keeps the later of two @param lines for one name, so a filler written after the real description would replace it.

Functions§

attrs_have_roxygen_tag 🔒
Whether the doc comment in attrs has the roxygen tag tag (matched as has_roxygen_tag does), for a caller deciding a block’s RdPage before it reads the block’s tags.
class_source_tag 🔒
The @source line for a class definition: Generated by miniextendr from Rust type `Type` , subject to source_tag’s opt-in.
classify 🔒
The role of each of lines (doc_lines): the one rule the tag extractor, the leading-prose reader and the rustdoc strip share.
closes_fence 🔒
Whether line, whose fence run is close, ends the block open began: the same character, at least as long, and nothing after it.
common_indent 🔒
The leading whitespace every non-blank line of lines starts with.
describe_in_topic 🔒
The topic named by the tag list’s own @describeIn <topic> <description> tag, if it has one.
doc_conflict_warnings 🔒
Check for conflicts between explicit @title/@description tags and implicit values.
doc_lines 🔒
The lines of every string-literal doc attribute in attrs, in order.
explicit_roxygen_tags_from_attrs 🔒
Parse only the author-written @tag lines from doc attributes — no leading-prose promotion.
extract_param_names 🔒
Extract the set of parameter names declared via @param in a list of roxygen tags.
fence_marker 🔒
The fence run (3 or more ` or ~) a CommonMark code-fence line starts with, after at most 3 spaces of indent.
find_param_tag 🔒
Like param_documented but returns the matching tag itself rather than a bool, for callers that reuse the tag’s rendered text verbatim (S7 constructor param doc forwarding pushes the found tag as-is).
find_tag_value 🔒
Find the value of a specific roxygen tag (e.g., “title” for @title ...).
formal_name 🔒
Extract the R parameter name from a single formal (e.g. mode = c("a","b") → mode). Pair with split_r_formals, never a raw split(',').
format_roxygen_tags 🔒
Render roxygen tag lines as “#’ …” comment lines.
forwarded_member_tag 🔒
Whether a method block without \usage (an env method Type$method, a trait method Type$Trait$method) forwards the author tag tag: every tag but a bare @export. On such a block roxygen2’s namespace roclet turns a bare @export into export("Type$method"), and R refuses to load the namespace (“undefined exports”). The member is reachable through its exported class, so exporting it is never valid. An @export <symbol> names its own target and is forwarded.
has_export_tag 🔒
Whether the author registers the function themselves, with @export or @exportS3Method (bare or pkg::generic), so a public standalone fn gets no automatic @export. Next to a delayed @exportS3Method pkg::generic a bare @export makes roxygen2 write an eager registration as well, and the package fails to load when pkg is only in Suggests (#1944).
has_roxygen_tag 🔒
Return true if the tag list contains a specific roxygen tag.
implicit_description_from_attrs 🔒
Extract the implicit description from doc attributes (second paragraph).
implicit_title_from_attrs 🔒
Extract the implicit title from doc attributes (first sentence, up to first . or newline).
inherits_params 🔒
Whether the author’s tags inherit the parameter docs from another topic: @inheritParams source, or @inherit source whose field list includes params (roxygen2 inherits every field when none is listed). roxygen2 fills only the arguments the merged topic leaves undocumented, so a generated line would block the inheritance.
inline_rustdoc_destination 🔒
The end (past its )) of the destination of an inline link [text](dest) starting at byte start (just past the (), when that destination was written for rustdoc: a Rust path (is_rust_path) containing ::, with an optional disambiguator prefix (strip_rustdoc_disambiguator), such as crate::x, serde::Serialize or fn@Self::new.
is_bare_topic_tag 🔒
A bare @name / @rdname (topic written on the next /// line, which roxygen2 accepts) takes exactly one continuation line as its topic. Once the tag has a topic it is single-line again, so following prose is not absorbed (see test_rdname_stays_single_line). The wrapper registry decides page routing from the single #' @name <topic> line, so a dropped topic would silently change which page a function lands on.
is_joined_tag 🔒
Check if a tag’s continuation lines are joined with a space (see JOINED_TAGS).
is_multiline_tag 🔒
Check if a tag name supports multi-line content.
is_rust_path 🔒
Whether dest is a Rust path as an inline link destination writes it: identifiers joined by ::, with an optional () or ! suffix. A URL with a /, ., #, ? or lone : never is one, even with a :: in it (https://a.b/c::d). A bare Foo can be either, so the caller also asks for a ::.
is_rustdoc_only_target 🔒
Whether roxygen2 can never resolve the link target target, so the link was written for rustdoc.
joins_author_topic 🔒
Whether the author’s tags put the block on a topic other than default_page: @describeIn topic ..., or an @rdname topic that names another page. The block then joins a topic whose own block (usually the author’s, often in R) documents the page, so generated lines that claim the page (a structural @param, the page \name and title) must give way to it.
leading_prose_from_attrs 🔒
Collect the leading prose of a doc comment (the lines before the first @tag, LineRole::Prose) as roxygen @description text, its links treated per the crate’s ProseLinks setting (passed in, so the unit tests need no manifest; roxygen_tags_with passes Strip for a block that renders no page).
method_page 🔒
The page a method’s block lands on: its @describeIn destination (roxygen2 files a @describeIn block under the destination’s topic), its own @rdname, else default_page (the class page). A companion block that must share the method’s page (the S3 generic block, whose class-qualified @name is also the method’s alias) gets @rdname this.
method_source_tag 🔒
The @source line for a class method: Generated by miniextendr from `Type::method` , subject to source_tag’s opt-in.
neutralize_tag_links 🔒
An explicit tag with the links of its text neutralized: the rustdoc-only ones (Neutralize::RustdocOnly), or all of them in a block that renders no page (Neutralize::AllLinks). A code tag (CODE_TAGS) stays as written.
normalize_for_comparison 🔒
Normalize text for comparison: lowercase, collapse whitespace, strip trailing punctuation.
orders_after_topic_blocks 🔒
Whether a block with the author’s tags gets @order NaN (ORDER_AFTER_TOPIC_BLOCKS): it joins an author topic (joins_author_topic against default_page), the author did not order it with their own @order, and it renders a page (no @noRd).
param_documented 🔒
Returns true if name is documented by any @param tag in tags.
param_names_token 🔒
Returns the @param name token (e.g. a,b,c in @param a,b,c desc) of a single tag, or None if tag isn’t an @param tag.
params_documented_elsewhere 🔒
Returns true when the author’s roxygen block takes its argument documentation from another block, so the generators must not add @param lines for the arguments it leaves undocumented (#1590):
push_fn_param_tags 🔒
Append the generated @param tags for a standalone function’s R parameters to the author’s tags, and return the (doc_placeholder, rust_param) pair of every match_arg parameter that received the write-time placeholder (the resolver registry needs one MX_MATCH_ARG_PARAM_DOCS entry each).
push_order_after_topic_blocks 🔒
Push #' @order NaN (ORDER_AFTER_TOPIC_BLOCKS) when orders_after_topic_blocks holds.
push_rdname_or_default 🔒
Push #' @rdname <topic> for a scaffolding block that follows its method: the method’s page (method_page: its @describeIn destination or own @rdname), else default (the class page).
push_roxygen_tags 🔒
Push roxygen tag lines into a vector of R wrapper lines.
push_roxygen_tags_str 🔒
Like push_roxygen_tags but takes &[&str] for filtered tag slices.
rdname_value 🔒
The topic named by the tag list’s own @rdname tag, if it has one.
roxygen_line 🔒
One roxygen comment line: #' text, or a bare #' for a blank text (no trailing whitespace in the generated R). Render author tag text through this (or the push_roxygen_tags* helpers), never format!("#' {}", ..).
roxygen_tag_name 🔒
Extract the tag name from a roxygen line (everything between @ and the first whitespace character). Returns None for lines that don’t start with a tag.
roxygen_tags_from_attrs 🔒
Extract roxygen tag lines (starting with ‘@’) from Rust doc attributes.
roxygen_tags_from_attrs_for_r6_method 🔒
Extract roxygen tags for an impl-block method.
roxygen_tags_from_attrs_impl 🔒
Core implementation of roxygen tag extraction from #[doc = "..."] attributes.
roxygen_tags_with 🔒
roxygen_tags_from_attrs_impl with the crate’s ProseLinks setting passed in (testable without a manifest).
sanitize_prose_links 🔒
sanitize_roxygen_links over prose lines, one paragraph (the lines between blank lines) at a time, joined back with their line breaks.
sanitize_roxygen_links 🔒
Neutralize rustdoc intra-doc link syntax so prose is valid roxygen2 markdown.
source_tag 🔒
The @source provenance line for a generated documentation block, or None unless the crate opted in with [package.metadata.miniextendr] source_tags = true (#1552). On a shared Rd page the tag collects one paragraph per function, so it is off by default; the # Generated from Rust fn … (file:line:col) comment above each wrapper stays as the navigation pointer. Every emitter goes through here (or the two specialisations below), so the knob has one implementation.
source_tag_with 🔒
source_tag with the crate setting passed in (testable without a manifest).
split_r_formals 🔒
Split an R formals/argument string on top-level commas only.
strip_method_tags 🔒
Filter out method-specific roxygen tags from impl-block-level docs and emit compile warnings for each stripped tag.
strip_method_tags_r6 🔒
Like strip_method_tags but for R6 impl blocks.
strip_roxygen_from_attrs 🔒
Strip roxygen tag lines from doc attributes, keeping only regular documentation.
strip_rustdoc_disambiguator 🔒
dest without a rustdoc disambiguator prefix (fn@crate::x -> crate::x). rustdoc’s prefixes are the item kinds below; any other word@rest is left whole and so fails is_rust_path.
strip_tags_in 🔒
Shared body of strip_method_tags and strip_method_tags_r6: drop every tag whose name is in method_only and emit one warning const scope per dropped tag. The two public entry points differ only in the tag table.
tag_documents_param 🔒
Shared predicate: does this single @param tag document name?
tag_names 🔒
Extract the set of tag names from a list of roxygen tag strings.