1#' `roxy_tag` S3 constructor
2#'
3#' `roxy_tag()` is the constructor for tag objects.
4#' `roxy_tag_warning()` generates a warning that gives the location of the tag.
5#'
6#' @section Methods:
7#' Define a method for `roxy_tag_parse` to support new tags. See [tag_parsers]
8#' for more details.
9#'
10#' @keywords internal
11#' @export
12#' @param tag Tag name. Arguments starting with `.` are reserved for internal
13#'   usage.
14#' @param raw Raw tag value, a string.
15#' @param val Parsed tag value, typically a character vector, but sometimes
16#'   a list. Usually filled in by `tag_parsers`
17#' @param file,line Location of the tag
18roxy_tag <- function(tag, raw, val = NULL, file = NA_character_, line = NA_integer_) {
19  structure(
20    list(
21      file = file,
22      line = line,
23      raw = raw,
24      tag = tag,
25      val = val
26    ),
27    class = c(paste0("roxy_tag_", tag), "roxy_tag")
28  )
29}
30
31#' @rdname roxy_tag
32#' @param x A tag
33#' @export
34roxy_tag_parse <- function(x) {
35  UseMethod("roxy_tag_parse")
36}
37
38#' @export
39roxy_tag_parse.default <- function(x) {
40  roxy_tag_warning(x, "unknown tag")
41}
42
43is.roxy_tag <- function(x) inherits(x, "roxy_tag")
44
45#' @export
46format.roxy_tag <- function(x, ..., file = NULL) {
47  if (identical(x$file, file)) {
48    file <- "line"
49  } else if (is.na(x$file)) {
50    file <- "????"
51  } else {
52    file <- basename(x$file)
53  }
54  line <- if (is.na(x$line)) "???" else format(x$line, width = 3)
55
56  loc <- paste0("[", file, ":", line, "]")
57
58  if (!is.null(x$raw)) {
59    lines <- strsplit(x$raw, "\n")[[1]]
60    ellipsis <- FALSE
61
62    if (length(lines) > 1) {
63      raw <- lines[[1]]
64      ellipsis <- TRUE
65    } else {
66      raw <- x$raw
67    }
68
69    if (nchar(raw) > 50) {
70      raw <- substr(raw, 1, 47)
71      ellipsis <- TRUE
72    }
73
74    raw <- paste0(raw, if (ellipsis) "...")
75  } else {
76    raw <- "<generated>"
77  }
78
79  parsed <- if (is.null(x$val)) "{unparsed}" else "{parsed}"
80
81  paste0(loc, " @", x$tag, " '", raw, "' ", parsed)
82}
83
84#' @export
85print.roxy_tag <- function(x, ...) {
86  cat_line(format(x, ...))
87}
88
89#' @export
90#' @rdname roxy_tag
91roxy_tag_warning <- function(x, ...) {
92  roxy_warning(file = x$file, line = x$line, "@", x$tag, " ", ...)
93}
94