diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index b542e234..091012fd 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -39,7 +39,6 @@ jobs: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - name: Check testthat - if: runner.os != 'Windows' id: check_check run: | error_num=$(Rscript --vanilla '.github/workflows/check_testthat.R') diff --git a/.github/workflows/check_testthat.R b/.github/workflows/check_testthat.R index 7f338808..831d1d2b 100644 --- a/.github/workflows/check_testthat.R +++ b/.github/workflows/check_testthat.R @@ -8,21 +8,38 @@ library(magrittr) # Find .git root directory root_dir <- rprojroot::find_root(rprojroot::has_dir(".git")) +# Read in the testthat results out_file <- list.files(pattern = "testthat.Rout$|Rout.fail$", file.path(root_dir, "check"), recursive = TRUE, full.names = TRUE) -check_content <- readLines(out_file) -test_result <- grep("\\[ FAIL", check_content, value = TRUE)[1] -test_result <- unlist(strsplit(test_result, "\\||\\[|\\]")) +# Extract testhat results +testthat_check_content <- readLines(out_file) +testthat_result <- grep("\\[ FAIL", testthat_check_content, value = TRUE)[1] +testthat_result <- unlist(strsplit(testthat_result, "\\||\\[|\\]")) + +# Read in standard check results +check_content <- readLines(file.path(root_dir, "check", "ottrpal.Rcheck", "00check.log")) + +# Extract standard check results +check_result <- grep("Status\\:", check_content, value = TRUE) +check_result <- unlist(strsplit(check_result, ",")) +check_result <- stringr::str_remove(check_result, "Status:| ") # Format the data into a dataframe -test_result_df <- data.frame(result = trimws(test_result)) %>% +testthat_result_df <- data.frame(result = trimws(testthat_result)) %>% dplyr::filter(result != "") %>% tidyr::separate(result, sep = " ", into = c("test_name", "num")) %>% dplyr::mutate(num = as.numeric(num)) -fail_num <- test_result_df %>% - dplyr::filter(test_name %in% c("FAIL", "WARN")) %>% +# Do the same for the check results +check_result_df <- data.frame(result = trimws(check_result)) %>% + tidyr::separate(result, sep = " ", into = c("num", "test_name")) %>% + dplyr::mutate(num = as.numeric(num)) %>% + dplyr::select("test_name", "num") + +# We only want warnings or errors or fails +fail_num <- dplyr::bind_rows(check_result_df, testthat_result_df) %>% + dplyr::filter(test_name %in% c("FAIL", "WARN", "WARNINGs", "ERROR")) %>% dplyr::summarize(total = sum(num)) fail_num <- as.character(fail_num$total) diff --git a/DESCRIPTION b/DESCRIPTION index f0fb1eb9..efbdf960 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,7 +23,6 @@ Imports: curl, dplyr, fs, - glue, httr, jsonlite, knitr (>= 1.33), diff --git a/NAMESPACE b/NAMESPACE index 6d54d6f2..9746629a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,12 +4,6 @@ export("%>%") export(auth_from_secret) export(authorize) export(bad_quiz_path) -export(bookdown_destination) -export(bookdown_file) -export(bookdown_path) -export(bookdown_rmd_files) -export(bookdown_to_book_txt) -export(bookdown_to_embed_leanpub) export(check_all_questions) export(check_question) export(check_quiz) @@ -18,14 +12,12 @@ export(check_quiz_question_attributes) export(check_quizzes) export(convert_coursera_quizzes) export(convert_quiz) -export(convert_utube_link) +export(course_path) +export(course_to_book_txt) export(download_ottr_template) -export(example_repo_cleanup) -export(example_repo_setup) export(extract_meta) export(extract_object_id) export(extract_quiz) -export(get_bookdown_spec) export(get_chapters) export(get_gs_pptx) export(get_image_from_slide) @@ -33,29 +25,27 @@ export(get_image_link_from_slide) export(get_object_id_notes) export(get_slide_id) export(get_slide_page) +export(get_yaml_spec) export(good_quiz_path) export(gs_id_from_slide) export(gs_png_download) export(gs_png_url) export(include_slide) -export(leanpub_check) export(make_embed_markdown) +export(output_destination) export(parse_q_tag) export(parse_quiz) export(parse_quiz_df) export(pptx_notes) export(pptx_slide_note_df) export(pptx_slide_text_df) -export(remove_yaml_header) +export(qrmd_files) export(render_without_toc) -export(replace_html) -export(replace_single_html) export(set_knitr_image_path) export(set_up_leanpub) -export(simple_references) export(unzip_pptx) +export(website_to_embed_leanpub) export(xml_notes) -importFrom(fs,dir_copy) importFrom(httr,GET) importFrom(httr,accept_json) importFrom(httr,config) diff --git a/R/coursera_and_leanpub.R b/R/coursera_and_leanpub.R index df478e85..2cb7c4dc 100644 --- a/R/coursera_and_leanpub.R +++ b/R/coursera_and_leanpub.R @@ -197,9 +197,10 @@ convert_coursera_quizzes <- function(input_quiz_dir = "quizzes", ) } -#' Create TOC-less Bookdown for use in Coursera +#' Create TOC-less course website for use in Coursera or Leanpub #' -#' Create a version of Leanpub that does not have a TOC and has quizzes in the Coursera yaml format. Requires Bookdown output files including "assets", "resources", and "libs". +#' Create a version of the course that does not have a TOC and has quizzes in the Coursera yaml format. +#' This is only needed to be used on Bookdown courses. Quarto has a simple command for this. #' #' @param output_dir A folder (existing or not) that the TOC-less Bookdown for Coursera files should be saved. By default is file.path("docs", "coursera") #' @param output_yaml A output.yml file to be provided to bookdown. By default is "_output.yml" @@ -220,8 +221,8 @@ render_without_toc <- function(output_dir = file.path("docs", "no_toc"), input_quiz_dir = "quizzes", output_quiz_dir = "coursera_quizzes", verbose = TRUE) { - # Find root directory by finding `_bookdown.yml` file - root_dir <- bookdown_path() + # Find root directory by finding `.git` folder + root_dir <- course_path() # Output files: output_dir <- file.path(root_dir, output_dir) diff --git a/R/data.R b/R/data.R index 0751e9cc..c0d1c2f0 100644 --- a/R/data.R +++ b/R/data.R @@ -47,6 +47,38 @@ download_ottr_template <- function(dir = "inst/extdata", type = "rmd") { return(output_dir) } + +#' Path to good example quiz +#' +#' @export +#' @return The file path to an example good quiz included in the package that should pass the quiz checks. +#' +good_quiz_path <- function() { + list.files( + pattern = "quiz_good.md$", + recursive = TRUE, + system.file("extdata", package = "ottrpal"), + full.names = TRUE + ) +} + +#' Path to bad example quiz +#' +#' @export +#' @return The file path to an example bad quiz included in the package that will fail the quiz checks. +#' +#' @examples +#' +#' quiz_path <- bad_quiz_path() +bad_quiz_path <- function() { + list.files( + pattern = "quiz_bad.md$", + recursive = TRUE, + system.file("extdata", package = "ottrpal"), + full.names = TRUE + ) +} + #' Get file path to an key encryption RDS key_encrypt_creds_path <- function() { list.files( diff --git a/R/example_data.R b/R/example_data.R deleted file mode 100644 index 1af693f5..00000000 --- a/R/example_data.R +++ /dev/null @@ -1,89 +0,0 @@ -# C. Savonen 2021 - -#' Path to good example quiz -#' -#' @export -#' @return The file path to an example good quiz included in the package that will pass the quiz checks. -#' @examples -#' -#' quiz_path <- good_quiz_path() -#' -good_quiz_path <- function() { - list.files( - pattern = "quiz_good.md$", - recursive = TRUE, - system.file("extdata", package = "ottrpal"), - full.names = TRUE - ) -} - -#' Path to bad example quiz -#' -#' @export -#' @return The file path to an example bad quiz included in the package that will fail the quiz checks. -#' -#' @examples -#' -#' quiz_path <- bad_quiz_path() -bad_quiz_path <- function() { - list.files( - pattern = "quiz_bad.md$", - recursive = TRUE, - system.file("extdata", package = "ottrpal"), - full.names = TRUE - ) -} - -#' Set up example repo files -#' -#' @param dest_dir The destination directory you would like the example repo files to be placed. By default is current directory. -#' @return Sets up example files that can be used to test 'ottrpal' functions. -#' -#' @export -#' -#' @importFrom fs dir_copy -#' @examples \dontrun{ -#' -#' # Run this to get the files we need -#' example_files <- ottrpal::example_repo_setup() -#' } -example_repo_setup <- function(dest_dir = tempdir()) { - bookdown_path <- list.files( - pattern = "_bookdown.yml$", - system.file("extdata/", package = "ottrpal"), - full.names = TRUE - ) - - # Copy over whole directory - fs::dir_copy(dirname(bookdown_path), dest_dir, overwrite = TRUE) - - copied_files <- list.files(dirname(bookdown_path), full.names = TRUE) - - return(copied_files) -} - -#' Clean up example repo files -#' -#' @param files_to_remove List of example files to delete. -#' @param verbose TRUE/FALSE would you like progress messages? -#' @return Will delete example files copied from [ottrpal::example_repo_setup()] function -#' @export -#' -#' @examples \dontrun{ -#' -#' # Run this to get the files we need -#' example_files <- ottrpal::example_repo_setup() -#' -#' # Run this to delete them -#' example_repo_cleanup(files_to_remove = basename(example_files)) -#' } -example_repo_cleanup <- function(files_to_remove, verbose = FALSE) { - message("Cleaning up and removing example repo files") - - lapply(files_to_remove, function(file2remove, verbose = verbose) { - if (file.exists(file2remove)) { - message(paste0("Removing: ", file2remove)) - file.remove(file2remove) - } - }) -} diff --git a/R/bookdown_to_leanpub.R b/R/iframe_leanpub.R similarity index 93% rename from R/bookdown_to_leanpub.R rename to R/iframe_leanpub.R index 5afbc0f4..cd226b74 100644 --- a/R/bookdown_to_leanpub.R +++ b/R/iframe_leanpub.R @@ -1,6 +1,6 @@ -#' Convert Bookdown to Leanpub +#' Convert Website Course to Leanpub #' -#' @param path path to the bookdown book, must have a `_bookdown.yml` file +#' @param path path to the bookdown or quarto course repository, must have a `_bookdown.yml` or `_quarto.yml` file #' @param chapt_img_key File path to a TSV whose contents are the chapter urls (`url`), #' the chapter titles (`chapt_title`), the file path to the image to be used for the chapter (`img_path`). #' Column names `url`, `chapt_title`, and `img_path` must be used. @@ -17,13 +17,11 @@ #' @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::bookdown_to_book_txt()] be run +#' @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 clean_up TRUE/FALSE the old output directory should be deleted and -#' everything created fresh. #' @param footer_text Optionally can add a bit of text that will be added to the #' end of each file before the references section. #' @@ -32,19 +30,18 @@ #' #' @examples \dontrun{ #' -#' ottrpal::bookdown_to_embed_leanpub( +#' ottrpal::website_to_embed_leanpub( #' base_url = "https://jhudatascience.org/OTTR_Template/", #' make_book_txt = TRUE, #' quiz_dir = NULL #' ) #' } -bookdown_to_embed_leanpub <- function(path = ".", +website_to_embed_leanpub <- function(path = ".", chapt_img_key = NULL, + render = NULL, html_page = file.path(base_url, "index.html"), base_url = NULL, - clean_up = FALSE, default_img = NULL, - render = TRUE, output_dir = "manuscript", make_book_txt = FALSE, quiz_dir = "quizzes", @@ -55,8 +52,6 @@ bookdown_to_embed_leanpub <- function(path = ".", # Run the set up set_up_leanpub( path = path, - embed = TRUE, - clean_up = clean_up, render = render, output_dir = output_dir, make_book_txt = make_book_txt, @@ -110,10 +105,10 @@ bookdown_to_embed_leanpub <- function(path = ".", ####################### Book.txt creation #################################### out <- NULL if (make_book_txt) { - if (verbose) message("Running bookdown_to_book_txt") + if (verbose) message("Running course_to_book_txt") md_files <- basename(unlist(md_output_files)) - bookdown_to_book_txt( + course_to_book_txt( md_files = md_files, output_dir = output_dir, quiz_dir = quiz_dir, @@ -149,7 +144,7 @@ bookdown_to_embed_leanpub <- function(path = ".", #' Create Book.txt file from files existing in quiz directory #' -#' @param path path to the bookdown book, must have a `_bookdown.yml` file +#' @param path path to the bookdown or quarto course repository, must have a `_bookdown.yml` or `_quarto.yml` file #' @param md_files vector of file path of the md's to be included #' @param output_dir output directory to put files. It should likely be #' relative to path @@ -159,7 +154,7 @@ bookdown_to_embed_leanpub <- function(path = ".", #' @return A list of quiz and chapter files in order in a file called Book.txt -- How Leanpub wants it. #' @export #' -bookdown_to_book_txt <- function(path = ".", +course_to_book_txt <- function(path = ".", md_files = NULL, output_dir = "manuscript", quiz_dir = "quizzes", @@ -167,12 +162,12 @@ bookdown_to_book_txt <- function(path = ".", # If md_files are not specified, then try to get them if (is.null(md_files)) { # Establish path - path <- bookdown_path(path) + path <- course_path(path) rmd_regex <- "[.][R|r]md$" # Extract the names of the Rmd files (the chapters) - md_files <- bookdown_rmd_files(path = path) + md_files <- qrmd_files(path = path) } if (!is.null(quiz_dir)) { diff --git a/R/leanpub_checks.R b/R/leanpub_checks.R deleted file mode 100644 index 6f32e1ac..00000000 --- a/R/leanpub_checks.R +++ /dev/null @@ -1,206 +0,0 @@ -#' Check Leanpub Course or Book -#' -#' @param path path to the Leanpub book/course -#' @param verbose print diagnostic messages -#' -#' @return A list of output files and diagnostics -#' @export -#' -leanpub_check <- function(path = ".", - verbose = TRUE) { - if (verbose) { - message("Checking the Book.txt files") - } - check_book_txt(path = path) - extra_book_result <- check_extra_md_files(path = path) - - if (verbose) { - message("Checking if HTML is present") - } - html_result <- full_html_check(path = path) - attribute_result <- full_attribute_check(path = path) - - files <- get_md_files(path) - - L <- list( - extra_book_result = extra_book_result, - html_result = html_result, - attribute_result = attribute_result - ) - return(L) -} - -check_book_txt <- function(path = ".") { - file <- file.path(path, "Book.txt") - # if Book.txt not there, fail - stopifnot(file.exists(file)) - x <- readLines(file, warn = FALSE) - files <- file.path(path, x) - fe <- file.exists(files) - if (!all(fe)) { - msg <- paste(x[fe], collapse = ", ") - msg <- paste0("Book.txt has files specified, but missing: ", msg) - stop(msg) - } - return(NULL) -} -get_md_files <- function(path) { - files <- list.files(pattern = ".md$", ignore.case = TRUE, path = path) - files -} - -check_extra_md_files <- function(path = ".") { - files <- get_md_files(path) - bn <- basename(files) - file <- file.path(path, "Book.txt") - # if Book.txt not there, fail - stopifnot(file.exists(file)) - x <- readLines(file, warn = FALSE) - sd <- setdiff(files, x) - if (length(sd) > 0) { - sd <- paste(sd, collapse = ", ") - warning( - "Markdown files exist in path but are not in Book.txt, may be left out ", - sd - ) - return(FALSE) - } - return(FALSE) -} - -full_html_check <- function(path = ".") { - files <- get_md_files(path) - out <- lapply(files, check_html) - names(out) <- basename(files) - html_result <- any(sapply(out, function(x) x$result)) - if (any(html_result)) { - tag_list <- mapply(function(x, name) { - if (!x$result) { - return(NULL) - } - paste0("file ", name, ": ", paste(x$tags_found, collapse = ", ")) - }, SIMPLIFY = FALSE) - tag_list <- c(unlist(tag_list)) - tag_list <- paste(tag_list, collapse = "\n\n") - message(tag_list) - warning(tag_list) - return(FALSE) - } - return(TRUE) -} - -check_html <- function(x) { - if (length(x) == 1 && file.exists(x)) { - x <- readLines(x, warn = FALSE) - } - # taken from dput(names(shiny::tags)) - tags_to_check <- c( - "a", "abbr", "address", "animate", "animateMotion", "animateTransform", - "area", "article", "aside", "audio", "b", "base", "bdi", "bdo", - "blockquote", "body", "br", "button", "canvas", "caption", "circle", - "cite", "clipPath", "code", "col", "colgroup", "color-profile", - "command", "data", "datalist", "dd", "defs", "del", "desc", "details", - "dfn", "dialog", "discard", "div", "dl", "dt", "ellipse", "em", - "embed", "eventsource", "feBlend", "feColorMatrix", "feComponentTransfer", - "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", - "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", - "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", - "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", - "feSpotLight", "feTile", "feTurbulence", "fieldset", "figcaption", - "figure", "filter", "footer", "foreignObject", "form", "g", "h1", - "h2", "h3", "h4", "h5", "h6", "hatch", "hatchpath", "head", "header", - "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", - "ins", "kbd", "keygen", "label", "legend", "li", "line", "linearGradient", - "link", "main", "map", "mark", "marker", "mask", "menu", "meta", - "metadata", "meter", "mpath", "nav", "noscript", "object", "ol", - "optgroup", "option", "output", "p", "param", "path", "pattern", - "picture", "polygon", "polyline", "pre", "progress", "q", "radialGradient", - "rb", "rect", "rp", "rt", "rtc", "ruby", "s", "samp", "script", - "section", "select", "set", "slot", "small", "solidcolor", "source", - "span", "stop", "strong", "style", "sub", "summary", "sup", "svg", - "switch", "symbol", "table", "tbody", "td", "template", "text", - "textarea", "textPath", "tfoot", "th", "thead", "time", "title", - "tr", "track", "tspan", "u", "ul", "use", "var", "video", "view", - "wbr" - ) - agrepl <- function(...) { - any(grepl(...)) - } - start_strings <- paste("<\\s*", tags_to_check, ".*>") - start_res <- sapply(start_strings, function(pattern) { - agrepl(x = x, pattern = pattern) - }) - end_strings <- paste("<\\s*/", tags_to_check, ".*>") - end_res <- sapply(start_strings, function(pattern) { - agrepl(x = x, pattern = pattern) - }) - res <- start_res | end_res - tag_df <- tibble::tibble( - tag = tags_to_check, - start_present = start_res, - end_present = end_res, - present = res - ) - L <- list( - result = any(res), - tag_data = tag_df - ) - if (any(res)) { - L$tags_found <- tag_df$tag[tag_df$present] - } - L -} - -is_html_present <- function(x) { - out <- check_html(x) - out$result -} - - - -make_sure_attributes_above <- function(x) { - if (length(x) == 1 && file.exists(x)) { - x <- readLines(x, warn = FALSE) - } - index <- lag_attribute <- lag_trimmed <- trimmed <- link <- link_index <- NULL - rm(list = c( - "link_index", "link", "trimmed", "lag_trimmed", - "lag_attribute", "index" - )) - df <- tibble::tibble( - x = x, - index = 1:length(x), - trimmed = trimws(x) - ) %>% - dplyr::mutate( - link = grepl(trimmed, pattern = "^!\\s*\\[.*\\]\\s*\\("), - attributes = grepl(pattern = "^\\{", trimmed), - lag_trimmed = dplyr::lag(trimmed, n = 1), - lag_attribute = grepl(pattern = "^\\{", lag_trimmed) - ) - if (!any(df$link)) { - return(TRUE) - } - bad <- df %>% - dplyr::filter(link & !lag_attribute) - if (nrow(bad) > 0) { - bad_lines <- df %>% - dplyr::filter(index %in% c(bad$index, bad$index - 1)) %>% - dplyr::select(x, index) %>% - as.data.frame() - warning("Links without attributes in the last") - print(bad_lines) - return(FALSE) - } - return(TRUE) -} - -# See if any filenames are duplicated in resources/ and resources/images/ -# just PNGs -# list.files() -# if image specified, see if image actually exists *somewhere* - -full_attribute_check <- function(path = ".") { - files <- get_md_files(path) - out <- lapply(files, make_sure_attributes_above) -} diff --git a/R/remove_yaml.R b/R/remove_yaml.R deleted file mode 100644 index e98dde9d..00000000 --- a/R/remove_yaml.R +++ /dev/null @@ -1,51 +0,0 @@ -partition_yaml_front_matter <- function(input_lines) { - # taken from rmarkdown package - validate_front_matter <- function(delimiters) { - if (length(delimiters) >= 2 && (delimiters[2] - delimiters[1] > - 1) && grepl("^---\\s*$", input_lines[delimiters[1]])) { - if (delimiters[1] == 1) { - TRUE - } else { - all(grepl( - "^\\s*()?\\s*$", - input_lines[1:delimiters[1] - 1] - )) - } - } else { - FALSE - } - } - delimiters <- grep("^(---|\\.\\.\\.)\\s*$", input_lines) - if (validate_front_matter(delimiters)) { - front_matter <- input_lines[(delimiters[1]):(delimiters[2])] - input_body <- c() - if (delimiters[1] > 1) { - input_body <- c(input_body, input_lines[1:delimiters[1] - - 1]) - } - if (delimiters[2] < length(input_lines)) { - input_body <- c(input_body, input_lines[-(1:delimiters[2])]) - } - list(front_matter = front_matter, body = input_body) - } else { - list(front_matter = NULL, body = input_lines) - } -} - -#' Remove YAML header -#' -#' @param file file name of the markdown file -#' -#' @return A character vector of the text without the YAML header -#' @export -#' -#' @examples -#' file <- system.file("extdata/00_template.Rmd", package = "ottrpal") -#' out <- remove_yaml_header(file) -#' head(out) -remove_yaml_header <- function(file) { - file <- readLines(file, warn = FALSE) - out <- partition_yaml_front_matter(file) - out <- out$body - return(out) -} diff --git a/R/replace_html.R b/R/replace_html.R deleted file mode 100644 index 26026bc7..00000000 --- a/R/replace_html.R +++ /dev/null @@ -1,514 +0,0 @@ -#' Convert youtube link -#' -#' @param utube_link a link to a youtube video that may or may not be "www.youtube.com/embed" or "www.youtube.com/watch?v=" -#' format. -#' -#' @return Returns a youtube link in the "watch" format so it will render properly in Leanpub or Coursera-friendly files -#' @export -#' -convert_utube_link <- function(utube_link) { - # If it has a youtube embed link, switch to the watch format link - if (grepl("www.youtube.com/embed", utube_link)) { - utube_link <- paste0( - "https://www.youtube.com/watch?v=", - strsplit(utube_link, - split = "www.youtube.com/embed/" - )[[1]][2] - ) - } - return(utube_link) -} - - -get_html_element <- function(x, element = "img") { - x <- paste(x, collapse = "\n") - doc <- xml2::read_html(x) - nodes <- rvest::html_nodes(doc, xpath = paste0("//", element)) - nodes -} - - -get_figure_div <- function(x) { - div <- get_html_element(x, element = 'div[@class="figure"]') - types <- div %>% - rvest::html_elements(xpath = ".//img|.//iframe") %>% - rvest::html_name() - img <- div %>% - rvest::html_elements(xpath = ".//img|.//iframe") %>% - rvest::html_attrs() - # missing something - not a img or iframe - stopifnot(length(img) == length(div)) - div_aligns <- div %>% - rvest::html_attr(name = "style") - div_aligns <- trimws(sub("text-align: ", "", div_aligns)) - # markua - div_aligns[div_aligns == "center"] <- "middle" - div_aligns[is.na(div_aligns)] <- "middle" - captions <- div %>% - rvest::html_elements(xpath = './p[@class="caption"]') %>% - rvest::html_text() - img <- mapply(function(x, y) { - c(x, caption = y) - }, img, captions, SIMPLIFY = FALSE) - img <- mapply(function(x, y) { - c(x, element_type = y) - }, img, types, SIMPLIFY = FALSE) - img <- mapply(function(x, y) { - y[y %in% ""] <- NA_character_ - if (!all(is.na(y))) { - x <- c(x, align = y) - } - x - }, img, div_aligns, SIMPLIFY = FALSE) - - return(img) -} - - - -get_html_attr <- function(x, element = "img", name = "src") { - x <- get_html_element(x, element = element) - rvest::html_attr(x, name) -} - -get_iframe_attr <- function(x, name = "src") { - x <- get_html_attr(x, element = "iframe", name = name) -} - -get_img_attr <- function(x, name = "src") { - x <- get_html_attr(x, element = "img", name = name) -} - -get_iframe_src <- get_iframe_attr -get_img_src <- get_img_attr - -get_iframe_alt <- function(x) { - get_iframe_attr(x, name = "alt") -} - -get_img_alt <- function(x) { - get_img_attr(x, name = "alt") -} - - - - -find_figure_div <- function(x) { - regex <- paste0('
") - end <- which(grepl(regex, x = x) & !grepl("^ - - - + + + + - Page not found (404) • ottrpal - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - -
-
- + +
+ +
+ - - -
+
+
-
+ + - - diff --git a/docs/LICENSE.html b/docs/LICENSE.html index 500ddc90..0a6986ff 100644 --- a/docs/LICENSE.html +++ b/docs/LICENSE.html @@ -1,66 +1,12 @@ - - - - - - - -GNU General Public License • ottrpal - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -GNU General Public License • ottrpal - - - - + + -
-
- -
- -
+