1#' Construct an `rd_section` object
2#'
3#' An `rd_section` represents an Rd command that can appear at the top-level
4#' of an Rd document, like `\name{}`, `\title{}`, `\description{}`, or
5#' `\section{}`.
6#'
7#' @section Methods:
8#' If provide your own `rd_section` type, you'll also need to define a
9#' `format.rd_section_{type}` method that returns formatted Rd output. You
10#' may also need to provide a `merge.rd_section_{type}` method if two
11#' sections can not be combined with `rd_section(x$type, c(x$value, y$value))`.
12#' See `vignette("extending")` for more details.
13#'
14#' @param type Section type. Stored in `type` field, and in class
15#'   `rd_section_{type}`. To avoid namespace clashes between different
16#'   extensions, this should include the package name.
17#' @param value Section data. Only used by `format()` and `merge()` methods.
18#' @export
19#' @keywords internal
20rd_section <- function(type, value) {
21  if (is.null(value) || identical(value, "NULL")) {
22    # NULL is special sentinel value that suppresses output of that field
23    return()
24  }
25
26  structure(
27    list(
28      type = type,
29      value = value
30    ),
31    class = c(paste0("rd_section_", type), "rd_section")
32  )
33}
34
35#' @export
36print.rd_section <- function(x, ...) {
37  cat(format(x), "\n")
38}
39
40#' @export
41format.rd_section <- function(x, ...) {
42  abort(paste0("`format.", class(x)[[1]], "` not found"))
43}
44
45#' @export
46merge.rd_section <- function(x, y, ...) {
47  stopifnot(identical(class(x), class(y)))
48  rd_section(x$type, c(x$value, y$value))
49}
50
51format_rd <- function(x, ..., sort = TRUE) {
52  # One rd macro for each value
53  x$value <- unique(x$value)
54  if (sort) {
55    x$value <- sort_c(x$value)
56  }
57
58  map_chr(x$value, rd_macro, field = x$type)
59}
60
61format_first <- function(x, ...) {
62  # Only use the first value
63  rd_macro(x$type, x$value[1])
64}
65
66format_collapse <- function(x, ..., indent = 0, exdent = 0) {
67  # Collapse all into a single string
68  value <- paste0(x$value, collapse = "\n\n")
69  rd_macro(x$type, value, space = TRUE)
70}
71
72rd_section_description <- function(name, dt, dd) {
73  if (length(dt) == 0) return("")
74
75  items <- paste0("\\item{\\code{", dt, "}}{", dd, "}", collapse = "\n\n")
76  paste0("\\section{", name, "}{\n\n",
77    "\\describe{\n",
78    items,
79    "\n}}\n"
80  )
81}
82
83