R/rd-examples.R

Defines functions escape_examples format.rd_section_examples roxy_tag_rd.roxy_tag_example roxy_tag_rd.roxy_tag_examplesIf roxy_tag_rd.roxy_tag_examples roxy_tag_parse.roxy_tag_example roxy_tag_parse.roxy_tag_examplesIf roxy_tag_parse.roxy_tag_examples

Documented in escape_examples

#' @export
roxy_tag_parse.roxy_tag_examples <- function(x) {
  tag_examples(x)
}
#' @export
roxy_tag_parse.roxy_tag_examplesIf <- function(x) {
  lines <- unlist(strsplit(x$raw, "\r?\n"))

  condition <- lines[1]
  tryCatch(
    suppressWarnings(parse(text = condition)),
    error = function(err) {
      roxy_tag_warning(x, "failed to parse condition of @examplesIf")
    }
  )

  dontshow <- paste0(
    "\\dontshow{if (",
    condition,
    ") (if (getRversion() >= \"3.4\") withAutoprint else force)(\\{ # examplesIf}"
  )

  x$raw <- paste(
    c(dontshow, lines[-1], "\\dontshow{\\}) # examplesIf}"),
    collapse = "\n"
  )

  x <- tag_examples(x)
}
#' @export
roxy_tag_parse.roxy_tag_example <- function(x) {
  x <- tag_value(x)

  nl <- str_count(x$val, "\n")
  if (any(nl) > 0) {
    roxy_tag_warning(x, "spans multiple lines. Do you want @examples?")
    return()
  }

  x
}

#' @export
roxy_tag_rd.roxy_tag_examples <- function(x, base_path, env) {
  rd_section("examples", x$val)
}
#' @export
roxy_tag_rd.roxy_tag_examplesIf <- function(x, base_path, env) {
  rd_section("examples", x$val)
}
#' @export
roxy_tag_rd.roxy_tag_example <- function(x, base_path, env) {
  path <- file.path(base_path, x$val)
  if (!file.exists(path)) {
    roxy_tag_warning(x, "'", path, "' doesn't exist")
    return()
  }

  code <- read_lines(path)
  rd_section("examples", escape_examples(code))
}

#' @export
format.rd_section_examples <- function(x, ...) {
  value <- paste0(x$value, collapse = "\n")
  rd_macro(x$type, value, space = TRUE)
}

#' Escape examples
#'
#' This documentation topic is used primarily for testing and to record
#' our understanding of the `\example{}` escaping rules.
#' See <https://developer.r-project.org/parseRd.pdf> for the details provided
#' by R core.
#'
#' @keywords internal
#' @examples
#' # In examples we automatically escape Rd comments (%):
#' 100 %% 30
#' # even if they are in strings
#' "50%"
#'
#' # and \\ and \v inside of strings and symbols
#' "\v" # vertical tab
#' "\\"
#' # but not comments: \l \v
#'
#' # other string escapes are left as is
#' "\""
#' "\n"
#'
#' # Otherwise, backslashes and parentheses are left as is. This
#' # means that you need to escape unbalanced parentheses, which typically only
#' # occur in \dontshow{}:
#' \dontshow{if (FALSE) \{ }
#' print("Hello")
#' \dontshow{ \} }
#'
#' # You also need to escape backslashes in infix operators and comments
#' # (this is generally rare)
#' `%\\%` <- function(x, y) x + y
#' 10 %\\% 20
#' # \\\\ (renders as two backslashes)
escape_examples <- function(x) {
  x <- paste0(x, collapse = "\n")
  rd(escapeExamples(x))
}

Try the roxygen2 package in your browser

Any scripts or data that you put into this service are public.

roxygen2 documentation built on Sept. 8, 2021, 9:08 a.m.