0.1.0
When pointed at the root directory of an R Package Project, this function will automatically generate and render a Quarto/Revealjs presentation for that package. It will have a title slide and description slide generated from the package’s DESCRIPTION file and each exported function will have slides with its description and returns, parameters, examples, and source code.
Topic: build_presentation
Description: When pointed at the root directory of an R Package Project, this function will automatically generate and render a Quarto/Revealjs presentation for that package. It will have a title slide and description slide generated from the package’s DESCRIPTION file and each exported function will have slides with its description and returns, parameters, examples, and source code.
Return: This function creates and renders a .qmd presentation but does not return an R object.
package: A file path to the root directory of an R package source folder, the name of an R package from CRAN, or an R package from GitHub in the username/repository format.file: The file name for your .qmd file. This can be a path so long as it ends with a file_name.qmdyaml: A _pkgslides.yml file or function call to create_yaml()build_presentation <- function(package = getwd(), file = NULL, yaml = create_yaml()) {
package <- .find_package(package)
file <- .find_file(package$path, file)
yaml <- .parse_yaml(yaml)
if (package$name %in% rownames(utils::installed.packages())) {
chunk_opt <- "echo"
} else { chunk_opt <- "eval" }
credits <- .get_credits(package$path)
title_contents <-
.get_title(package$path, credits) |>
.collate_title(yaml)
package_contents <-
.get_description(package$path, credits) |>
.collate_description(chunk_opt)
contents <- .get_roxygen(package$path, yaml)
function_contents <- .get_functions(contents$functions, yaml)
r_files <-
sapply(contents$functions, \(b) .get_file_from_path(b$file))
function_contents <-
r_files |>
unique() |>
lapply(
.construct_verticals,
r_files, function_contents, chunk_opt
) |>
unlist()
data_contents <-
.get_datasets(contents$datasets, yaml) |>
lapply(.collate_datasets) |>
unlist()
file_contents <- c(
title_contents,
package_contents,
function_contents,
data_contents
)
print(file)
file.create(file)
fileConn <- file(file)
writeLines(file_contents, fileConn)
close(fileConn)
quarto::quarto_render(file)
}.find_fileTopic: .find_file
Return: A file path to write the .qmd to
package: A path to a package sourcefile: A file pathTopic: .find_package
Return: A path to a package source
package: A package name or file path to a package source.find_package <- function(package) {
if (package == getwd() | dir.exists(package)) {
name <- rev(strsplit(package, "/")[[1]])[1]
return(list(name = name, path = package))
}
source_path <- tempdir()
if (package %in% rownames(utils::available.packages())) {
print("cran")
utils::download.packages(package, source_path)
source_name <-
list.files(source_path, pattern = glue::glue("{package}.*\\.tar\\.gz"))
utils::untar(
glue::glue("{source_path}/{source_name}"),
exdir = glue::glue("{source_path}")
)
} else {
print("github")
repo <- remotes::parse_repo_spec(package)
package <- repo$repo
stopifnot(repo$username != "" & repo$repo != "")
zip <- glue::glue("{source_path}/{package}.zip")
utils::download.file(url = glue::glue("https://github.com/{repo$username}/{repo$repo}/archive/master.zip"), zip)
if (file.exists(zip)) {
utils::unzip(zip, exdir = glue::glue("{source_path}"), overwrite = TRUE)
}
dirs <- list.dirs(glue::glue("{source_path}"), recursive = FALSE)
dirs <- grep(glue::glue("({package}-(main|master))"), dirs, value = TRUE)
new_name <- glue::glue("{source_path}/{package}")
unlink(new_name, recursive = TRUE)
file.rename(dirs, new_name)
# file.copy(glue::glue("{getwd()}/_pkgslides.yml"), source_path)
}
package_path <- glue::glue("{source_path}/{package}")
return(list(name = package, path = package_path))
}_pkgslides.ymlTopic: create_yaml
Return: This will create the file and write to it, then return the file path.
path: A file path to where you want the yaml file written. This should not end in a slash of any kind.format_theme: A length-one character vector of theme detailsformat_functions: A named list of format function optionsformat_datasets: A named list of format dataset optionschoose_functions: A list of file or function nameschoose_datasets: A vector of dataset namescreate_yaml <- function(
path = getwd(),
format_theme = c(), format_functions = list(), format_datasets = list(),
choose_functions = list(), choose_datasets = c()
) {
# package <- .find_package(package)
file <- glue::glue("{path}/_pkgslides.yml")
# stopifnot(!file.exists(file))
# formatting
format_theme <- format_theme[format_theme %in% c("theme")]
format_functions <-
format_functions[names(format_functions) %in% c("description", "return", "parameters", "examples", "code")]
format_datasets <-
format_datasets[names(format_datasets) %in% c("format", "source", "references")]
.append_to_yaml <- function(yaml, obj, name) {
if (length(obj) > 0) { yaml$format[[name]] <- obj }
return(yaml)
}
yaml <-
list() |>
.append_to_yaml(format_theme, "theme") |>
.append_to_yaml(format_functions, "functions") |>
.append_to_yaml(format_datasets, "datasets")
# print options
if (length(choose_functions) > 0) {
yaml <- .process_choose_functions(yaml, choose_functions)
}
yaml$datasets <- choose_datasets
yaml |>
.check_yaml() |>
yaml::write_yaml(file)
print(glue::glue("Config written to '{file}'"))
return(file)
}_pkgslides.ymlTopic: .parse_yaml
Return: A list representing a yaml file
file: A file path the _pkgslides.yml file_pkgslides.ymlTopic: .check_yaml
Return: A list representing a yaml file
yaml: A list of properties from .parse_yaml().check_yaml <- function(yaml) {
if (is.null(yaml$functions)) { yaml$functions <- "auto" }
if (is.null(yaml$datasets)) { yaml$datasets <- "all" }
if (is.null(yaml$format$theme)) { yaml$format$theme <- "default" }
yaml <-
yaml |>
.set_as_true(
"functions",
c("description", "return", "parameters",
"examples", "code")
) |>
.set_as_true(
"datasets",
c("format", "source", "references")
)
return(yaml)
}Topic: .set_as_true
Return: A yaml where non-included options are set to TRUE
yaml: A yaml file as a listtype: “functions” or “datasets”options: A vector of the options exposed to users in the yaml formatTopic: .process_choose_functions
Return: A list representing a yaml file
yaml: A list representing a yaml filechoose: The list passed to choose_functions in the create_yaml function.process_choose_functions <- function(yaml, choose) {
yaml2 <- list()
dim <- vapply(choose, length, FUN.VALUE = 1)
choose_names <- names(choose)
opt_regex <- "^(auto|exported|all)$|\\.R$"
if (all(dim == 1) & is.null(choose_names)) {
stopifnot(all(grepl(opt_regex, choose)))
yaml2$functions <- lapply(choose, \(x) { list(file = x) })
} else {
if (any(choose_names == "")) {
needs_name <- which(choose_names == "" & dim == 1)
names(choose)[needs_name] <- unlist(sapply(choose, unlist)[needs_name])
choose[needs_name] <- "all"
choose_names <- names(choose)
}
stopifnot(all(grepl(opt_regex, choose_names)))
yaml2$functions <-
mapply(\(x, y) {
list(file = x, slides = y)
}, choose_names, choose, SIMPLIFY = FALSE, USE.NAMES = FALSE)
}
yaml <-
list(yaml, yaml2) |>
unlist(recursive = FALSE)
return(yaml)
}Gus Lipkin [aut, cre]