diff --git a/DESCRIPTION b/DESCRIPTION index b848b1b957..4e3cf068f2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -94,7 +94,7 @@ Suggests: rgl (>= 0.95.1201), codetools, rmarkdown, - htmlwidgets, + htmlwidgets (>= 0.7), webshot, tikzDevice (>= 0.10), png, diff --git a/NEWS.md b/NEWS.md index bd9b5099f2..37b8d8e1e0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,8 @@ - added a `block2` engine for R Markdown documents as an alternative to the `block` engine; it should be faster and supports arbitrary Pandoc's Markdown syntax, but it is essentially a hack; note when the output format is LaTeX/PDF, you have to define `\let\BeginKnitrBlock\begin \let\EndKnitrBlock\end` in the LaTeX preamble +- figure captions specified in the chunk option `fig.cap` are also applied to HTML widgets (thanks, @byzheng, https://github.com/rstudio/bookdown/issues/118) + - added a `width` argument to `write_bib()` so long lines in bib entries can be wrapped - the inline syntax `` `r#code` `` is also supported besides `` `r code` ``; this can make sure the inline expression is not split when the line is wrapped (thanks, Dave Jarvis) diff --git a/R/output.R b/R/output.R index e0e09b5561..6d78f50b22 100644 --- a/R/output.R +++ b/R/output.R @@ -470,6 +470,11 @@ wrap.knit_asis = function(x, options, inline = FALSE) { # store metadata in an object named of the form .hash_meta when cache=TRUE if (length(m) && options$cache == 3) assign(cache_meta_name(options$hash), m, envir = knit_global()) + if (inherits(x, 'knit_asis_htmlwidget')) { + options$fig.cur = plot_counter() + options = reduce_plot_opts(options) + return(add_html_caption(options, x)) + } } x = as.character(x) if (!out_format('latex') || inline) return(x) @@ -595,15 +600,18 @@ wrap.html_screenshot = function(x, options = opts_chunk$get(), inline = FALSE) { wrap.knit_embed_url = function(x, options = opts_chunk$get(), inline = FALSE) { options$fig.cur = plot_counter() options = reduce_plot_opts(options) - iframe = sprintf( + add_html_caption(options, sprintf( '', escape_html(x$url), options$out.width %n% '100%', x$height %n% '400px' - ) + )) +} + +add_html_caption = function(options, code) { cap = .img.cap(options) - if (cap == '') return(iframe) + if (cap == '') return(code) sprintf( '
\n%s\n

%s

\n
', - css_text_align(options$fig.align), iframe, cap + css_text_align(options$fig.align), code, cap ) } diff --git a/R/utils.R b/R/utils.R index 240d9e145e..8ae3d326aa 100644 --- a/R/utils.R +++ b/R/utils.R @@ -708,7 +708,13 @@ current_input = function(dir = FALSE) { default_handlers = evaluate:::default_output_handler # change the value handler in evaluate default handlers knit_handlers = function(fun, options) { - if (!is.function(fun)) fun = knit_print + if (!is.function(fun)) fun = function(x, ...) { + res = knit_print(x, ...) + # indicate the htmlwidget result with a special class so we can attach + # the figure caption to it later in wrap.knit_asis + if (inherits(x, 'htmlwidget')) class(res) = c(class(res), 'knit_asis_htmlwidget') + res + } if (length(formals(fun)) < 2) stop("the chunk option 'render' must be a function of the form ", "function(x, options) or function(x, ...)")