R package documentation with roxygen2 and Rd files, including mathematical notation, selective Rd parsing, and structured sections. Use when writing/updating/refactoring roxygen2 documentation, adding math formulas to R help pages, programmatically reading Rd files, or troubleshooting Rd rendering
Install with Tessl CLI
npx tessl i github:jjjermiah/dotagents --skill r-documentation100
Does it follow best practices?
Validation for skill structure
Write and manipulate R package documentation using roxygen2 and the Rd format. Covers structured documentation (sections, lists, tables), mathematical notation (\eqn/\deqn), and programmatic Rd parsing/extraction.
Roxygen2 blocks map to Rd sections. The implicit structure is:
#' Title (first paragraph)
#'
#' Description (second paragraph).
#'
#' Details (third+ paragraphs).
#' @param x Argument docs.
#' @return What it returns.
#' @export
my_func <- function(x) {}Explicit tags override implicit placement: @title, @description, @details.
@details blocks@details can appear multiple times — all merge into a single Details section:
#' @details
#' First block.
#'
#' @param x Input.
#'
#' @details
#' Second block (merged with first in output).Two equivalent approaches:
#' @section Algorithm:
#' Description of the algorithm.Or with Markdown headings (requires Roxygen: list(markdown = TRUE) in DESCRIPTION):
#' @details
#' # Algorithm
#' Description of the algorithm.
#'
#' ## Phase 1
#' ...Top-level # creates \section{}. ##/### create subsections. Headings only valid after @description or @details.
Gotcha: \describe{\item{label}{desc}} uses two-arg \item. \itemize{\item} and \enumerate{\item} use bare \item. Mixing these up is a common error.
#' \tabular{lcr}{
#' Name \tab Value \tab Unit \cr
#' foo \tab 42 \tab kg \cr
#' }Column alignment: l/c/r. Columns: \tab. Rows: \cr.
Use \preformatted{} for matrix output examples — preserves exact whitespace.
Two macros for math in Rd:
| Macro | Purpose | LaTeX equivalent |
|---|---|---|
\eqn{latex}{ascii} | Inline math | $...$ |
\deqn{latex}{ascii} | Display (block) math | $$...$$ |
Always use the two-argument form for anything beyond trivial expressions. The second argument is the plain-text fallback shown in terminal ?help.
| Output | Renderer | Math source |
|---|---|---|
| Full LaTeX | 1st argument | |
| HTML (R >= 4.2.0) | KaTeX | 1st argument |
| Text/terminal | Plain text | 2nd argument (or raw LaTeX if omitted) |
#' The variance is \eqn{\sigma^2}{sigma^2}.
#'
#' The expected value:
#' \deqn{E[X] = \sum_{i} p_i x_i}{E[X] = sum(p_i * x_i)}YOU MUST define every symbol before or at its first use. Never introduce P, O, t, etc. in a formula without saying what they are in the surrounding prose.
#' Let \eqn{P_{ij}}{P[i,j]} be the joint probability and
#' \eqn{O_{ij}}{O[i,j]} the outcome value. Then:
#' \deqn{E[X] = \sum_{i,j} P_{ij} \cdot O_{ij}}{E[X] = sum(P[i,j] * O[i,j])}For detailed math formatting syntax, multi-line equations, mathjaxr, and gotchas, load references/math-formatting.md.
tools::parse_Rd() parses the entire Rd file into a nested tagged list. There is no partial parsing — selective reading happens post-parse by filtering tags.
rd <- tools::parse_Rd("man/my_function.Rd")
tags <- vapply(rd, attr, character(1L), "Rd_tag")
# => "\\name", "\\alias", "\\title", "\\description", ...idx <- which(tags == "\\description")
trimws(paste(unlist(rd[[idx[1L]]]), collapse = ""))fragment <- rd[which(tags == "\\description")]
class(fragment) <- "Rd"
tools::Rd2txt(fragment, out = stdout(), fragment = TRUE)The fragment = TRUE flag is essential when rendering subsets.
For full patterns (batch extraction, HTML rendering, helper packages like gbRd/Rdpack), load references/rd-parsing.md.
After writing or editing roxygen2 documentation:
# 1. Regenerate Rd files
roxygen2::roxygenise()
# 2. Parse and validate (should produce no output = success)
rd <- tools::parse_Rd("man/MyTopic.Rd")
tools::checkRd(rd)
# 3. Render to text (verify terminal help looks right)
tools::Rd2txt(rd, out = stdout())Check for:
\eqn/\deqn\preformatted{} blocks rendering with correct whitespace$...$ and $$...$$ are NOT supported in Rd. Use \eqn{}/\deqn{}.\eqn{}/\deqn{} (they are verbatim).\\ for LaTeX newlines requires \\\\ in roxygen2 source.\describe{\item{}{}} takes two-arg items. \itemize{\item} takes bare items.Rd2txt), not just HTML — terminal users see the ASCII fallback.If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.