The animation.hook chunk option works for HTML output but has no effect for LaTeX/PDF output.
For a chunk with fig.show: animate, we only inject a default hook when the format is not LaTeX
|
# automatically set gifski hook for fig.animate |
|
opts_hooks[["fig.show"]] <- function(options) { |
|
# get current value of fig.show |
|
fig.show <- options[["fig.show"]] |
|
|
|
# use gifski as default animation hook for non-latex output |
|
if (identical(fig.show, "animate")) { |
|
if ( |
|
!is_pandoc_latex_output(format) && is.null(options[["animation.hook"]]) |
|
) { |
|
options[["animation.hook"]] <- "gifski" |
|
} |
The HTML branch then delegates to knitr's hook_animation(), so a user-supplied hook is honored there. The LaTeX branch instead calls our own latex_animation(), which always emits \animategraphics{} and never looks at animation.hook
|
# ported from: |
|
# https://github.com/yihui/knitr/blob/f8f90baad99d873202b8dc8042eab7a88fac232f/R/hooks-latex.R#L151-L171 |
|
latex_animation <- function(x, options) { |
|
fig.num = options$fig.num %||% 1L |
|
|
|
ow = options$out.width |
|
# maxwidth does not work with animations |
|
if (identical(ow, '\\maxwidth')) { |
|
ow = NULL |
|
} |
|
if (is.numeric(ow)) { |
|
ow = paste0(ow, 'px') |
|
} |
|
size = paste( |
|
c( |
|
sprintf('width=%s', ow), |
|
sprintf('height=%s', options$out.height), |
|
options$out.extra |
|
), |
|
collapse = ',' |
|
) |
|
|
|
aniopts = options$aniopts |
|
aniopts = if (is.na(aniopts)) NULL else gsub(';', ',', aniopts) |
|
size = paste(c(size, sprintf('%s', aniopts)), collapse = ',') |
|
if (nzchar(size)) { |
|
size = sprintf('[%s]', size) |
|
} |
|
sprintf( |
|
'\\animategraphics%s{%s}{%s}{%s}{%s}', |
|
size, |
|
1 / options$interval, |
|
sub(sprintf('%d$', fig.num), '', xfun::sans_ext(x)), |
|
1L, |
|
fig.num |
|
) |
|
} |
It also adds a dependency on the LaTeX animate package unconditionally
|
# check for latex |
|
if (is_pandoc_latex_output(format)) { |
|
# include dependency on animate package |
|
knitr::knit_meta_add(list( |
|
rmarkdown::latex_dependency("animate") |
|
)) |
Upstream knitr changed this in yihui/knitr#2452: hook_plot_tex() now calls a user-supplied animation.hook (or the package option animation.fun) to generate the LaTeX code, so LaTeX packages other than animate can be used, xmpmulti for beamer overlays being the motivating example. The built-in hooks (ffmpeg, gifski, scianimator, r2swf) generate HTML and keep being ignored for LaTeX. Our latex_animation() is a port of knitr's code from before that change.
So with the next knitr release this will work in .Rmd but not in .qmd.
We could port the same logic into latex_animation(): when animation.hook is a function and is not one of knitr's built-in HTML hooks, call it instead of emitting \animategraphics{}, and skip the animate dependency in that case.
Two things to sort out if we do this. Our schema documents animation-hook with default: ffmpeg while we actually inject gifski for non-LaTeX output, and it is typed as a string with completions, so a function can only be passed with the classic R chunk syntax ({r, animation.hook=my_hook}) and not with #| YAML.
|
- name: animation-hook |
|
tags: |
|
engine: knitr |
|
schema: |
|
string: |
|
completions: [ffmpeg, gifski] |
|
default: ffmpeg |
|
description: |
|
short: "Hook function to create animations in HTML output" |
|
long: | |
|
Hook function to create animations in HTML output. |
|
|
|
The default hook (`ffmpeg`) uses FFmpeg to convert images to a WebM video. |
|
|
|
Another hook function is `gifski` based on the |
|
[**gifski**](https://cran.r-project.org/package=gifski) package to |
|
create GIF animations. |
The
animation.hookchunk option works for HTML output but has no effect for LaTeX/PDF output.For a chunk with
fig.show: animate, we only inject a default hook when the format is not LaTeXquarto-cli/src/resources/rmd/hooks.R
Lines 115 to 126 in d4cb49f
The HTML branch then delegates to knitr's
hook_animation(), so a user-supplied hook is honored there. The LaTeX branch instead calls our ownlatex_animation(), which always emits\animategraphics{}and never looks atanimation.hookquarto-cli/src/resources/rmd/hooks.R
Lines 1170 to 1206 in d4cb49f
It also adds a dependency on the LaTeX animate package unconditionally
quarto-cli/src/resources/rmd/hooks.R
Lines 713 to 718 in d4cb49f
Upstream knitr changed this in yihui/knitr#2452:
hook_plot_tex()now calls a user-suppliedanimation.hook(or the package optionanimation.fun) to generate the LaTeX code, so LaTeX packages other than animate can be used, xmpmulti for beamer overlays being the motivating example. The built-in hooks (ffmpeg,gifski,scianimator,r2swf) generate HTML and keep being ignored for LaTeX. Ourlatex_animation()is a port of knitr's code from before that change.So with the next knitr release this will work in
.Rmdbut not in.qmd.We could port the same logic into
latex_animation(): whenanimation.hookis a function and is not one of knitr's built-in HTML hooks, call it instead of emitting\animategraphics{}, and skip the animate dependency in that case.Two things to sort out if we do this. Our schema documents
animation-hookwithdefault: ffmpegwhile we actually injectgifskifor non-LaTeX output, and it is typed as a string with completions, so a function can only be passed with the classic R chunk syntax ({r, animation.hook=my_hook}) and not with#|YAML.quarto-cli/src/resources/schema/cell-figure.yml
Lines 219 to 235 in d4cb49f