diff --git a/NEWS.md b/NEWS.md index e5835c1b4..ce88ac27b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,8 @@ * New tag `@rawRd` allows you to insert raw (unescaped) Rd code. `@evalRd()` is similar, but instead of literal Rd, you give it R code that produces literal Rd code when run. This should make it easier to experiment with new types of - output (#385). + output. `@rawNamespace` allows you to insert literal text in your namespace: + this can be useful for conditional imports (#385). * `register.preref.parser()` and `register.preref.parsers()` have been deprecated - please use `register_tags()` instead. diff --git a/R/parse-preref.R b/R/parse-preref.R index 638580e82..c803c31d3 100644 --- a/R/parse-preref.R +++ b/R/parse-preref.R @@ -88,7 +88,7 @@ parse.code <- function(x) { tag_warning(x, "requires a value") } else { tryCatch({ - x$val <- parse(text = x$val) + parse(text = x$val) x }, error = function(e) { tag_warning(x, "code failed to parse.\n", e$message) diff --git a/R/roclet-namespace.R b/R/roclet-namespace.R index ae73686d8..3529a649c 100644 --- a/R/roclet-namespace.R +++ b/R/roclet-namespace.R @@ -10,12 +10,13 @@ register_tags( importClassesFrom = words_parser(2), importFrom = words_parser(2), importMethodsFrom = words_parser(2), + rawNamespace = parse.code, S3method = words_parser(2, 2), useDynLib = words_parser(1) ) ns_tags <- c('export', 'exportClass', 'exportMethod', 'exportPattern', - 'S3method', 'import', 'importFrom', 'importClassesFrom', + 'rawNamespace', 'S3method', 'import', 'importFrom', 'importClassesFrom', 'importMethodsFrom', 'useDynLib') #' Roclet: make NAMESPACE. @@ -121,6 +122,7 @@ ns_useDynLib <- function(tag, part) { repeat_first("useDynLib", tag) } } +ns_rawNamespace <- function(tag, part) tag # Functions used by both default_export and ns_* functions export <- function(x) one_per_line("export", x) diff --git a/R/roclet-rd.R b/R/roclet-rd.R index 89be93a45..7d2680def 100644 --- a/R/roclet-rd.R +++ b/R/roclet-rd.R @@ -115,7 +115,8 @@ block_to_rd <- function(block, base_path, env) { add_tag(rd, process_doc_type(block)) add_tag(rd, process_tag(block, "rawRd")) add_tag(rd, process_tag(block, "evalRd", function(tag, param) { - out <- eval(param, envir = env) + expr <- parse(text = param) + out <- eval(expr, envir = env) new_tag("rawRd", as.character(out)) })) add_tag(rd, process_tag(block, "title")) diff --git a/tests/testthat/test-raw.R b/tests/testthat/test-raw.R index adf3c55cc..b7a17903c 100644 --- a/tests/testthat/test-raw.R +++ b/tests/testthat/test-raw.R @@ -30,3 +30,22 @@ test_that("rawRd inserted unchanged", { args <- get_tag(out, "rawRd")$values expect_equal(args, "20") }) + +test_that("rawNamespace must be valid code", { + expect_warning( + roc_proc_text(namespace_roclet(), " + #' @rawNamespace if() { + #' @name a + NULL"), + "code failed to parse" + ) +}) + +test_that("rawNamespace inserted unchanged", { + out <- roc_proc_text(namespace_roclet(), " + #' @rawNamespace xyz + #' abc + NULL") + + expect_equal(out, "xyz\n abc") +})