From 29743e6b37955cfc01b887bc4cb31f870ebbc8ae Mon Sep 17 00:00:00 2001 From: Candace Savonen Date: Thu, 12 Dec 2024 14:34:13 -0500 Subject: [PATCH] Add cleanup and docs --- NAMESPACE | 2 +- R/auth.R | 1 - R/get_data.R | 18 +- R/github_handling.R | 6 +- R/google_slides.R | 9 +- R/leanpub.R | 338 ++++++++++--------------- R/quiz_formatting.R | 14 +- R/render_without_toc.R | 3 +- R/utils.R | 19 +- man/check_quizzes.Rd | 3 + man/course_path.Rd | 19 ++ man/coursera.Rd | 1 + man/get_chapters.Rd | 8 +- man/make_embed_markdown.Rd | 23 +- man/make_screenshots.Rd | 15 +- man/set_up_leanpub.Rd | 53 ---- man/website_to_embed_leanpub.Rd | 1 + tests/testthat/test-rmd_leanpub_prep.R | 53 ++-- 18 files changed, 269 insertions(+), 317 deletions(-) create mode 100644 man/course_path.Rd delete mode 100644 man/set_up_leanpub.Rd diff --git a/NAMESPACE b/NAMESPACE index d00007a5..cdcc59c8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -14,6 +14,7 @@ export(check_quizzes) export(clean_up) export(convert_coursera_quizzes) export(convert_quiz) +export(course_path) export(course_to_book_txt) export(extract_meta) export(extract_object_id) @@ -42,7 +43,6 @@ export(pptx_notes) export(pptx_slide_note_df) export(pptx_slide_text_df) export(render_without_toc) -export(set_up_leanpub) export(setup_ottr_template) export(unzip_pptx) export(website_to_embed_leanpub) diff --git a/R/auth.R b/R/auth.R index f5626bfb..25cb2a06 100644 --- a/R/auth.R +++ b/R/auth.R @@ -122,4 +122,3 @@ app_set_up <- function() { return(list(app = app, endpoint = endpoint)) } - diff --git a/R/get_data.R b/R/get_data.R index 747e516f..17ebc38e 100644 --- a/R/get_data.R +++ b/R/get_data.R @@ -53,9 +53,10 @@ setup_ottr_template <- function(dir = "inst/extdata", type) { } if (type == "quarto") { quarto::quarto_render(output_dir, - metadata = list(sidebar = F, toc = F), - quarto_args = c('--output-dir', 'docs/no_toc/'), - as_job = FALSE) + metadata = list(sidebar = F, toc = F), + quarto_args = c("--output-dir", "docs/no_toc/"), + as_job = FALSE + ) } return(output_dir) } @@ -65,11 +66,12 @@ setup_ottr_template <- function(dir = "inst/extdata", type) { #' @return Looks for dangling zips and directories downloaded for testing and removes them #' @export clean_up <- function() { - - dirs <- c("OTTR_Template-main", - "OTTR_Quarto-main", - "OTTR_Template_Website-main", - "OTTR_Quarto_Website-main") + dirs <- c( + "OTTR_Template-main", + "OTTR_Quarto-main", + "OTTR_Template_Website-main", + "OTTR_Quarto_Website-main" + ) zips <- paste0(dirs, ".zip") diff --git a/R/github_handling.R b/R/github_handling.R index 3a163f46..949d9849 100644 --- a/R/github_handling.R +++ b/R/github_handling.R @@ -197,14 +197,14 @@ check_git_repo <- function(repo_name, # If git_pat is supplied, use it test_repo <- report( try(system(paste0("git ls-remote https://", git_pat, "@github.com/", repo_name), - intern = TRUE, ignore.stderr = TRUE + intern = TRUE, ignore.stderr = TRUE )) ) } else { # Try to git ls-remote the repo_name given test_repo <- report try(system(paste0("git ls-remote https://github.com/", repo_name), - intern = TRUE, ignore.stderr = TRUE + intern = TRUE, ignore.stderr = TRUE )) } # If 128 is returned as a status attribute it means it failed @@ -244,12 +244,10 @@ get_git_auth <- function(git_pat = NULL, git_username = "PersonalAccessToken", q # If git pat is not provided, try to get credentials with gitcreds if (is.null(git_pat)) { - # Try getting credentials auth_arg <- try(gitcreds::gitcreds_get(), silent = TRUE) if (grepl("Could not find any credentials", auth_arg[1])) { - # Only if we're running this interactively if (interactive()) { # Set credentials if null diff --git a/R/google_slides.R b/R/google_slides.R index 49b7e18b..80e41b60 100644 --- a/R/google_slides.R +++ b/R/google_slides.R @@ -78,6 +78,7 @@ get_slide_page <- function(url) { #' @param output_dir path to output png #' @param overwrite should the slide PNG be overwritten? gs_png_download <- function(url, output_dir = ".", overwrite = TRUE) { + id <- get_slide_id(url) slide_id <- get_slide_page(url) url <- gs_png_url(url) @@ -185,7 +186,7 @@ get_image_from_slide <- function(file) { is.Token <- function(token) { inherits(token, "Token") || (inherits(token, "request") && - inherits(token$auth_token, "Token")) + inherits(token$auth_token, "Token")) } png_url <- function(id, page_id) { @@ -208,7 +209,7 @@ download_png_urls <- function(urls) { ctype <- strsplit(ctype, " ")[[1]] ctype <- sub(";$", "", ctype) if (any(ctype == "text/html") && - !any(grepl("png", ctype))) { + !any(grepl("png", ctype))) { stop("Output is not a PNG!") } tfile @@ -223,7 +224,7 @@ add_footer <- function(rmd_path, footer_text = NULL) { } footer_text <- paste0("\n", footer_text, collapse = "\n") write(as.character(footer_text), - file = rmd_path, - append = TRUE + file = rmd_path, + append = TRUE ) } diff --git a/R/leanpub.R b/R/leanpub.R index e7f17d0f..17191691 100644 --- a/R/leanpub.R +++ b/R/leanpub.R @@ -9,6 +9,7 @@ #' @param html_page The file path of the rendered index.html file #' @param base_url The base url of where the chapters are published -- the url to provide to the iframe in Leanpub #' e.g. https://jhudatascience.org/OTTR_Template/coursera +#' @param html_page The file path of the rendered index.html file #' @param default_img A google slide link to the default image to be used for all chapters #' @param output_dir output directory to put files. It should likely be #' relative to path @@ -37,34 +38,62 @@ #' ) #' } website_to_embed_leanpub <- function(path = ".", - chapt_img_key = NULL, - render = NULL, - html_page = file.path(base_url, "index.html"), - base_url = NULL, - default_img = NULL, - output_dir = "manuscript", - make_book_txt = FALSE, - quiz_dir = "quizzes", - run_quiz_checks = FALSE, - remove_resources_start = FALSE, - verbose = TRUE, - footer_text = "") { - # Run the set up - set_up_leanpub( - path = path, - render = render, - output_dir = output_dir, - make_book_txt = make_book_txt, - quiz_dir = quiz_dir, - run_quiz_checks = run_quiz_checks, - remove_resources_start = remove_resources_start, - verbose = verbose - ) + chapt_img_key = NULL, + render = NULL, + html_page = file.path(base_url, "index.html"), + base_url = NULL, + clean_up = TRUE, + default_img = NULL, + output_dir = "manuscript", + make_book_txt = FALSE, + quiz_dir = "quizzes", + run_quiz_checks = FALSE, + remove_resources_start = FALSE, + verbose = TRUE, + footer_text = "") { + + # Find the OTTR course + root_dir <- course_path(path = path) + + rooted_output_dir <- file.path(root_dir, output_dir) + rooted_quiz_dir <- file.path(root_dir, quiz_dir) + + if (clean_up) { + + if (dir.exists(rooted_output_dir)) { + message(paste("Clearing out old version of output files:", rooted_output_dir)) + + unlink(rooted_output_dir, recursive = TRUE) + } + } + + # If output directory doesn't exist, make it + if (!dir.exists(rooted_output_dir)) { + dir.create(rooted_output_dir, recursive = TRUE, showWarnings = FALSE) + } + + if (!is.null(quiz_dir)) { + #### Run quiz checks + if (run_quiz_checks) { + message("Checking quizzes") + quiz_checks <- check_quizzes( + path = root_dir, + quiz_dir = quiz_dir, + verbose = verbose + ) + } + if (verbose) message("Copying quiz files") + copy_quizzes( + path = root_dir, + quiz_dir = quiz_dir, + output_dir = output_dir + ) + } # If TSV chapter image key file is specified read it in if (!is.null(chapt_img_key)) { - message(paste("Reading in a chapt_img_key TSV file:", chapt_img_key)) - chapt_df <- readr::read_tsv(chapt_img_key) + message(paste("Reading in a chapt_img_key TSV file:", file.path(root_dir, chapt_img_key))) + chapt_df <- readr::read_tsv(file.path(root_dir, chapt_img_key)) } else { # If its not supplied, create it from the get_chapters function message("Creating a chapt_img_key TSV file") @@ -73,6 +102,7 @@ website_to_embed_leanpub <- function(path = ".", stop("No base_url is supplied and no chapt_img_key file was supplied. Need one or the other.") } chapt_df <- get_chapters( + path = root_dir, html_page = paste0(base_url, "index.html"), base_url = file.path(base_url, "no_toc/") ) %>% @@ -86,7 +116,7 @@ website_to_embed_leanpub <- function(path = ".", default_img <- "https://docs.google.com/presentation/d/1jEUxUY1qXDZ3DUtvTU6NCc6ASG5nx4Gwczv5aAglYX4/edit#slide=id.p" } # Set up location to store default image - img_dir <- file.path(output_dir, "embed_chapt_images") + img_dir <- file.path(rooted_output_dir, "embed_chapt_images") if (!dir.exists(img_dir)) { dir.create(img_dir, recursive = TRUE) @@ -100,7 +130,10 @@ website_to_embed_leanpub <- function(path = ".", # Make the data.frame be in the same order dplyr::select(dplyr::any_of("url"), dplyr::any_of("chapt_title"), dplyr::any_of("img_path")) %>% # Run it make_embed_markdown on each row - purrr::pmap(~ make_embed_markdown(url = ..1, chapt_title = ..2, img_path = ..3, footer_text = footer_text)) + purrr::pmap(~ make_embed_markdown( + url = ..1, chapt_title = ..2, img_path = ..3, footer_text = footer_text, + output_dir = output_dir, path = root_dir + )) ####################### Book.txt creation #################################### out <- NULL @@ -109,6 +142,7 @@ website_to_embed_leanpub <- function(path = ".", md_files <- basename(unlist(md_output_files)) course_to_book_txt( + path = root_dir, md_files = md_files, output_dir = output_dir, quiz_dir = quiz_dir, @@ -117,7 +151,7 @@ website_to_embed_leanpub <- function(path = ".", out <- book_txt_file <- file.path(output_dir, "Book.txt") } else { # If false, look for Book.txt file to copy to output folder. - book_txt_file <- file.path(path, "Book.txt") + book_txt_file <- file.path(root_dir, "Book.txt") if (file.exists(book_txt_file)) { # Copy over an existing book.txt file if it exists @@ -155,19 +189,19 @@ website_to_embed_leanpub <- function(path = ".", #' @export #' course_to_book_txt <- function(path = ".", - md_files = NULL, - output_dir = "manuscript", - quiz_dir = "quizzes", - verbose = TRUE) { + md_files = NULL, + output_dir = "manuscript", + quiz_dir = "quizzes", + verbose = TRUE) { # If md_files are not specified, then try to get them if (is.null(md_files)) { # Establish path - path <- course_path(path) + root_dir <- course_path(path = path) - rmd_regex <- "[.][R|r]md$" + rmd_regex <- "[.][q|R|r]md$" # Extract the names of the Rmd files (the chapters) - md_files <- qrmd_files(path = path) + md_files <- qrmd_files(path = root_dir) } if (!is.null(quiz_dir)) { @@ -222,38 +256,49 @@ course_to_book_txt <- function(path = ".", #' Make Leanpub file that has embed webpage of a chapter #' +#' @param path path to the bookdown or quarto course repository, must have a `_bookdown.yml` or `_quarto.yml` file #' @param url The url to the chapter that is to be embed #' @param chapt_title Title of chapter to be used as file name and printed on iframe -#' @param width_spec How wide should the iframe be in pixels? -#' @param height_spec How high should the iframe be in pixels? #' @param img_path File path to image to use for poster #' @param output_dir output directory to put files. It should likely be #' relative to path -#' @param verbose print diagnostic messages #' @param footer_text Optionally can add a bit of text that will be added to the #' end of each file before the references section. +#' @param width_spec How wide should the iframe be in pixels? +#' @param height_spec How high should the iframe be in pixels? +#' @param verbose print diagnostic messages #' @return A markdown file with an iframe of the provided chapter #' #' @export -make_embed_markdown <- function(url, +make_embed_markdown <- function(path = ".", + url, chapt_title, - width_spec = 800, - height_spec = 600, img_path, output_dir = "manuscript", - verbose = TRUE, - footer_text = "") { + footer_text = "", + width_spec = 800, + height_spec = 600, + verbose = TRUE) { # Arguments: # url: The url to the chapter # chapt_title: The title of the chapter to be used as a header # img: file path to the image to be used in the preview # # Returns: A markdown document ready for Leanpub and the image copied to the manuscript folder + # Find the OTTR course + root_dir <- course_path(path = path) chapt_file_name <- gsub(" ", "-", chapt_title) + # Leanpub hates question marks and exclamation marks in titles + chapt_file_name <- gsub("\\!|\\?", "", chapt_file_name) + # Declare output file - output_file <- file.path(output_dir, paste0(chapt_file_name, ".md")) + output_file <- file.path(root_dir, output_dir, paste0(chapt_file_name, ".md")) + + if (!dir.exists(output_dir)) { + dir.create(output_dir, recursive = TRUE) + } file_contents <- c( paste("#", chapt_title), @@ -272,13 +317,13 @@ make_embed_markdown <- function(url, write(file_contents, file = output_file) - manuscript_dir <- file.path(output_dir, dirname(img_path)) + new_img_path <- file.path(root_dir, output_dir, dirname(img_path)) - if (!dir.exists(manuscript_dir)) { - dir.create(manuscript_dir, recursive = TRUE) + if (!dir.exists(new_img_path)) { + dir.create(new_img_path, recursive = TRUE, showWarnings = TRUE) } - file.copy(from = img_path, to = file.path(output_dir, img_path), overwrite = TRUE) + file.copy(from = file.path(root_dir, img_path), to = file.path(root_dir, output_dir, img_path), overwrite = TRUE) if (verbose) { message(paste0("Output saved to: ", output_file)) @@ -289,6 +334,7 @@ make_embed_markdown <- function(url, #' Make Leanpub file that has embed webpage of a chapter #' +#' @param path path to the bookdown or quarto course repository, must have a `_bookdown.yml` or `_quarto.yml` file #' @param html_page The file path of the rendered index.html file. It can be a url #' @param base_url The base url of where the chapters are published -- the url to provide to the iframe in Leanpub #' e.g. https://jhudatascience.org/OTTR_Template/coursera @@ -298,8 +344,13 @@ make_embed_markdown <- function(url, #' #' @export #' -get_chapters <- function(html_page = file.path("docs", "index.html"), +get_chapters <- function(path = ".", + html_page = file.path("docs", "index.html"), base_url = ".") { + + # Put this relative to project path + html_page <- file.path(root_dir, html_page) + # Read in html index_html <- suppressWarnings(try(xml2::read_html(html_page))) @@ -312,24 +363,23 @@ get_chapters <- function(html_page = file.path("docs", "index.html"), nodes <- rvest::html_nodes(index_html, xpath = paste0("//", 'div[@class="sidebar-item-container"]')) # We only want chapters - nodes <- nodes[grep("chapter",as.character(nodes))] + nodes <- nodes[grep("chapter", as.character(nodes))] # Extract chapter nodes from the sidebar chapt_title <- nodes %>% - rvest::html_nodes('span.chapter-title') %>% + rvest::html_nodes("span.chapter-title") %>% rvest::html_text() data_level <- nodes %>% - rvest::html_nodes('span.chapter-number') %>% + rvest::html_nodes("span.chapter-number") %>% rvest::html_text() data_path <- nodes %>% - rvest::html_nodes('a.sidebar-item-text.sidebar-link') %>% - rvest::html_attr('href') %>% + rvest::html_nodes("a.sidebar-item-text.sidebar-link") %>% + rvest::html_attr("href") %>% stringr::str_remove("^\\.\\/") chapt_data <- data.frame(chapt_title, data_level, url = paste0(base_url, "/", data_path)) - } else { chapt_data <- rvest::html_attrs(nodes) %>% dplyr::bind_rows() %>% @@ -353,6 +403,7 @@ get_chapters <- function(html_page = file.path("docs", "index.html"), #' A function to make screenshots from an OTTR bookdown website #' @description This function creates screenshots of course chapters that are stored in a created output directory #' +#' @param path path to the bookdown or quarto course repository, must have a `_bookdown.yml` or `_quarto.yml` file #' @param git_pat required argument; a Git secret -- see https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens for more info #' @param repo required argument; GitHub repository name, e.g., jhudsl/OTTR_Template #' @param output_dir default is "resources/chapt_screen_images"; Output directory where the chapter's screen images should be stored. For OTTR courses, don't change this unless you've changed the downstream functions accordingly. @@ -371,44 +422,49 @@ get_chapters <- function(html_page = file.path("docs", "index.html"), #' #' @examples \dontrun{ #' -#' make_screenshots(git_pat = Sys.getenv("secrets.GH_PAT"), -#' repo = "jhudsl/OTTR_Template") -#' +#' make_screenshots( +#' git_pat = Sys.getenv("secrets.GH_PAT"), +#' repo = "jhudsl/OTTR_Template" +#' ) #' } -make_screenshots <- function(git_pat, +make_screenshots <- function(path = ".", + git_pat, repo, output_dir = file.path(path, "resources", "chapt_screen_images"), - base_url = NULL, - path = "."){ - - # Find .git root directory - root_dir <- rprojroot::find_root(has_dir(".github"), path = path) + base_url = NULL) { + # Find .github root directory + root_dir <- course_path(path = path) output_folder <- file.path(output_dir) if (!dir.exists(output_folder)) { dir.create(output_folder, recursive = TRUE) } - if (is.null(base_url)){ - base_url <- ottrpal::get_pages_url(repo_name = repo, git_pat = git_pat) #what if these arguments are still NULL/not supplied? + if (is.null(base_url)) { + base_url <- ottrpal::get_pages_url(repo_name = repo, git_pat = git_pat) # what if these arguments are still NULL/not supplied? base_url <- gsub("/$", "", base_url) } # Collect all the chapter pages for the url given - chapt_df <- ottrpal::get_chapters(html_page = file.path(root_dir, "docs", "index.html"), - base_url = base_url) + chapt_df <- ottrpal::get_chapters( + path = root_dir, + html_page = file.path("docs", "index.html"), + base_url = base_url + ) # Now take screenshots for each - file_names <- lapply(chapt_df$url, function(url){ - file_name <- gsub(".html", - ".png", - file.path(output_folder, basename(url)) + file_names <- lapply(chapt_df$url, function(url) { + file_name <- gsub( + ".html", + ".png", + file.path(output_folder, basename(url)) ) # Get rid of special characters because leanpub no like - file_name <- gsub(":|?|!|\\'", - "", - file_name + file_name <- gsub( + ":|?|!|\\'", + "", + file_name ) # Take the screenshot @@ -427,10 +483,9 @@ make_screenshots <- function(git_pat, message(paste("Image Chapter key written to: ", file.path(output_folder, "chapter_urls.tsv"))) return(file.path(output_folder, "chapter_urls.tsv")) - } -copy_quizzes <- function(quiz_dir = "quizzes", output_dir = "manuscript") { +copy_quizzes <- function(path = ".", quiz_dir = "quizzes", output_dir = "manuscript") { quiz_dir <- file.path(quiz_dir) if (!is.null(quiz_dir)) { @@ -448,132 +503,3 @@ copy_quizzes <- function(quiz_dir = "quizzes", output_dir = "manuscript") { } } } - -#' Set up Manuscript folder for Leanpub publishing -#' -#' @param path path to the top of course repository (looks for .git folder) -#' @param output_dir output directory to put files. It should likely be -#' relative to path -#' @param clean_up TRUE/FALSE the old output directory should be deleted and -#' everything created fresh. -#' @param render If NULL will not be run. If "quarto" or "bookdown" then the respective render type will be run -#' @param verbose print diagnostic messages -#' @param remove_resources_start remove the word `resources/` at the front -#' of any image path. -#' @param run_quiz_checks TRUE/FALSE run quiz checks -#' @param make_book_txt Should [ottrpal::course_to_book_txt()] be run -#' to create a `Book.txt` in the output directory? -#' @param quiz_dir directory that contains the quiz .md files that should be -#' checked and incorporated into the Book.txt file. If you don't have quizzes, -#' set this to NULL -#' @param footer_text Optionally can add a bit of text that will be added to the -#' end of each file before the references section. -#' @return A list of output files and diagnostics -#' @export -#' -set_up_leanpub <- function(path = ".", - clean_up = FALSE, - render = NULL, - output_dir = "manuscript", - make_book_txt = FALSE, - quiz_dir = "quizzes", - run_quiz_checks = FALSE, - remove_resources_start = FALSE, - verbose = TRUE, - footer_text = NULL) { - - - # Check that render is something we can use - if (!is.null(render)) { - if (!render %in% c("quarto", "bookdown")) stop("`render` argument invalid. ") - } - - if (clean_up) { - message(paste("Clearing out old version of output files:", output_dir)) - - file.remove(output_dir, recursive = TRUE, showWarnings = FALSE) - } - - # If output directory doesn't exist, make it - if (!dir.exists(output_dir)) { - dir.create(output_dir, recursive = TRUE, showWarnings = FALSE) - } - - if (!is.null(render)) { - # Declare regex for finding rmd files - rmd_regex <- "[.][q|R|r]md$" - - # Get the path to the _bookdown.yml or _quarto.yml - path <- course_path(path) - - if (verbose) { - message(paste0("Looking for bookdown or quarto md files in ", path)) - } - md_files <- qrmd_files(path = path) - - if (verbose) { - message(paste0(c("Processing these files: ", rmd_files), collapse = "\n")) - } - - if (render == "bookdown") { - if (verbose) { - message("Rendering bookdown Book") - } - # Get the index file path - index_file <- grep("index", rmd_files, ignore.case = TRUE, value = TRUE) - - index_file <- normalizePath(index_file) - - if (length(index_file) == 0 || is.na(index_file)) { - index_file <- md_files[1] - } - message(paste("index_file is", index_file)) - - if (rmarkdown::pandoc_version() >= "2.11") { - output_format <- bookdown::gitbook(pandoc_args = "--citeproc") - output_format$pandoc$args <- c(output_format$pandoc$args, "--citeproc") - } else { - warning("Pandoc version is not greater than 2.11 so citations will not be able to be rendered properly") - output_format <- NULL - } - bookdown::render_book( - input = index_file, - output_format = output_format, - clean_envir = FALSE - ) - } - if (render == "quarto") { - if (verbose) { - message("Rendering Quarto Book") - } - # Get the index file path - index_file <- grep("index", rmd_files, ignore.case = TRUE, value = TRUE) - - index_file <- normalizePath(index_file) - - if (length(index_file) == 0 || is.na(index_file)) { - index_file <- md_files[1] - } - message(paste("index_file is", index_file)) - - quarto::quarto_render('.') - } - - } - - if (!is.null(quiz_dir)) { - #### Run quiz checks - if (run_quiz_checks) { - message("Checking quizzes") - quiz_checks <- check_quizzes( - quiz_dir, - verbose = verbose - ) - } - if (verbose) message("Copying quiz files") - copy_quizzes( - quiz_dir = quiz_dir, - output_dir = output_dir - ) - } -} diff --git a/R/quiz_formatting.R b/R/quiz_formatting.R index a0fcf557..8755c955 100644 --- a/R/quiz_formatting.R +++ b/R/quiz_formatting.R @@ -819,6 +819,7 @@ check_question <- function(question_df, quiz_name = NA, verbose = TRUE, ignore_c #' #' Check the formatting of all quizzes in a given directory. #' +#' @param path path to the top of course repository (looks for .github folder) #' @param quiz_dir A path to a directory full of quizzes that should all be checked with [ottrpal::check_all_quizzes]. #' @param verbose print diagnostic messages #' @param write_report TRUE/FALSE save warning report to a CSV file? @@ -838,14 +839,19 @@ check_question <- function(question_df, quiz_name = NA, verbose = TRUE, ignore_c #' ## Now check the quizzes in that directory #' all_quiz_results <- check_quizzes(quiz_dir = quiz_dir) #' } -check_quizzes <- function(quiz_dir = "quizzes", +check_quizzes <- function(path = ".", + quiz_dir = "quizzes", write_report = TRUE, verbose = TRUE, ignore_coursera = TRUE) { + + # Find .github root directory + root_dir <- course_path(path = path) + files <- list.files( pattern = "\\.md", ignore.case = TRUE, - path = quiz_dir, + path = file.path(root_dir, quiz_dir), full.names = TRUE ) @@ -871,9 +877,9 @@ check_quizzes <- function(quiz_dir = "quizzes", if (write_report) { if (nrow(question_report) > 0) { - message("\n Question error report saved to 'question_error_report.tsv'") + message("\n Question error report saved to:", file.path(root_dir, "question_error_report.tsv")) readr::write_tsv(question_report, - file = "question_error_report.tsv" + file = file.path(root_dir, "question_error_report.tsv") ) } else { message("\n No question errors to report!") diff --git a/R/render_without_toc.R b/R/render_without_toc.R index 80fe2ebc..c5ddddbc 100644 --- a/R/render_without_toc.R +++ b/R/render_without_toc.R @@ -18,7 +18,8 @@ #' #' @importFrom utils download.file #' -render_without_toc <- function(output_dir = file.path("docs", "no_toc"), +render_without_toc <- function(course_path = ".", + output_dir = file.path("docs", "no_toc"), output_yaml = "_output.yml", convert_quizzes = FALSE, input_quiz_dir = "quizzes", diff --git a/R/utils.R b/R/utils.R index 73deff1e..d004754c 100644 --- a/R/utils.R +++ b/R/utils.R @@ -9,7 +9,25 @@ utils::globalVariables(c( "convert_footnotes", "rmd_files" )) +#' Find root of OTTR course provided +#' @param path Where should we be looking for a OTTR course. By default will look in current working directory. +#' @return Absolute file path to the course pointed to +#' @importFrom rprojroot find_root has_dir +#' @return Returns a absolute file path to where the course is +#' @export +#' +course_path <- function(path = ".") { + + # Find .git root directory + root_dir <- rprojroot::find_root(has_dir(".github"), path = path) + + bookdown <- file.exists(file.path(root_dir, "_bookdown.yml")) + quarto <- file.exists(file.path(root_dir, "_quarto.yml")) + if (bookdown & quarto) stop("No OTTR course found in this repository. Looking for a _bookdown.yml or _quarto.yml file.") + + return(root_dir) +} #' Pipe operator #' #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. @@ -24,4 +42,3 @@ utils::globalVariables(c( #' @param rhs A function call using the magrittr semantics. #' @return The result of calling `rhs(lhs)`. NULL - diff --git a/man/check_quizzes.Rd b/man/check_quizzes.Rd index 545a6f62..39b2e4d1 100644 --- a/man/check_quizzes.Rd +++ b/man/check_quizzes.Rd @@ -5,6 +5,7 @@ \title{Check all quizzes in a directory} \usage{ check_quizzes( + path = ".", quiz_dir = "quizzes", write_report = TRUE, verbose = TRUE, @@ -12,6 +13,8 @@ check_quizzes( ) } \arguments{ +\item{path}{path to the top of course repository (looks for .github folder)} + \item{quiz_dir}{A path to a directory full of quizzes that should all be checked with [ottrpal::check_all_quizzes].} \item{write_report}{TRUE/FALSE save warning report to a CSV file?} diff --git a/man/course_path.Rd b/man/course_path.Rd new file mode 100644 index 00000000..1f59783b --- /dev/null +++ b/man/course_path.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{course_path} +\alias{course_path} +\title{Find root of OTTR course provided} +\usage{ +course_path(path = ".") +} +\arguments{ +\item{path}{Where should we be looking for a OTTR course. By default will look in current working directory.} +} +\value{ +Absolute file path to the course pointed to + +Returns a absolute file path to where the course is +} +\description{ +Find root of OTTR course provided +} diff --git a/man/coursera.Rd b/man/coursera.Rd index af7b6a33..b9606027 100644 --- a/man/coursera.Rd +++ b/man/coursera.Rd @@ -5,6 +5,7 @@ \title{Create TOC-less course website for use in Coursera or Leanpub} \usage{ render_without_toc( + course_path = ".", output_dir = file.path("docs", "no_toc"), output_yaml = "_output.yml", convert_quizzes = FALSE, diff --git a/man/get_chapters.Rd b/man/get_chapters.Rd index 63b6278b..2aa7a0d2 100644 --- a/man/get_chapters.Rd +++ b/man/get_chapters.Rd @@ -4,9 +4,15 @@ \alias{get_chapters} \title{Make Leanpub file that has embed webpage of a chapter} \usage{ -get_chapters(html_page = file.path("docs", "index.html"), base_url = ".") +get_chapters( + path = ".", + html_page = file.path("docs", "index.html"), + base_url = "." +) } \arguments{ +\item{path}{path to the bookdown or quarto course repository, must have a `_bookdown.yml` or `_quarto.yml` file} + \item{html_page}{The file path of the rendered index.html file. It can be a url} \item{base_url}{The base url of where the chapters are published -- the url to provide to the iframe in Leanpub diff --git a/man/make_embed_markdown.Rd b/man/make_embed_markdown.Rd index c74166ac..12d3b5c2 100644 --- a/man/make_embed_markdown.Rd +++ b/man/make_embed_markdown.Rd @@ -5,34 +5,37 @@ \title{Make Leanpub file that has embed webpage of a chapter} \usage{ make_embed_markdown( + path = ".", url, chapt_title, - width_spec = 800, - height_spec = 600, img_path, output_dir = "manuscript", - verbose = TRUE, - footer_text = "" + footer_text = "", + width_spec = 800, + height_spec = 600, + verbose = TRUE ) } \arguments{ +\item{path}{path to the bookdown or quarto course repository, must have a `_bookdown.yml` or `_quarto.yml` file} + \item{url}{The url to the chapter that is to be embed} \item{chapt_title}{Title of chapter to be used as file name and printed on iframe} -\item{width_spec}{How wide should the iframe be in pixels?} - -\item{height_spec}{How high should the iframe be in pixels?} - \item{img_path}{File path to image to use for poster} \item{output_dir}{output directory to put files. It should likely be relative to path} -\item{verbose}{print diagnostic messages} - \item{footer_text}{Optionally can add a bit of text that will be added to the end of each file before the references section.} + +\item{width_spec}{How wide should the iframe be in pixels?} + +\item{height_spec}{How high should the iframe be in pixels?} + +\item{verbose}{print diagnostic messages} } \value{ A markdown file with an iframe of the provided chapter diff --git a/man/make_screenshots.Rd b/man/make_screenshots.Rd index 99a76a9f..6dcb0b2a 100644 --- a/man/make_screenshots.Rd +++ b/man/make_screenshots.Rd @@ -5,14 +5,16 @@ \title{A function to make screenshots from an OTTR bookdown website} \usage{ make_screenshots( + path = ".", git_pat, repo, output_dir = file.path(path, "resources", "chapt_screen_images"), - base_url = NULL, - path = "." + base_url = NULL ) } \arguments{ +\item{path}{default is to look for OTTR files in current directory based on existence of .github. But if you'd like to run this in a different path, you can point to that file path.} + \item{git_pat}{required argument; a Git secret -- see https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens for more info} \item{repo}{required argument; GitHub repository name, e.g., jhudsl/OTTR_Template} @@ -20,8 +22,6 @@ make_screenshots( \item{output_dir}{default is "resources/chapt_screen_images"; Output directory where the chapter's screen images should be stored. For OTTR courses, don't change this unless you've changed the downstream functions accordingly.} \item{base_url}{default is NULL; rendered bookdown URL where screenshots are taken from, if NULL, the function will use the repo_name and and git_pat to find the base_url} - -\item{path}{default is to look for OTTR files in current directory based on existence of .github. But if you'd like to run this in a different path, you can point to that file path.} } \value{ the file path for file where chapter urls are saved @@ -32,9 +32,10 @@ This function creates screenshots of course chapters that are stored in a create \examples{ \dontrun{ - make_screenshots(git_pat = Sys.getenv("secrets.GH_PAT"), - repo = "jhudsl/OTTR_Template") - +make_screenshots( + git_pat = Sys.getenv("secrets.GH_PAT"), + repo = "jhudsl/OTTR_Template" +) } } \author{ diff --git a/man/set_up_leanpub.Rd b/man/set_up_leanpub.Rd deleted file mode 100644 index b1c05f9c..00000000 --- a/man/set_up_leanpub.Rd +++ /dev/null @@ -1,53 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/leanpub.R -\name{set_up_leanpub} -\alias{set_up_leanpub} -\title{Set up Manuscript folder for Leanpub publishing} -\usage{ -set_up_leanpub( - path = ".", - clean_up = FALSE, - render = NULL, - output_dir = "manuscript", - make_book_txt = FALSE, - quiz_dir = "quizzes", - run_quiz_checks = FALSE, - remove_resources_start = FALSE, - verbose = TRUE, - footer_text = NULL -) -} -\arguments{ -\item{path}{path to the top of course repository (looks for .git folder)} - -\item{clean_up}{TRUE/FALSE the old output directory should be deleted and -everything created fresh.} - -\item{render}{If NULL will not be run. If "quarto" or "bookdown" then the respective render type will be run} - -\item{output_dir}{output directory to put files. It should likely be -relative to path} - -\item{make_book_txt}{Should [ottrpal::course_to_book_txt()] be run -to create a `Book.txt` in the output directory?} - -\item{quiz_dir}{directory that contains the quiz .md files that should be -checked and incorporated into the Book.txt file. If you don't have quizzes, -set this to NULL} - -\item{run_quiz_checks}{TRUE/FALSE run quiz checks} - -\item{remove_resources_start}{remove the word `resources/` at the front -of any image path.} - -\item{verbose}{print diagnostic messages} - -\item{footer_text}{Optionally can add a bit of text that will be added to the -end of each file before the references section.} -} -\value{ -A list of output files and diagnostics -} -\description{ -Set up Manuscript folder for Leanpub publishing -} diff --git a/man/website_to_embed_leanpub.Rd b/man/website_to_embed_leanpub.Rd index 225d1a9d..095b5dcf 100644 --- a/man/website_to_embed_leanpub.Rd +++ b/man/website_to_embed_leanpub.Rd @@ -10,6 +10,7 @@ website_to_embed_leanpub( render = NULL, html_page = file.path(base_url, "index.html"), base_url = NULL, + clean_up = TRUE, default_img = NULL, output_dir = "manuscript", make_book_txt = FALSE, diff --git a/tests/testthat/test-rmd_leanpub_prep.R b/tests/testthat/test-rmd_leanpub_prep.R index 6dc01a30..0e0e0761 100644 --- a/tests/testthat/test-rmd_leanpub_prep.R +++ b/tests/testthat/test-rmd_leanpub_prep.R @@ -27,26 +27,47 @@ test_that("Make screenshots", { testthat::expect_equal(chapt_df_file, "resources/chapt_screen_images/chapter_urls.tsv") - chapt_df <- readr::read_tsv("resources/chapt_screen_images/chapter_urls.tsv") + chapt_df <- readr::read_tsv(file.path("OTTR_Template-main", + "resources", + "chapt_screen_images", + "chapter_urls.tsv")) # Expect column names should still be the - expect_names(chapt_df, c("url", "chapt_title", "img_path")) -}) + testthat::expect_names(chapt_df, c("url", "chapt_title", "img_path")) -test_that("Set Up", { - #set_up_leanpub( - # make_book_txt = TRUE, - # quiz_dir = NULL - #) + testthat::expect_number(nrow(chapt_df), 5) }) - #website_to_embed_leanpub( - #chapt_img_key = 'resources/chapt_screen_images/chapter_urls.tsv', - #make_book_txt = TRUE, - #quiz_dir = NULL) +test_that("Set Up Leanpub", { + dir <- setup_ottr_template(dir = ".", type = "rmd") + + # We're going to delete this so we can test making it again + unlink(file.path(dir, "manuscript"), recursive = TRUE) + + # Now run the iframe maker bit + website_to_embed_leanpub( + path = dir, + chapt_img_key = file.path('resources', 'chapt_screen_images', 'chapter_urls.tsv'), + make_book_txt = TRUE, + quiz_dir = NULL, + output_dir = "manuscript") + + testthat::expect_true( + file.exists(file.path(dir, + "manuscript", + "resources", + "chapt_screen_images", + "introduction.png"))) - ## TEST HERE: - # 1. Did each chapter get a md in the manuscript folder? - # 2. Does each md link to the appropriate sceenshot? - # 3. Did the screenshot file path that's in the md lead to the appropriate file path? + # Lets check what the file looks like + intro <- readLines(file.path(dir, "manuscript", "1-Introduction.md")) + + # Make sure the png is pointed to + testthat::expect_true(any(grepl("poster:resources/chapt_screen_images/introduction.png", intro))) + + # Make sure we link to the page + testthat::expect_true(any(grepl("![](https://jhudatascience.org/OTTR_Template/introduction.html)", intro, fixed = TRUE))) + + clean_up() +})