diff --git a/DESCRIPTION b/DESCRIPTION index 69e413f..8b49806 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: quarto Title: R Interface to 'Quarto' Markdown Publishing System -Version: 1.3.2 +Version: 1.3.3 Authors@R: c( person("JJ", "Allaire", , "jj@rstudio.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-0174-9868")), diff --git a/NEWS.md b/NEWS.md index 0e3961f..b10d269 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # quarto (development version) +* Add `profile` arguments to `quarto_render()` and `quarto_inspect()` (thanks, #95, @andrewheiss, #123, @salim-b). + * Add `metadata` and `metadata_file` to `quarto_render()` to pass modify Quarto metadata from calling render. If both are set, `metadata` will be merged over `metadata_file` content. Internally, metadata will be passed as a `--metadata-file` to `quarto render` (thanks, @mcanouil, #52, @maelle, #49). * Added a `NEWS.md` file to track changes to the package. diff --git a/R/inspect.R b/R/inspect.R index 963082b..f3f6788 100644 --- a/R/inspect.R +++ b/R/inspect.R @@ -4,12 +4,13 @@ #' config and engines. Inspecting an input path return its formats, engine, #' and dependent resources. #' +#' @inheritParams quarto_render #' @param input The input file or project directory to inspect. #' -#' @return Named list. For input files, the list has members engine, format, -#' and resources. For projects the list has members engines and config -#' -#' @importFrom jsonlite fromJSON +#' @return Named list. For input files, the list contains the elements +#' `quarto`, `engines`, `formats`, `resources`, plus `project` if the file is +#' part of a Quarto project. For projects, the list contains the elements +#' `quarto`, `dir`, `engines`, `config` and `files`. #' #' @examples #' \dontrun{ @@ -18,18 +19,26 @@ #' #' # Inspect project #' quarto_inspect("myproject") -#' } #' +#' # Inspect project's advanced profile +#' quarto_inspect( +#' input = "myproject", +#' profile = "advanced" +#' )} +#' @importFrom jsonlite fromJSON #' @export -quarto_inspect <- function(input = ".") { +quarto_inspect <- function(input = ".", + profile = NULL) { quarto_bin <- find_quarto() - output <- system2(quarto_bin, stdout = TRUE, c( - "inspect", - path.expand(input) - )) + args <- c("inspect", path.expand(input)) - fromJSON(output) -} + if (!is.null(profile)) { + args <- c(args, c("--profile", paste0(profile, collapse = ","))) + } + + res <- processx::run(quarto_bin, args, echo_cmd = getOption("quarto.echo_cmd", FALSE)) + fromJSON(res$stdout) +} diff --git a/R/quarto-args.R b/R/quarto-args.R new file mode 100644 index 0000000..81757c1 --- /dev/null +++ b/R/quarto-args.R @@ -0,0 +1,9 @@ +cli_arg_profile <- function(profile, ...) { + arg <- c("--profile", paste0(profile, collapse = ",")) + append_cli_args(arg, ...) +} + +append_cli_args <- function(new, append_to = NULL, after = length(append_to)) { + if (!is.null(append_to)) return(append(append_to, new, after)) + new +} diff --git a/R/render.R b/R/render.R index d97373c..ab3e6a9 100644 --- a/R/render.R +++ b/R/render.R @@ -36,6 +36,9 @@ #' specified, with low precedence on `metadata` options. #' @param debug Leave intermediate files in place after render. #' @param quiet Suppress warning and other messages. +#' @param profile [Quarto project +#' profile(s)](https://quarto.org/docs/projects/profiles.html) to use. Either +#' a character vector of profile names or `NULL` to use the default profile. #' @param pandoc_args Additional command line options to pass to pandoc. #' @param as_job Render as an RStudio background job. Default is "auto", #' which will render individual documents normally and projects as @@ -76,6 +79,7 @@ quarto_render <- function(input = NULL, metadata_file = NULL, debug = FALSE, quiet = FALSE, + profile = NULL, pandoc_args = NULL, as_job = getOption("quarto.render_as_job", "auto")) { @@ -107,7 +111,7 @@ quarto_render <- function(input = NULL, workingDir = getwd(), importEnv = TRUE ) - return (invisible(NULL)) + return(invisible(NULL)) } @@ -167,6 +171,9 @@ quarto_render <- function(input = NULL, if (isTRUE(quiet)) { args <- c(args, "--quiet") } + if (!is.null(profile)) { + args <- cli_arg_profile(profile, args) + } if (!is.null(pandoc_args)) { args <- c(args, pandoc_args) } diff --git a/man/quarto_inspect.Rd b/man/quarto_inspect.Rd index 4b1cd1e..ea87f96 100644 --- a/man/quarto_inspect.Rd +++ b/man/quarto_inspect.Rd @@ -4,14 +4,19 @@ \alias{quarto_inspect} \title{Inspect Quarto Input File or Project} \usage{ -quarto_inspect(input = ".") +quarto_inspect(input = ".", profile = NULL) } \arguments{ \item{input}{The input file or project directory to inspect.} + +\item{profile}{\href{https://quarto.org/docs/projects/profiles.html}{Quarto project profile(s)} to use. Either +a character vector of profile names or \code{NULL} to use the default profile.} } \value{ -Named list. For input files, the list has members engine, format, -and resources. For projects the list has members engines and config +Named list. For input files, the list contains the elements +\code{quarto}, \code{engines}, \code{formats}, \code{resources}, plus \code{project} if the file is +part of a Quarto project. For projects, the list contains the elements +\code{quarto}, \code{dir}, \code{engines}, \code{config} and \code{files}. } \description{ Inspect a Quarto project or input path. Inspecting a project returns its @@ -25,6 +30,10 @@ quarto_inspect("notebook.Rmd") # Inspect project quarto_inspect("myproject") -} +# Inspect project's advanced profile +quarto_inspect( + input = "myproject", + profile = "advanced" +)} } diff --git a/man/quarto_render.Rd b/man/quarto_render.Rd index ce853c7..7d80300 100644 --- a/man/quarto_render.Rd +++ b/man/quarto_render.Rd @@ -21,6 +21,7 @@ quarto_render( metadata_file = NULL, debug = FALSE, quiet = FALSE, + profile = NULL, pandoc_args = NULL, as_job = getOption("quarto.render_as_job", "auto") ) @@ -74,6 +75,9 @@ specified, with low precedence on \code{metadata} options.} \item{quiet}{Suppress warning and other messages.} +\item{profile}{\href{https://quarto.org/docs/projects/profiles.html}{Quarto project profile(s)} to use. Either +a character vector of profile names or \code{NULL} to use the default profile.} + \item{pandoc_args}{Additional command line options to pass to pandoc.} \item{as_job}{Render as an RStudio background job. Default is "auto", diff --git a/tests/testthat/project/_quarto-test.yml b/tests/testthat/project/_quarto-test.yml new file mode 100644 index 0000000..b42c8ff --- /dev/null +++ b/tests/testthat/project/_quarto-test.yml @@ -0,0 +1,2 @@ +execute: + echo: true diff --git a/tests/testthat/project/_quarto.yml b/tests/testthat/project/_quarto.yml index b998f74..eb8af50 100644 --- a/tests/testthat/project/_quarto.yml +++ b/tests/testthat/project/_quarto.yml @@ -1,2 +1,5 @@ project: type: site + +execute: + echo: false diff --git a/tests/testthat/test-inspect.R b/tests/testthat/test-inspect.R index 0df63af..74c2ffe 100644 --- a/tests/testthat/test-inspect.R +++ b/tests/testthat/test-inspect.R @@ -1,11 +1,22 @@ -test_that("R Markdown documents can be inspected", { +test_that("Documents can be inspected", { skip_if_no_quarto() - metadata <- quarto_inspect("test.Rmd") + metadata <- quarto_inspect(test_path("test.Rmd")) + expect_type(metadata$formats, "list") + metadata <- quarto_inspect(test_path("test.qmd")) + expect_type(metadata$formats, "list") + metadata <- quarto_inspect(test_path("test.ipynb")) expect_type(metadata$formats, "list") }) test_that("Quarto projects can be inspected", { skip_if_no_quarto() - metadata <- quarto_inspect("project") + metadata <- quarto_inspect(test_path("project")) + expect_type(metadata$config, "list") +}) + +test_that("Quarto projects can be inspected with profile", { + skip_if_no_quarto() + metadata <- quarto_inspect(test_path("project"), "test") expect_type(metadata$config, "list") + expect_identical(metadata$config$execute$echo, TRUE) }) diff --git a/tests/testthat/test-quarto-args.R b/tests/testthat/test-quarto-args.R new file mode 100644 index 0000000..abfa382 --- /dev/null +++ b/tests/testthat/test-quarto-args.R @@ -0,0 +1,13 @@ +test_that("append to existing", { + expect_identical(append_cli_args("a"), "a") + expect_identical(append_cli_args(c("a", "b")), c("a", "b")) + expect_identical(append_cli_args("c", c("a", "b")), c("a", "b", "c")) + expect_identical(append_cli_args("b", c("a", "c"), 1), c("a", "b", "c")) + expect_identical(append_cli_args(c("b","c"), c("a", "d"), 1), c("a", "b", "c", "d")) +}) + +test_that("create profile arg", { + expect_identical(cli_arg_profile("a"), c("--profile", "a")) + expect_identical(cli_arg_profile(c("a", "b")), c("--profile", "a,b")) + expect_identical(cli_arg_profile(c("a", "b"), "input.qmd"), c("input.qmd", "--profile", "a,b")) +}) diff --git a/tests/testthat/test.ipynb b/tests/testthat/test.ipynb new file mode 100644 index 0000000..b36e93d --- /dev/null +++ b/tests/testthat/test.ipynb @@ -0,0 +1,49 @@ +{ + "cells": [ + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "---\n", + "title: \"Untitled\"\n", + "format: html\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Quarto\n", + "\n", + "Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see .\n", + "\n", + "## Running Code\n", + "\n", + "When you click the **Render** button a document will be generated that includes both content and the output of embedded code. You can embed code like this:\n", + "\n", + "```{r}\n", + "1 + 1\n", + "```\n", + "\n", + "You can add options to executable code like this\n", + "\n", + "```{r}\n", + "#| echo: false\n", + "2 * 2\n", + "```\n", + "\n", + "The `echo: false` option disables the printing of code (only output is displayed)." + ] + } + ], + "metadata": { + "kernelspec": { + "name": "python3", + "language": "python", + "display_name": "Python 3 (ipykernel)" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} \ No newline at end of file diff --git a/tests/testthat/test.qmd b/tests/testthat/test.qmd new file mode 100644 index 0000000..719c496 --- /dev/null +++ b/tests/testthat/test.qmd @@ -0,0 +1,25 @@ +--- +title: "Untitled" +format: html +--- + +## Quarto + +Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see . + +## Running Code + +When you click the **Render** button a document will be generated that includes both content and the output of embedded code. You can embed code like this: + +```{r} +1 + 1 +``` + +You can add options to executable code like this + +```{r} +#| echo: false +2 * 2 +``` + +The `echo: false` option disables the printing of code (only output is displayed).