Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions R/z_knitr.R
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems unusual. can you please post an issue on quarto to ask how we should do this?

@ashishtiwari03 ashishtiwari03 May 25, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that makes sense. I opened an issue on Quarto to ask for the recommended way to get the project output
directory from inside knit_print():
https://github.com/orgs/quarto-dev/discussions/14545

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quarto maintainers replied here:

https://github.com/orgs/quarto-dev/discussions/14545

They suggested that fig.path is probably not the right mechanism, and that dependencies associated with output
should probably go through knit_meta / knit_print() metadata, possibly via htmltools dependencies.

So I agree the current _quarto.yml parsing in this PR is probably not the right final approach. I can try revising
the fix in that direction.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok thanks.
please try to do it without htmltools.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the Quarto discussion, I will try revising this without htmltools and without parsing _quarto.yml.

I will look at using knitr::asis_output(..., meta = ...) / knit_meta directly, since knit_print.animint()
already returns metadata.

@ashishtiwari03 ashishtiwari03 May 25, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cderv added another note in the Quarto discussion:

https://github.com/orgs/quarto-dev/discussions/14545

They suggested looking at how other packages ship HTML dependencies with knitr output. They mentioned that in rmarkdown contexts this is usually done through htmlwidgets or html dependencies.

Since you asked to try without htmltools, I will first check whether this can be done using knit_meta directly,
without adding htmltools-based dependencies.

@ashishtiwari03 ashishtiwari03 May 31, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I revised the fix to avoid parsing _quarto.yml and to avoid htmltools.

The updated knit_print.animint() now leaves Quarto/rmarkdown to discover the generated animint files through plain HTML resource links emitted with the chunk output. The existing knitr metadata flag is still used only to avoid injecting the shared JS/CSS more than once.

I also added an assertion that the rendered Quarto site contains myplot/animint.js in addition to myplot/plot.json.

Locally, the focused Quarto test passes:
FAIL 0 | WARN 0 | SKIP 0 | PASS 2

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
Expand Down
36 changes: 36 additions & 0 deletions tests/testthat/test-compiler-knit-print-quarto.R
Original file line number Diff line number Diff line change
@@ -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")))
})