Skip to content

Commit

Permalink
add a function include_graphics() to embed existing images into knitr…
Browse files Browse the repository at this point in the history
  • Loading branch information
yihui committed Nov 10, 2015
1 parent 1b43c9f commit 542b616
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Expand Up @@ -6,6 +6,8 @@

- `kable()` supports generating multiple tables from a list of data objects, and the tables will be placed side by side when the output format is HTML or LaTeX

- added a new function `include_graphics()` to embed existing image files into **knitr** documents; see `?include_graphics` for details

- added a chunk option `ffmpeg.bitrate` (default: `1M`) to control the quality of WebM videos created from FFmpeg (thanks, @JsonPunyon, #1090)

- added a chunk option `ffmpeg.format` (default: `webm`) to control the video format of FFmpeg; this option specifies the filename extension of the video (#712)
Expand Down
10 changes: 10 additions & 0 deletions R/output.R
Expand Up @@ -539,6 +539,16 @@ wrap.recordedplot = function(x, options) {
knit_hooks$get('plot')(file, reduce_plot_opts(options))
}

#' @export
wrap.knit_image_paths = function(x, options, inline = FALSE) {
hook_plot = knit_hooks$get('plot')
options$fig.num = length(x)
paste(unlist(lapply(seq_along(x), function(i) {
options$fig.cur = i
hook_plot(x[i], options)
})), collapse = '')
}

#' A custom printing function
#'
#' The S3 generic function \code{knit_print} is the default printing function in
Expand Down
33 changes: 33 additions & 0 deletions R/plot.R
Expand Up @@ -319,3 +319,36 @@ plot_crop = function(x, quiet = !opts_knit$get('progress')) {
showtext = function(show) {
if (isTRUE(show)) getFromNamespace('showtext.begin', 'showtext')()
}

#' Embed external images in \pkg{knitr} documents
#'
#' When plots are not generated from R code, there is no way for \pkg{knitr} to
#' capture plots automatically. In this case, you may generate the images
#' manually and pass their file paths to this function to include them in the
#' output. The major advantage of using this function is that it is portable in
#' the sense that it works for all document formats that \pkg{knitr} supports,
#' so you do not need to think if you have to use, for example, LaTeX or
#' Markdown syntax, to embed an external image. Chunk options related to
#' graphics output that work for normal R plots also work for these images, such
#' as \code{out.width} and \code{out.height}.
#' @param path a character vector of image paths
#' @param auto_pdf whether to use PDF images automatically when the output
#' format is LaTeX, e.g. \file{foo/bar.png} will be replaced by
#' \file{foo/bar.pdf} if the latter exists; this can be useful since normally
#' PDF images are of higher qualities than raster images like PNG when the
#' output is LaTeX/PDF
#' @note This function is supposed to be used in R code chunks or inline R code
#' expressions. You are recommended to use forward slashes (\verb{/}) as path
#' separators instead of backslashes in the image paths.
#' @return The same as the input character vector \code{path} but it is marked
#' with special internal S3 classes so that \pkg{knitr} will convert the file
#' paths to proper output code according to the output format.
#' @export
include_graphics = function(path, auto_pdf = TRUE) {
if (auto_pdf && is_latex_output()) {
path2 = sub_ext(path, 'pdf')
i = file.exists(path2)
path[i] = path2[i]
}
structure(path, class = c('knit_image_paths', 'knit_asis'))
}
15 changes: 15 additions & 0 deletions tests/testit/test-hooks.R
Expand Up @@ -16,4 +16,19 @@ assert(
)
)

render_markdown()

img_output = function(path, opts = list()) {
opts = opts_chunk$merge(opts)
wrap(knit_print(include_graphics(path)), opts)
}

assert(
'include_graphics() includes custom images correctly',
identical(img_output('a.png'), '![](a.png) '),
identical(img_output(c('a.png', 'b.png')), '![](a.png) ![](b.png) '),
identical(img_output('a.png', list(fig.cap = 'foo bar')), '![foo bar](a.png) '),
identical(img_output('a.png', list(out.width = '50%')), '<img src="a.png" title="" alt="" width="50%" />')
)

knit_hooks$restore()

0 comments on commit 542b616

Please sign in to comment.