Skip to content

Commit 8195c42

Browse files
committed
support setting preamble content
1 parent 4fd3deb commit 8195c42

File tree

8 files changed

+222
-9
lines changed

8 files changed

+222
-9
lines changed

R/spin.R

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#' See <https://quarto.org/docs/computations/render-scripts.html#knitr>
1010
#'
1111
#' @section Preamble format:
12-
#' For a script named `analysis.R`, the function adds this preamble:
12+
#' For a script named `analysis.R`, the function adds this preamble by default:
1313
#' ```
1414
#' #' ---
1515
#' #' title: analysis
@@ -23,15 +23,46 @@
2323
#' [Engine Bindings](https://quarto.org/docs/computations/execution-options.html#engine-binding) works.
2424
#'
2525
#' @param script Path to the R script file
26+
#' @param title Custom title for the preamble. If provided, overrides any title
27+
#' in the `preamble` list. If NULL, uses `preamble$title` or filename as fallback.
28+
#' @param preamble Named list of YAML metadata to include in preamble.
29+
#' The `title` parameter takes precedence over `preamble$title` if both are provided.
2630
#' @return Invisibly returns the script path if modified, otherwise invisible NULL
31+
#'
32+
#' @examples
33+
#' \dontrun{
34+
#' # Basic usage with default title
35+
#' add_spin_preamble("analysis.R")
36+
#'
37+
#' # Custom title
38+
#' add_spin_preamble("analysis.R", title = "My Analysis")
39+
#'
40+
#' # Custom preamble with multiple fields
41+
#' add_spin_preamble("analysis.R", preamble = list(
42+
#' title = "Advanced Analysis",
43+
#' author = "John Doe",
44+
#' date = Sys.Date(),
45+
#' format = "html"
46+
#' ))
47+
#'
48+
#' # Title parameter overrides preamble title
49+
#' add_spin_preamble("analysis.R",
50+
#' title = "Final Title", # This takes precedence
51+
#' preamble = list(
52+
#' title = "Ignored Title",
53+
#' author = "John Doe"
54+
#' )
55+
#' )
56+
#' }
2757
#' @export
28-
add_spin_preamble <- function(script) {
58+
add_spin_preamble <- function(script, title = NULL, preamble = NULL) {
2959
if (!fs::file_exists(script)) {
3060
cli::cli_abort(c(
3161
"File {.file {script}} does not exist.",
3262
"Please provide a valid file path."
3363
))
3464
}
65+
3566
content <- xfun::read_utf8(script)
3667

3768
# if files starts with a spin preamble, do nothing
@@ -42,13 +73,32 @@ add_spin_preamble <- function(script) {
4273
))
4374
return(invisible())
4475
}
45-
# prepend the spin preamble
46-
filename <- fs::path_file(fs::path_ext_remove(script))
47-
preamble <- paste(
76+
77+
# Build preamble metadata
78+
metadata <- list()
79+
80+
# Start with preamble list if provided
81+
if (!is.null(preamble)) {
82+
if (!is.list(preamble)) {
83+
cli::cli_abort("`preamble` must be a named list.")
84+
}
85+
metadata <- preamble
86+
}
87+
88+
# Add or override title
89+
if (!is.null(title)) {
90+
metadata$title <- title
91+
} else if (is.null(metadata$title)) {
92+
# Use filename as default title if none provided
93+
metadata$title <- fs::path_file(fs::path_ext_remove(script))
94+
}
95+
96+
preamble_text <- paste(
4897
"#'",
49-
xfun::split_lines(as_yaml_block(list(title = filename)))
98+
xfun::split_lines(as_yaml_block(metadata))
5099
)
51-
new_content <- c(preamble, "", content) # Changed "\n" to ""
100+
101+
new_content <- c(preamble_text, "", content)
52102
xfun::write_utf8(new_content, con = script)
53103

54104
cli::cli_inform("Added spin preamble to {.file {script}}")

man/add_spin_preamble.Rd

Lines changed: 34 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/spin.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,11 @@
77
! File 'non_existent_file.R' does not exist.
88
Please provide a valid file path.
99

10+
# add_spin_preamble validates preamble argument
11+
12+
Code
13+
add_spin_preamble(tmp_file, preamble = "not a list")
14+
Condition
15+
Error in `add_spin_preamble()`:
16+
! `preamble` must be a named list.
17+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#' ---
2+
#' title: My Report
3+
#' author: John Doe
4+
#' format: html
5+
#' ---
6+
#'
7+
8+
library(ggplot2)
9+
plot(1:10)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#' ---
2+
#' title: Custom Analysis
3+
#' ---
4+
#'
5+
6+
x <- 1
7+
y <- 2
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#' ---
2+
#' title: Preamble Title
3+
#' author: Jane Doe
4+
#' ---
5+
#'
6+
7+
x <- 1
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#' ---
2+
#' title: Override Title
3+
#' author: John Doe
4+
#' ---
5+
#'
6+
7+
x <- 1

tests/testthat/test-spin.R

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,96 @@ test_that("add_spin_preamble works with empty file", {
9595
announce_snapshot_file(name = "spin_preamble-empty.R")
9696
expect_snapshot_file(script, "spin_preamble-empty.R")
9797
})
98+
99+
test_that("add_spin_preamble works with custom title", {
100+
tmp_dir <- withr::local_tempdir()
101+
withr::local_dir(tmp_dir)
102+
script <- "analysis.R"
103+
xfun::write_utf8(c("x <- 1", "y <- 2"), script)
104+
105+
expect_message(
106+
result <- add_spin_preamble(script, title = "Custom Analysis"),
107+
"Added spin preamble"
108+
)
109+
110+
expect_equal(result, script)
111+
112+
announce_snapshot_file(name = "spin_preamble-custom-title.R")
113+
expect_snapshot_file(script, "spin_preamble-custom-title.R")
114+
})
115+
116+
test_that("add_spin_preamble works with custom preamble", {
117+
tmp_dir <- withr::local_tempdir()
118+
withr::local_dir(tmp_dir)
119+
script <- "report.R"
120+
xfun::write_utf8(c("library(ggplot2)", "plot(1:10)"), script)
121+
122+
expect_message(
123+
result <- add_spin_preamble(
124+
script,
125+
preamble = list(
126+
title = "My Report",
127+
author = "John Doe",
128+
format = "html"
129+
)
130+
),
131+
"Added spin preamble"
132+
)
133+
134+
expect_equal(result, script)
135+
136+
announce_snapshot_file(name = "spin_preamble-custom-preamble.R")
137+
expect_snapshot_file(script, "spin_preamble-custom-preamble.R")
138+
})
139+
140+
test_that("title parameter overrides preamble title", {
141+
tmp_dir <- withr::local_tempdir()
142+
withr::local_dir(tmp_dir)
143+
script <- "override.R"
144+
writeLines("x <- 1", script)
145+
146+
expect_message(
147+
result <- add_spin_preamble(
148+
script,
149+
title = "Override Title",
150+
preamble = list(title = "Original Title", author = "John Doe")
151+
),
152+
"Added spin preamble"
153+
)
154+
155+
expect_equal(result, script)
156+
157+
announce_snapshot_file(name = "spin_preamble-title-override.R")
158+
expect_snapshot_file(script, "spin_preamble-title-override.R")
159+
})
160+
161+
test_that("preamble title is used when title parameter is NULL", {
162+
tmp_dir <- withr::local_tempdir()
163+
withr::local_dir(tmp_dir)
164+
script <- "preamble_title.R"
165+
writeLines("x <- 1", script)
166+
167+
expect_message(
168+
result <- add_spin_preamble(
169+
script,
170+
title = NULL,
171+
preamble = list(title = "Preamble Title", author = "Jane Doe")
172+
),
173+
"Added spin preamble"
174+
)
175+
176+
expect_equal(result, script)
177+
178+
announce_snapshot_file(name = "spin_preamble-preamble-title.R")
179+
expect_snapshot_file(script, "spin_preamble-preamble-title.R")
180+
})
181+
182+
test_that("add_spin_preamble validates preamble argument", {
183+
tmp_file <- withr::local_tempfile(fileext = ".R")
184+
writeLines("x <- 1", tmp_file)
185+
186+
expect_snapshot(
187+
error = TRUE,
188+
add_spin_preamble(tmp_file, preamble = "not a list")
189+
)
190+
})

0 commit comments

Comments
 (0)