From 070c5aa185e46dfae9bb41de62507b6b2022fbed Mon Sep 17 00:00:00 2001 From: ashishtiwari03 Date: Sun, 24 May 2026 14:33:02 +0200 Subject: [PATCH 1/3] Add failing test for quarto animint output copy --- .../test-compiler-knit-print-quarto.R | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 tests/testthat/test-compiler-knit-print-quarto.R diff --git a/tests/testthat/test-compiler-knit-print-quarto.R b/tests/testthat/test-compiler-knit-print-quarto.R new file mode 100644 index 00000000..214c3d81 --- /dev/null +++ b/tests/testthat/test-compiler-knit-print-quarto.R @@ -0,0 +1,36 @@ +acontext("knitting quarto website outputs") + +test_that("quarto website output includes animint directory", { + skip_if_not_installed("quarto") + skip_if_not(nzchar(quarto::quarto_path()), "Quarto CLI not installed") + + temp.dir <- tempfile() + dir.create(temp.dir) + on.exit(unlink(temp.dir, recursive = TRUE), add = TRUE) + + writeLines(c( + "project:", + " type: website", + " output-dir: _site" + ), file.path(temp.dir, "_quarto.yml")) + + writeLines(c( + "---", + "title: Home", + "---", + "", + "```{r myplot}", + "library(animint2)", + "p <- ggplot() + geom_point(aes(x = 1:10, y = 1:10))", + "animint(plot = p)", + "```" + ), file.path(temp.dir, "index.qmd")) + + old_wd <- getwd() + setwd(temp.dir) + on.exit(setwd(old_wd), add = TRUE) + + quarto::quarto_render("index.qmd", quiet = TRUE) + + expect_true(file.exists(file.path(temp.dir, "_site", "myplot", "plot.json"))) +}) From b2243a4aae1647eb370cce316b527baee0f5f656 Mon Sep 17 00:00:00 2001 From: ashishtiwari03 Date: Mon, 25 May 2026 14:03:14 +0200 Subject: [PATCH 2/3] Copy animint output for quarto websites --- R/z_knitr.R | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/R/z_knitr.R b/R/z_knitr.R index 35f99000..b611c4fe 100644 --- a/R/z_knitr.R +++ b/R/z_knitr.R @@ -12,6 +12,7 @@ knit_print.animint <- function(x, options, ...) { viz_id <- gsub("[^[:alnum:]]", "", options$label) out.dir <- file.path(output.dir, viz_id) animint2dir(x, out.dir = out.dir, open.browser = FALSE) + copy_quarto_animint_dir(out.dir, viz_id) res <- if(knitr::is_latex_output())sprintf( "\\IfFileExists{%s/Capture.PNG}{\\includegraphics[width=\\textwidth]{%s/Capture.PNG}}{}", out.dir, out.dir ) else sprintf( @@ -36,6 +37,33 @@ knit_print.animint <- function(x, options, ...) { knitr::asis_output(res, meta = list(animint = structure("", class = "animint"))) } +quarto_output_dir <- function(project.root) { + quarto.yml <- file.path(project.root, "_quarto.yml") + if (!file.exists(quarto.yml)) return(NULL) + + yml.lines <- readLines(quarto.yml, warn = FALSE) + output.line <- grep("^[[:space:]]+output-dir:", yml.lines, value = TRUE) + if (!length(output.line)) return("_site") + + sub("^[[:space:]]+output-dir:[[:space:]]*", "", output.line[[1]]) +} + +copy_quarto_animint_dir <- function(out.dir, viz_id) { + project.root <- Sys.getenv("QUARTO_PROJECT_ROOT") + if (project.root == "") return(invisible(FALSE)) + + output.dir <- quarto_output_dir(project.root) + if (is.null(output.dir)) return(invisible(FALSE)) + + site.dir <- file.path(project.root, output.dir) + if (!dir.exists(site.dir)) return(invisible(FALSE)) + + to.dir <- file.path(site.dir, viz_id) + if (dir.exists(to.dir)) unlink(to.dir, recursive = TRUE) + + file.copy(out.dir, site.dir, recursive = TRUE) +} + #' Shiny ui output function #' @param outputId output variable to read the plot from #' @seealso http://shiny.rstudio.com/articles/building-outputs.html From 2a868466b3331550de74ca3c4342aadc19685b07 Mon Sep 17 00:00:00 2001 From: ashishtiwari03 Date: Sun, 31 May 2026 16:29:31 +0200 Subject: [PATCH 3/3] Revise quarto animint resource handling --- R/z_knitr.R | 55 +++++++------------ .../test-compiler-knit-print-quarto.R | 1 + 2 files changed, 21 insertions(+), 35 deletions(-) diff --git a/R/z_knitr.R b/R/z_knitr.R index b611c4fe..f7d9ddcd 100644 --- a/R/z_knitr.R +++ b/R/z_knitr.R @@ -12,17 +12,17 @@ knit_print.animint <- function(x, options, ...) { viz_id <- gsub("[^[:alnum:]]", "", options$label) out.dir <- file.path(output.dir, viz_id) animint2dir(x, out.dir = out.dir, open.browser = FALSE) - copy_quarto_animint_dir(out.dir, viz_id) - res <- if(knitr::is_latex_output())sprintf( - "\\IfFileExists{%s/Capture.PNG}{\\includegraphics[width=\\textwidth]{%s/Capture.PNG}}{}", out.dir, out.dir - ) else sprintf( + if(knitr::is_latex_output()){ + res <- sprintf( + "\\IfFileExists{%s/Capture.PNG}{\\includegraphics[width=\\textwidth]{%s/Capture.PNG}}{}", out.dir, out.dir) + }else{ + res <- sprintf( ##
- '
\n', viz_id, viz_id, viz_id, viz_id - ) - # if this is the first plot, place scripts just before the plot - # there has to be a better way to do this, but this will do for now -- http://stackoverflow.com/questions/14308240/how-to-add-javascript-in-the-head-of-a-html-knitr-document - if (length(knitr::knit_meta(class = "animint", clean = FALSE)) == 0) { - res <- sprintf(' + '
\n', viz_id, viz_id, viz_id, viz_id) + # if this is the first plot, place scripts just before the plot + # there has to be a better way to do this, but this will do for now -- http://stackoverflow.com/questions/14308240/how-to-add-javascript-in-the-head-of-a-html-knitr-document + if (length(knitr::knit_meta(class = "animint", clean = FALSE)) == 0) { + res <- sprintf(' @@ -33,35 +33,20 @@ knit_print.animint <- function(x, options, ...) { %s', viz_id, viz_id, viz_id, viz_id, viz_id, viz_id, viz_id, viz_id, viz_id, res) + } + res <- paste(res, animint_resources(out.dir, viz_id), sep = "\n") } knitr::asis_output(res, meta = list(animint = structure("", class = "animint"))) } -quarto_output_dir <- function(project.root) { - quarto.yml <- file.path(project.root, "_quarto.yml") - if (!file.exists(quarto.yml)) return(NULL) - - yml.lines <- readLines(quarto.yml, warn = FALSE) - output.line <- grep("^[[:space:]]+output-dir:", yml.lines, value = TRUE) - if (!length(output.line)) return("_site") - - sub("^[[:space:]]+output-dir:[[:space:]]*", "", output.line[[1]]) -} - -copy_quarto_animint_dir <- function(out.dir, viz_id) { - project.root <- Sys.getenv("QUARTO_PROJECT_ROOT") - if (project.root == "") return(invisible(FALSE)) - - output.dir <- quarto_output_dir(project.root) - if (is.null(output.dir)) return(invisible(FALSE)) - - site.dir <- file.path(project.root, output.dir) - if (!dir.exists(site.dir)) return(invisible(FALSE)) - - to.dir <- file.path(site.dir, viz_id) - if (dir.exists(to.dir)) unlink(to.dir, recursive = TRUE) - - file.copy(out.dir, site.dir, recursive = TRUE) +animint_resources <- function(out.dir, viz_id) { + files <- list.files(out.dir, recursive = TRUE, all.files = TRUE, no.. = TRUE) + files <- files[!dir.exists(file.path(out.dir, files))] + if(!length(files))return("") + hrefs <- file.path(viz_id, files) + hrefs <- gsub("\\\\", "/", hrefs) + links <- sprintf('', hrefs) + paste0('
', paste(links, collapse = "\n"), '
') } #' Shiny ui output function diff --git a/tests/testthat/test-compiler-knit-print-quarto.R b/tests/testthat/test-compiler-knit-print-quarto.R index 214c3d81..a5229068 100644 --- a/tests/testthat/test-compiler-knit-print-quarto.R +++ b/tests/testthat/test-compiler-knit-print-quarto.R @@ -33,4 +33,5 @@ test_that("quarto website output includes animint directory", { quarto::quarto_render("index.qmd", quiet = TRUE) expect_true(file.exists(file.path(temp.dir, "_site", "myplot", "plot.json"))) + expect_true(file.exists(file.path(temp.dir, "_site", "myplot", "animint.js"))) })