A general-purpose tool for dynamic report generation in R
Added a new chunk option tab.cap
to specify the table caption for kable()
(thanks, @ulyngs, #1679). Previously, the caption could only be specified via the caption
argument of kable()
. Now you can set it in the chunk header if you want. Please note that this chunk option only works with a single kable()
in each code chunk, and its value must be of length 1.
spin()
now recognizes # %%
as a valid code chunk delimiter (thanks, @kylebutts, #2307).
spin()
also recognizes #|
comments as code chunks now (thanks, @kylebutts, #2320).
Chunk hooks can have the ...
argument now. Previously, only arguments before
, options
, envir
, and name
are accepted. If a chunk hook function has the ...
argument, all the aforementioned four arguments are passed to the hook. This means the hook function no longer has to have the four arguments explicitly in its signature, e.g., function(before, ...)
is also valid if only the before
argument is used inside the hook. See https://yihui.org/knitr/hooks/#chunk-hooks for more information.
For package vignettes, PNG plots will be optimized by optipng
and pngquant
if they are installed and can be found from the system PATH
variable. This can help reduce the package size if vignettes contain PNG plots (thanks, @nanxstats, https://nanx.me/blog/post/rpkgs-pngquant-ragg/).
spin()
stopped working with input that cannot be parsed as R code due to #1605. Now it works again (thanks, @Hemken, #1773).
write_bib()
generated empty entries for packages without URLs (thanks, @bastistician, #2304).
The family
argument was not passed to the pdf
device (thanks, @sebkopf, rstudio/rmarkdown#2526).
Trailing spaces escaped by \
should not be trimmed in kable()
(thanks, @mjsmith037, #2308).
kable()
fails when the value of the caption
argument is of length > 1 (thanks, @LeeMendelowitz, #2312).
include_graphics()
may provide an incorrect plot width to LaTeX when the locale setting for LC_NUMERIC
is not C
because the decimal separator may not be a dot (thanks, @tdhock, rstudio/rmarkdown#2525).
When TinyTeX and the LaTeX package pdfcrop are installed, knitr::pdf_crop()
is unable to find pdfcrop
(thanks, @dmkaplan2000, rstudio/tinytex#435).
Unbalanced chunk delimiters (fences) in R Markdown documents are no longer allowed, as announced two years ago at https://yihui.org/en/2021/10/unbalanced-delimiters/ (#2306). This means the opening delimiter must strictly match the closing delimiter, e.g., if a code chunk starts with four backticks, it must also end with four; or if a chunk header is indented by two spaces, the closing fence must be indented by exactly two spaces. For authors who cannot update their R Markdown documents for any reason at the moment, setting options(knitr.unbalanced.chunk = TRUE)
(e.g., in .Rprofile
) can temporarily prevent knitr from throwing an error, but it is strongly recommended that you fix the problems as soon as possible, because this workaround will be removed in future.
Package vignettes are tangled by default during R CMD check
, per request from CRAN maintainers (d0d1b47). The consequence is that R CMD check
will check R scripts tangled from vignettes by default, unless you set the environment variable _R_CHECK_VIGNETTES_SKIP_RUN_MAYBE_=true
. Previously, knitr would skip tangling vignettes during R CMD check
, because R scripts tangled from vignettes are not guaranteed to valid. With the skip undone, R CMD check
may fail in places other than CRAN (because CRAN has set the environment variable).
Fixed broken vignettes, improved CSS for HTML vignettes, and reduced the file sizes.
SQL code chunks that run ALTER
statements are only executed and not tried to fecth a result (thanks, @maxschmi, #2330).
The function imgur_upload()
has been moved to (and enhanced in) the xfun package as xfun::upload_imgur()
so it is no longer tied to knitr and can be reused by other pakages. Now knitr::imgur_upload()
is only a wrapper function of xfun::upload_imgur()
. You are recommended to use the latter (#2325).
spin()
dropped support for #-
as the chunk delimiter token. Please use #+
or # %%
or #|
instead.
Faster processing of cache dependencies in dep_auto()
(thanks, @knokknok, #2318).
Removed some S3 methods that are used internally and changed them to normal functions: print.block -> print_block
, print.inline -> print_inline
, process_group.block/process_group.inline -> process_group
, and process_tangle.block/process_tangle.inline -> process_tangle
.
Special characters in the chunk option fig.alt
are properly escaped now (thanks, @jay-sf, #2290).
Negative numbers returned from inline R expressions lost their minus signs when formatted in the scientific notation (thanks, @fkohrt, #2288).
convert_chunk_header(type = 'yaml')
will now use dash option name for known knitr options, and numeric option are kept with same significant digits, e.g fig.width = 10
is converted to fig-width: 10
.
Add the necessary \newline
to the last subfigure (thanks, @slrellison, rstudio/rmarkdown#2518).
Percent signs (%
) in LaTeX figure captions and short captions are properly escaped now (thanks, @s-u, #2302).
The object opts_current
will be restored after each code chunk has finished executing. Previously, it would not be restored, which means even for inline R expressions, opts_current$get()
will inherit chunk options from a previous code chunk (thanks, @rundel, #1988). Besides, opts_current$get('label')
will return a unique label for inline expressions. One possible application is to construct unique figure paths via fig_path()
(e.g., ropensci/magick#310).
opts_current$set()
without opts_current$lock(FALSE)
will trigger a warning instead of an error for now and it will become an error in future (#2296).
kable()
can generate Emacs org-mode tables now via kable(..., format = 'org')
(thanks, @xvrdm #1372, @maxecharel #2258).
Added support for the qmd
(Quarto) output format to spin()
, e.g., spin('script.R', format = 'qmd')
(thanks, @cderv, #2284).
write_bib()
has a new argument packageURL
to control whether to use a URL from the DESCRIPTION
file or the one generated by utils::citation()
(thanks, @dmurdoch, #2264).
Updated the package vignette vignette('knit_print', 'knitr')
to mention that package authors no longer have to make knitr a hard dependency if they want to define S3 methods for knitr::knit_print
with R >= 3.6.0 (thanks, @cderv, #1929).
Added a new function download_image()
to download an image from a URL and include it via include_graphics()
. This is mainly for including online images when the output format is not HTML (e.g., LaTeX), because the URL will not work as the image path, and it has to be downloaded beforehand (thanks, @bayeslearner, #2274).
Make the internal function add_html_caption()
work with Quarto <= v1.3.353 (thanks, @giabaio, #2261).
Fixed a bug in spin(format = 'Rnw')
reported by @Tarious14 at https://github.com/yihui/yihui.org/discussions/769#discussioncomment-6587927
When the chunk option dev = 'svglite'
, the svglite
device should be used to record plots (thanks, @Darxor, #2272).
Figure captions are no longer escaped for reStructuredText output, and the alt text can also be specified via the fig.alt
chunk option now (thanks, @trevorld, #2023).
Use the correct type of progress bar when rendering Quarto documents in RStudio, which takes place in RStudio's background jobs pane or build pane (thanks, @hadley, #2271).
The opts_current
object can no longer be modified within code chunks via its $set()
method (thanks, @AshesITR, #1798).
The argument col.names
of kable()
can be used to specify the column name of row names now, e.g., kable(head(mtcars), col.names = c("car", names(mtcars)))
("car"
will be the column name of row names in the first column) (thanks, @iago-pssjd, #1933).
-
) in the names of all chunk options are normalized to dots (.
) now, e.g., fig-height
will be converted to fig.height
. This is to make knitr more compatible with Quarto since Quarto always use dashes in chunk option names (#2282).In-body chunk options (#|
) are now preserved when extracting code from a document via purl()
(thanks, @LuisLauM, #2268).
A warning message will be issued when taking PDF screenshots for HTML widgets with the webshot2 package, because webshot2 doesn't use the correct figure size at the moment (thanks, @icejean, #2276).
If the title
argument of knit2wp()
is omitted and a title
field is specified in the YAML metadata of the input document, the YAML title
will be used (thanks, @arencambre, #1924).
Progress bar includes the chunk location (chunk-name @ file:line
) when options(knitr.progress.linenums = TRUE)
is set (thanks, @zeehio, #2232).
The global option knitr.progress.simple
can be used to decide whether to output the bar in the progress. When set to FALSE
, only the step numbers and chunk labels will be printed, and the progress bar is omitted. This can be more useful for logging purposes since the bar itself is not useful (thanks, @hadley, #2221). By default, the simple progress output is used when the progress is not written to a connection such as stdout
or stderr
(e.g., written to a file instead), or the output connection is not a "terminal".
HTML Widgets can now support alt text by specifying an attribute aria-labelledby="<label>"
in their first HTML tag. The text will be obtained from the fig.alt
or fig.cap
chunk option in the usual way (thanks, @dmurdoch, #2243).
Added a new argument newline
to kable()
to handle newlines in data when the table output format is Markdown-based (simple
, pipe
, rst
, or jira
). By default, newlines are not processed, which can result in broken tables. To substitute newlines with spaces, use kable(..., newline = ' ')
. To remove newlines, use kable(..., newline = '')
(thanks, @aronatkins, #2255).
The chunk option collapse = TRUE
works with HTML widgets now (thanks, @dmurdoch, #2212).
Option hooks should be run before child documents are processed (thanks, @richarddmorey, #2247).
For .Rnw
documents, is_latex_output()
returns TRUE
for output formats sweave
(render_sweave()
) and listings
(render_listings()
) now (thanks, @DavisVaughan, #2231).
write_bib()
does not fail anymore if an empty string is passed as package name (thanks, @phargarten2, #2240).
Fix an issue with using cache = TRUE
on sql
engine chunk not defining a output.var
(thanks, @mfherman, @eitsupi, #1842).
plot_crop()
correctly checks the required tools (pdfcrop
and ghostscript
) on Windows when the LaTeX is distribution is TeX Live or TinyTeX (thanks, @remlapmot, #2246). An external installation of ghostscript
is no longer required on Windows, since TeX Live's built-in ghostscript
will be used.
The chunk option dev.args
was not recognized in certain cases (thanks, @petrbouchal, #2238).
The css
and js
engines work for the markdown
output format now. Previous these engines will not output anything when the output format is markdown
. If you still want to disable them for markdown
output, you may use the chunk option eval = FALSE
or eval = knitr::is_html_output(excludes = 'markdown')
.
is_html_output()
recognizes R Markdown v1 documents now (.Rmd
documents compiled via the markdown package).
For .Rnw
documents, dots in figure file paths are no longer sanitized to underscores (thanks, @otoomet, #2213). Other special characters are still sanitized, but this feature can be turned off via options(knitr.sanitize.paths = FALSE)
.
imgur_upload()
now recognizes a global option knitr.imgur.key
or an environment variable R_KNITR_IMGUR_KEY
for a custom client ID (thanks, @jonthegeek, #2233).
imgur_upload()
requires fewer package dependencies now. It only requires the curl package; httr is no longer required, and xml2 has become optional.
Better .qmd
(Quarto) file support:
purl()
will keep the in-chunk YAML syntax for options in the tangled R fileknit()
will produce a .md
file instead of .txt
Users can specify a custom progress bar for knit()
now. The default is still a text progress bar created from utils::txtProgressBar()
. To specify a custom progress bar, set options(knitr.progress.fun = function(total, labels) {})
. This function should take arguments total
(the total number of chunks) and labels
(the vector of chunk labels), create a progress bar, and return a list of two methods: list(update = function(i) {}, done = function() {})
. The update()
method takes i
(index of the current chunk) as the input and updates the progress bar. The done()
method closes the progress bar. See https://yihui.org/knitr/options/#global-r-options for documentation and examples.
The default text progress bar is still written to stdout()
by default, but can also be written to other connections or stderr()
now. To do so, set options(knitr.progress.output = )
to a connection or stderr()
.
Allow concordances to be embedded in HTML output (thanks, @dmurdoch, #2200).
knit()
no longer prints out chunk options beneath the text progress bar while knitting a document (thanks, @hadley, #1880).
Due to a change in the evaluate package, the chunk options message = FALSE
and warning = FALSE
will completely suppress the messages/warnings now, instead of sending them to the console. To get back to the old behavior, you can use NA
instead of FALSE
(thanks, @gadenbuie, https://github.com/yihui/yihui.org/discussions/1458).
The stringr dependency has been removed. All string operations are done with base R now (thanks, @HughParsonage #1549 #1552, @rich-iannone #2174 #2177 #2186 #2187 #2195 #2202 #2205).
Improved the error message when inline R code cannot be parsed (thanks, @hadley #2173, @rich-iannone #2198).
If the chunk option child
is used for a code chunk but the chunk is not empty, you will get a warning indicating that this non-empty code will not be executed when you knit the document. Now this warning can be silenced by options(knitr.child.warning = FALSE)
(thanks, @jwijffels, #2191).
Devices from the package cairoDevice (Cairo_pdf
, Cairo_png
, Cairo_ps
, Cairo_svg
) are no longer supported since the package has been archived on CRAN for more than a year (thanks, @jessekps, #2204).
sql
engine now correctly prints tables with NA
in the first column (thanks, @mariusbommert, #2207).Added support for generating Jira tables via kable(, format = 'jira')
(thanks, @pedropark99 #2180, @mruessler #2024).
Added a new chunk option fig.id
. When it is TRUE
, the chunk option out.extra
will gain an id
attribute for each image from a code chunk in R Markdown (thanks, @jooyoungseo, #2169). By default, the attribute consists of a prefix, the chunk label, and the figure number. See https://yihui.org/knitr/options/ for detailed documentation of fig.id
.
Added an argument exact
to pandoc_to()
and pandoc_from()
to decide whether to use/return the exact Pandoc output/input format name. If not (default), Pandoc extensions will be removed from the format name, e.g., latex-smart
will be treated as latex
.
Plot created outside of knit()
could sneak into knit_child()
results (thanks, @niklaswillrich, #2166).
User-provided background colors for code chunks in .Rnw
documents may fail (thanks, @nielsrhansen, #2167).
tabularx
and xltabular
tables should work without captions (thanks, @amarakon, #2188).
Added a function convert_chunk_header()
to convert the old in-header chunk options to the new in-body chunk options (#2149 #2151).
Added a new "graphics device", dev = "gridSVG"
, which uses gridSVG::grid.export()
to export grid graphics to SVG (thanks, @jooyoungseo, #2152).
Added a new engine eviews
, which calls the EviewsR package to execute EViews code (thanks, @sagirumati, #2158).
Added support for a php
engine like other engines for interpreted languages. It will call php -r <code>
, with <code>
being the chunk content (thanks, @ralmond, #2144).
Per suggestion of @jakubkaczor (#2116) and discussion with @pedropark99 (#2140), the chunk option fig.sep
can also be used to add LaTeX code before the first sub-figure now. Previously this option can only be used for adding LaTeX code after each sub-figure.
knitr::kable()
supports tabularx
and xltabular
environments now for LaTeX tables, e.g., knitr::kable(head(iris), format = 'latex', tabular = 'tabularx')
(thanks, @amarakon, #2138).
For HTML output formats of R Markdown, SVG plots (e.g., in case of chunk option dev = 'svg'
or dev = 'gridSVG'
) can be embedded differently now when options(knitr.svg.object = TRUE)
: if the HTML output is self-contained, the raw SVG code will be embedded directly in HTML, otherwise the .svg
file is embedded in the <object>
tag. By default, this feature is not enabled, i.e., the default is options(knitr.svg.object = FALSE)
for backward-compatibility, which means the <img>
tag is used for SVG plots just like other plot formats. This new feature will make assistive technology agents, such as screen readers, interact with SVG plots (thanks, @jooyoungseo, #2152).
Fixed epub2
output not being considered as HTML format (thanks, @flipacholas, #2145).
kable(format = 'pipe')
calculates column widths correctly now if any text columns contain Markdown hyperlinks (thanks, @jacobbien, #2148).
dev.args = list(engine = ...)
was ignored by dev = 'tikz'
when the tikz plot is compiled to PDF (thanks, @fkohrt, #2150).
When the inline R code cannot be correctly parsed, the error message will show the original code in addition to the parsing error, which can make it easier to identify the code error in the source document (thanks, @AlbertLei, #2141).
The internal function knitr:::wrap()
has been removed from this package. If you rely on this function, you will have to use the exported function knitr::sew()
instead.
Duplicate chunk label error will now be thrown with code chunks using code
or file
chunk options (thanks, @mine-cetinkaya-rundel, #2126).
Simplified R Markdown's inline code parser (thanks, @atusy, #2143).
rel_path
to include_graphics()
, which defaults to TRUE
, meaning that this function will try to convert absolute paths to relative paths automatically. If the conversion fails, it will issue a warning. If you want to suppress the conversion (and the warning), you may use rel_path = FALSE
or set the global option options(knitr.graphics.rel_path = FALSE)
. In the previous version of knitr, this function would always issue a warning when it detects absolute paths (thanks, @davidski @kendavidn, #2119).For knitr source documents that generate .tex
output documents (such as .Rnw
and .Rtex
), the LaTeX package xcolor will be used instead of color (#2085). This may cause option clashes if xcolor is already loaded by users with options, e.g., \usepackage[dvipsnames]{xcolor}
. If this happens, you may set the package option knitr::opts_knit$set(latex.options.xcolor = 'OPTIONS')
where OPTIONS
is the options you used for xcolor, e.g., dvipsnames
.
The evaluation of chunk options written after #|
using the YAML !expr
syntax will be delayed until before the chunk is to be evaluated (#2120).
The chunk option file
can take a vector of file paths now, i.e., this option can be used to read more than one file (e.g., file = c("foo.R", "bar.R")
.
Added a new engine named exec
(#2073) to execute an arbitrary command on the code chunk, e.g.,
```{exec, command='Rscript'}
1 + 1
```
The above code chunk executes the Rscript
command with the chunk body as its input (which basically means executing the R code in a new R session). See the example #124 in the repo https://github.com/yihui/knitr-examples for more info.
There exists several command-based engines in knitr, such as awk
, bash
, perl
, go
, and dot
, etc. This new exec
engine provides a general mechanism to execute any command that users provide. For example, the code chunk
```{bash}
echo 'Hello world!'
```
is equivalent to the chunk using the exec
engine and the bash
command:
```{exec, command='bash'}
echo 'Hello world!'
```
With this new engine, we no longer need to provide or maintain other simple command-based engines. For example, to support TypeScript (https://github.com/yihui/knitr/pull/1833), we only need to specify command = 'ts-node'
with the exec
engine.
If the command has significant side-effects (e.g., compile source code to an executable and run the executable, or generate plots to be included in the output), it is also possible to create a new engine based on the exec
engine. The example #124 in the knitr-examples
repo has provided a gcc
example.
We'd like to thank @TianyiShi2001 for the inspiration (#1829 #1823 #1833).
Added a new engine ditaa
based on the exec
engine to convert ASCII art diagrams to bitmaps via the ditaa
command (thanks, @kondziu, #2092).
Added two new chunk options, class.chunk
and attr.chunk
, for R Markdown output. These options can enclose the whole chunk output (source and results) in a fenced Div. Their syntax follows other chunk options with the similar names class.*
and attr.*
(e.g., class.source
and attr.source
). For example, class.chunk = "foo"
would wrap the chunk output inside ::: {.foo}
and :::
(thanks, @atusy, #2099).
Added a new chunk option lang
to set the language name of a code chunk. By default, the language name is the engine name. This is primarily useful for syntax highlighting the source chunks in Markdown-based output. Previously the lang
option was only available to a few engines such as verbatim
and embed
. Now it is available to all engines.
Added a new wrapper function rnw2pdf()
. It allows users to specify an arbitrary output file path, clean the intermediate files, and stop when any error occurs in knitting (thanks, @shrektan, #2113).
New calling.handlers
option for opts_chunk$set()
to register calling handlers within chunks. See ?evaluate::new_output_handler
for details.
The minimal required version of R was bumped from 3.2.3 to 3.3.0 (thanks, @essemenoff, #2100).
The working directory under which chunk options are evaluated has been changed to the directory of the source document by default. If the package option root.dir
is set to a different directory, that directory will be used as the working directory (#2081).
include_graphics()
will expand ~
in the image paths now and also warn against absolute paths (thanks, @kcarnold, #2063).
opts_chunk$set()
returns values of old chunk options after setting new chunk options now, instead of returning NULL
, which can make it a little simpler to reset chunk options, e.g., you can temporarily change a few chunk options and save them with old = opts_chunk$set(error = FALSE, fig.height = 3)
, and reset them later with opts_chunk$set(old)
. This works for any other objects in knitr that have the $set()
methods, such as opts_knit
, opts_hooks
, knit_hooks
, knit_engines
, and so on.
fig.scap
has been added to eval.after
in opts_knit
(thanks, @knokknok, #2061).Chunk options defined in the #|
style are not recognized when the code chunk is indented or quoted (thanks, @mine-cetinkaya-rundel, #2086).
Fixed a bug in Sweave2knitr()
#2097 (thanks, @chroetz).
Added a new chunk option named file
so that the chunk content can be read from an external file. Setting the chunk option file = "test.R"
is equivalent to using the chunk option code = xfun::read_utf8("test.R")
.
For R Markdown documents, code chunks can be embedded in a parent code chunk with more backticks now. For example, a code chunk with four backticks can contain code chunks with three backticks. One application is to conditionally include some verbatim content that contains code chunks via the asis
engine, e.g.,
````{asis, echo=format(Sys.Date(), "%w") == 1}
Some conditional content only included when report is built on a Monday
```{r}
1 + 1
```
On another day, this content won't be included.
````
Note that the embedded child code chunks (e.g., in the asis
chunk above) are not parsed or evaluated by knitr, and only the top-level code chunk is parsed and evaluated.
Added a new engine named comment
to comment out content, e.g.,
````{comment}
Arbitrary content to be commented out.
```{r}
1 + 1
```
The above code chunk will not be executed.
Inline code like `r pi * 5^2` will be ignored, too.
````
Note that if any line of the content to be commented out contains N
backticks, you will have to use at least N + 1
backticks in the chunk header and footer of the comment
chunk.
Added a new engine named verbatim
mainly for R Markdown documents to output verbatim content that contains code chunks and/or inline expressions, e.g.,
````{verbatim}
We can output arbitrary content verbatim.
```{r}
1 + 1
```
The content can contain inline code like
`r pi * 5^2`, too.
````
By default, the verbatim content is placed in a fenced default
code block:
````default
We can output arbitrary content verbatim.
```{r}
1 + 1
```
The content can contain inline code like
`r pi * 5^2`, too.
````
You can change the default
language name of the block via the chunk option lang
, e.g., lang = 'markdown'
will output a code block like this:
````markdown
We can output arbitrary content verbatim.
```{r}
1 + 1
```
The content can contain inline code like
`r pi * 5^2`, too.
````
To disable the language name on the block, use an empty string lang = ''
.
The difference between the verbatim
and asis
engine is that the former will put the content in a fenced code block, and the latter just output the content as-is.
You can also display a file verbatim by using the chunk option file
, e.g.,
```{verbatim, file="test.Rmd"}
```
This engine also works for other types of documents (e.g., Rnw
) but it will not allow for nested code chunks within the verbatim
code chunk.
Added a new engine named embed
to embed external plain-text files. It is essentially a simple wrapper based on the verbatim
engine, with the chunk content read from an external file and default language guessed from file extension. That is,
```{embed, file="foo.R"}
```
is equivalent to
```{verbatim, file="foo.R", lang="r"}
```
If you provide the chunk option file
to the embed
engine, it will read the file and show its content verbatim in the output document. Alternatively, you can specify the file path in the chunk body, e.g.,
```{embed}
"foo.txt"
```
The quotes are optional but can be helpful for editors (e.g., RStudio IDE) to autocomplete the file paths.
The syntax highlighting language name is from the filename extension by default, and you can override it with the chunk option lang
(e.g., file = "foo.sh", lang = "bash"
) which is then identical to the verbatim
engine.
The chunk option child
also respects the package option root.dir
now (thanks, @salim-b, https://community.rstudio.com/t/117563).
Fixed a LaTeX error "Package xcolor Error: Undefined color `fgcolor'"
with .Rnw
documents (thanks, Kurt Hornik).
"````{r}"
(four backticks) but the closing fence is "```"
(three backticks---should also be four to match the opening fence), or the opening fence is indented " ```{r}"
but the closing fence is not "```"
. Note that this warning message may become an error in the future, i.e., unbalanced chunk delimiters will no longer be allowed.