Skip to content

Commit 589c937

Browse files
mcanouilcderv
andauthored
feat: new override argument to pass metadata (#52)
Co-authored-by: Christophe Dervieux <[email protected]>
1 parent b93ce9e commit 589c937

File tree

10 files changed

+136
-15
lines changed

10 files changed

+136
-15
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: quarto
22
Title: R Interface to 'Quarto' Markdown Publishing System
3-
Version: 1.3.1
3+
Version: 1.3.2
44
Authors@R:
55
person("JJ", "Allaire", , "[email protected]", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0003-0174-9868"))

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# quarto (development version)
22

3+
* 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).
4+
35
* Added a `NEWS.md` file to track changes to the package.
46

57
* `execute_params` in `quarto_render()` now converts boolean value to `true/false` correctly as expected by `quarto render` (thanks, @marianklose, #124).

R/render.R

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,15 @@
2525
#' @param use_freezer Force use of frozen computations for an incremental
2626
#' file render.
2727
#' @param cache Cache execution output (uses knitr cache and jupyter-cache
28-
#' respectively for Rmd and Jupyter input files).
28+
#' respectively for Rmd and Jupyter input files).
2929
#' @param cache_refresh Force refresh of execution cache.
30+
#' @param metadata An optional named list used to override YAML
31+
#' metadata. It will be passed as a YAML file to `--metadata-file` CLI flag.
32+
#' This will be merged over `metadata-file` options if both are
33+
#' specified.
34+
#' @param metadata_file A yaml file passed to `--metadata-file` CLI flags to
35+
#' overrite metadata. This will be merged with `metadata` if both are
36+
#' specified, with low precedence on `metadata` options.
3037
#' @param debug Leave intermediate files in place after render.
3138
#' @param quiet Suppress warning and other messages.
3239
#' @param pandoc_args Additional command line options to pass to pandoc.
@@ -48,6 +55,9 @@
4855
#'
4956
#' # Render Jupyter Markdown
5057
#' quarto_render("notebook.md")
58+
#'
59+
#' # Override metadata
60+
#' quarto_render("notebook.Rmd", override = list(lang = "fr", echo = "false"))
5161
#' }
5262
#' @export
5363
quarto_render <- function(input = NULL,
@@ -62,6 +72,8 @@ quarto_render <- function(input = NULL,
6272
use_freezer = FALSE,
6373
cache = NULL,
6474
cache_refresh = FALSE,
75+
metadata = NULL,
76+
metadata_file = NULL,
6577
debug = FALSE,
6678
quiet = FALSE,
6779
pandoc_args = NULL,
@@ -136,6 +148,19 @@ quarto_render <- function(input = NULL,
136148
if (isTRUE(cache_refresh)) {
137149
args <- c(args, "--cache-refresh")
138150
}
151+
# metadata to pass to quarto render
152+
if (!missing(metadata)) {
153+
# We merge meta if there is metadata_file passed
154+
if (!missing(metadata_file)) {
155+
metadata <- merge_list(yaml::read_yaml(metadata_file, eval.expr = FALSE), metadata)
156+
}
157+
meta_file <- tempfile(pattern = "quarto-meta", fileext = ".yml")
158+
on.exit(unlink(meta_file), add = TRUE)
159+
write_yaml(metadata, meta_file)
160+
args <- c(args, "--metadata-file", meta_file)
161+
} else if (!missing(metadata_file)) {
162+
args <- c(args, "--metadata-file", metadata_file)
163+
}
139164
if (isTRUE(debug)) {
140165
args <- c(args, "--debug")
141166
}
@@ -152,9 +177,3 @@ quarto_render <- function(input = NULL,
152177
# no return value
153178
invisible(NULL)
154179
}
155-
156-
157-
158-
159-
160-

R/utils.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,10 @@ write_yaml <- function(x, file) {
1515
})
1616
yaml::write_yaml(x, file, handlers = handlers)
1717
}
18+
19+
20+
# inline knitr:::merge_list()
21+
merge_list <- function(x, y) {
22+
x[names(y)] <- y
23+
x
24+
}

man/quarto_render.Rd

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Pandoc
2+
Meta
3+
{ unMeta =
4+
fromList [ ( "title" , MetaInlines [ Str "test" ] ) ]
5+
}
6+
[ Para [ Str "content" ] ]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Pandoc
2+
Meta
3+
{ unMeta =
4+
fromList [ ( "title" , MetaInlines [ Str "test2" ] ) ]
5+
}
6+
[ Para [ Str "content" ] ]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Pandoc
2+
Meta
3+
{ unMeta =
4+
fromList [ ( "title" , MetaInlines [ Str "test" ] ) ]
5+
}
6+
[ Para [ Str "content" ] ]

tests/testthat/helper.R

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,49 @@ skip_if_quarto <- function() {
99
local_qmd_file <- function(..., .env = parent.frame()) {
1010
skip_if_not_installed("xfun")
1111
skip_if_not_installed("withr")
12-
path <- withr::local_tempfile(.local_envir = .env, fileext = ".qmd")
12+
# create a directory to delete for correct cleaning
13+
dir <- withr::local_tempdir("quarto-test", .local_envir = .env)
14+
# create a file in this directory
15+
path <- withr::local_tempfile(tmpdir = dir, fileext = ".qmd", .local_envir = .env)
1316
xfun::write_utf8(c(...), path)
1417
path
1518
}
1619

17-
.render <- function(input, ...) {
20+
.render <- function(input, output_file = NULL, ..., .env = parent.frame()) {
1821
skip_if_no_quarto()
19-
output_file <- xfun::with_ext(basename(input), "test.out")
20-
quarto_render(input, output_file = output_file, quiet = TRUE, ...)
21-
output_file
22+
skip_if_not_installed("withr")
23+
# work inside input directory
24+
withr::local_dir(dirname(input))
25+
if (is.null(output_file)) {
26+
output_file <- basename(withr::local_file(
27+
xfun::with_ext(input, "test.out"),
28+
.local_envir = .env
29+
))
30+
}
31+
quarto_render(basename(input), output_file = output_file, quiet = TRUE, ...)
32+
expect_true(file.exists(output_file))
33+
normalizePath(output_file)
2234
}
2335

2436
.render_and_read <- function(input, ...) {
2537
skip_if_not_installed("xfun")
2638
skip_if_not_installed("withr")
2739
out <- .render(input, ...)
28-
withr::local_dir(dirname(input))
2940
xfun::read_utf8(out)
3041
}
42+
43+
expect_snapshot_qmd_output <- function(name, input, output_file = NULL, ...) {
44+
local_edition(3)
45+
skip_if_not_installed("xfun")
46+
name <- xfun::with_ext(name, ".test.out")
47+
48+
# Announce the file before touching `code`. This way, if `code`
49+
# unexpectedly fails or skips, testthat will not auto-delete the
50+
# corresponding snapshot file.
51+
announce_snapshot_file(name = name)
52+
53+
# render with quarto and snapshot
54+
output_file <- .render(input, output_file, ...)
55+
56+
expect_snapshot_file(output_file, name)
57+
}

tests/testthat/test-render.R

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
test_that("An error is reported when Quarto is not installed", {
32
skip_if_quarto()
43
expect_error(quarto_render("test.Rmd"))
@@ -11,3 +10,38 @@ test_that("R Markdown documents can be rendered", {
1110
expect_true(file.exists("test.html"))
1211
unlink("test.html")
1312
})
13+
14+
test_that("metadata argument works in quarto_render", {
15+
skip_if_no_quarto()
16+
qmd <- local_qmd_file(c("content"))
17+
# metadata
18+
expect_snapshot_qmd_output(name = "metadata", input = qmd, output_format = "native", metadata = list(title = "test"))
19+
})
20+
21+
test_that("metadata-file argument works in quarto_render", {
22+
skip_if_no_quarto()
23+
skip_if_not_installed("withr")
24+
qmd <- local_qmd_file(c("content"))
25+
yaml <- withr::local_tempfile(fileext = ".yml")
26+
write_yaml(list(title = "test"), yaml)
27+
expect_snapshot_qmd_output(
28+
name = "metadata-file",
29+
input = qmd,
30+
output_format = "native",
31+
metadata_file = yaml
32+
)
33+
})
34+
35+
test_that("metadata-file and metadata are merged in quarto_render", {
36+
skip_if_no_quarto()
37+
skip_if_not_installed("withr")
38+
qmd <- local_qmd_file(c("content"))
39+
yaml <- withr::local_tempfile(fileext = ".yml")
40+
write_yaml(list(title = "test"), yaml)
41+
expect_snapshot_qmd_output(
42+
name = "metadata-merged",
43+
input = qmd,
44+
output_format = "native",
45+
metadata_file = yaml, metadata = list(title = "test2")
46+
)
47+
})

0 commit comments

Comments
 (0)