/
bookdown_zenodo.R
130 lines (121 loc) · 4.48 KB
/
bookdown_zenodo.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#' Render a `bookdown` and upload to Zenodo
#'
#' First clears all the existing files in the `output_dir` set in
#' `_bookdown_.yml`.
#' Then renders all required output formats and uploads them to Zenodo.
#' @param path The root folder of the report
#' @param zip_format A vector with output formats that generate multiple files.
#' The function will bundle all the files in a zip file for every format.
#' @param single_format A vector with output formats that generate a single
#' output file.
#' The output will remain as is.
#' @param token the user token for Zenodo.
#' By default an attempt will be made to retrieve token using `zenodo_pat()`.
#' @param sandbox When `TRUE`, upload a test version to
#' https://sandbox.zenodo.org.
#' When `FALSE`, upload the final version to https://zenodo.org.
#' @param logger Type of logger for Zenodo upload.
#' Defaults to `"INFO"` which provides minimal logs.
#' Use `NULL` to hide the logs.
#' `"DEBUG"` provides the full log.
#' @family utils
#' @export
#' @importFrom assertthat assert_that is.string noNA
#' @importFrom fs dir_create dir_delete dir_ls file_delete is_dir is_file
#' path_abs path_ext_remove path_rel
#' @importFrom rmarkdown clean_site render_site yaml_front_matter
#' @importFrom utils zip
#' @importFrom withr defer
bookdown_zenodo <- function(
path, zip_format = c("bookdown::gitbook", "INBOmd::gitbook"),
single_format = c(
"bookdown::pdf_book", "bookdown::epub_book", "INBOmd::pdf_report",
"INBOmd::epub_book"
), token, sandbox = TRUE, logger = "INFO"
) {
assert_that(
is.string(path), noNA(path), inherits(zip_format, "character"),
noNA(zip_format), inherits(single_format, "character"), noNA(single_format),
assert_that(requireNamespace("bookdown", quietly = TRUE))
)
assert_that(is_dir(path), msg = "`path` is not an existing directory")
assert_that(
is_file(path(path, "index.Rmd")), msg = "index.Rmd not found in `path`"
)
assert_that(
is_file(path(path, "_bookdown.yml")),
msg = "_bookdown.yml not found in `path`"
)
path(path, "_bookdown.yml") |>
file(encoding = "UTF-8") -> con
bookdown_yml <- readLines(con)
close(con)
bookname <- bookdown_yml[grepl("book_filename", bookdown_yml)]
gsub("book_filename:\\s*\"(.*)\"", "\\1", bookname) |>
path_ext_remove() -> bookname
bookdown_yml[grepl("output_dir:", bookdown_yml)] |>
gsub(pattern = "output_dir: \"(.*)\"", replacement = "\\1") -> output_dir
stopifnot(
"no `output_dir:` found in `_bookdown.yml`" = length(output_dir) > 0,
"multiple `output_dir:` found in `_bookdown.yml`" = length(output_dir) < 2
)
yml <- yaml_front_matter(path(path, "index.Rmd"))
formats <- names(yml[["output"]])
assert_that(
any(formats %in% c(zip_format, single_format)), msg = "No formats to render"
)
zip_format <- zip_format[zip_format %in% formats]
single_format <- single_format[single_format %in% formats]
cit <- citation_meta$new(path)
if (length(cit$get_errors) > 0) {
return(cit)
}
if (!is.null(logger)) {
cit$print()
}
file_scope <- getOption("bookdown.render.file_scope")
options(bookdown.render.file_scope = FALSE)
defer(options(bookdown.render.file_scope = file_scope))
old_wd <- getwd()
defer(setwd(old_wd))
path(path, output_dir) |>
path_abs(output_dir) -> output_dir
dir_create(output_dir)
setwd(path)
testing <- identical(Sys.getenv("TESTTHAT"), "true")
clean_site(path, preview = !testing, quiet = testing)
for (zip_i in seq_along(zip_format)) {
# render report
render_site(
output_format = zip_format[zip_i], encoding = "UTF-8",
quiet = is.null(logger)
)
# pack report into a zip archive
dir_ls(output_dir, recurse = TRUE, regexp = "\\.zip", invert = TRUE) |>
path_rel(output_dir) -> files
setwd(output_dir)
path(
output_dir, paste(c(bookname, letters[zip_i - 1]), collapse = "_"),
ext = "zip"
) |>
zip(files = files, flags = "-r9XqT")
# remove output except zip archive
dir_ls(output_dir, type = "dir") |>
dir_delete()
dir_ls(output_dir, type = "file", regexp = "\\.zip", invert = TRUE) |>
file_delete()
setwd(path)
}
for (output_format in single_format) {
render_site(
output_format = output_format, encoding = "UTF-8", quiet = is.null(logger)
)
}
dir_ls(output_dir, regexp = "reference-keys.txt") |>
file_delete()
path(path, ".zenodo.json") |>
file_copy(output_dir, overwrite = TRUE)
upload_zenodo(
path = output_dir, token = token, sandbox = sandbox, logger = logger
)
}