From 79a2cccc25e385ef4bb389497cc95be59bb809eb Mon Sep 17 00:00:00 2001 From: olivroy Date: Thu, 4 Jul 2024 08:27:07 -0400 Subject: [PATCH 1/5] Lint to test --- tests/testthat/test-vignette.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-vignette.R b/tests/testthat/test-vignette.R index 82b7a4690..9fe965446 100644 --- a/tests/testthat/test-vignette.R +++ b/tests/testthat/test-vignette.R @@ -25,8 +25,9 @@ test_that("use_vignette() does the promised setup", { expect_true("inst/doc" %in% ignores) deps <- proj_deps() - expect_true( - all(c("knitr", "rmarkdown") %in% deps$package[deps$type == "Suggests"]) + expect_contains( + deps$package[deps$type == "Suggests"], + c("knitr", "rmarkdown") ) expect_identical(proj_desc()$get_field("VignetteBuilder"), "knitr") From c7e7243247d32478c0540c0afe79e638658b90a0 Mon Sep 17 00:00:00 2001 From: olivroy Date: Thu, 4 Jul 2024 08:28:19 -0400 Subject: [PATCH 2/5] Support quarto vignettes and articles --- NEWS.md | 2 ++ R/vignette.R | 50 ++++++++++++++++++++++++++-------- man/use_vignette.Rd | 8 ++++-- tests/testthat/test-vignette.R | 31 +++++++++++++++++++++ 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/NEWS.md b/NEWS.md index a8444a635..347d13007 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # usethis (development version) +* `use_vignette()` and `use_article()` gain `type` to allow creating Quarto vignettes and articles (@olivroy, #1997). + * `use_git()` no longer asks if you want to restart RStudio when using Positron. * `use_test()` and `use_r()` now work when you are in `tests/testthat/_snaps/{foo}.md` (@olivroy, #1988). diff --git a/R/vignette.R b/R/vignette.R index ceab26aa0..c35b19ad8 100644 --- a/R/vignette.R +++ b/R/vignette.R @@ -13,40 +13,60 @@ #' @param name Base for file name to use for new vignette. Should consist only #' of numbers, letters, `_` and `-`. Lower case is recommended. #' @param title The title of the vignette. +#' @param type One of `"quarto"` or `"rmarkdown"` #' @seealso The [vignettes chapter](https://r-pkgs.org/vignettes.html) of -#' [R Packages](https://r-pkgs.org). +#' [R Packages](https://r-pkgs.org) and the [Quarto vignettes](https://quarto-dev.github.io/quarto-r/articles/hello.html) reference. #' @export #' @examples #' \dontrun{ #' use_vignette("how-to-do-stuff", "How to do stuff") #' } -use_vignette <- function(name, title = name) { +use_vignette <- function(name, title = name, type = c("rmarkdown", "quarto")) { check_is_package("use_vignette()") check_required(name) check_vignette_name(name) + type <- arg_match(type) use_dependency("knitr", "Suggests") - use_dependency("rmarkdown", "Suggests") - proj_desc_field_update("VignetteBuilder", "knitr", overwrite = TRUE) + if (type == "rmarkdown") { + use_dependency("rmarkdown", "Suggests") + proj_desc_field_update("VignetteBuilder", "knitr", overwrite = FALSE) + use_vignette_template("vignette.Rmd", name, title) + } else if (type == "quarto") { + proj_desc_field_update("VignetteBuilder", "quarto", overwrite = FALSE) + use_vignette_template("vignette.qmd", name, title) + use_build_ignore("vignettes/*_files") + #use_git_ignore("*_files", "vignettes/") + } use_git_ignore("inst/doc") - use_vignette_template("vignette.Rmd", name, title) invisible() } #' @export #' @rdname use_vignette -use_article <- function(name, title = name) { +use_article <- function(name, title = name, type = c("rmarkdown", "quarto")) { check_is_package("use_article()") + type <- arg_match(type) deps <- proj_deps() - if (!"rmarkdown" %in% deps$package) { - proj_desc_field_update("Config/Needs/website", "rmarkdown", append = TRUE) + + if (type == "rmarkdown") { + if (!"rmarkdown" %in% deps$package) { + proj_desc_field_update("Config/Needs/website", "rmarkdown", append = TRUE) + } + + use_vignette_template("article.Rmd", name, title, subdir = "articles") + } else if (type == "quarto") { + if (!"quarto" %in% deps$package) { + proj_desc_field_update("Config/Needs/website", "quarto", append = TRUE) + } + + use_vignette_template("article.qmd", name, title, subdir = "articles") } - use_vignette_template("article.Rmd", name, title, subdir = "articles") use_build_ignore("vignettes/articles") invisible() @@ -62,12 +82,20 @@ use_vignette_template <- function(template, name, title, subdir = NULL) { if (!is.null(subdir)) { use_directory(path("vignettes", subdir)) } + use_git_ignore(c("*.html", "*.R"), directory = "vignettes") + # make sure nothing else is caught. (this should be assured as `.` are not allowed.) + vignette_ext <- path_ext(template) + arg_match0(vignette_ext, c("qmd", "Rmd")) + if (vignette_ext == "qmd") { + # https://quarto-dev.github.io/quarto-r/articles/hello.html + use_git_ignore("*_files", directory = "vignettes") + } if (is.null(subdir)) { - path <- path("vignettes", asciify(name), ext = "Rmd") + path <- path("vignettes", asciify(name), ext = vignette_ext) } else { - path <- path("vignettes", subdir, asciify(name), ext = "Rmd") + path <- path("vignettes", subdir, asciify(name), ext = vignette_ext) } data <- list( diff --git a/man/use_vignette.Rd b/man/use_vignette.Rd index 8c5fa70fa..efc54f2cc 100644 --- a/man/use_vignette.Rd +++ b/man/use_vignette.Rd @@ -5,15 +5,17 @@ \alias{use_article} \title{Create a vignette or article} \usage{ -use_vignette(name, title = name) +use_vignette(name, title = name, type = c("rmarkdown", "quarto")) -use_article(name, title = name) +use_article(name, title = name, type = c("rmarkdown", "quarto")) } \arguments{ \item{name}{Base for file name to use for new vignette. Should consist only of numbers, letters, \verb{_} and \code{-}. Lower case is recommended.} \item{title}{The title of the vignette.} + +\item{type}{One of \code{"quarto"} or \code{"rmarkdown"}} } \description{ Creates a new vignette or article in \verb{vignettes/}. Articles are a special @@ -38,5 +40,5 @@ use_vignette("how-to-do-stuff", "How to do stuff") } \seealso{ The \href{https://r-pkgs.org/vignettes.html}{vignettes chapter} of -\href{https://r-pkgs.org}{R Packages}. +\href{https://r-pkgs.org}{R Packages} and the \href{https://quarto-dev.github.io/quarto-r/articles/hello.html}{Quarto vignettes} reference. } diff --git a/tests/testthat/test-vignette.R b/tests/testthat/test-vignette.R index 9fe965446..b09f92ef7 100644 --- a/tests/testthat/test-vignette.R +++ b/tests/testthat/test-vignette.R @@ -33,6 +33,24 @@ test_that("use_vignette() does the promised setup", { expect_identical(proj_desc()$get_field("VignetteBuilder"), "knitr") }) +test_that("use_vignette() works with Quarto", { + create_local_package() + + use_vignette("name", "title", type = "quarto") + expect_proj_file("vignettes/name.qmd") + + ignores <- read_utf8(proj_path(".gitignore")) + expect_true("inst/doc" %in% ignores) + + deps <- proj_deps() + expect_contains( + deps$package[deps$type == "Suggests"], + "knitr" + ) + + expect_identical(proj_desc()$get_field("VignetteBuilder"), "quarto") +}) + # use_article ------------------------------------------------------------- test_that("use_article goes in article subdirectory", { @@ -55,6 +73,19 @@ test_that("use_article() adds rmarkdown to Config/Needs/website", { ) }) +test_that("use_article() adds quarto to Config/Needs/website", { + create_local_package() + local_interactive(FALSE) + + proj_desc_field_update("Config/Needs/website", "somepackage", append = TRUE) + use_article("name", "title", "quarto") + + expect_setequal( + proj_desc()$get_list("Config/Needs/website"), + c("quarto", "somepackage") + ) +}) + # helpers ----------------------------------------------------------------- test_that("valid_vignette_name() works", { From 1fb0a631e808685dd07e2e89c7145aec3ac6ae21 Mon Sep 17 00:00:00 2001 From: olivroy Date: Thu, 4 Jul 2024 08:28:44 -0400 Subject: [PATCH 3/5] Add templates --- inst/templates/article.qmd | 15 +++++++++++++++ inst/templates/vignette.qmd | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 inst/templates/article.qmd create mode 100644 inst/templates/vignette.qmd diff --git a/inst/templates/article.qmd b/inst/templates/article.qmd new file mode 100644 index 000000000..c54437eaa --- /dev/null +++ b/inst/templates/article.qmd @@ -0,0 +1,15 @@ +--- +title: "{{{ vignette_title }}}" +format: html +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library({{Package}}) +``` diff --git a/inst/templates/vignette.qmd b/inst/templates/vignette.qmd new file mode 100644 index 000000000..767c58983 --- /dev/null +++ b/inst/templates/vignette.qmd @@ -0,0 +1,20 @@ +--- +title: "{{{ vignette_title }}}" +format: html +vignette: > + %\VignetteIndexEntry{Vignette's Title} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup} +library({{Package}}) +``` + From 2c7adeaeef3433ce0fcd79ccfe0677d97b84108b Mon Sep 17 00:00:00 2001 From: olivroy <52606734+olivroy@users.noreply.github.com> Date: Thu, 15 Aug 2024 16:48:11 -0400 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Jon Harmon --- R/vignette.R | 3 +-- inst/templates/article.qmd | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/R/vignette.R b/R/vignette.R index c35b19ad8..13f53a00c 100644 --- a/R/vignette.R +++ b/R/vignette.R @@ -37,7 +37,6 @@ use_vignette <- function(name, title = name, type = c("rmarkdown", "quarto")) { proj_desc_field_update("VignetteBuilder", "quarto", overwrite = FALSE) use_vignette_template("vignette.qmd", name, title) use_build_ignore("vignettes/*_files") - #use_git_ignore("*_files", "vignettes/") } use_git_ignore("inst/doc") @@ -87,7 +86,7 @@ use_vignette_template <- function(template, name, title, subdir = NULL) { # make sure nothing else is caught. (this should be assured as `.` are not allowed.) vignette_ext <- path_ext(template) arg_match0(vignette_ext, c("qmd", "Rmd")) - if (vignette_ext == "qmd") { + if (vignette_ext == "qmd" && uses_git()) { # https://quarto-dev.github.io/quarto-r/articles/hello.html use_git_ignore("*_files", directory = "vignettes") } diff --git a/inst/templates/article.qmd b/inst/templates/article.qmd index c54437eaa..da18c08bb 100644 --- a/inst/templates/article.qmd +++ b/inst/templates/article.qmd @@ -1,6 +1,10 @@ --- title: "{{{ vignette_title }}}" format: html +knitr: + opts_chunk: + collapse: true + comment: "#>" --- ```{r, include = FALSE} From 3dd240e10da9cbe63d9a20ae5c734e9ec0a1a94a Mon Sep 17 00:00:00 2001 From: Olivier Roy Date: Thu, 15 Aug 2024 17:32:33 -0400 Subject: [PATCH 5/5] Update vignette and article template --- inst/templates/article.qmd | 7 ------- inst/templates/vignette.qmd | 16 +++++++--------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/inst/templates/article.qmd b/inst/templates/article.qmd index da18c08bb..78f975db2 100644 --- a/inst/templates/article.qmd +++ b/inst/templates/article.qmd @@ -7,13 +7,6 @@ knitr: comment: "#>" --- -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) -``` - ```{r setup} library({{Package}}) ``` diff --git a/inst/templates/vignette.qmd b/inst/templates/vignette.qmd index 767c58983..b587c2d2c 100644 --- a/inst/templates/vignette.qmd +++ b/inst/templates/vignette.qmd @@ -1,20 +1,18 @@ --- title: "{{{ vignette_title }}}" format: html +knitr: + opts_chunk: + collapse: true + comment: "#>" vignette: > - %\VignetteIndexEntry{Vignette's Title} + %\VignetteIndexEntry{{{ braced_vignette_title }}} %\VignetteEngine{quarto::html} %\VignetteEncoding{UTF-8} --- -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) -``` - -```{r setup} +```{r} +#| label: setup library({{Package}}) ```