rmarkdown
rmarkdown copied to clipboard
`rmarkdown::render` fails when code chunks contain `sink(...)`
Context
I am writing a package that implements a standardized logging function using sink(...)
. I would like to be able to use RMarkdown to write the vignettes for the package.
Issue
Code chunks containing sink(...)
commands do not sink if not followed in the same ~~line~~ expression by a sink()
command closing the new connection. This is due to evaluate
's use of sink()
to capture output. See issue opened with evaluate
: https://github.com/r-lib/evaluate/issues/104
See also this relevant Stack Overflow issue: https://stackoverflow.com/questions/39131017/sink-wont-print-output-to-text-file-in-rmarkdown
Proposed resolution
One option would be to modify the evaluate
package so that these conditions throw an error and then have rmarkdown
handle that error with either a warning to the user or by executing the sink(...)
statement with eval()
.
Alternately rmarkdown
could identify offending statements separately.
Reprex
Submit the following Rmd file via rmarkdown::render()
or by clicking the "knit" button in Rstudio:
---
title: "Untitled"
output: html_document
---
# Log `sessionInfo()`
```{r}
log_path <- file.path(tempdir(), 'temp.log')
sink(log_path)
print(sessionInfo())
sink()
```
# Did it work?
```{r}
readLines(log_path)
```
The final line will indicate that the log was empty and sink(...)
failed: ## character(0)
In contrast, if you run the chunks interactively with the Rstudio "Run chunk" commands, the log contains the expected output of sessionInfo()
.
xfun::sessionInfo()
R version 4.1.2 (2021-11-01) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 19043), RStudio 2021.9.0.351
Locale: LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252 LC_NUMERIC=C LC_TIME=English_United States.1252
Package version: base64enc_0.1.3 bslib_0.3.1 compiler_4.1.2 digest_0.6.28 evaluate_0.14 fastmap_1.1.0
fs_1.5.0 glue_1.4.2 graphics_4.1.2 grDevices_4.1.2 highr_0.9 htmltools_0.5.2 jquerylib_0.1.4 jsonlite_1.7.2 knitr_1.36 magrittr_2.0.1 methods_4.1.2 R6_2.5.1
rappdirs_0.3.3 rlang_0.4.12 rmarkdown_2.11.3 rstudioapi_0.13 sass_0.4.0 stats_4.1.2
stringi_1.7.5 stringr_1.4.0 tinytex_0.35 tools_4.1.2 utils_4.1.2 xfun_0.27
yaml_2.2.1
Checklist
When filing a bug report, please check the boxes below to confirm that you have provided us with the information we need. Have you:
-
[X] formatted your issue so it is easier for us to read?
-
[X] included a minimal, self-contained, and reproducible example?
-
[X] pasted the output from
xfun::session_info('rmarkdown')
in your issue? -
[X] upgraded all your packages to their latest versions (including your versions of R, the RStudio IDE, and relevant R packages)?
-
[X] installed and tested your bug with the development version of the rmarkdown package using
remotes::install_github("rstudio/rmarkdown")
?
Would someone be able to triage this?
Try curly braces around your code block.
---
title: "Untitled"
output: html_document
---
# Log `sessionInfo()`
```{r}
{
log_path <- file.path(tempdir(), 'temp.log')
sink(log_path)
print(sessionInfo())
sink()
}
```
# Did it work?
```{r}
readLines(log_path)
```
@dschmidt-hgu Thank you for the suggestion. It does indeed correct the issue in the reproducible example I provided. Unfortunately it does not address the underlying issue:
Code chunks containing sink(...) commands do not sink if not followed in the same line by a sink() command closing the new connection.
By wrapping the statement in curly braces we are simply reducing multiple lines to a single expression, with the same effect as if we had included the closing sink()
statement in the same line following a semicolon. So perhaps we should modify the issue to read:
Code chunks containing sink(...) commands do not sink if not followed in the same ~~line~~ expression by a sink() command closing the new connection.